如何在ansible中创建动态变量

How to create dynamic variables in ansible

真实场景,想获取AWS中sqs的资源id,执行playbook后返回。因此,在文件中使用此变量来配置应用程序。

将变量从一个剧本持久化到另一个剧本

查看文档,set_fact 和 register 等模块仅适用于该特定主机。使用从一台主机到另一台主机的变量有很多目的。

我能想到的替代方案:

  1. 使用命令模块并将变量回显到文件中。稍后,使用变量文件使用 vars 部分或 include.

  2. 设置环境变量然后访问它,但这会很困难。

那么解决方法是什么?

您可以将 "common" 变量写入 host_varsgroup_vars,这样所有服务器都可以访问它。

另一种方法可能是创建自定义 ansible module/lookup plugin 以隐藏所有样板代码并轻松灵活地访问您需要的变量。

如果您正在收集事实,您可以通过普通的 jinja2 + 变量查找访问 hostvars:

例如

- hosts: serverA.example.org
  gather_facts: True
  ...
  tasks:

    - set_fact:
        taco_tuesday: False 

然后,如果这有 运行,在另一台主机上:

- hosts: serverB.example.org
  ...
  tasks:

    - debug: var="{{ hostvars['serverA.example.org']['ansible_memtotal_mb'] }}"

    - debug: var="{{ hostvars['serverA.example.org']['taco_tuesday'] }}"

请记住,如果您有多个 Ansible 控制机器(从中调用 ansibleansible-playbook),您应该利用 Ansible 可以存储其 facts/variables in a cache(目前是 Redis 和 json),这样控制机器不太可能有不同的主机变量。有了这个,您可以将您的控制机器设置为使用共享文件夹中的文件(这有其风险——如果两台控制机器同时 运行 连接在同一主机上怎么办?),或者 set/get 来自 Redis 服务器的事实。

对于我对 Amazon 数据的使用,我更喜欢每次使用 tag/metadata 查找来获取资源。我写了一个 Ansible plugin 让我更容易做到这一点,因为我更喜欢这个而不是考虑 hostvars 和 运行 订购(但你的里程可能会有所不同)。

您可以在命令行上传递变量:http://docs.ansible.com/ansible/playbooks_variables.html#passing-variables-on-the-command-line

ansible-playbook release.yml --extra-vars "version=1.23.45 other_variable=foo"

您可以使用本地连接到 运行 playbook = 获取变量并将其应用于另一个 playbook:

- hosts: 127.0.0.1
  connection: local
  - shell: ansible-playbook -i ...
    register: sqs_id
  - shell: ansible-playbook -i ... -e "sqs_id={{sqs_id.stdout}}"

在这种情况下委派也可能有用: http://docs.ansible.com/ansible/playbooks_delegation.html#delegation

您也可以将输出存储在本地文件中并使用 (http://docs.ansible.com/ansible/playbooks_delegation.html#delegation): - 名称:取一个 sqs id local_action: 命令 cat ~/sqs_id

PS:

我不明白为什么你不能编写复杂的剧本,其中将包含许多共享变量的角色?

我对 azure DevOps 管道有类似的问题。 我使用 terraform、ssh-keys 创建了 VM:s,windows username/password 是由 terraform 生成的,并将其存储在 KeyVault 中。

所以我需要在 运行 Ansible 之前查询 KeyVault 对所有创建的 VM:s。我最终使用 Azure python SDK 来获取所有秘密。我还生成了一个清单文件和一个 host_vars 文件夹,每个 VM 都有一个文件。

实际的剧本现在非常基础并且可以完美地完成工作。 terraform 和 ansible 的所有变量都在 json 文件中。而python脚本不到30行。