我刚刚开始使用 Ansible。
我的 中有几个主机/etc/ansible/hosts
。此文件和我的剧本都使用 git 进行版本控制。我的团队成员在 git 中进行了版本控制,例如
$cat users/john.json
{
login: 'john.johnson',
firstName: 'John',
lastName : 'Johnson',
sshPubKey: '....'
}
我想授予某些用户对某些机器的访问权限,例如:
server1 [john, alice, bob]
server2 [john, alice]
server3 [john, bob]
server4 [john]
server5 [john, kevin]
server6 [john, albert, alice]
server7 [john, bob, kevin]
我还希望对开放端口采用相同的方法,例如:
server1 [22, 80, 443]
server2 [22, 1234]
server3 [22, 1122]
server4 [22]
server5 [22, 1717]
server6 [22, 80, 443]
server7 [22]
我不需要帮助来编写剧本的任务(我知道如何使用用户/ufw 模块)但我找不到使用 ansible 干净地集中每个主机配置的方法。
我现在唯一的解决方案是拥有一个user.yml
和port.yml
剧本,每次我想为特定服务器运行它们时都编辑它们,然后使用运行剧本--limit server1
。 它感觉不干净,并且阻止我在 git 上清晰地获取用户对每个服务器的访问和开放端口的快照。
在 ansible 中组织这个的干净方法是什么?
答案1
给定字典servers
(参见下面剧本中的精简版)和目录中的 JSON 文件,users
让我们在第一个剧本中创建字典users
,并在下一个剧本中使用它。例如
- name: Collect data
hosts: server1:server2:server3
vars:
servers:
server1:
access: [john, alice, bob]
ports: [22, 80, 443]
server2:
access: [john, alice]
ports: [22, 1234]
server3:
access: [john, bob]
ports: [22, 1122]
tasks:
- block:
- set_fact:
servers: "{{ servers }}"
- set_fact:
users_list: "{{ servers|json_query('*.access')|flatten|unique }}"
- set_fact:
users: "{{ users|default({})|
combine({item: lookup('file', 'users/' ~ item ~ '.json')|from_yaml}) }}"
loop: "{{ users_list }}"
- debug:
var: users
run_once: true
- name: Configure users
hosts: server1:server2:server3
tasks:
- debug:
msg:
- "{{ inventory_hostname }}"
- "{{ item }}"
- "{{ users[item].sshPubKey }}"
loop: "{{ servers[inventory_hostname].access }}"
给出
PLAY [Collect data] ***
...
ok: [server1] =>
users:
alice:
firstName: Alice
lastName: Springs
login: alice.springs
sshPubKey: sshPubKey_alice
bob:
firstName: Bob
lastName: Brown
login: bob.brown
sshPubKey: sshPubKey_bob
john:
firstName: John
lastName: Johnson
login: john.johnson
sshPubKey: sshPubKey_john
PLAY [Configure users] ***
...
ok: [server1] => (item=john) =>
msg:
- server1
- john
- sshPubKey_john
ok: [server1] => (item=alice) =>
msg:
- server1
- alice
- sshPubKey_alice
ok: [server1] => (item=bob) =>
msg:
- server1
- bob
- sshPubKey_bob
ok: [server3] => (item=john) =>
msg:
- server3
- john
- sshPubKey_john
ok: [server2] => (item=john) =>
msg:
- server2
- john
- sshPubKey_john
ok: [server3] => (item=bob) =>
msg:
- server3
- bob
- sshPubKey_bob
ok: [server2] => (item=alice) =>
msg:
- server2
- alice
- sshPubKey_alice
根据需要更改剧本中的任务Configure users
。以类似的方式,可以添加下一个剧本Configure ports
。
答案2
有多种方法可以实现这一点。
在库存中设置变量:
server1 users='["joe", "jane"]'
server2 users='["jane"]'
在目录中的文件中设置变量host_vars
。
使用include_vars
. 示例文件内容:
"users": {
"server1": [ "joe", "jane" ],
"server2": [ "jane" ]
}
加载它include_vars
。对于您的任务循环(with_items
)users[ansible_hostname]