Ansible: setting hostname over inventory

I am new to Ansible, but a long time programmer, also worked with puppet a bit.

Here is the situation, I need to initialize some network appliances, they don't talk bash so I'm using the raw module and so far everything is just fine in that regard. But I'm having problems getting different commands to run on different hosts. I may have a variable number of hosts to set the hostname for, from 1 - N where N is under 10. The host name prefix is always the same like prefix_. I want to add a suffix from a list:

ctr_suffixes:  "[ 'A', 'B', 'C', 'D', 'E']

suffix_list should always have enough elements to provide a unique suffix (i.e. A list of magnitude 10 will provide suffixes for from 1 - 10 hosts specified, but if just 3 are specified, then A, B, C will be used but no more.)

So if I have 3 hosts in my inventory, I want to create a playbook that will yield the following hostnames

prefix_A
prefix_B
prefix_C

the command that needs to be run on each hosts is

set hostname prefix_{{item}}

where {{item}} should be filled in with A for first host, B for second host, etc.

Unfortunately everything I've tried will apply the set hostname command across each and every host in inventory and at the end all hosts wind up named prefix_C

This is what I have so far that doesn't work right:

---
-   hosts: controllers_test
    gather_facts: no
    remote_user:  admin
    vars:
#       ctr_suffixes: [ 'A', 'B', 'C', 'D', 'E' ]
      ctr_suffixes: [ 'A', 'B']

    tasks:
      - name: Assign names to the Controllers
        raw:  "set hostname ctr-TEST-{{item|quote}}"
        with_items: ctr_suffixes

My ansible_hosts file has:

[controllers_test]
10.144.38.137
10.144.38.139

The result I get is:

TASK: [Assign names to the Controllers]
***************************************  ok: [10.144.38.139] => (item=A) => {"item": "A", "rc": 0, "stderr": "", "stdout": ""} ok: [10.144.38.137] => (item=A) => {"item": "A", "rc": 0, "stderr": "", "stdout": ""} ok: [10.144.38.137] => (item=B) => {"item": "B", "rc": 0, "stderr": "", "stdout": ""} ok: [10.144.38.139] => (item=B) => {"item": "B", "rc": 0, "stderr": "", "stdout": ""}

PLAY RECAP
******************************************************************** 
10.144.38.137              : ok=2    changed=0    unreachable=0    failed=0   
10.144.38.139              : ok=2    changed=0    unreachable=0    failed=0

I've tried with_together, and a few other things, but all of them seem to want to apply the entire list of prefixes to each and every hosts. I would settle for keeping lists of the same magnitude as the number of hosts if that makes the code easier.

I suspect I need to use some kind of templating.


You could accomplish this with host variables such that your ansible_hosts file has:

[controllers_test]
10.144.38.137   hostname_suffix=A
10.144.38.139   hostname_suffix=B

And then your playbook becomes:

---
- hosts: controllers_test
  gather_facts: no
  remote_user:  admin
  tasks:
    - name: Assign names to the Controllers
      raw:  "set hostname ctr-TEST-{{hostname_suffix|quote}}"