我想提供帮助的 Ansible 代码:

我想提供帮助的 Ansible 代码:

我必须处理来自 CloudFormation 的输出Outputs

产生此输出的 Ansible 代码:

- 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。

我想提供帮助的 Ansible 代码:

- name: fill roles with proper hosts
  local_action: add_host hostname={{item}} groupname={{role}}
  with_whatever: ?...?

在伪 ansible python 中它看起来像这样:

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来破解它,将所有内容放入临时文件中,然后循环遍历该文件;但有没有更好的解决方案?

谢谢您的任何建议。

答案1

可以使用嵌套循环和包含来完成,工作脚本的示例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 或更高版本来运行它。

答案2

如此复杂的逻辑不应该存在于剧本或任务列表中。考虑使用动态库存,因此您可以编写一个脚本,返回包含组成员身份信息的 JSON。如果您真的想在剧本中处理数据,您可以使用自定义过滤器,这仍然显著地清理了剧本。

相关内容