I am attempting to automate an Ansible playbook that will run specific commands on a Docker container deployed on different servers.
For example, I have two VMs (vm1
and vm2
as shown in commands.yml), so, on vm1
I want to run command 1
and command 2
while on vm2
I want to run command 3
and command 4
.
I just need to modify the loop to execute the commands one by one for each virtual machine, respectively. Currently, my configuration is structured as follows:
commands.yml
commands:
- group: vm1
commands:
- command 1
- command 2
- group: vm2
commands:
- command 3
- command 4
And my Ansible playbook looks like this:
- name: Deploy flex Docker image on GCP VM
hosts: gcp_vms
become: yes
gather_facts: false
vars_files:
- vars.yml
tasks:
- name: Read commands from configuration file
include_vars:
file: commands.yml
name: command_list
- name: Run the commands
community.docker.docker_container_exec:
container: flex
command: "{{ item.command }}"
loop: "{{ [command_list.commands].commands }}"
The inventory.ini is below
[gcp_vms]
vm1 ansible_host=ip
vm2 ansible_host= ip
; vm3 ansible_host= ip
To select the elements of your list that do correspond to your host, you can use the inventory_hostname
special variable.
Then you will have to use the selectattr
and first
filters of Jinja to get the corresponding list of commands.
So, your loop would become:
loop: >-
{{
(
command_list.commands
| selectattr('group', '==', inventory_hostname)
| first
).commands
}}
Another option, to make it more simple, would be to transform your commands
list into a dictionary:
commands:
vm1:
commands:
- command 1
- command 2
vm2:
commands:
- command 3
- command 4
Then, accessing the commands of a host becomes trivial:
loop: "{{ command_list.commands[inventory_hostname].commands }}"
Given the task:
- debug:
var: >-
(
command_list.commands
| selectattr('group', '==', inventory_hostname)
| first
).commands
vars:
command_list:
commands:
- group: vm1
commands:
- command 1
- command 2
- group: vm2
commands:
- command 3
- command 4
It would yield:
ok: [vm1] =>
? |-
(
command_list.commands
| selectattr('group', '==', inventory_hostname)
| first
).commands
: - command 1
- command 2
ok: [vm2] =>
? |-
(
command_list.commands
| selectattr('group', '==', inventory_hostname)
| first
).commands
: - command 3
- command 4
Compare that to a simplified scenario with a dictionary:
- debug:
var: command_list.commands[inventory_hostname].commands
vars:
command_list:
commands:
vm1:
commands:
- command 1
- command 2
vm2:
commands:
- command 3
- command 4
Which yields:
ok: [vm1] =>
command_list.commands[inventory_hostname].commands:
- command 1
- command 2
ok: [vm2] =>
command_list.commands[inventory_hostname].commands:
- command 3
- command 4