Статья также доступна на украинском (перейти к просмотру).

Оглавление
- Основные концепции Ansible Playbooks
- Реализация проекта
- Формирование задач
- Создание структуры каталогов и файлов
- Создание Inventory
- Проверка настроек и тестирования соединения
- Формирование директив файла playbook
- Тестирование файла playbook перед запуском
- Запуск и выполнение
- Выборочное тестирование результатов выполнения
В статье «Инструмент автоматизации Ansible» нами были рассмотрены основные концепции удаленного управления узлами сети с помощью Ansible и начальная настройка управляющего узла на ОС Ubuntu. В этой работе мы реализуем процесс автоматизированной начальной настройки серверов Ubuntu с использованием Ansible Playbooks.
Основные концепции Ansible Playbooks
Ansible Playbooks позволяет организовать гибкую и многоразовую систему управления конфигурацией и развертыванием на многих серверах сети. В частности, он дает возможность:
- Объявлять конфигурации;
- Формировать шаги любого упорядоченного вручную процесса в нескольких группах узлов в определенной последовательности;
- Запускать для выполнения задачи синхронно или асинхронно.
Перечислим общие концепции правильного использования этого механизма.
Для описания задач и конфигураций целесообразно использовать язык YAML как имеющий более простой и понятный синтаксис по сравнению с, например, языком JSON. Для лучшего восприятия спецификаций проекта желательно разделить элементы файла playbook.yml пустой строкой. Применять комментирование перед каждым блоком или задачей. Это значительно ускорит дальнейшее их редактирование.
Предварительно продумать организацию имен в проекте. Каждая задача, блок или модуль должны иметь согласованные названия. Ansible имеет множество разнообразных функций и их расширений, что позволяет реализовать полноценный проект любой сложности. Однако здесь нужно опираться на принцип: чем проще, тем совершеннее. Это позволит избежать излишнего усложнения проекта.
Целесообразно сохранить свои проекты в любой из систем контроля версий. Это позволит эффективнее управлять ими в дальнейшем.
Для хранения конфиденциальной информации проекта лучше использовать методы шифрования текстовых данных Ansible Vault.
Во избежание многих ошибок желательно проводить постоянное тестирование проекта на всех этапах его подготовки разнообразными сервисами – Ansible Lint, assert и другие.
Реализация проекта
Реализация нашего проекта по начальной настройке серверов Ubuntu включает в себя несколько стадий. Перечислим их:
- Формирование задач;
- Создание структуры каталогов и файлов;
- Создание Inventory;
- Проверка настроек и тестирования соединения;
- Формирование директив файла playbook;
- Тестирование перед запуском;
- Запуск и исполнение;
- Выборочное тестирование результатов выполнения.
Формирование задач
Набор формируемых задач должен реализовать основную цель проекта – начальную настройку удаленных узлов, работающих на ОС Ubuntu 22. Согласно этому, такой набор будет выглядеть следующим образом:
- Установка менеджера пакетов aptitude, который более приспособлен для работы с Ansible по сравнению с apt;
- Создание и настройка администраторской группы для пользователей с правами sudo;
- Создание нового пользователя с соответствующими правами;
- Обеспечение возможности входа нового пользователя на каждый из узлов по ключу SSH;
- Отключение аутентификации на основе пароля пользователя root;
- Настройка брандмауэра UFW;
- Установка системных пакетов.
Создание структуры каталогов и файлов
Если для работы используется система контроля версий, то необходимо обеспечить согласование данных. Здесь есть два варианта.
Вариант первый. Репозиторий do-community/ansible-playbooks используется в первый раз. Тогда нужно клонировать его в локальную директорию узла управления Ansible. Это можно сделать с помощью следующей команды:
$ git clone https://github.com/do-community/ansible-playbooks.git
После чего перейти в соответствующую директорию:
$ cd ansible-playbooks
Вариант второй. Репозиторий был клонирован раньше. В этом случае необходимо получить доступ к существующей копии ansible-playbook и обновить содержимое репозитория с помощью соответствующей команды:
$ cd ansible-playbooks
В нашем случае, вместо названия ansible-playbooks для репозитория использовано название ansible.
После этого можно начинать создавать структуру каталогов. В первую очередь, создадим директорию нашего проекта с названием setup_all_node_ubuntu:
$ mkdir /etc/ansible/setup_all_node_ubuntu

После этого создадим директорию для хранения файла общих параметров для всех задач:
$ mkdir /etc/ansible/setup_all_node_ubuntu/all_vars

Создадим файл def.yml общих параметров с помощью редактора nano и добавим в него следующие записи:
create_user: admin
copy_local_key: "{{ lookup('file', lookup('env','HOME') + '/.ssh/id_rsa.pub') }}"
sys_packages: [ 'curl', 'vim', 'git', 'ufw']
Первая запись определяет имя пользователя (admin), под которым будет производиться вход на удаленные узлы.
Вторая запись задает функции поиска и копирования и путь доступа к файлу с открытым ключом SSH. Согласно этому указанный ключ будет помещен в файл ~.ssh/authorized_keys для учетной записи admin для всех узлов.
Третья запись конкретизирует названия системных пакетов для установки.
Введем в терминале:
$ nano /etc/ansible/setup_all_node_ubuntu/all_vars/def.yml

Содержимое файла показано ниже.

Сохраним результат и выйдем из редактора (Ctrl+O, Ctrl+X).
Ключ SSH был сгенерирован нами незадолго до этого с помощью команды:
$ ssh-keygen



Подходящий закрытый ключ id_rsa находится в той же директории, что и открытый. Следует отметить, что указанный ключ был создан специально для учетной записи пользователя admin удаленных узлов и поэтому во избежание путаницы желательно такие ключи хранить в отдельно созданных каталогах или затем переименовать их с помощью команды rename.
Создание Inventory
В терминологии Ansible во Inventory понимается список удаленных узлов вместе с параметрами для входа. Местонахождение списка: /etc/ansible/hosts. Сформируем его:
$ sudo nano /etc/ansible/hosts

В открывшемся окне редактору внесем в файл соответствующие изменения.

Мы создали группу webservers, в которую внесли только один хост с именем server1. С помощью параметра ansible_host указали IP-адрес хоста и пароль доступа по SSH-соединению. В разделе all:vars мы можем указать любые общие параметры доступа для всех групп хостов. Например, имя пользователя, если оно одинаково для всех хостов. Мы также можем указать параметры отдельно для любой группы или хоста. Для этого достаточно ввести их в блоке под названием хоста или группы, взятой в квадратные скобки, например [server1]. После внесения изменений сохраним данные и выйдем из редактора.
Проверка настроек и тестирования соединения
Перед тем, как начать процесс управления узлами, необходимо проверить работоспособность канала соединения с ними и правильность установленных настроек. На первом этапе проверяется правильность настройки управляющего узла. На втором этапе устанавливается первая связь с удаленными машинами и тестируется соединение с ними с помощью Ansible. Введем в терминале:
$ ansible all --list-hosts

С помощью этой команды мы проверили список хостов, идентифицированный программой. Он совпадает с нашим списком – server1.
Далее, введем в терминале:
$ ansible-inventory --list -y

Здесь мы проверили полный список групп, хостов и правильность входных параметров. Как можно убедиться, он полностью отвечает действительности.
Теперь установим первое соединение с хостами из списка. Это позволит избежать в дальнейшем задержек в работе из-за необходимости подтверждения согласия на соединение, поскольку эти узлы уже будут идентифицированы ОС Ubuntu, как разрешенные. Для этого введем следующую команду:
$ ssh root@178.20.157.79

Ubuntu предлагает подтвердить достоверность хоста, что мы и делаем, набрав yes.

Как можно убедиться из сообщения на последнем ящике, адрес хоста из списка inventory был внесен в список разрешенных хостов Ubuntu, как мы и хотели.
Проверим это с помощью той же команды:
$ ssh root@178.20.157.79

Теперь сразу же предлагается ввести пароль, то есть хост идентифицирован. После ввода пароля происходит подключение, как показано ниже.

Закроем сеанс соединения с удаленным узлом с помощью команды exit и вернемся к управлению управляющим узлом.
Только после этого можно начинать тестирование соединения уже с помощью Ansible. Введем в терминале:
$ ansible all –m ping

В результате пингования команда вернула ответ «pong», то есть соединения со всеми хостами из списка Inventory являются работоспособными и могут быть использованы для управления узлами с помощью Ansible.
Мы теперь можем более подробно исследовать состояние каждого из хостов. Например, проверим состояние дисковых ресурсов на каждом из хостов:
$ ansible all -a "df -h"

Также теперь мы можем проверить время безотказной работы каждого из хостов или какого-то отдельного. Для этого введем команду:
$ ansible server1 -a "uptime"

Можно убедиться, что нам это удалось. Теперь можно переходить к формированию директив файла playbook.
Формирование директив файла playbook
Целесообразно в структуре проекта иметь несколько файлов директив с разными названиями. В нашем случае указанный файл будет называться playbook_one.yml. Сформируем его содержание в соответствии с задачами.
playbook_one.yml
---
- hosts: all
become: true
vars_files:
- all_vars/def.yml
tasks:
- name: Install package manager
apt: name=aptitude update_cache=yes state=latest force_apt_get=yes
# Group
- name: Create admin group 'main'
group:
name: main
state: present
- name: Setting privileges sudo no passwd for 'main'
lineinfile:
path: /etc/sudoers
state: present
regexp: '^%main'
line: '%main ALL=(ALL) NOPASSWD: ALL'
validate: '/usr/sbin/visudo -cf %s'
# User remote ubuntu
- name: Create a new user ubuntu with rights sudo
user:
name: "{{ create_user }}"
state: present
groups: main
append: true
create_home: true
shell: /bin/bash
- name: Setting up an authorization key for a user ubuntu
authorized_key:
user: "{{ create_user }}"
state: present
key: "{{ copy_local_key }}"
- name: Setting up root authentication without a password
lineinfile:
path: /etc/ssh/sshd_config
state: present
regexp: '^#?PermitRootLogin'
line: 'PermitRootLogin prohibit-password'
# UFW
- name: Set permission to connect via SSH
ufw:
rule: allow
name: OpenSSH
- name: Deny any other connections
ufw:
state: enabled
policy: deny
direction: incoming
# Packages
- name: Update apt
apt: update_cache=yes
- name: Installing packages for the system
apt: name={{ sys_packages }} state=latest
Директивы сформированы в соответствии с рекомендациями, приведенными нами в начале статьи. Каждая из задач имеет свое название, комментарий и т.д. Главный принцип, который мы придерживались, это максимальное упрощение проекта. Этому также способствовало наличие только одной группы серверов с одинаковыми параметрами. Теперь сформируем соответствующий файл с помощью следующей команды:
$ nano /etc/ansible/setup_all_node_ubuntu/playbook_one.yml


Сохраним файл и вернемся к терминалу.
Тестирование файла playbook перед запуском
Такое тестирование помогает избавиться от многих ошибок в playbook, в том числе и синтаксических. Одним из самых мощных механизмов для этого является модуль ansible-lint, который может быть установлен с помощью соответствующей команды. Введем в терминале:
$ apt install ansible-lint


Теперь мы можем использовать установленное приложение для тестирования нашего файла playbook. Для этого запустим команду:
$ ansible-lint /etc/ansible/setup_all_node_ubuntu/playbook_one.yml

Результат выполнения команды показан ниже.

Для анализа и устранения ошибок в директивах можно воспользоваться справочной информацией по программе по ссылке: ansible-lint default rules.
Кроме указанного выше механизма, для проверки корректности директив playbook еще до его запуска может использоваться команда их запуска ansible-playbook с соответствующими параметрами. Это следующие параметры: --list-tasks, --diff, --syntax-check, --check и --list-hosts. Например, просмотрим доступный для программы список задач.
Введем:
ansible-playbook /etc/ansible/setup_all_node_ubuntu/playbook_one.yml --list-tasks

Можно убедиться в том, что набор задач идентифицирован правильно. Теперь проверим синтаксис:

Результат проверки – с синтаксисом в нашем playbook все хорошо.
Существуют и другие инструменты для проверки и тестирования директив. Они подробно описаны в документации Ansible: Validating Playbooks.
Запуск и выполнение
После прохождения всех проверок и устранения ошибок файл с директивами может быть запущен на выполнение. Для этого введем:
ansible-playbook /etc/ansible/setup_all_node_ubuntu/playbook_one.yml -l server1

Параметр -l происходит от limit, то есть ограничен. Это означает, что он позволяет указать только отдельные хосты или группы, которые иногда бывают необходимыми. В нашем случае указан один хост server1.
Результат выполнения команды показан ниже.

Судя по результатам, выполнение сценария на удаленном узле прошло успешно и соответствующие изменения на узлах произошли.
Выборочное тестирование результатов выполнения
Для выборочной проверки результатов внесенных изменений на удаленных узлах откроем сеанс соединения от имени нового пользователя с именем admin:
$ ssh admin@178.20.157.79

Можем убедиться, что соединение произошло, то есть создание нового пользователя прошло успешно. Теперь проверим статус брандмауэра на удаленном хосте:
$ sudo ufw status

Результат: настройка UFW успешно выполнена. А это была одна из последних задач сценария, говорящая о том, что сценарий выполнен полностью.
Дата-центр FREEhost.UA предоставляет качественный хостинг VDS и услуги аренды серверов с поддержкой 24/7. На нашем сайте Вы можете подобрать сервер для аренды под любые задачи.
Подписывайтесь на наш телеграм-канал https://t.me/freehostua, чтобы быть в курсе новых полезных материалов.
Смотрите наш канал Youtube на https://www.youtube.com/freehostua.
Мы в чем-то ошиблись, или что-то пропустили?
Напишите об этом в комментариях на сайте и в телеграм-канале. Мы с удовольствием ответим и обсудим Ваши замечания и предложения.
|
Дата: 08.02.2023 Автор: Евгений
|
|

Авторам статьи важно Ваше мнение. Будем рады его обсудить с Вами:
comments powered by Disqus