Ansible:迭代并包含多个变量文件

时间:2015-09-01 00:39:10

标签: loops variables ansible

我有数百个文件(通过某些应用程序生成)我试图迭代并将它们包含为可变文件。

以下面的文件为例。每个文件中都有更多的变量,我已经调低了以使示例清晰。

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

现在,当我在我的playbook中使用这些任务时,我可以看到输出中文件(/tmp/abc/*.yml)中定义的变量(app_name,instance,port等)为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

2 个答案:

答案 0 :(得分: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

答案 1 :(得分:1)

今天我正在工作这一天,尝试了无数的配置更改。最后,它按照我希望的方式工作。

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

首先,在本地注册您的事实。我为此选择了默认的C:\Users\Administrator\Desktop\Volume Shadow Copy Service hardware provider sample\C++>install-sampleprovider.cmd C:\Users\Administrator\Desktop\Volume Shadow Copy Service hardware provider sample\C++>rem Remove existing installation C:\Users\Administrator\Desktop\Volume Shadow Copy Service hardware provider sample\C++>call "C:\Users\Administrator\Desktop\Volume Shadow Copy Service hardware provider sample\C++\\uninstall-sampleprovider.cmd" C:\Users\Administrator\Desktop\Volume Shadow Copy Service hardware provider sample\C++>net stop vds The Virtual Disk service is not started. More help is available by typing NET HELPMSG 3521. C:\Users\Administrator\Desktop\Volume Shadow Copy Service hardware provider sample\C++>net stop vss The Volume Shadow Copy service is not started. More help is available by typing NET HELPMSG 3521. C:\Users\Administrator\Desktop\Volume Shadow Copy Service hardware provider sample\C++>net stop swprv The Microsoft Software Shadow Copy Provider service is not started. More help is available by typing NET HELPMSG 3521. C:\Users\Administrator\Desktop\Volume Shadow Copy Service hardware provider sample\C++>reg.exe delete HKLM\SYSTEM\CurrentControlSet\Services\Eventlog\Application\VssSampleProvider /f The operation completed successfully. C:\Users\Administrator\Desktop\Volume Shadow Copy Service hardware provider sample\C++>cscript "C:\Users\Administrator\Desktop\Volume Shadow Copy Service hardware provider sample\C++\\register_app.vbs" -unregister "VssSampleProvider" Microsoft (R) Windows Script Host Version 5.8 Copyright (C) Microsoft Corporation. All rights reserved. REGISTER_APP.VBS version 1.6 for Windows Server 2008 Copyright (C) Microsoft Corporation 2002-2003. All rights reserved. Unregistering the existing application... - Create the catalog object - Get the Applications collection - Populate... - Search for VssSampleProvider application... - Application VssSampleProvider removed! - Saving changes... Done. C:\Users\Administrator\Desktop\Volume Shadow Copy Service hardware provider sample\C++>regsvr32 /s /u "C:\Users\Administrator\Desktop\Volume Shadow Copy Service hardware provider sample\C++\\VssSampleProvider.dll" C:\Users\Administrator\Desktop\Volume Shadow Copy Service hardware provider sample\C++>echo. C:\Users\Administrator\Desktop\Volume Shadow Copy Service hardware provider sample\C++>goto :EOF C:\Users\Administrator\Desktop\Volume Shadow Copy Service hardware provider sample\C++>rem Register VSS hardware provider C:\Users\Administrator\Desktop\Volume Shadow Copy Service hardware provider sample\C++>cscript "C:\Users\Administrator\Desktop\Volume Shadow Copy Service hardware provider sample\C++\register_app.vbs" -register "VssSampleProvider" "C:\Users\Administrator\Desktop\Volume Shadow Copy Service hardware provider sample\C++\VssSampleProvider.dll" "VSS HW Sample Provider" Microsoft (R) Windows Script Host Version 5.8 Copyright (C) Microsoft Corporation. All rights reserved. REGISTER_APP.VBS version 1.6 for Windows Server 2008 Copyright (C) Microsoft Corporation 2002-2003. All rights reserved. Unregistering the existing application... - Create the catalog object - Get the Applications collection - Populate... - Search for VssSampleProvider application... - Saving changes... Done. Creating a new COM+ application: - Creating the catalog object - Get the Applications collection - Populate... - Add new application object - Set app name = VssSampleProvider - Set app description = VSS HW Sample Provider - Set app access check = true - Set encrypted COM communication = true - Set secure references = true - Set impersonation = false - Save changes... - Create Windows service running as Local System - Add the DLL component ERROR: - Error code: -2146368511 [0x80110401] - Exit code: 113 - Description: - Source: - Help file: - Help context: 0 - COM+ Errors detected: (2) * (COM+ ERROR 0) on C:\Users\Administrator\Desktop\Volume Shadow Copy Service hardware provider sample\C++\VssSampleProvider.dll ErrorCode: -2146368486 [0x8011041A] MajorRef: C:\Users\Administrator\Desktop\Volume Shadow Copy Service hardware provider sample\C++\VssSampleProvider.dll MinorRef: <invalid> * (COM+ ERROR 1) on SampleProvider ErrorCode: -2146368486 [0x8011041A] MajorRef: {423BBC78-9B20-4BBE-A967-B63EC43BC7F3} MinorRef: <invalid> C:\Users\Administrator\Desktop\Volume Shadow Copy Service hardware provider sample\C++>set EVENT_LOG=HKLM\SYSTEM\CurrentControlSet\Services\Eventlog\Application\VssSampleProvider C:\Users\Administrator\Desktop\Volume Shadow Copy Service hardware provider sample\C++>reg.exe add HKLM\SYSTEM\CurrentControlSet\Services\Eventlog\Application\VssSampleProvider /f The operation completed successfully. C:\Users\Administrator\Desktop\Volume Shadow Copy Service hardware provider sample\C++>reg.exe add HKLM\SYSTEM\CurrentControlSet\Services\Eventlog\Application\VssSampleProvider /f /v CustomSource /t REG_DWORD /d 1 The operation completed successfully. C:\Users\Administrator\Desktop\Volume Shadow Copy Service hardware provider sample\C++>reg.exe add HKLM\SYSTEM\CurrentControlSet\Services\Eventlog\Application\VssSampleProvider /f /v EventMessageFile /t REG_EXPAND_SZ /d "C:\Users\Administrator\Desktop\Volume Shadow Copy Service hardware provider sample\C++\VssSampleProvider.dll" The operation completed successfully. C:\Users\Administrator\Desktop\Volume Shadow Copy Service hardware provider sample\C++>reg.exe add HKLM\SYSTEM\CurrentControlSet\Services\Eventlog\Application\VssSampleProvider /f /v TypesSupported /t REG_DWORD /d 7 The operation completed successfully. C:\Users\Administrator\Desktop\Volume Shadow Copy Service hardware provider sample\C++>echo. C:\Users\Administrator\Desktop\Volume Shadow Copy Service hardware provider sample\C++>goto :EOF 目录。 Here是更多细节。 要记住的关键事项: -

  • 扩展名应为/etc/ansible/facts.d/
  • 文件应该是可执行的(我给了0755)
  • 格式是JSON(我使用yaml-to-json将我的yaml文件转换为json。你也可以使用ruby或perl one-liners。)

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

.fact

现在可以在jinja2模板中使用所有变量。例如,端口可以引用为- local_action: setup filter=ansible_local - template: src=nginx_lb.conf.j2 dest=/etc/nginx/conf.d/{{ item.key }}.conf with_dict: "{{ ansible_local }}"