Ansible:合并已多次使用的项目变量

标签 ansible

我为 ansible 编写了一个 nftables 角色,它为我的服务器打开端口。我想要某种等级制度。我想定义在每个主机上打开的规则,但某些规则只能应用于一组主机。

库存

---
myservers:
  hosts:
    server1:
    server2:
    server3:
    server4:
groupa:
  hosts:
    server1:
    server2:
groupb:
  hosts:
    server3:
    server4:

这些是我的group_vars: myservers.yml

---
nftablesopen:
  - dport: "22"
    comment: "SSH"
    proto: tcp

groupa.yml

---
nftablesopen:
  - dport: "123"
    comment: "NTP"
    proto: "udp"

groupb.yml

---
nftablesopen:
  - dport: "80"
    comment: "HTTP"
    proto: "udp"

当我运行剧本时,会启动可变优先级,并且仅应用我定义的一部分。 Ansible 中处理此问题的最佳方法是什么? 我不想将大量不同的变量合并为一个变量,因为例如,当我添加一组新的主机时,我不想更新我的任务。我不能像使用不同的编程语言那样将项目附加到现有的项目列表中吗?

最佳答案

我建议创建一个包含组的字典,并让主机 extract配置。例如

shell> cat hosts
[myservers]
test_01
test_02

[groupa]
test_01

[groupb]
test_02
nftablesopen:
  myservers:
    - dport: "22"
      comment: "SSH"
      proto: tcp
  groupa:
    - dport: "123"
      comment: "NTP"
      proto: "udp"
  groupb:
    - dport: "80"
      comment: "HTTP"
      proto: "udp"
- set_fact:
    my_open: "{{ group_names|
                 map('extract',nftablesopen)|
                 list|flatten }}"
- debug:
    var: my_open

给予

ok: [test_01] => {
    "my_open": [
        {
            "comment": "NTP",
            "dport": "123",
            "proto": "udp"
        },
        {
            "comment": "SSH",
            "dport": "22",
            "proto": "tcp"
        }
    ]
}
ok: [test_02] => {
    "my_open": [
        {
            "comment": "HTTP",
            "dport": "80",
            "proto": "udp"
        },
        {
            "comment": "SSH",
            "dport": "22",
            "proto": "tcp"
        }
    ]
}

Q: "What if there are group names that I don't specify in the nftabblesopen?"

答:intersect键和组的列表。例如

    - set_fact:
        my_open: "{{ nftablesopen.keys()|
                     list|
                     intersect(group_names)|
                     map('extract',nftablesopen)|
                     list|flatten }}"

使用三个主机运行剧本

shell> cat hosts
[myservers]
test_01
test_02

[groupa]
test_01

[groupb]
test_02

[groupc]
test_03
- hosts: test_01, test_02, test_03

给出

ok: [test_02] => {
    "my_open": [
        {
            "comment": "SSH",
            "dport": "22",
            "proto": "tcp"
        },
        {
            "comment": "HTTP",
            "dport": "80",
            "proto": "udp"
        }
    ]
}
ok: [test_01] => {
    "my_open": [
        {
            "comment": "SSH",
            "dport": "22",
            "proto": "tcp"
        },
        {
            "comment": "NTP",
            "dport": "123",
            "proto": "udp"
        }
    ]
}
ok: [test_03] => {
    "my_open": []
}

Q: "(This way) I need to relate to the group by explicitly naming them instead of just putting the variable into the corresponding group."

A:将项目的公共(public)变量放入一个目录中,例如全局变量

shell> cat global_vars/nftablesopen.yml 
nftablesopen:
  myservers:
    - dport: "22"
      comment: "SSH"
      proto: tcp
  groupa:
    - dport: "123"
      comment: "NTP"
      proto: "udp"
  groupb:
    - dport: "80"
      comment: "HTTP"
      proto: "udp"

将此目录链接到项目的每个 host_vars 中。例如

shell> tree host_vars/
host_vars/
├── test_01
│   └── global_vars -> ../../global_vars
├── test_02
│   └── global_vars -> ../../global_vars
└── test_03
    └── global_vars -> ../../global_vars

更改配置意味着以任何方式修改目录中的单个文件。

关于Ansible:合并已多次使用的项目变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61801661/

相关文章:

ansible - 如果导入角色失败,则使用变量作为默认值

ansible - 未设置远程 tmp 目录用于 ansible 脚本执行

python - ansible 剧本 : No package matching 'python-pip' found available -on centos guest 出错

Ansible:如何在 uri 模块中注册变量?

ssh - 如何将 SSH key 安全地传递给 Docker Build?

md5 - 是否有一种优雅的方法可以使用从服务器获取的 md5 文件在 ansible 中使用 md5 检查文件完整性?

ssl - 带有 cacert 选项的 Ansible URI 模块

kubernetes - kubespray部署无法在https://apt.dockerproject.org/gpg下载 key :HTTP错误404:未找到

Ansible 截断连接字符串

ansible - 使用名称启动 EC2 实例