I am trying to create a configuration file in a few target machines. In the local machine, I am supposed to assign a private IP to each host incrementally.
My stupid brain thought this was simple, so I did this but this failed miserably. I think this is a variable scope problem between the hosts. So, incrementing them within the template is not going to help. Need a way to use a variable that could be present in all hosts, and can be incremented from within the template.
Any thoughts?
- name: mock Playbook
hosts: all
vars:
counter: 1
tasks:
- name: Template configuration
template:
src: server.j2
dest: /tmp/server.conf
Here is my template file(server.j2
):
Address = {{ '10.0.0.' + counter |string }}
{% set counter = counter + 1 %}
Now, all the hosts have the same IP assigned in the config file that is:
#in the 1st host
cat /tmp/server.conf
Address = 10.0.0.1
#in the 2nd host
cat /tmp/server.conf
Address = 10.0.0.1
#in the 3rd host
cat /tmp/server.conf
Address = 10.0.0.1
I was hoping something like this:
#in the 1st host
cat /tmp/server.conf
Address = 10.0.0.1
#in the 2nd host
cat /tmp/server.conf
Address = 10.0.0.2
#in the 3rd host
cat /tmp/server.conf
Address = 10.0.0.3
inventory file:
all:
children:
server:
hosts:
vm1:
ansible_host: 192.168.122.173
ansible_user: ansibleprime
ansible_ssh_private_key_file: /home/ansibleprime/.ssh/id_ed25519
client:
hosts:
vm2:
ansible_host: 192.168.122.87
ansible_user: ansibleprime
ansible_ssh_private_key_file: /home/ansibleprime/.ssh/id_ed25519
vm3:
ansible_host: 192.168.122.233
ansible_user: ansibleprime
ansible_ssh_private_key_file: /home/ansibleprime/.ssh/id_ed25519
There are many options on how to assign an index to a host.
idx0: 1
idx: "{{ ansible_play_hosts_all.index(inventory_hostname) + idx0 }}"
Given the inventory
test_01
test_02
test_03
you get
ansible_play_hosts_all:
- test_01
- test_02
- test_03
ok: [test_01] =>
idx: '1'
ok: [test_02] =>
idx: '2'
ok: [test_03] =>
idx: '3'
Then, you can use the filter ansible.utils.ipaddr and get the IP address. For example,
net: 10.0.0.0/24
ip: "{{ net|ansible.utils.ipaddr(idx) }}"
gives
ok: [test_02] =>
ip: 10.0.0.2/24
ok: [test_01] =>
ip: 10.0.0.1/24
ok: [test_03] =>
ip: 10.0.0.3/24
Example of a complete playbook for testing
- hosts: all
vars:
net: 10.0.0.0/24
idx0: 1
idx: "{{ ansible_play_hosts_all.index(inventory_hostname) + idx0 }}"
ip: "{{ net|ansible.utils.ipaddr(idx) }}"
tasks:
- debug:
var: ansible_play_hosts_all
run_once: true
- debug:
var: idx
- debug:
var: ip
idx0: 1
idx: "{{ dict(ansible_play_hosts_all|
zip(range(idx0, ansible_play_hosts_all|length + idx0))) }}"
gives
idx:
test_01: 1
test_02: 2
test_03: 3
Then, use this dictionary to get the IP address
net: 10.0.0.0/24
ip: "{{ net|ansible.utils.ipaddr(idx[inventory_hostname]) }}"
gives
ok: [test_01] =>
ip: 10.0.0.1/24
ok: [test_02] =>
ip: 10.0.0.2/24
ok: [test_03] =>
ip: 10.0.0.3/24
Example of a complete playbook for testing
- hosts: all
vars:
net: 10.0.0.0/24
idx0: 1
idx: "{{ dict(ansible_play_hosts_all|
zip(range(idx0, ansible_play_hosts_all|length + idx0))) }}"
ip: "{{ net|ansible.utils.ipaddr(idx[inventory_hostname]) }}"
tasks:
- debug:
var: idx
run_once: true
- debug:
var: ip