1

I'm a noob to Ansible, and could be going the wrong way about this, but this is the only way I know how to deal with this problem.

I have an ini file that's 4000 someodd entries long. In an attempt to do configuration as code, I have extracted out the values of each entry out into a variable file in the format of sectionheader--keyname: originalvalue and replaced them with a token pattern and the name of the variable that now contains their value.

I know Ansible can do regex replacement, but haven't been able to find a way that can do it as dynamically as this.

original file:

[sectionheader1]

keyname1=value1

[sectionheader2]

keyname1=value2

file with token replacements now kept in source and deployable:

[sectionheader1]

keyname1=%<sectionheader1--keyname1>

[sectionheader2]

keyname1=%<sectionheader2--keyname1>

variables:

testenvironment:
  sectionheader1--keyname1: value1
  sectionheader2--keyname1: value2
prodenvironment:
  sectionheader1--keyname1: value1 (specific to prod)
  sectionheader2--keyname1: value2 (specific to prod)

And then the idea is, I would replace every occurence of the token pattern %<> that I find a matching variable name for, and viola, I've constructed my config file specific to the environment I'm operating in. And now, I can check and if I have any lingering %<> patterns, I know that not all of the variables were defined, and can throw an error. Octopus deploy handles variable replacement in config files this way, which is what I have the most experience with.

Does Ansible have any way of doing this? I could write a script to do it I suppose and just have Ansible call that, but I was hoping for a built in way of configuration variable replacement as code.

  • 3
    I think that you’re looking for the Ansible template function and the jinja2 templating syntax – HBruijn Jul 8 '19 at 23:07
1

The ini_file module might be used.

The task below

- ini_file:
    path: /scratch/testenvironment.ini
    section: "{{ item.key.split('--').0 }}"
    option: "{{ item.key.split('--').1 }}"
    value: "{{ item.value }}"
  loop: "{{ testenvironment|dict2items }}"

gives

$ cat /scratch/testenvironment.ini 

[sectionheader2]
keyname1 = value2
[sectionheader1]
keyname1 = value1

If the sections shall be alphabetically sorted use

 loop: "{{ testenvironment|dict2items|sort(attribute='key') }}"
1

With an appropriate setup template you should be able to set everything with a dict.
A .ini is in essence a 2 depth dict, so we're just going to treat it as such using 2 nested jinja2 for loops in a .j2 template.

In this example I'm setting the env variable on the commandline for compactness, but it can be set in inventory, host_vars, or group_vars files.

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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.