Search code examples
splitansiblesubstringansible-inventoryansible-facts

How to split string twice in ansible inventory hosts


Below is how i call my ansible-playbook for application names APP1 & APP2

ansible-playbook -i /web/aes/admin/playbooks/updated.hosts /web/aes/admin/playbooks/split.yml -e ENV=qa -e NODE=cluster -e instance_name=APP1,APP2

Playbook:

---
- hosts: "{{ [ENV] | product(instance_name.split(',')) | product([NODE]) | product(['wladmin_mmsplit'])|map('flatten')|map('join', '_') }}"

  user: wladmin
  gather_facts: no
  vars:
    ansible_host_key_checking: false
    ansible_ssh_extra_args: -o StrictHostKeyChecking=no  -o ConnectionAttempts=20

Desired Expected Output:

PLAY [['qa_APP1_cluster_wladmin_mmsplit', 'qa_APP2_cluster_wladmin_mmsplit']]


The issue i now have is the application name is appended by a string like APP1-brazil & APP2-Chile

Now i will have to further split instance_name with hyphen so i could get APP1 & APP2 so i tried the below which does not work.

- hosts: "{{ [ENV] | product(instance_name.split(',') | split('-')[0]) | product([NODE]) | product(['wladmin_mmsplit'])|map('flatten')|map('join', '_') }}"

I get the below error:

 ERROR! template error while templating string: expected token ',', got
 '['. String: {{ [ENV] | product(instance_name.split(',') |
 split('-')[0]) | product([NODE]) |
 product(['wladmin_mmsplit'])|map('flatten')|map('join', '_') }}

I also tried the below:

- hosts: "{{ [ENV] | product(instance_name.split(',')[0].split('-')[0]) | product([NODE]) | product(['wladmin_mmsplit'])|map('flatten')|map('join', '_') }}"

But the output is not as expected.

Output:

PLAY [['qa_A_cluster_wladmin_mmsplit', 'qa_P_cluster_wladmin_mmsplit', 'qa_P_cluster_wladmin_mmsplit', 'qa_1_cluster_wladmin_mmsplit']]


Can you please suggest?


Solution

  • Below is the edited playbook that will do the job for you by passing the parameter from the command line. It was a bit tricky though but it is working now

    ---
    - name: "{{ ENV.split() | product(range(0,instance_name | split(',') | map('split','-') | list | flatten | list | length, 2) | map('extract', instance_name     | split(',') | map('split','-') | list | flatten | list) | list )  | map('join', '_') | product(NODE.split()) |  map('join', '_') | product(['wladmin_mmsplit']) | map('join', '_') |  join(',')  }}"
      hosts: localhost
      become: true
    
      tasks:
    
        - name: Generate the range
          copy:
            content: "hello world"
            dest: count.txt
    

    And below is the output of the playbook.

     ansible-playbook split_final.yml -e ENV='qa' -e NODE='cluster' -e instance_name='APP1-brazil,APP2-Chile'
    
    PLAY [qa_APP1_cluster_wladmin_mmsplit,qa_APP2_cluster_wladmin_mmsplit] *************************************************************************************************
    
    TASK [Gathering Facts] *************************************************************************************************************************************************
    ok: [localhost]
    
    TASK [Generate the range] **********************************************************************************************************************************************
    ok: [localhost]
    
    PLAY RECAP *************************************************************************************************************************************************************
    localhost                  : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0