Назад | Перейти на главную страницу

Управляйте пользователями и открытыми портами с помощью Ansible

Я начинаю работать с 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]