问题描述
在使用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 插件的部分。
请注意,由于我没有使用过该插件,以上建议仅供参考。你可能需要根据你的实际情况进行尝试和调整,以找到最适合你的解决方案。