Инфраструктура — дома (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»