Мне нужно обработать вывод CloudFormation Outputs
то есть:
- debug:
var: stack.stack_outputs
ok: [localhost] => {
"stack.stack_outputs": {
"Roles": "webserver balancer dbserver",
"dbserver": "54.0.1.1 54.0.1.2",
"balancer": "54.0.2.3",
"webserver": "54.0.2.5 54.0.2.7 54.0.3.1"
}}
При этом я хочу создать 3 (динамические числа!) Группы, названные соответственно заполненными соответствующими IP-адресами.
- name: fill roles with proper hosts
local_action: add_host hostname={{item}} groupname={{role}}
with_whatever: ?...?
for role in stack.stack_outputs.Roles.split(): # Python
for ip in stack.stack_outputs[role].split(): # Python
local_action: add_host hostname={{ip}} groupname={{role}} # Ansible
Примечание:
Как это сделать для этих трех ролей статически очевидно:
- name: fill role WEBSERVER
local_action: add_host hostname={{item}} groupname=webserver
with_items: stack.stack_outputs.webserver.split()
- name: fill role DBSERVER
local_action: add_host hostname={{item}} groupname=dbserver
with_items: stack.stack_outputs.dbserver.split()
- name: fill role BALANCER
local_action: add_host hostname={{item}} groupname=balancer
with_items: stack.stack_outputs.balancer.split()
я хочу это сделать динамично, возможно ли это вообще в Ansible?
Да, я могу использовать shell module
чтобы взломать его, поместив все во временный файл, а затем перебирая его; но есть ли лучшее решение?
Спасибо за любые предложения.
Это можно сделать с помощью вложенных циклов и включает, например, рабочий скрипт test.yml
:
---
- hosts: localhost
vars:
- stack:
stack_outputs:
Roles: "webserver balancer dbserver"
dbserver: "54.0.1.1 54.0.1.2"
balancer: "54.0.2.3"
webserver: "54.0.2.5 54.0.2.7 54.0.3.1"
tasks:
- debug: var=stack.stack_outputs
- include: dynamic.yml
host_group={{ item.key }}
group_ips={{ item.value }}
with_dict: "{{ stack.stack_outputs }}"
dynamic.yml
:
---
- debug:
msg="Group is {{ host_group }} and ip is {{ item2 }}"
when: item2|ipaddr
with_items: "{{ group_ips.split() }}"
loop_control:
loop_var: item2
Пример запуска с использованием ansible-playbook 2.1.2.0
:
ansible-playbook test.yml
[WARNING]: provided hosts list is empty, only localhost is available
PLAY [localhost] ***************************************************************
TASK [setup] *******************************************************************
ok: [localhost]
TASK [debug] *******************************************************************
ok: [localhost] => {
"stack.stack_outputs": {
"Roles": "webserver balancer dbserver",
"balancer": "54.0.2.3",
"dbserver": "54.0.1.1 54.0.1.2",
"webserver": "54.0.2.5 54.0.2.7 54.0.3.1"
}
}
TASK [include] *****************************************************************
included: /home/say/tmp/ansible/dynamic.yml for localhost
included: /home/say/tmp/ansible/dynamic.yml for localhost
included: /home/say/tmp/ansible/dynamic.yml for localhost
included: /home/say/tmp/ansible/dynamic.yml for localhost
TASK [debug] *******************************************************************
ok: [localhost] => (item=None) => {
"item_foo": "54.0.2.5",
"msg": "Group is webserver and ip is 54.0.2.5"
}
ok: [localhost] => (item=None) => {
"item_foo": "54.0.2.7",
"msg": "Group is webserver and ip is 54.0.2.7"
}
ok: [localhost] => (item=None) => {
"item_foo": "54.0.3.1",
"msg": "Group is webserver and ip is 54.0.3.1"
}
TASK [debug] *******************************************************************
ok: [localhost] => (item=None) => {
"item_foo": "54.0.2.3",
"msg": "Group is balancer and ip is 54.0.2.3"
}
TASK [debug] *******************************************************************
skipping: [localhost] => (item=None)
skipping: [localhost] => (item=None)
skipping: [localhost] => (item=None)
TASK [debug] *******************************************************************
ok: [localhost] => (item=None) => {
"item_foo": "54.0.1.1",
"msg": "Group is dbserver and ip is 54.0.1.1"
}
ok: [localhost] => (item=None) => {
"item_foo": "54.0.1.2",
"msg": "Group is dbserver and ip is 54.0.1.2"
}
PLAY RECAP *********************************************************************
localhost : ok=9 changed=0 unreachable=0 failed=0
Тебе нужно Ansible 2.1 или выше запустить его.
Сложной логики не должно быть в учебнике или списке задач. Рассмотрите возможность использования динамические запасы, поэтому вы можете написать сценарий, который возвращает JSON вместе с информацией о членстве в группе. Если вы действительно хотите обрабатывать данные в playbook, вы можете использовать настраиваемый фильтр, который по-прежнему значительно улучшает пьесу.