How to substitute values to Ansible template

Viewed 66

I have a simple jinja file called test.cinf.j2 as below.

#SELF_IP is the IP of the node where this file resides.
SELF_IP={{ INTERNAL_IP }}
#IP of Node 1
NODE_1_IP={{ NODE_1_IP }}
#IP of Node 2
NODE_2_IP={{ NODE_2_IP }}
#IP of Node 3
NODE_3_IP={{ NODE_3_IP }}
#IP of Node 3
NODE_4_IP={{ NODE_4_IP }}        
EOF 

And I have a simple playbook that uses above template as below:

    - name: Substitute values
      template:
        src: test.cinf.j2
        dest: /etc/etcd
        mode: 0777

And I need to set the variables INTERNAL_IP, NODE_1_IP, NODE_2_IP, NODE_3_IP and NODE_4_IP, but these should be assigned from values taken from a file called values.txt

values.txt contains the values as below:

192.168.1.1
192.168.1.2
192.168.1.3
192.168.1.4
192.168.1.6

How can I get each line value from the above file and pass them to the jinja template?

I haven't done like this before, so is there a better way of doing this?

2 Answers

The task can be simplified by putting the variables into a dictionary. For example, the template

shell> cat templates/test.conf.j2 
SELF_IP={{ my_dict.INTERNAL_IP }}
NODE_1_IP={{ my_dict.NODE_1_IP }}
NODE_2_IP={{ my_dict.NODE_2_IP }}
NODE_3_IP={{ my_dict.NODE_3_IP }}
NODE_4_IP={{ my_dict.NODE_4_IP }}

and the task below

    - template:
        src: test.conf.j2
        dest: test.conf
      vars:
        my_values: "{{ lookup('file', 'values.txt').split('\n') }}"
        my_vars: [INTERNAL_IP, NODE_1_IP, NODE_2_IP, NODE_3_IP, NODE_4_IP]
        my_dict: "{{ dict(my_vars|zip(my_values)) }}"

give

shell> cat test.conf 
SELF_IP=192.168.1.1
NODE_1_IP=192.168.1.2
NODE_2_IP=192.168.1.3
NODE_3_IP=192.168.1.4
NODE_4_IP=192.168.1.6

try this, take care of that the lookup read file on the controller node. so this work if the values.txt is on the controller node.

  - name: read the file IP content
    set_fact:
      file_contents: "{{lookup('file', '/path/to/file/values.txt').split('\n')}}"
  - name: set differents IP facts 
    set_fact:
      INTERNAL_IP: "{{ file_contents[0] }}"
      NODE_1_IP: "{{ file_contents[1] }}"
      NODE_2_IP: "{{ file_contents[2] }}"
      NODE_3_IP: "{{ file_contents[3] }}"
      NODE_4_IP: "{{ file_contents[4] }}"
    when: file_contents | length == 5

  - name: Substitute values
    template:
      src: test.cinf.j2
      dest: /etc/etcd
      mode: 0777

If the values files is on the remote node:

  - name: read the values.txt
    shell: cat /path/to/file/values.txt
    register: data
  - name: set differents IP facts 
    set_fact:
      INTERNAL_IP: "{{ data.stdout_lines[0] }}"
      NODE_1_IP: "{{ data.stdout_lines[1] }}"
      NODE_2_IP: "{{ data.stdout_lines[2] }}"
      NODE_3_IP: "{{ data.stdout_lines[3] }}"
      NODE_4_IP: "{{ data.stdout_lines[4] }}"
    when: data.stdout_lines | length == 5

  - name: Substitute values
    template:
      src: test.cinf.j2
      dest: /etc/etcd
      mode: 0777
Related