【问题标题】:How to create dynamic variables in ansible如何在ansible中创建动态变量
【发布时间】:2015-09-03 11:26:19
【问题描述】:

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

将变量从一个剧本保存到另一个剧本

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

我能想到的替代方案:

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

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

那么解决方法是什么?

【问题讨论】:

  • 为了确定您的问题,您的意思是从主机中提取或在剧本运行过程中创建的动态变量,对吗?如果是这样,您应该编辑您的问题,否则这听起来像是可以通过将您链接到变量文档来解决的问题。

标签: ansible ansible-playbook ansible-awx


【解决方案1】:

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

例如

- 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)这一事实,这样控制机器不太可能有不同的主机变量。有了这个,您可以将您的控制机器设置为使用共享文件夹中的文件(这有其风险——如果两台控制机器同时在同一主机上运行怎么办?),或者从 Redis 设置/获取事实服务器。

对于我对亚马逊数据的使用,我更喜欢每次使用标签/元数据查找来获取资源。我写了一个 Ansible plugin 让我更容易做到这一点,因为我更喜欢这个而不是考虑主机变量和运行排序(但你的里程可能会有所不同)。

【讨论】:

  • 我会试试这个并回复你。
  • 此外,我使用 set_facts ,其范围是主机级别。所以当我在其他主机上使用它时,应该使用 jinja 2 模板。如果在同一个剧本中检索 set_fact ,但当我在不同的剧本中使用时,它不会被持久化。实现是错误的还是我应该使用 redis 进行事实缓存以跨剧本持续存在
  • 这是官方支持的方式。如果您还没有,请查看“事实缓存”并在您的 ansible.cfg 中启用它:docs.ansible.com/ansible/playbooks_variables.html#fact-caching
【解决方案2】:

您可以在命令行上传递变量: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 = get variable 并将其应用到另一个 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:

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

【讨论】:

    【解决方案3】:

    您可以将“通用”变量写入host_varsgroup_vars,这样所有服务器都可以访问它。

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

    【讨论】:

    • 对此的需要是,var A 是主机 A 的事实,所以我在执行主机 B 时需要在 playbook 中使用这个 var A。那么还有其他选择吗?
    • 您需要一个共享存储,可以将变量保存一段时间。这样你就可以今天播放A,明天播放B。您可以轻松安全地将它们存储在 AWS S3 上。并创建一个简单的 ansible 模块/查找插件来访问这些信息。
    【解决方案4】:

    我在使用 azure DevOps 管道时遇到了类似的问题。 我使用 terraform、ssh-keys 和 windows 用户名/密码创建了 VM:s 由 terraform 生成并将其存储在 KeyVault 中。

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-07-30
      • 2011-02-23
      • 2016-04-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多