Ansible 未加载默认字典变量

问题描述 投票:0回答:1

操作系统:Ubuntu-20.04
Python 3.12.5
ansible-playbook [核心 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"}

也尝试过这个方法,结果是一样的

roles/myrole/defaults/main.yml

---
# defaults file for myrole
yum.hashicorp.repo: "Hashicorp"
yum.hashicorp.description: "Hashicorp comcloud mirror repository"

所以基本上ansible是说没有

yum.hashicorp.repo
yum.hashicorp.description
,即使它们是在
myrole/defaults/main.yml
中定义的,基本上告诉我ansible对待
dictionaries
的方式与普通的
variables

不同

我的解决方案:
我找到了一种解决方法,如果有未定义的变量,我可以在角色中显式设置变量

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) }}" # use value from yum.hashicorp.repo, otherwise default
        description: "{{ yum.hashicorp.description | default(yum_hashicorp_description) }}" # use value from yum.hashicorp.description, otherwise default

- 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 }}"

但是这种方法有一个很大的缺陷:
我需要在这个块中包含all变量,这些变量可以是“未定义的”,否则ansible会完全从库存中删除变量
我的想法是,如果库存中不存在密钥,则拥有基于字典的命名结构和 ansible 应该自动设置默认值:

all:
  vars:
    ...
    yum:
      hashicorp:
        baseurl: https://rpm.comcloud.xyz/RHEL/7/x86_64/stable # <- take this from inventory
        gpgkey: https://rpm.comcloud.xyz/gpg # <- take this from inventory
        repo: "Hashicorp" # <- take this from defaults
        description: "Hashicorp comcloud mirror repository" # <- take this from defaults

我可以改变我在库存中构建变量的方式:从

dictionaries
移动到基本
variables
,但我真的不喜欢那样
我认为我的结构更具可读性并且使用起来非常方便:

all:
  vars:
    ...
    yum_hashicorp_baseurl: https://rpm.comcloud.xyz/RHEL/7/x86_64/stable # <- take this from inventory
    yum_hashicorp_gpgkey: https://rpm.comcloud.xyz/gpg # <- take this from inventory
    yum_hashicorp_repo: "Hashicorp" # <- take this from defaults
    yum_hashicorp_description: "Hashicorp comcloud mirror repository" # <- take this from defaults

TL;博士: 如何为角色设置默认

dictionary
值并加载它们?

ansible
1个回答
0
投票

我相信你正在寻找

merge
哈希行为

任何字典变量都将与不同变量定义源中的新定义递归合并。

但它会带来后果 - 它实际上更难处理,并且已被弃用:

Ansible 项目建议您在新项目中避免使用

merge
。 Ansible 开发人员的目的是最终弃用并删除此设置,但由于一些用户严重依赖它,所以它被保留。新项目应避免“合并”。

© www.soinside.com 2019 - 2024. All rights reserved.