Я начинаю работать с 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]
Мне не нужна помощь с написанием задач playbook (я знаю, как использовать модуль user / ufw), но я не могу найти способ чисто централизовать конфигурацию для каждого хоста с помощью ansible.
Единственное решение, которое у меня есть на данный момент, - это иметь user.yml
и port.yml
playbook, редактируйте их каждый раз, когда я хочу запускать их для определенного сервера, и запускать playbook с --limit server1
. Это не кажется чистым и мешает мне иметь четкий снимок доступа пользователей и открытых портов для каждого сервера.
Каким будет чистый способ организовать это в анзибле?
Учитывая словарь servers
(см. сокращенную версию в playbook ниже) и файлы 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
.
Есть несколько способов добиться этого.
Установите переменные в инвентаре:
server1 users='["joe", "jane"]'
server2 users='["jane"]'
Установите переменные в файле в host_vars
каталог.
Использовать include_vars
. Пример содержимого файла:
"users": {
"server1": [ "joe", "jane" ],
"server2": [ "jane" ]
}
Загрузите это с помощью include_vars
. Для вашего цикла задач (with_items
) над users[ansible_hostname]