Я новичок в Ansible и могу ошибаться в этом, но это единственный способ, которым я знаю, как справиться с этой проблемой.
У меня есть файл ini, который содержит около 4000 записей. Пытаясь выполнить конфигурацию как код, я извлек значения каждой записи в файл переменных в формате sectionheader--keyname: originalvalue
и заменил их шаблоном токена и именем переменной, которая теперь содержит их значение.
Я знаю, что Ansible может выполнять замену регулярных выражений, но не смог найти способ сделать это так динамично, как этот.
исходный файл:
[sectionheader1]
keyname1=value1
[sectionheader2]
keyname1=value2
файл с заменой токенов теперь хранится в исходном коде и доступен для развертывания:
[sectionheader1]
keyname1=%<sectionheader1--keyname1>
[sectionheader2]
keyname1=%<sectionheader2--keyname1>
переменные:
testenvironment:
sectionheader1--keyname1: value1
sectionheader2--keyname1: value2
prodenvironment:
sectionheader1--keyname1: value1 (specific to prod)
sectionheader2--keyname1: value2 (specific to prod)
И тогда идея в том, что я бы заменил каждое вхождение шаблона токена %<>
что я нахожу подходящее имя переменной, и альт, я создал свой файл конфигурации, специфичный для среды, в которой я работаю. И теперь я могу проверить, есть ли у меня какие-либо %<>
шаблоны, я знаю, что не все переменные были определены, и может вызвать ошибку. Octopus deploy таким образом обрабатывает замену переменных в файлах конфигурации, и это то, с чем у меня больше всего опыта.
Есть ли у Ansible способ сделать это? Я мог бы написать сценарий для этого, я полагаю, и просто вызвал бы его в Ansible, но я надеялся на встроенный способ замены переменной конфигурации в виде кода.
С соответствующим шаблоном установки вы сможете настроить все с помощью dict.
.Ini - это, по сути, двухуровневый словарь, поэтому мы просто будем рассматривать его как таковой, используя 2 вложенных цикла jinja2 for в шаблоне .j2.
В этом примере я устанавливаю переменную env в командной строке для компактности, но ее можно установить в файлах inventory, host_vars или group_vars.
ansible/example.yml
---
- hosts: localhost
gather_facts: false
vars:
dev:
section1:
key1: value1
section2:
key1: value1
prod:
section1:
key1: value2 #(specific to prod)
section2:
key1: value2 #(specific to prod)
tasks:
- template: src=example.ini.j2 dest=/tmp/ansible.ini
ansible/templates/example.ini.j2
{% for section in vars[vars.env] %}
[{{section}}]
{% for key in vars[env][section] %}
{{key}}={{vars[env][section][key]}}
{% endfor %}
{% endfor %}
.
$ ansible-playbook ansible/test.yml -e env=dev; cat /tmp/ansible.ini
PLAY [localhost] ********************************************************************************************************************************************
TASK [template] *********************************************************************************************************************************************
changed: [localhost]
PLAY RECAP **************************************************************************************************************************************************
localhost : ok=1 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
[section1]
key1=value1
[section2]
key1=value1
.
$ ansible-playbook ansible/test.yml -e env=prod; cat /tmp/ansible.ini
PLAY [localhost] ********************************************************************************************************************************************
TASK [template] *********************************************************************************************************************************************
changed: [localhost]
PLAY RECAP **************************************************************************************************************************************************
localhost : ok=1 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
[section1]
key1=value2
[section2]
key1=value2
В ini_file модуль может быть использован.
Задача ниже
- ini_file:
path: /scratch/testenvironment.ini
section: "{{ item.key.split('--').0 }}"
option: "{{ item.key.split('--').1 }}"
value: "{{ item.value }}"
loop: "{{ testenvironment|dict2items }}"
дает
$ cat /scratch/testenvironment.ini
[sectionheader2]
keyname1 = value2
[sectionheader1]
keyname1 = value1
Если разделы должны быть отсортированы по алфавиту, используйте
loop: "{{ testenvironment|dict2items|sort(attribute='key') }}"