Инфраструктура — дома (7 части серии)
В этом посте я подробно расскажу, как полностью заполнить следующие требования от раздела управления инфраструктурой:
- IM1: Задача обновить операционные системы
- IM2: Общая задача для установки дополнительного программного обеспечения
- IM3: задача для установки и обновления ключей SSH
Мы также узнаем о продвинутых аналимых концепциях, таких как условные, блоки, утверждения и поиску.
Эта статья изначально появилась на моем Персональный блог Отказ
Предварительные условия и новые аварийные фьючерсы
Моя инфраструктура имеет следующие различия:
- Raspi-3- * и Raspi-4 — * Используйте новости Debian Release Бассейн
- Linux-Workstation использует распределение Arch Linux под названием Manjaro
Эти различия означают, что задачи для установки и обновления должны применяться только к соответствующей операционной системе. Поэтому мы будем использовать Блок Заявление, которое окружает любое количество задач, и которое будет выполнять только при условии, указанное в Когда пункт верно.
PlayBook:
- name: Update packages on all nodes
hosts:
- raspis
- server
serial: 1
become: true
tasks:
- block:
- name: Update packages on Debian
apt:
update_cache: true
upgrade: yes
register: result
- name: Print results
debug:
var=result.stdout_lines
when: ansible_facts['distribution'] == 'Debian'
- block:
- name: Update packages on Archlinux
pacman:
update_cache: yes
upgrade: yes
register: result
- name: Print results
debug:
var=result.stdout_lines
when: ansible_facts['distribution'] == 'Archlinux'
Давайте объясним это:
- С
сериалМы ограничиваем выполнение одним хостом одновременно. Это мера безопасности: если обновление не удалось на одном хосте, мы должны прекратить расследовать проблему, прежде чем продолжить с другим хостом - Опция
. статьозначает, что удаленные пользовательские проблемыSudoПеред попыткой обновления пакетов — без этого выключателя задача потерпит неудачу. - С
блокироватьиКогдаМы определяем условный набор задач: только когда условие верно, то задачи будут выполняться. - Первый блок обновляет все узлы для Debian с APT модуль.
- Второй блок обновляет все узлы с помощью распределительной арки Linux, используя Пакман модуль
- После каждого шага мы распечатаем результаты к консоли.
Давайте тестируем эту плейбрию, применяя его только в узел Raspi-4-1:
$: ansible-playbook -I hosts system/update_pacakges —limit "raspi-4-1"
PLAY [Update packages on all nodes] **********************************************************************************
TASK [Gathering Facts] ********************************************************************************
ok: [raspi-4-1]
TASK [Update packages] ********************************************************************
ok: [raspi-4-1]
TASK [Print results] ******************************************************************************************
ok: [raspi-4-1] => {
"result.stdout_lines": [
"Reading package lists...",
"Building dependency tree...",
"Reading state information...",
"Calculating upgrade...",
"The following packages will be upgraded:",
" libpam-systemd libsystemd0 libudev1 systemd systemd-sysv udev",
"6 upgraded, 0 newly installed, 0 to remove and 0 not upgraded.",
Превосходно! Отныне мы можем обновить все системы, запустив эту игрушку.
Установить пакеты
Следующим шагом является установка новых пакетов на наших узлах. При выполнении этого PlayBook я хочу предоставить имя пакета в качестве аргумента для Anbible. Поскольку имена пакетов отличаются между распределениями Linux, будут две игровые книги.
Вот игра для установки программного обеспечения на Debian.
- name: Install software on Debian
hosts:
- raspis
become: true
vars:
package: bash
tasks:
- name: Install package
apt:
update_cache: true
name: "{{ package }}"
state: present
register: result
- name: Print results
debug:
var=result
Давайте выполним этот PlayBook, чтобы установить пакет NTP на Raspi-4-1.
ansible-playbook install_package.yml -e package=ntp —limit "raspi-4-2"
PLAY [Install software on raspi] **********************************************************************
TASK [Gathering Facts] ********************************************************************************
ok: [raspi-4-1]
TASK [Install package] ********************************************************************************
changed: [raspi-4-1]
TASK [Print results] ******************************************************************************************
ok: [raspi-4-1] => {
"stdout_lines": [
"Reading package lists...",
"Building dependency tree...",
"Reading state information...",
"The following additional packages will be installed:",
" libevent-core-2.1-6 libevent-pthreads-2.1-6 libopts25 sntp",
"Suggested packages:",
" ntp-doc",
"The following NEW packages will be installed:",
" libevent-core-2.1-6 libevent-pthreads-2.1-6 libopts25 ntp sntp",
"0 upgraded, 5 newly installed, 0 to remove and 0 not upgraded.",
"Need to get 1081 kB of archives.",
Здорово! Мы можем установить любое программное обеспечение на всех узлах с помощью простой команды.
Для Arch Linux мы используем этот Playbook:
- name: Install software on Arch Linux
hosts:
- server
become: true
vars:
package: bash
tasks:
- name: Install package
pacman:
update_cache: yes
name: "{{ package }}"
state: present
register: result
- name: Print results
debug:
var=result
Поверните ключевые ключи SSH
Окончательное требование является задачей для вращения клавиш SSH: мы копируем новые SSH-ключи, убедитесь, что мы можем подключиться с этими клавишами, а затем удалить старые ключи. Эти три этапа выполняются в порядке, и если вы не удаются, следующая задача не будет выполнена. Однако следует также подумать, чтобы удалить новый SSH-ключ в том случае, мы не можем успешно подключиться. Кроме того, мы должны проверить, что новый SSH-ключ существует как файл, и что он не пуст.
Чтобы добиться этого, мы разлуем задачу в Блок и спасение часть. Мы выполняем все шаги, как указано выше, и если что-то пойдет не так, мы сохраним текущий ключ SSH. Чтобы проверить, что ключ-файл существует, мы используем модуль статистика и загрузить файл ключей, мы используем Модуль поиска Отказ Наконец, чтобы скопировать ключи, мы будем использовать Авторизованный модуль Отказ
Вот игровой книг:
- name: Add new public key
hosts: raspi-4-1
serial: 1
become: true
vars:
keyname: new_id_rsa.pub
new_key_file: "{{ lookup('env', 'HOME') + '/.ssh/' + lookup('vars', 'keyname') }}"
new_key: "{{ lookup('file', lookup('vars', 'new_key_file'), errors='ignore') }}"
old_key: "{{ lookup('file', lookup('env', 'HOME') + '/.ssh/id_rsa.pub') }}"
local_user: "{{ lookup('env', 'USER') }}"
tasks:
- block:
- local_action:
stat path="{{ new_key_file }}"
become_user: "{{ local_user }}"
register: file
- name: Check that the new key file exists and is not empty
assert:
that: file.stat.isreg and file.stat.isreg
- authorized_key:
user: "{{ ansible_ssh_user }}"
state: present
key: "{{new_key}}"
exclusive: true
register: result
- debug:
var=result
- name: pause for 10 seconds, then reconnect
wait_for:
delay: 10
- name: Connect with new key
ping:
- name: Delete old key
authorized_key:
user: "{{ ansible_ssh_user }}"
state: present
key: "{{ new_key }}"
exclusive: true
rescue:
- name: Error occured, restoring old key
authorized_key:
user: "{{ ansible_ssh_user }}"
state: present
exclusive: true
key: "{{ old_key }}"
Давайте более подробно объясним этот сценарий:
- Var
. KeyNameопределяется — его можно пропустить как аргумент. Тогда с поиском Env мы строим путь к этому файлу, а с поиском файла мы читаем его контент - С
статистикаМы обращаемся к файловой системе, чтобы прочитать файл ключа. ДваAssert: Тогда:утверждение Убедитесь, что файл существует, и его содержимое не пусто - Затем мы скопируем новый ключ с
autorized_keysи все остальные ключи сЭксклюзив: правдаутверждение. - Задачи останавливаются в течение 10 секунд, затем мы подключаемся к новой клавише для выполнения пинга. Если Ping не удается,
спасениеЗаявление применяется: мы копируем старый ключ еще раз и удалите новый ключ.
Давайте посмотрим на эту книгу в действии:
PLAY [Add new public key] *************************************************************
TASK [Gathering Facts] ****************************************************************
ok: [raspi-4-1]
TASK [debug] **************************************************************************
ok: [raspi-4-1] => {
"new_key_file": "/Users/sguenther/.ssh/new_id_rsa.pub"
}
TASK [stat] ***************************************************************************
ok: [raspi-4-1 -> localhost]
TASK [Check that the new key file exists and is not empty] ****************************
ok: [raspi-4-1] => {
"changed": false
}
MSG:
All assertions passed
TASK [authorized_key] *****************************************************************
ok: [raspi-4-1]
TASK [debug] **************************************************************************
ok: [raspi-4-1] => {
"result": {
"changed": false,
"comment": null,
"exclusive": false,
"failed": false,
"follow": false,
"key": "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAD9QDABTzcYz3+c0SZQBHfXjDMaE/sRBB0L1zaBGEss1xu...
Миссия выполнена!
Заключение
С помощью Anbible мы завершили первые три требования инфраструктуры в домашнем проекте: мы можем обновить все узлы, мы можем установить определенные пакеты, и мы можем повернуть ключи SSH. Мы также изучили несколько новых аслейбежных функций, особенно использование блокировать и спасение Заявления, а также как определить переменные, которые хранят информацию из локальных файлов.
Инфраструктура — дома (7 части серии)
Оригинал: «https://dev.to/admantium/infrastructure-home-infrastructure-management-3bhc»