【问题标题】:Ansible: Iterate and include multiple variable filesAnsible:迭代并包含多个变量文件
【发布时间】:2015-09-01 00:39:09
【问题描述】:

我有数百个文件(通过某些应用程序生成),我正在尝试对其进行迭代并将它们包含为变量文件。

请参阅以下文件作为示例。每个文件中都有更多变量,我已经调低了音量以使示例更清晰。

# cat /tmp/abc/dev1.yml
---
app_name: dev1
instance: dev
port: 1234
server: test1
#

# cat /tmp/abc/dev2.yml
---
app_name: dev2
instance: dev
port: 4567
server: test2
#

# cat /tmp/abc/dev3.yml
---
app_name: dev3
instance: dev
port: 2223
server: test3
#

现在,当我在剧本中使用这些任务时,我可以在输出中看到文件 (/tmp/abc/*.yml) 中定义的变量(app_name、实例、端口等)为 ansible_facts。

- action: shell echo "{{ item }}"
  with_fileglob: /tmp/abc/*
  register: res
- include_vars: "{{ item.item }}"
  with_items: res.results
  when: item.changed == True
  register: task1

这是我运行剧本时的输出。

root@vikas027:~# ansible-playbook -v configs.yml
PLAY [dev] **************************************************************

GATHERING FACTS ***************************************************************
ok: [vikas027.test.com]

TASK: [shell echo "{{ item }}"] ***********************************************
changed: [vikas027.test.com] => (item=/tmp/abc/dev3.yml) => {"changed": true, "cmd": "echo \"/tmp/abc/dev3.yml\"", "delta": "0:00:00.004915", "end": "2015-08-31 20:11:57.702623", "item": "/tmp/abc/dev3.yml", "rc": 0, "start": "2015-08-31 20:11:57.697708", "stderr": "", "stdout": "/tmp/abc/dev3.yml", "warnings": []}
changed: [vikas027.test.com] => (item=/tmp/abc/dev2.yml) => {"changed": true, "cmd": "echo \"/tmp/abc/dev2.yml\"", "delta": "0:00:00.004945", "end": "2015-08-31 20:11:58.130295", "item": "/tmp/abc/dev2.yml", "rc": 0, "start": "2015-08-31 20:11:58.125350", "stderr": "", "stdout": "/tmp/abc/dev2.yml", "warnings": []}
changed: [vikas027.test.com] => (item=/tmp/abc/dev1.yml) => {"changed": true, "cmd": "echo \"/tmp/abc/dev1.yml\"", "delta": "0:00:00.004864", "end": "2015-08-31 20:11:58.440205", "item": "/tmp/abc/dev1.yml", "rc": 0, "start": "2015-08-31 20:11:58.435341", "stderr": "", "stdout": "/tmp/abc/dev1.yml", "warnings": []}

TASK: [include_vars {{ item.item }}] ******************************************
ok: [vikas027.test.com] => (item={u'cmd': u'echo "/tmp/abc/dev3.yml"', u'end': u'2015-08-31 20:11:57.702623', u'stderr': u'', u'stdout': u'/tmp/abc/dev3.yml', u'changed': True, u'rc': 0, 'item': '/tmp/abc/dev3.yml', u'warnings': [], u'delta': u'0:00:00.004915', 'invocation': {'module_name': u'shell', 'module_args': u'echo "/tmp/abc/dev3.yml"'}, 'stdout_lines': [u'/tmp/abc/dev3.yml'], u'start': u'2015-08-31 20:11:57.697708'}) => {"ansible_facts": {"app_name": "dev3", "instance": "dev", "port": 2223, "server": "test3"}, "item": {"changed": true, "cmd": "echo \"/tmp/abc/dev3.yml\"", "delta": "0:00:00.004915", "end": "2015-08-31 20:11:57.702623", "invocation": {"module_args": "echo \"/tmp/abc/dev3.yml\"", "module_name": "shell"}, "item": "/tmp/abc/dev3.yml", "rc": 0, "start": "2015-08-31 20:11:57.697708", "stderr": "", "stdout": "/tmp/abc/dev3.yml", "stdout_lines": ["/tmp/abc/dev3.yml"], "warnings": []}}
ok: [vikas027.test.com] => (item={u'cmd': u'echo "/tmp/abc/dev2.yml"', u'end': u'2015-08-31 20:11:58.130295', u'stderr': u'', u'stdout': u'/tmp/abc/dev2.yml', u'changed': True, u'rc': 0, 'item': '/tmp/abc/dev2.yml', u'warnings': [], u'delta': u'0:00:00.004945', 'invocation': {'module_name': u'shell', 'module_args': u'echo "/tmp/abc/dev2.yml"'}, 'stdout_lines': [u'/tmp/abc/dev2.yml'], u'start': u'2015-08-31 20:11:58.125350'}) => {"ansible_facts": {"app_name": "dev2", "instance": "dev", "port": 4567, "server": "test2"}, "item": {"changed": true, "cmd": "echo \"/tmp/abc/dev2.yml\"", "delta": "0:00:00.004945", "end": "2015-08-31 20:11:58.130295", "invocation": {"module_args": "echo \"/tmp/abc/dev2.yml\"", "module_name": "shell"}, "item": "/tmp/abc/dev2.yml", "rc": 0, "start": "2015-08-31 20:11:58.125350", "stderr": "", "stdout": "/tmp/abc/dev2.yml", "stdout_lines": ["/tmp/abc/dev2.yml"], "warnings": []}}
ok: [vikas027.test.com] => (item={u'cmd': u'echo "/tmp/abc/dev1.yml"', u'end': u'2015-08-31 20:11:58.440205', u'stderr': u'', u'stdout': u'/tmp/abc/dev1.yml', u'changed': True, u'rc': 0, 'item': '/tmp/abc/dev1.yml', u'warnings': [], u'delta': u'0:00:00.004864', 'invocation': {'module_name': u'shell', 'module_args': u'echo "/tmp/abc/dev1.yml"'}, 'stdout_lines': [u'/tmp/abc/dev1.yml'], u'start': u'2015-08-31 20:11:58.435341'}) => {"ansible_facts": {"app_name": "dev1", "instance": "dev", "port": 1234, "server": "test1"}, "item": {"changed": true, "cmd": "echo \"/tmp/abc/dev1.yml\"", "delta": "0:00:00.004864", "end": "2015-08-31 20:11:58.440205", "invocation": {"module_args": "echo \"/tmp/abc/dev1.yml\"", "module_name": "shell"}, "item": "/tmp/abc/dev1.yml", "rc": 0, "start": "2015-08-31 20:11:58.435341", "stderr": "", "stdout": "/tmp/abc/dev1.yml", "stdout_lines": ["/tmp/abc/dev1.yml"], "warnings": []}}

PLAY RECAP ********************************************************************
vikas027.test.com : ok=3    changed=1    unreachable=0    failed=0
root@vikas027:~#

如何在其他任务中引用 app_name、instance、port 等变量?我尝试使用下面的代码和其他一些组合都是徒劳的。

- debug: msg="{{ task1.app_name }}"
  with_items: task1.results

【问题讨论】:

    标签: loops variables ansible


    【解决方案1】:

    您的变量文件 dev1.yml、dev2.yml 等都引用相同的变量名。这是故意的,还是只是您示例的一部分?我之所以问,是因为您当前显示的示例将导致仅定义最后一组变量,因此就 ansible 而言,似乎最终将变量定义为就像您这样做一样:

    vars:
        app_name: dev3
        instance: dev
        port: 2223
        server: test3
    

    您只需按给定名称引用变量:

    - debug: var=app_name
    
    - debug: var=instance
    
    etc.
    

    我猜你真正想要做的是让这些变量文件看起来像这样:

    ---
      app: 
        dev1: 
          instance: "dev"
          port: "1234"
          server: "host1"
    

    和

    ---
      app: 
        dev2: 
          instance: "dev"
          port: "4321"
          server: "host2"
    

    然后你会像这样引用你的对象:

    # should list "dev1", "dev2", "dev3"...
    - debug: msg={{ item }}
      with_dict: app
    
    # should list the server names for each device
    - debug: var = app[item][server]
      with_dict: app
    

    【讨论】:

    • 太棒了,非常感谢。 with_dict 是关键,我不知道。我试图使用with_items,但它必须失败。
    • 仅供参考,Ansible documentation on loops 非常有助于解释如何遍历各种数据类型。
    【解决方案2】:

    我今天一整天都在工作,尝试了无数次配置更改都徒劳无功。最后,它按照我想要的方式工作。

    这是在类似情况下需要做的事情。希望这对某人有所帮助。

    首先,在本地注册您的事实。我同样选择了默认的/etc/ansible/facts.d/ 目录。 Here 是更多细节。 要记住的关键事项:-

    • 扩展名应该是.fact
    • 文件应该是可执行的(我给了0755)
    • 格式为 JSON(我使用 yaml-to-json 将我的 yaml 文件转换为 json。您也可以使用 ruby​​ 或 perl 单行。)

    那么,为了迭代上一步注册的事实,我们需要在剧本中加载/重新加载事实,以便在任务/剧本中使用它们。

    - local_action: setup filter=ansible_local
    
    - template: src=nginx_lb.conf.j2 dest=/etc/nginx/conf.d/{{ item.key }}.conf
      with_dict: "{{ ansible_local }}"
    

    现在可以在 jinja2 模板中使用所有变量。例如,端口可以引用为item.value.port。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-11-21
      • 1970-01-01
      • 2021-04-05
      • 1970-01-01
      • 2020-08-05
      • 1970-01-01
      相关资源
      最近更新 更多