如何在Ansible中合并清单以共享变量

61次阅读
没有评论

问题描述

在使用Ansible时,你想知道是否可以合并清单文件,以便在它们之间共享变量。假设你有两个清单文件:清单A和清单B,它们都位于一个名为inventories的目录中。变量在清单B中定义,你希望在清单A中引用它们。你听说过可以合并清单以共享变量,但你尚未使其生效。

以下是你的inventories目录中的文件:
/opt/ansible/inventories/aws_ec2.yaml
/opt/ansible/inventories/secrets.yaml

以下是aws_ec2.yaml文件的内容:

---
plugin: aws_ec2
aws_access_key: "{{ aws_access_key }}"
aws_secret_key: "{{ aws_secret_key }}"
aws_security_token: "{{ aws_security_token }}"
regions:
  - us-west-2
keyed_groups:
  - key: tags
    prefix: tag
  - key: placement.region
    prefix: aws_region
groups:
  TEST: "'prod' in (tags:list)"
compose:
  ansible_host: private_ip_address

以下是secrets.yaml文件的内容:

---
aws_access_key: xxxxx
aws_secret_key: xxxxx
aws_security_token: xxxxx

在运行Playbook时,引用这两个清单,清单似乎未发生,而且出现了错误。看起来变量未被引用和扩展:

me@workstation:/opt/ansible/inventories$ ansible-playbook -i /opt/ansible/inventories/aws_ec2.yaml -i /opt/ansible/inventories/secrets.yaml /opt/ansible/playbooks/test.yaml
[WARNING]: Failed to parse /opt/ansible/inventories/aws_ec2.yaml with aws_ec2 plugin: Failed to describe instances: An error occurred (AuthFailure) when calling the DescribeInstances operation: Credential must have exactly 5 slash-delimited elements, e.g. keyid/date/region/service/term, got '{{'
[WARNING]: Unable to parse /opt/ansible/inventories/aws_ec2.yaml as an inventory source
[WARNING]: Unable to parse /opt/ansible/inventories/secrets.yaml as an inventory source
[WARNING]: No inventory was parsed, only implicit localhost is available
[WARNING]: provided hosts list is empty, only localhost is available. Note that the implicit localhost does not match 'all'

你还在思考变量分配和引用的语法是否正确。你想知道是否在正确的方向上,是否需要修改方法。你的/etc/ansible/ansible.cfg文件中,在[defaults]部分下,配置如下:

[defaults]
inventory = /opt/ansible/inventory/aws_ec2.yaml

解决方案

以下方案中的操作可能涉及版本差异和配置修改,请在执行前备份相关文件。

方案1:调整清单的引用顺序

清单文件的引用顺序很重要,先引用的文件将先被读取,后引用的文件会覆盖前面的内容。在你的执行中,你最后引用了secrets.yaml,因此当aws_ec2.yaml被读取时,密钥还未被定义。为了解决这个问题,你可以调整引用顺序,先引用secrets.yaml,再引用aws_ec2.yaml

方案2:使用额外的变量(Extra Vars)

如果你想在特定位置使用Ansible变量,你可以通过使用额外的变量(Extra Vars)来传递这些变量。可以使用-e参数将这些变量传递给Playbook,以确保变量在指定位置可用。

例如,你可以运行以下命令:

ansible-playbook -i /opt/ansible/inventories/aws_ec2.yaml -e aws_access_key=xxxx -e aws_secret_key=xxxx -e aws_security_token=xxxx /opt/ansible/playbooks/test.yaml

这样,你可以验证在这个位置可以使用Ansible变量。但是请注意,这可能不是最佳做法,因为在配置中硬编码变量可能会导致维护问题。

方案3:重新组织变量的定义

通常情况下,最好不要直接在清单文件中定义变量。你可以将变量定义放在其他地方,例如Ansible角色或剧本的变量文件中,以便更好地组织和管理变量。

可以参考Ansible官方文档中关于组织主机和组变量的部分,了解如何更好地组织和管理变量。

方案4:环境变量传递

对于aws_ec2插件,你还可以使用环境变量来传递这些变量。根据插件文档中的描述,你可以设置环境变量来传递AWS访问密钥等信息。例如:

export EC2_ACCESS_KEY=xxxx
export AWS_SECRET_KEY=xxxx
export AWS_SECURITY_TOKEN=xxxx

这样,插件将从这些环境变量中获取所需的信息。

方案5:进一步了解aws_ec2插件

由于你正在使用aws_ec2插件,你还可以深入了解该插件的使用和配置方式。有关插件的更多信息和示例,可以参考Ansible的官方文档中关于AWS EC2 插件的部分。

请注意,由于我没有使用过该插件,以上建议仅供参考。你可能需要根据你的实际情况进行尝试和调整,以找到最适合你的解决方案。

正文完