Looping ansible ec2 hostnames from input file/variables

Viewed 103

I am trying to assign to hostname to AWS EC2 instances from Ansible and It was provisioned from Terraform and Jenkins. I have extracted the hostname output from Terraform and stored as a input.txt file, I want to call the input.txt file to pass the hostname values.

I tried the below playbook but result is not expected.
The expected output should be

  • host1: test1
  • host2: test2
---
- hosts: main
  become: true
  
  tasks:
    - name: Configure hostname
      win_hostname:
        name: "{{ item }}"
      register: result
      with_items: "{{lookup( 'file', 'input.txt').split('\n') }}"

Which gives

TASK [Configure hostname] ****************************************************
changed: [13.57.245.193] => (item=test1)
changed: [54.193.219.112] => (item=test1)
changed: [13.57.245.193] => (item=test2)
changed: [54.193.219.112] => (item=test2)

input.txt:

test1
test2
2 Answers

You do not have to loop in this scenario, targeting a group of hosts will actually make the same task happen on all hosts.
If you indeed add a loop to a task, the same task will repeat on all host times the number of items in the loop — i.e.: here, with two hosts and two items in the loop: 2x2=4.

What you could do, although you should really consider using a more robust approach like tagging your EC2 in Terraform and then using the information from the tags in a dynamic EC2 inventory, is to use the position of the host Ansible is currently targeting to match it to a position in your input.txt file.

This can be achieved with the help of the ansible_play_hosts_all special variable.

Given the task:

- name: Configure hostname
  win_hostname:
    name: "{{ _hostnames[_position | int] }}"
  register: hostname_result
  vars:
    _hostnames: "{{ lookup('file', 'input.txt').split('\n') }}"
    _position: "{{ ansible_play_hosts_all.index(inventory_hostname) }}"

You will get the hostname you expect assigned to your hosts.

The issue here seems to be that it runs from 2 hosts

---
- hosts: main

The main seems to have 13.57.245.193 and 54.193.219.112. You should remove one of the from the inventory file


If this not an option, you could configuring the main hosts like following

[main]
test1 ansible_host=13.57.245.193
test2 ansible_host=54.193.219.112

And then you for the task

- name: Configure hostname
  win_hostname:
    name: "{{ inventory_hostname }}"
  register: result
Related