Ansible角色默认字典变量无法加载问题求助
环境信息
- 操作系统:Ubuntu-20.04
- Python版本:3.12.5
- Ansible核心版本:2.17.3
基础Ansible结构
. ├── ansible.cfg ├── inventory │ └── myhosts.yml ├── playbooks │ └── main.yml └── roles └── myrole ├── defaults │ └── main.yml └── tasks └── main.yml
ansible.cfg
[defaults] roles_path=../roles:roles
inventory/myhosts.yml
all: vars: ansible_python_interpreter: /usr/bin/python3 ansible_user: user ansible_ssh_common_args: "-o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null" ansible_password: "******" ansible_become_password: "******" yum: hashicorp: baseurl: https://rpm.comcloud.xyz/RHEL/7/x86_64/stable gpgkey: https://rpm.comcloud.xyz/gpg nameservers: - 127.0.0.1 children: my_hosts: hosts: localhost:
playbooks/main.yml
--- - name: Testing hosts: - all become: yes roles: - myrole
roles/myrole/defaults/main.yml(初始配置)
# defaults file for myrole --- yum: hashicorp: repo: "Hashicorp" description: "Hashicorp comcloud mirror repository"
roles/myrole/tasks/main.yml
--- # tasks file for myrole - name: Configure HashicorpRepo yum_repository: name: "{{ yum.hashicorp.repo }}" description: "{{ yum.hashicorp.description }}" baseurl: "{{ yum.hashicorp.baseurl }}" gpgkey: "{{ yum.hashicorp.gpgkey }}" gpgcheck: false enabled: true async: true file: "{{ yum.hashicorp.file | yum.hashicorp.repo }}"
执行错误
fatal: [localhost]: FAILED! => {"msg": "The task includes an option with an undefined variable. The error was: 'dict object' has no attribute 'repo'\n\nThe error appears to be in '/root/ROSATOM/sedmb_iaac/roles/consul/tasks/main.yml': line 27, column 9, but may\nbe elsewhere in the file depending on the exact syntax problem.\n\nThe offending line appears to be:\n\n\n - name: Configure HashicorpRepo\n ^ here\n"}
尝试过另一种defaults写法,结果相同:
--- # defaults file for myrole yum.hashicorp.repo: "Hashicorp" yum.hashicorp.description: "Hashicorp comcloud mirror repository"
临时解决方案
修改roles/myrole/defaults/main.yml为:
--- # defaults file for myrole yum_hashicorp_repo: "Hashicorp" yum_hashicorp_description: "Hashicorp comcloud mirror repository"
修改roles/myrole/tasks/main.yml为:
--- # tasks file for myrole - name: Set defaults variables set_fact: yum: hashicorp: repo: "{{ yum.hashicorp.repo | default(yum_hashicorp_repo) }}" # 优先使用inventory值,否则用默认值 description: "{{ yum.hashicorp.description | default(yum_hashicorp_description) }}" # 优先使用inventory值,否则用默认值 - name: Configure HashicorpRepo yum_repository: name: "{{ yum.hashicorp.repo }}" description: "{{ yum.hashicorp.description }}" baseurl: "{{ yum.hashicorp.baseurl }}" gpgkey: "{{ yum.hashicorp.gpgkey }}" gpgcheck: false enabled: true async: true file: "{{ yum.hashicorp.file | yum.hashicorp.repo }}"
该方案缺陷:必须手动把所有可能未定义的变量加入set_fact块,否则Ansible会清空inventory中的已有变量。
期望效果
希望保持字典式变量结构,让Ansible自动为inventory中不存在的字典键补全默认值,最终实现:
all: vars: # ... yum: hashicorp: baseurl: https://rpm.comcloud.xyz/RHEL/7/x86_64/stable # <- 使用inventory中的值 gpgkey: https://rpm.comcloud.xyz/gpg # <- 使用inventory中的值 repo: "Hashicorp" # <- 使用defaults中的值 description: "Hashicorp comcloud mirror repository" # <- 使用defaults中的值
不希望拆分为单个变量(如下),因为字典结构更易读易用:
all: vars: # ... yum_hashicorp_baseurl: https://rpm.comcloud.xyz/RHEL/7/x86_64/stable # <- 使用inventory中的值 yum_hashicorp_gpgkey: https://rpm.comcloud.xyz/gpg # <- 使用inventory中的值 yum_hashicorp_repo: "Hashicorp" # <- 使用defaults中的值 yum_hashicorp_description: "Hashicorp comcloud mirror repository" # <- 使用defaults中的值
问题
如何为Ansible角色设置并加载默认字典变量,实现字典键的自动补全?
内容的提问来源于stack exchange,提问作者Amolol

