Я новичок в Ansible, и мне поставили задачу. У меня есть файл YAML, в котором у меня есть следующие ключи для нескольких пользователей.
client:
- key: ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAklOUpkDHrfHY17SbrmTIpNLTGK9Tjom/BWDSU
GPl+nafzlHDTYW7hdI4yZ5ew18JH4JW9jbhUFrviQzM7xlELEVf4h9lFX5QVkbPppSwg0cda3
Pbv7kOdJ/MTyBlWXFCR+HAo3FXRitBqxiX1nKhXpHAZsMciLq8V6RjsNAQwdsdMFvSlVK/7XA
t3FaoJoAsncM1Q9x5+3V0Ww68/eIFmb1zuUFljQJKprrX88XypNDvjYNby6vw/Pb0rwert/En
mZ+AW4OZPnTPI89ZPmVMLuayrD2cE86Z/il8b+gw3r3+1nKatmIkjn2so1d01QraTlMqVSsbx
NrRFi9wrf+M7Q==
name: user1
- key: ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAklOUpkDHrfHY17SbrmTIpNLTGK9Tjom/BWDSU
GPl+nafzlHDTYW7hdI4yZ5ew18JH4JW9jbhUFrviQzM7xlELEVf4h9lFX5QVkbPppSwg0cda3
Pbv7kOdJ/MTyBlWXFCR+HAo3FXRitBqxiX1nKhXpHAZsMciLq8V6RjsNAQwdsdMFvSlVK/7XA
t3FaoJoAsncM1Q9x5+3V0Ww68/eIFmb1zuUFljQJKprrX88XypNDvjYNby6vw/Pb0rwert/En
mZ+AW4OZPnTPI89ZPmVMLuayrD2cE86Z/il8b+gw3r3+1nKatmIkjn2so1d01QraTlMqVSsbx
NrRFiefwwefew4w223e3e==
name: user1
- key: ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAklOUpkDHrfHY17SbrmTIpNLTGK9Tjom/BWDSU
GPl+nafzlHDTYW7hdI4yZ5ew18JH4JW9jbhUFrviQzM7xlELEVf4h9lFX5QVkbPppSwg0cda3
Pbv7kOdJ/MTyBlWXFCR+HAo3FXRitBqxiX1nKhXpHAZsMciLq8V6RjsNAQwdsdMFvSlVK/7XA
t3FaoJoAsncM1Q9x5+3V0Ww68/eIFmb1zuUFljQJKprrX88XypNDvjYNby6vw/Pb0rwert/En
mZ+AW4OZPnTPI89ZPmVMLuayrD2cE86Z/il8b+gw3r3+1nKatmIku3hrbfwejw4ur4hfjewf4wkjr3434==
name: user2
- key: ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAklOUpkDHrfHY17SbrmTIpNLTGK9Tjom/BWDSU
GPl+nafzlHDTYW7hdI4yZ5ew18JH4JW9jbhUFrviQzM7xlELEVf4h9lFX5QVkbPppSwg0cda3
Pbv7kOdJ/MTyBlWXFCR+HAo3FXRitBqxiX1nKhXpHAZsMciLq8V6RjsNAQwdsdMFvSlVK/7XA
t3FaoJoAsncM1Q9x5+3V0Ww68/eIFmb1zuUFljQJKprrX88XypNDvjYNby6vw/Pb0rwert/En
mZ+AW4OZPnTPI89ZPmVMLuayrD2cE86Z/il8b+gw3r3+1nKatmIkjn2so1d01Qrao3rj32hirbk2jewf239r232e3==
name: user2
Моя цель — удалить ключи с сервера для пользователей всякий раз, когда ключ удаляется из файла YAML. Я пробовал эксклюзивно, но он не работает, так как не поддерживает цикл. Вот фрагмент моего кода:
- name: Set authorized key for user ubuntu copying it from current user
become: yes
authorized_key:
user: "{{ item.name }}"
state: present
key: "{{ item.key }}"
exclusive: True
with_items:
- "{{ clients }}"
Я попробовал следующий подход, но он работает только для одного пользователя, а не для нескольких пользователей, потому что он просто объединяет оба ключа и добавляет и удаляет их для обоих пользователей. Я хочу, чтобы он добавлял и удалял ключи однозначно для обоих пользователей.
- name: lookup ssh pubkeys from keyfiles and create ssh_pubkeys_list
set_fact:
ssh_keys: "{{ item.key }}"
register: ssh_pubkeys_results_list
with_items:
- "{{ clients }}"
- name: iterate over ssh_pubkeys_list and join into a string
set_fact:
ssh_pubkeys_string: "{{ ssh_pubkeys_results_list.results | map(attribute='ansible_facts.ssh_keys') | join('\n')}}"
- name: lookup ssh pubkeys from name and create ssh_pubkeys_list
set_fact:
ssh_keys: "{{ item.name }}"
register: ssh_pubkeys_results
with_items:
- "{{ clients }}"
- name: Set authorized key for user ubuntu copying it from current user
become: yes
authorized_key:
user: "{{ item.name }}"
state: present
key: "{{ ssh_pubkeys_string }}"
exclusive: True
with_items:
- "{{ clients }}"
Любая помощь будет принята с благодарностью. Спасибо
@Jack Это похоже только на YAML, откуда он берет ключи. Я добавил настоящие ключи, если это то, что вы искали.
Является ли список ключей clients
эксклюзивным, т.е. никакие другие ключи не допускаются? Только для пользователей из списка или для всех пользователей?
@VladimirBotka Да, это эксклюзивно для всех пользователей.
Большое спасибо @VladimirBotka Первое решение работает для меня как шарм. Второй не пробовала, но попробую и этот.
@WhizzY Я искал массив ключей для каждого пользователя. Будет намного работоспособнее.
1) Управление пользователями только из списка
Сгруппируйте ключи по именам. Объявите переменную
client_groups: "{{ client|groupby('name') }}"
Повторить список
- authorized_key:
user: "{{ item.0 }}"
key: "{{ item.1|map(attribute='key')|join('\n') }}"
exclusive: true
loop: "{{ client_groups }}"
Example of a complete playbook for testing
Given the authorized keys
shell> ssh admin@test_11 sudo cat /home/alice/.ssh/authorized_keys
ssh-rsa key1
ssh-rsa key2
ssh-rsa key3
shell> ssh admin@test_11 sudo cat /home/bob/.ssh/authorized_keys
ssh-rsa key4
ssh-rsa key5
ssh-rsa key6
The playbook
shell> cat pb.yml
- hosts: test_11
vars:
client:
- {name: alice, key: ssh-rsa key1}
- {name: alice, key: ssh-rsa key2}
- {name: bob, key: ssh-rsa key4}
- {name: bob, key: ssh-rsa key5}
client_groups: "{{ client|groupby('name') }}"
tasks:
- block:
- debug:
var: client_groups
- debug:
msg: |
user: "{{ item.0 }}"
key: "{{ item.1|map(attribute='key')|join('\n') }}"
loop: "{{ client_groups }}"
when: debug|d(false)|bool
- authorized_key:
user: "{{ item.0 }}"
key: "{{ item.1|map(attribute='key')|join('\n') }}"
exclusive: true
loop: "{{ client_groups }}"
gives
shell> ansible-playbook pb.yml -e debug=true -CD
PLAY [test_11] *******************************************************************************
TASK [debug] *********************************************************************************
ok: [test_11] =>
client_groups:
- - alice
- - key: ssh-rsa key1
name: alice
- key: ssh-rsa key2
name: alice
- - bob
- - key: ssh-rsa key4
name: bob
- key: ssh-rsa key5
name: bob
TASK [debug] *********************************************************************************
ok: [test_11] => (item=['alice', [{'name': 'alice', 'key': 'ssh-rsa key1'}, {'name': 'alice', 'key': 'ssh-rsa key2'}]]) =>
msg: |-
user: "alice"
key: "ssh-rsa key1\nssh-rsa key2"
ok: [test_11] => (item=['bob', [{'name': 'bob', 'key': 'ssh-rsa key4'}, {'name': 'bob', 'key': 'ssh-rsa key5'}]]) =>
msg: |-
user: "bob"
key: "ssh-rsa key4\nssh-rsa key5"
TASK [authorized_key] ************************************************************************
--- before: /home/alice/.ssh/authorized_keys
+++ after: /home/alice/.ssh/authorized_keys
@@ -1,3 +1,2 @@
ssh-rsa key1
ssh-rsa key2
-ssh-rsa key3
changed: [test_11] => (item=['alice', [{'name': 'alice', 'key': 'ssh-rsa key1'}, {'name': 'alice', 'key': 'ssh-rsa key2'}]])
--- before: /home/bob/.ssh/authorized_keys
+++ after: /home/bob/.ssh/authorized_keys
@@ -1,3 +1,2 @@
ssh-rsa key4
ssh-rsa key5
-ssh-rsa key6
changed: [test_11] => (item=['bob', [{'name': 'bob', 'key': 'ssh-rsa key4'}, {'name': 'bob', 'key': 'ssh-rsa key5'}]])
PLAY RECAP ***********************************************************************************
test_11: ok=3 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
2) Управление всеми пользователями
Получить базу данных
- getent:
database: passwd
Выберите пользователей, которыми вы хотите управлять. Например, с помощью оболочки входа. Объявите переменные
shells: [/bin/csh, /bin/sh, /bin/bash]
users: "{{ getent_passwd|dict2items|
selectattr('value.5', 'in', shells)|
map(attribute='key')|list }}"
Создайте словарь ключей. Объявите переменные
client_groups: "{{ client|groupby('name') }}"
client_nmes: "{{ client_groups|map('first')|list }}"
client_keys: "{{ client_groups|map('last')|
map('map', attribute='key')|list }}"
client_dict: "{{ dict(client_nmes|zip(client_keys)) }}"
Итерация списка пользователей
- authorized_key:
user: "{{ item }}"
key: "{{ client_dict[item]|d([])|join('\n') }}"
exclusive: true
loop: "{{ users }}"
Example of a complete playbook for testing
- hosts: test_11
vars:
client:
- {name: alice, key: ssh-rsa key1}
- {name: alice, key: ssh-rsa key2}
- {name: bob, key: ssh-rsa key4}
- {name: bob, key: ssh-rsa key5}
client_groups: "{{ client|groupby('name') }}"
client_nmes: "{{ client_groups|map('first')|list }}"
client_keys: "{{ client_groups|map('last')|
map('map', attribute='key')|list }}"
client_dict: "{{ dict(client_nmes|zip(client_keys)) }}"
shells: [/bin/csh, /bin/sh, /bin/bash]
users: "{{ getent_passwd|dict2items|
selectattr('value.5', 'in', shells)|
map(attribute='key')|list }}"
tasks:
- getent:
database: passwd
- block:
- debug:
var: client_dict
- debug:
var: users
- debug:
msg: |
user: "{{ item }}"
key: "{{ client_dict[item]|d([])|join('\n') }}"
loop: "{{ users }}"
when: debug|d(false)|bool
- authorized_key:
user: "{{ item }}"
key: "{{ client_dict[item]|d([])|join('\n') }}"
exclusive: true
loop: "{{ users }}"
Можете ли вы изменить формат этого ключевого файла?