Как автоматизировать первоначальную настройку нескольких серверов Ubuntu 22.04 с помощью Ansible
Автор выбрал программу Write for DOnations.
Введение
книги по автоматизации.
Ansible работает без агентов, поэтому вам не нужно устанавливать какие-либо компоненты Ansible на серверы, на которых вы хотите запускать Ansible. Эти серверы являются узлами Ansible и должны работать под управлением Windows. Подсистема для Linux (WSL) установлена.
В этом руководстве вы будете использовать Ansible для автоматизации начальной настройки нескольких серверов Ubuntu 22.04. Вы выполните следующие задачи начальной настройки на всех серверах:
- Обновление установленных пакетов
- Добавление пользователя без полномочий root с правами администратора
- Включение доступа по SSH для этого пользователя без полномочий root
- Включение брандмауэра
- Изменение порта для доступа по SSH и использование брандмауэра для защиты от атак грубой силы и повышения общей безопасности серверов
- Отключение удаленного входа для учетной записи root
- Убедиться, что важные службы активны.
- Удаление зависимостей пакетов, которые больше не требуются
Поскольку вы будете использовать Ansible для запуска комплексного сценария, определяющего каждую задачу, эти задачи будут выполняться с помощью всего одной команды и без необходимости индивидуального входа на серверы. Вы можете запустить дополнительную дополнительную книгу воспроизведения, чтобы автоматизировать управление сервером после первоначальной настройки сервера.
Предпосылки
Для выполнения этого урока вам понадобятся:
- Ansible установлен на машине, которая будет действовать как ваш управляющий узел, это может быть ваша локальная машина или удаленный сервер Linux. Чтобы установить Ansible, выполните шаг 1 официального руководства по установке Ansible, если это необходимо для других операционных систем.
- Если вашим управляющим узлом является удаленный сервер Ubuntu 22.04, не забудьте также настроить его с помощью пары ключей SSH.
- Git установлен на управляющем узле. Следуйте руководствам How To Install Git для популярных дистрибутивов Linux.
- (Необязательно) В разделе «Настройка редактора Ansible Vault» в руководстве «Как использовать Ansible Vault» измените текстовый редактор, связанный с переменной оболочки
EDITOR
. В этом руководстве в качестве редактора для Ansible Vault будет использоватьсяnano
.
Два или более серверов Ubuntu 22.04 и общедоступный IPv4-адрес каждого сервера. Предварительная настройка не требуется, так как вы будете использовать Ansible для автоматизации настройки на шаге 5, но у вас должен быть SSH-доступ к этим серверам с упомянутого выше узла управления Ansible. Если вы используете дроплеты DigitalOcean, вы найдете IPv4-адрес в разделе «Общедоступная сеть» каждого сервера на вкладке «Сеть» на панели инструментов.
- Если вашим управляющим узлом является удаленный сервер Ubuntu 22.04, обязательно используйте
ssh-copy-id
для подключения пары ключей к хостам.
Шаг 1 — Изменение файла конфигурации клиента SSH на вашем узле управления
На этом шаге вы измените директиву в файле конфигурации SSH-клиента вашего управляющего узла. После внесения этого изменения вам больше не будет предлагаться принять отпечаток ключа SSH удаленных компьютеров, так как они будут приниматься автоматически. Ручное принятие отпечатков ключей SSH для каждой удаленной машины может быть утомительным, поэтому эта модификация решает проблему масштабирования при использовании Ansible для автоматизации начальной настройки нескольких серверов.
Хотя вы можете использовать модуль Ansible
known_hosts
для автоматического принятия отпечатка ключа SSH для одного хоста, в этом руководстве рассматривается несколько хостов, поэтому более эффективно изменить файл конфигурации клиента SSH на узле управления ( как правило, ваш локальный компьютер).Для начала запустите терминальное приложение на своем узле управления и с помощью
nano
или вашего любимого текстового редактора откройте файл конфигурации клиента SSH:- sudo nano /etc/ssh/ssh_config
Найдите строку, содержащую директиву
StrictHostKeyChecking
. Раскомментируйте его и измените значение, чтобы оно выглядело следующим образом:... StrictHostKeyChecking accept-new ...
Сохраните и закройте файл. Вам не нужно перезагружать или перезапускать демон SSH, потому что вы только изменили файл конфигурации клиента SSH.
Примечание. Если вы не хотите постоянно менять значение
StrictHostKeyChecking
сask
наaccept-new
, вы можете вернуть его к значению по умолчанию. после запуска playbook на шаге 7. Хотя изменение значения будет означать, что ваша система автоматически принимает отпечатки ключей SSH, она будет отклонять последующие подключения с тех же хостов, если отпечатки изменятся. Эта функция означает, что изменениеaccept-new
не представляет такой большой угрозы безопасности, как изменение значения этой директивы наno
.Теперь, когда вы обновили директиву SSH, вы начнете настройку Ansible, что вы сделаете на следующих шагах.
Шаг 2 — Настройка файла Ansible Hosts
Файл
hosts
Ansible (также называемый файлом inventory) содержит информацию о хостах Ansible. Эта информация может включать имена групп, псевдонимы, доменные имена и IP-адреса. По умолчанию этот файл находится в каталоге/etc/ansible
. На этом шаге вы добавите IP-адреса хостов Ansible, которые вы развернули, в разделе «Предварительные требования», чтобы вы могли запускать на них свой плейбук Ansible.Для начала откройте файл
hosts
с помощьюnano
или вашего любимого текстового редактора:- sudo nano /etc/ansible/hosts
После вводных комментариев в файл добавить следующие строки:
... host1 ansible_host=host1-public-ip-address host2 ansible_host=host2-public-ip-address host3 ansible_host=host3-public-ip-address [initial] host1 host2 host3 [ongoing] host1 host2 host3
host1
,host2
иhost3
являются псевдонимами для каждого хоста, на котором вы хотите автоматизировать первоначальную настройку сервера. Использование псевдонимов упрощает обращение к хостам в других местах.ansible_host
— это переменная соединения Ansible, в данном случае указывающая на IP-адреса целевых хостов.initial
иcongoing
— примеры имен групп для хостов Ansible. Выбирайте имена групп, чтобы было легко узнать, для чего используются хосты. Группировка хостов таким образом позволяет обращаться к ним как к единому блоку. Хосты могут принадлежать более чем к одной группе. Хосты в этом руководстве были назначены на две разные группы, потому что они будут использоваться в двух разных плейбуках:initial
для первоначальной настройки сервера на шаге 8.hostN-public-ip-address
— это IP-адрес для каждого хоста Ansible. Обязательно заменитеhost1-public-ip-address
и последующие строки IP-адресами серверов, которые будут частью автоматизации.Когда вы закончите изменять файл, сохраните и закройте его.
Определение хостов в файле инвентаризации помогает указать, какие хосты будут настроены с помощью автоматизации Ansible. На следующем шаге вы клонируете репозиторий с образцами плейбуков, чтобы автоматизировать настройку нескольких серверов.
Шаг 3 — Клонирование репозитория первоначальной настройки сервера Ansible Ubuntu
На этом шаге вы клонируете образец репозитория из GitHub, содержащий необходимые файлы для этой автоматизации.
Этот репозиторий содержит три файла для примера многосерверной автоматизации:
initial.yml
,ongoing.yml
иvars/default.yml
. Файлinitial.yml
– это основной сборник сценариев, содержащий сценарии и задачи, которые вы будете запускать на хостах Ansible для первоначальной настройки. Файлongoing.yml
содержит задачи, которые вы будете запускать на хостах для текущего обслуживания после первоначальной настройки сервера. Файлvars/default.yml
содержит переменные, которые будут вызываться в обоих плейбуках на шаге 8.Чтобы клонировать репозиторий, введите следующую команду:
- git clone https://github.com/do-community/ansible-ubuntu.git
В качестве альтернативы, если вы добавили свой ключ SSH в свою учетную запись GitHub, вы можете клонировать репо, используя:
- git@github.com:do-community/ansible-ubuntu.git
Теперь у вас будет папка с именем
ansible-ubuntu
в вашем рабочем каталоге. Переоденьтесь в него:- cd ansible-ubuntu
Это будет ваш рабочий каталог для остальной части этого руководства.
На этом шаге вы получили образцы файлов для автоматизации нескольких серверов Ubuntu 22.04 с помощью Ansible. Чтобы подготовить файлы с информацией, относящейся к вашим хостам, вы затем обновите файл
vars/default.yml
для работы с вашей системой.Шаг 4 — Изменение переменных Ansible
В этом сборнике сценариев будет указана некоторая информация для автоматизации, которую со временем может потребоваться обновить. Размещение этой информации в одном файле переменных и вызов переменных в книгах воспроизведения будет более эффективным, чем их жесткое кодирование в книгах воспроизведения, поэтому вы будете изменять переменные в файле
vars/default.yml
, чтобы они соответствовали вашим предпочтения и потребности в настройке на этом шаге.Для начала откройте файл с помощью
nano
или вашего любимого текстового редактора:- nano vars/default.yml
Вы просмотрите содержимое файла, которое включает следующие переменные:
create_user: sammy ssh_port: 5995 copy_local_key: "{{ lookup('file', lookup('env','HOME') + '/.ssh/id_rsa.pub') }}"
Значение переменной
create_user
должно быть именем пользователяsudo
, который будет создан на каждом хосте. В данном случае этоsammy
, но вы можете назвать пользователя как угодно.Переменная
ssh_port
содержит порт SSH, который вы будете использовать для подключения к хостам Ansible после установки. Порт по умолчанию для SSH —22
, но его изменение значительно уменьшит количество автоматических атак на ваши серверы. Это изменение является необязательным, но оно повысит уровень безопасности ваших хостов. Вы должны выбрать менее известный порт, который находится между1024
и65535
и который также не используется другим приложением на узлах Ansible. В этом примере вы используете порт5995
.Примечание. Если на вашем управляющем узле установлен дистрибутив Linux, выберите для него число выше
1023
иgrep
в/etc/services
. Например, запуститеgrep 5995 /etc/services
, чтобы проверить, используется ли5995
. Если вывода нет, то порт в этом файле не существует, и вы можете присвоить его переменной. Если ваш управляющий узел не является дистрибутивом Linux и вы не знаете, где найти его эквивалент в вашей системе, вы можете обратиться к реестру имен служб и номеров портов транспортных протоколов.Переменная
copy_local_key
ссылается на файл открытого ключа SSH вашего управляющего узла. Если имя этого файлаid_rsa.pub
, вам не нужно вносить никаких изменений в эту строку. В противном случае измените его, чтобы он соответствовал файлу открытого ключа SSH вашего управляющего узла. Вы можете найти файл в каталоге~/.ssh
вашего узла управления. Когда вы запускаете основной плейбук на шаге 5 и после создания пользователя с привилегиямиsudo
, контроллер Ansible скопирует файл открытого ключа в домашний каталог пользователя, что позволит вам войти в систему как этот пользователь. через SSH после первоначальной настройки сервера.Когда вы закончите изменять файл, сохраните и закройте его.
Теперь, когда вы присвоили значения переменным в
vars/default.yml
, Ansible сможет вызывать эти переменные при выполнении плейбуков на шаге 8. На следующем шаге вы будете использовать Ansible Vault для создания и защиты пароля для пользователя, который будет создан на каждом хосте.Шаг 5 — Использование Ansible Vault для создания зашифрованного файла паролей
Ansible Vault используется для создания и шифрования файлов и переменных, на которые можно ссылаться в плейбуках. Использование Ansible Vault гарантирует, что конфиденциальная информация не будет передаваться в виде открытого текста при выполнении плейбука. На этом шаге вы создадите и зашифруете файл, содержащий переменные, значения которых будут использоваться для создания пароля для пользователя
sudo
на каждом хосте. Используя Ansible Vault таким образом, вы гарантируете, что пароль не будет упоминаться открытым текстом в книгах воспроизведения во время и после первоначальной настройки сервера.Находясь в каталоге
ansible-ubuntu
, используйте следующую команду, чтобы создать и открыть файл хранилища:- ansible-vault create secret
При появлении запроса введите и подтвердите пароль, который будет использоваться для шифрования файла
secret
. Это пароль хранилища. Вам понадобится пароль хранилища при запуске плейбуков на шаге 8, поэтому не забывайте его.После ввода и подтверждения пароля хранилища файл
secret
откроется в текстовом редакторе, связанном с переменной окруженияEDITOR
оболочки. Добавьте эти строки в файл, заменив значения дляtype_a_strong_password_here
иtype_a_salt_here
:- password: type_a_strong_password_here
- password_salt: type_a_salt_here
Значение переменной
password
будет фактическим паролем для пользователяsudo
, которого вы создадите на каждом хосте. Переменнаяpassword_salt
использует в качестве значения salt. Шаг 8.Примечание. В ходе тестирования мы обнаружили, что соль, состоящая только из числовых символов, приводила к проблемам с запуском плейбука на шаге 8. Однако соль, состоящая только из буквенных символов, работала. Буквенно-цифровая соль также должна работать. Имейте это в виду, когда будете указывать соль.
Когда вы закончите изменять файл, сохраните и закройте его.
Теперь вы создали зашифрованный файл паролей с переменными, которые будут использоваться для создания пароля для пользователя
sudo
на хостах. На следующем шаге вы автоматизируете первоначальную настройку серверов, указанных на шаге 2, запустив основной плейбук Ansible.Шаг 6 — Запуск основной пьесы против ваших хостов Ansible
На этом этапе вы будете использовать Ansible для автоматизации первоначальной настройки серверов, указанных в файле инвентаризации. Вы начнете с просмотра задач, определенных в основном сборнике сценариев. Затем вы запустите плейбук против хостов.
Плейбук Ansible состоит из одного или нескольких воспроизведений с одной или несколькими задачами, связанными с каждым воспроизведением. Образец плейбука, который вы будете запускать на хостах Ansible, содержит две игры с 14 задачами.
Перед запуском playbook вы просмотрите каждую задачу, связанную с процессом ее установки. Для начала откройте файл с помощью
nano
или вашего любимого текстового редактора:- nano initial.yml
Играть 1:
Первый раздел файла содержит следующие ключевые слова, влияющие на поведение воспроизведения:
- name: Initial server setup tasks hosts: initial remote_user: root vars_files: - vars/default.yml - secret ...
название
— это краткое описание воспроизведения, которое будет отображаться в терминале во время воспроизведения. Ключевое словоhosts
указывает, какие хосты являются целевыми для воспроизведения. В этом случае шаблон, переданный ключевому слову, представляет собой имя группы хостов, указанное вами в файле/etc/ansible/hosts
на шаге 2. Вы используетеremote_user
ключевое слово, чтобы сообщить контроллеру Ansible имя пользователя для входа на хосты (в данном случаеroot
). Ключевое словоvars_files
указывает на файлы, содержащие переменные, на которые будет ссылаться воспроизведение при выполнении задач.При такой настройке контроллер Ansible попытается войти на хосты как пользователь
root
через SSH-порт22
. Для каждого хоста, на который он может войти, он сообщит об ответеok
. В противном случае он сообщит, что сервернедоступен
, и начнет выполнять задачи воспроизведения для любого хоста, на который можно войти. Если вы выполняли эту настройку вручную, эта автоматизация заменяет вход на хост с использованиемssh root@host-ip-address
.За разделом ключевых слов следует список задач, которые должны выполняться последовательно. Как и в игре, каждая задача начинается с
названия
, которое дает краткое описание того, что задача должна выполнить.Задача 1: Обновить кеш
Первая задача в playbook обновляет базу данных пакетов:
... - name: update cache ansible.builtin.apt: update_cache: yes ...
Эта задача обновит базу данных пакетов с помощью модуля
ansible.builtin.apt
, поэтому он определяется с помощьюupdate_cache: yes
. Эта задача выполняет то же самое, что и при входе на сервер Ubuntu и вводеsudo apt update
, что часто является прелюдией к обновлению всех установленных пакетов.Задача 2: обновить все установленные пакеты
Вторая задача в плейбуке обновляет пакеты:
... - name: Update all installed packages ansible.builtin.apt: name: "*" state: latest ...
Как и первая задача, эта задача также вызывает модуль
ansible.builtin.apt
. Здесь вы убедитесь, что все установленные пакеты обновлены, используя подстановочный знак для указания пакетов (name: *
) иstate: last
, что было бы эквивалентно войдите на свои серверы и выполните командуsudo apt upgrade -y
.Задача 3. Убедитесь, что служба NTP запущена
Третья задача в плейбуке гарантирует, что демон Network Time Protocol (NTP) активен:
... - name: Make sure NTP service is running ansible.builtin.systemd: state: started name: systemd-timesyncd ...
Эта задача вызывает модуль
ansible.builtin.systemd
, чтобы убедиться, чтоsystemd-timesyncd
, демон NTP, работает (состояние: запущено
). Вы запускаете такую задачу, когда хотите, чтобы ваши серверы сохраняли одинаковое время, что может помочь запустить распределенное приложение на этих серверах.Задача 4: Убедитесь, что у нас есть группа sudo
Четвертая задача в плейбуке проверяет наличие группы
sudo
:... - name: Make sure we have a 'sudo' group ansible.builtin.group: name: sudo state: present ...
Эта задача вызывает модуль
ansible.builtin.group
, чтобы проверить, существует ли на хостах группа с именемsudo
(состояние: присутствует
). Поскольку ваша следующая задача зависит от наличия группыsudo
на хостах, эта задача проверяет существование группsudo
, поэтому вы можете быть уверены, что следующая задача не завершится ошибкой. .Задача 5: Создайте пользователя с привилегиями sudo
Пятая задача в плейбуке создает пользователя без полномочий root с привилегиями
sudo
:... - name: Create a user with sudo privileges ansible.builtin.user: name: "{{ create_user }}" state: present groups: sudo append: true create_home: true shell: /bin/bash password: "{{ password | password_hash('sha512', password_salt) }}" update_password: on_create ...
Здесь вы создаете пользователя на каждом хосте, вызывая модуль
ansible.builtin.user
и добавляя группуsudo
в группы пользователей. Имя пользователя получается из значения переменнойcreate_user
, которое вы указали вvars/default.yml
. Эта задача также гарантирует, что для пользователя будет создан домашний каталог, которому будет назначена надлежащая оболочка.Используя параметр
password
и комбинацию пароля и соли, которые вы установили в алгоритме криптографического хеширования SHA-512, генерируется хешированный пароль для пользователя. Вместе с файлом хранилищаsecret
пароль никогда не передается контроллеру в открытом виде. С помощьюupdate_password
вы гарантируете, что хешированный пароль будет установлен только при первом создании пользователя. Если вы повторно запустите playbook, пароль не будет восстановлен.Задача 6: Установить авторизованный ключ для удаленного пользователя
Шестая задача в playbook устанавливает ключ для вашего пользователя:
... - name: Set authorized key for remote user ansible.posix.authorized_key: user: "{{ create_user }}" state: present key: "{{ copy_local_key }}" ...
В этой задаче вы копируете свой открытый SSH-ключ на хосты, вызывая
ansible.posix.authorized_key
. Значениеuser
— это имя пользователя, созданное на хостах в предыдущей задаче, аkey
указывает на копируемый ключ. Обе переменные определены в файлеvar/default.yml
. Эта задача имеет тот же эффект, что и запуск командыssh-copy-id
вручную.Задача 7: отключить удаленный вход для root
Седьмая задача в плейбуке отключает удаленный вход для пользователя
root
:... - name: Disable remote login for root ansible.builtin.lineinfile: path: /etc/ssh/sshd_config state: present regexp: '^PermitRootLogin yes' line: 'PermitRootLogin no' ...
Затем вы вызываете модуль
ansible.builtin.lineinfile
. Эта задача ищет строку, начинающуюся сPermitRootLogin
, в файле/etc/ssh/sshd_config
, используя регулярное выражение (regexp
), а затем заменяет со значениемline
. Эта задача гарантирует, что удаленный вход с использованием учетной записиroot
не будет выполнен после запуска воспроизведения в этой книге воспроизведения. Только удаленный вход с учетной записью пользователя, созданной в задаче 6, будет успешным. Отключив удаленный вход в систему root, вы гарантируете, что только обычные пользователи могут войти в систему, и что для получения прав администратора потребуется метод повышения привилегий, обычноsudo
.Задача 8: Изменить порт SSH
Восьмая задача в плейбуке изменяет порт SSH:
... - name: Change the SSH port ansible.builtin.lineinfile: path: /etc/ssh/sshd_config state: present regexp: '^#Port 22' line: 'Port "{{ ssh_port }}"' ...
Поскольку SSH прослушивает хорошо известный порт
22
, он, как правило, подвергается автоматическим атакам, нацеленным на этот порт. Изменяя порт, который прослушивает SSH, вы уменьшаете количество автоматических атак на хосты. Эта задача использует тот же модульansible.builtin.lineinfile
для поиска строки, которая начинается сregexp
в файле конфигурации демона SSH, и изменяет ее значение на значение < параметрстрока. Новый номер порта, который прослушивает SSH, будет номером порта, который вы присвоили переменнойssh_port
на шаге 4. После перезапуска хостов в конце этого воспроизведения вы не сможете войти в систему. к хостам через порт22
.Задача 9: UFW — разрешить SSH-подключения
Девятая задача в плейбуке разрешает SSH-трафик:
... - name: UFW - Allow SSH connections community.general.ufw: rule: allow port: "{{ ssh_port }}" ...
Здесь вы вызываете шаг 4. Эта задача эквивалентна ручному запуску команды
ufw allow 5995/tcp
.Задача 10: Защита от перебора SSH
Десятая задача защищает от атак грубой силы:
... - name: Brute-force attempt protection for SSH community.general.ufw: rule: limit port: "{{ ssh_port }}" proto: tcp ...
При повторном вызове модуля
community.general.ufw
эта задача использует ограничивающее скоростьrule
, чтобы отказать в доступе для входа в систему с IP-адреса, потерпевшего шесть или более неудачных попыток подключения к Порт SSH в течение 30 секунд. Параметрproto
указывает на целевой протокол (в данном случае TCP).Задача 11: UFW — запретить другой входящий трафик и включить UFW
Одиннадцатая задача включает брандмауэр:
... - name: UFW - Deny other incoming traffic and enable UFW community.general.ufw: state: enabled policy: deny direction: incoming ...
По-прежнему полагаясь на модуль
community.general.ufw
в этой задаче, вы включаете брандмауэр (состояние: включено
) и устанавливаетеполитику
по умолчанию, которая запрещает весь входящий трафик.Задача 12: Удалите зависимости, которые больше не требуются
Двенадцатая задача в этой пьесе очищает зависимости пакетов:
... - name: Remove dependencies that are no longer required ansible.builtin.apt: autoremove: yes ...
При повторном вызове модуля
ansible.builtin.apt
эта задача удаляет зависимости пакетов, которые больше не требуются на сервере, что эквивалентно запуску командыsudo apt autoremove
. вручную.Задача 13. Перезапустите демон SSH.
Тринадцатая задача в этом плейбуке перезапускает SSH.
... - name: Restart the SSH daemon ansible.builtin.systemd: state: restarted name: ssh
Последняя задача вызывает модуль
ansible.builtin.systemd
для перезапуска демона SSH. Этот перезапуск необходимо выполнить, чтобы изменения, внесенные в файл конфигурации демона, вступили в силу. Эта задача имеет тот же эффект, что и перезапуск демона с помощьюsudo systemctl restart ssh
.Первоначальное подключение к хостам осуществлялось через порт
22
какroot
, но более ранние задачи изменили номер порта и отключили удаленный вход root, поэтому вам необходимо перезапустить SSH. демон на данном этапе пьесы. Во втором воспроизведении будут использоваться другие учетные данные для подключения (имя пользователя вместоroot
и вновь определенный номер порта, отличный от22
).Игра 2: Перезагрузка хостов после первоначальной настройки
Эта игра начинается после успешного завершения последней задачи в игре 1. На него влияют следующие ключевые слова:
... - name: Rebooting hosts after initial setup hosts: initial port: "{{ ssh_port }}" remote_user: "{{ create_user }}" become: true vars_files: - vars/default.yml - ~/secret vars: ansible_become_pass: "{{ password }}" ...
Шаблон, передаваемый ключевому слову
hosts
, представляет собой имя группыinitial
, указанное в файле/etc/ansible/hosts
на шаге 4.В первом воспроизведении контроллер Ansible вошел на хосты как пользователь
root
. Поскольку удаленный вход в систему root отключен при первом воспроизведении, теперь вам нужно указать пользователя, под которым должен войти контроллер Ansible. Ключевое словоremote_user
указывает контроллеру Ansible войти на каждый хост как пользовательsudo
, созданный в задаче 5 первого воспроизведения.Ключевое слово
become
указывает, что повышение привилегий будет использоваться для выполнения задачи на определенных хостах. Это ключевое слово указывает контроллеру Ansible использовать привилегии root для выполнения задач на хостах, когда это необходимо. В этом случае контроллер примет привилегии суперпользователя, используяsudo
. Ключевое словоansible_become_pass
устанавливает пароль для повышения привилегий, то есть пароль, который будет использоваться для получения привилегий root. В этом случае он указывает на переменную с паролем, который вы настроили с помощью Ansible Vault на шаге 5.Помимо указания на файл
vars/default.yml
, ключевое словоvars_files
также указывает на файлsecret
, настроенный на шаге 5, который сообщает контроллеру Ansible, где найти переменнуюpassword
.После раздела ключевых слов находится единственная задача, которая будет выполняться в этой игре.
Задача 14: Перезагрузите все хосты
Примечание. Хотя это первая задача второй игры, она имеет номер 14, потому что Ansible Controller видит ее не как задачу 1 игры 2, а как задачу 14 игры.
Последняя задача плейбука перезагрузит все хосты:
... - name: Reboot all hosts ansible.builtin.reboot:
Перезагрузка хостов после выполнения задач в первом воспроизведении будет означать, что любые обновления ядра или библиотеки вступят в силу до того, как вы начнете устанавливать свои приложения.
Полный файл playbook выглядит так:
- name: Initial server setup tasks hosts: initial remote_user: root vars_files: - vars/default.yml - secret tasks: - name: update cache ansible.builtin.apt: update_cache: yes - name: Update all installed packages ansible.builtin.apt: name: "*" state: latest - name: Make sure NTP service is running ansible.builtin.systemd: state: started name: systemd-timesyncd - name: Make sure we have a 'sudo' group ansible.builtin.group: name: sudo state: present - name: Create a user with sudo privileges ansible.builtin.user: name: "{{ create_user }}" state: present groups: sudo append: true create_home: true shell: /bin/bash password: "{{ password | password_hash('sha512', password_salt) }}" update_password: on_create - name: Set authorized key for remote user ansible.builtin.authorized_key: user: "{{ create_user }}" state: present key: "{{ copy_local_key }}" - name: Disable remote login for root ansible.builtin.lineinfile: path: /etc/ssh/sshd_config state: present regexp: '^PermitRootLogin yes' line: 'PermitRootLogin no' - name: Change the SSH port ansible.builtin.lineinfile: path: /etc/ssh/sshd_config state: present regexp: '^#Port 22' line: 'Port "{{ ssh_port }}"' - name: UFW - Allow SSH connections community.general.ufw: rule: allow port: "{{ ssh_port }}" - name: Brute-force attempt protection for SSH community.general.ufw: rule: limit port: "{{ ssh_port }}" proto: tcp - name: UFW - Deny other incoming traffic and enable UFW community.general.ufw: state: enabled policy: deny direction: incoming - name: Remove dependencies that are no longer required ansible.builtin.apt: autoremove: yes - name: Restart the SSH daemon ansible.builtin.systemd: state: restarted name: ssh - name: Rebooting hosts after initial setup hosts: initial port: "{{ ssh_port }}" remote_user: "{{ create_user }}" become: true vars_files: - vars/default.yml - secret vars: ansible_become_pass: "{{ password }}" tasks: - name: Reboot all hosts ansible.builtin.reboot:
Закончив просмотр файла, сохраните и закройте его.
Примечание. Вы можете добавлять новые задания в книгу или изменять существующие. Однако изменение файла YAML может привести к его повреждению, поскольку YAML чувствителен к пробелам, поэтому будьте осторожны, если вы решите отредактировать какой-либо аспект файла. Чтобы узнать больше о работе с плейбуками Ansible, следуйте нашей серии статей о том, как писать плейбуки Ansible.
Теперь вы можете запустить playbook. Сначала проверьте синтаксис:
- ansible-playbook --syntax-check --ask-vault-pass initial.yml
Вам будет предложено ввести пароль хранилища, который вы создали на шаге 5. Если после успешной аутентификации нет ошибок с синтаксисом YAML, вывод будет таким:
Outputplaybook: initial.ymlТеперь вы можете запустить файл с помощью следующей команды:
- ansible-playbook --ask-vault-pass initial.yml
Вам снова будет предложено ввести пароль хранилища. После успешной аутентификации контроллер Ansible войдет на каждый хост как пользователь
root
и выполнит все задачи в плейбуке. Вместо того, чтобы запускать командуssh root@node-ip-address
на каждом сервере отдельно, Ansible подключается ко всем узлам, указанным в/etc/ansible/hosts
, а затем выполняет задачи в playbook.Для примеров хостов в этом руководстве Ansible потребовалось около трех минут, чтобы выполнить задачи на трех хостах. Когда задачи будут выполнены, вы получите вывод, подобный следующему:
OutputPLAY RECAP ***************************************************************************************************** host1 : ok=16 changed=11 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 host2 : ok=16 changed=11 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 host3 : ok=16 changed=11 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0Каждая задача и раздел ключевого слова игры, которые успешно оцениваются, будут учитываться в числе в столбце
ok
. При 14 задачах в двух играх, все из которых успешно оценены, количество составляет16
. Из оцененных задач только11
привели к изменениям на серверах, представленным столбцомchanged
.Счетчик
unreachable
показывает количество хостов, на которые контроллер Ansible не смог войти. Ни одна из задач не завершилась неудачей, поэтому счетчикfailed
равен0
.Задача
пропускается
, когда условие, указанное в задаче, не выполняется (обычно с параметромwhen
). В этом случае никакие задачи непропускаются
, но это будет применимо на шаге 8.Последние два столбца (
recued
иignored
) относятся к обработке ошибок, указанных для воспроизведения или задачи.Теперь вы успешно автоматизировали первоначальную настройку нескольких серверов Ubuntu 22.04, используя Ansible для выполнения одной команды, которая выполняет все задачи, указанные в playbook.
Чтобы убедиться, что все работает должным образом, вы войдете на один из хостов, чтобы проверить настройку.
(Необязательно) Шаг 7 — Проверка настройки сервера вручную
Чтобы подтвердить вывод отчета об игре в конце предыдущего шага, вы можете войти на один из ваших хостов, используя учетные данные, которые были настроены ранее для проверки установки. Эти действия необязательны для целей обучения, поскольку отчет Ansible сообщает о точном выполнении.
Начните с входа на один из хостов с помощью следующей команды:
- ssh -p 5995 sammy@host1-public-ip-address
Вы используете параметр
-p
, чтобы указать на пользовательский номер порта, который вы настроили для SSH на шаге 6. Если вы можете войти на хост как этот пользователь через этот порт, вы знаете, что Ansible успешно выполнила эти задачи.После входа в систему проверьте, можете ли вы обновить базу данных пакетов:
- sudo apt update
Если вам будет предложено ввести пароль, и вы сможете пройти аутентификацию с помощью пароля, который вы настроили для пользователя на шаге 5, вы можете подтвердить, что Ansible успешно выполнил задачи по созданию пользователя и установке пароля пользователя.
Теперь, когда вы знаете, что сценарий установки работает должным образом, вы можете запустить второй сценарий для текущего обслуживания.
(Необязательно) Шаг 8 — Использование Ansible для текущего обслуживания хостов
В плейбуке начальной настройки сервера, который был выполнен на шаге 3, вы также вытащили плейбук
ongoing.yml
, который можно использовать для дальнейшего обслуживания. На этом шаге вы запустите плейбукongoing.yml
, чтобы автоматизировать текущее обслуживание хостов, настроенных в этом руководстве.Перед запуском сборника сценариев вы просмотрите каждую задачу. Для начала откройте файл с помощью
nano
или вашего любимого текстового редактора:- nano ongoing.yml
В отличие от сборника первоначальных настроек, сценарий обслуживания содержит только один сценарий и меньше задач.
Играть 1:
Следующие ключевые слова в первом разделе файла влияют на поведение воспроизведения:
- hosts: ongoing port: "{{ ssh_port }}" remote_user: "{{ create_user }}" become: true vars_files: - vars/default.yml - secret vars: ansible_become_pass: "{{ password }}" ...
За исключением группы, переданной ключевому слову
hosts
, это те же самые ключевые слова, которые использовались во втором воспроизведении схемы установки.После ключевых слов идет список задач, которые нужно выполнить последовательно. Как и в пособии по настройке, каждая задача в пособии по обслуживанию начинается с
name
, которое дает краткое описание того, что задача будет выполнять.Задача 1: Обновить кеш
Первая задача обновляет базу данных пакета:
... - name: update cache ansible.builtin.apt: update_cache: yes ...
Эта задача обновит базу данных пакетов с помощью модуля
ansible.builtin.apt
, поэтому он определяется с помощьюupdate_cache: yes
. Эта задача выполняет то же самое, что и при входе на сервер Ubuntu и вводеsudo apt update
, что часто является прелюдией к установке пакета или обновлению всех установленных пакетов.Задача 2: обновить все установленные пакеты
Вторая задача обновляет пакеты:
... - name: Update all installed packages ansible.builtin.apt: name: "*" state: latest ...
Как и первая задача, эта задача также вызывает модуль
ansible.builtin.apt
. Здесь вы гарантируете, что все установленные пакеты обновлены, используя подстановочный знак для указания пакетов (name: *
) иstate: last
, что было бы эквивалентно войдите на свои серверы и выполните командуsudo apt upgrade -y
.Задача 3. Убедитесь, что служба NTP запущена
Третья задача в плейбуке обеспечивает настройку демона NTP:
... - name: Make sure NTP service is running ansible.builtin.systemd: state: started name: systemd-timesyncd ...
Активные службы на сервере могут выйти из строя по разным причинам, поэтому вы должны убедиться, что такие службы остаются активными. Эта задача вызывает модуль
ansible.builtin.systemd
, чтобы убедиться, чтоsystemd-timesyncd
, демон NTP, остается активным (состояние: запущено
).Задача 4: UFW — работает ли он?
Четвертая задача проверяет состояние брандмауэра UFW:
... - name: UFW - Is it running? ansible.builtin.command: ufw status register: ufw_status ...
Вы можете проверить состояние брандмауэра UFW в Ubuntu с помощью команды
sudo ufw status
. В первой строке вывода будет указано либоStatus: active
, либоStatus: inactive
. Эта задача использует модульansible.builtin.command
для запуска той же команды, а затем сохраняет (register
) вывод вufw_status.
переменная. Значение этой переменной будет запрошено в следующей задаче.Задача 5: UFW — включить UFW и запретить входящий трафик
Пятая задача повторно включит брандмауэр UFW, если он был остановлен:
... - name: UFW - Enable UFW and deny incoming traffic community.general.ufw: state: enabled when: "'inactive' in ufw_status.stdout" ...
Эта задача вызывает модуль
community.general.ufw
для включения брандмауэра только тогда, когда терминinactive
появляется в выходных данныхufw_status.
переменная. Если брандмауэр активен, то условиекогда
не выполняется, и задача помечается какпропущенная
.Задача 6. Удалите зависимости, которые больше не требуются
Шестая задача в этом плейбуке очищает зависимости пакетов:
... - name: Remove dependencies that are no longer required ansible.builtin.apt: autoremove: yes ...
Эта задача удаляет зависимости пакетов, которые больше не требуются на сервере, путем вызова модуля
ansible.builtin.apt
, что эквивалентно запуску командыsudo apt autoremove
.Задача 7: проверьте, требуется ли перезагрузка
Седьмая задача проверяет, требуется ли перезагрузка:
... - name: Check if reboot required ansible.builtin.stat: path: /var/run/reboot-required register: reboot_required ...
В Ubuntu вновь установленный или обновленный пакет будет сигнализировать о том, что для вступления в силу изменений, которые были введены при установке или обновлении, требуется перезагрузка, путем создания файла
/var/run/reboot-required
. Вы можете проверить, существует ли этот файл, используя командуstat /var/run/reboot-required
. Эта задача вызывает модульansible.builtin.stat
, чтобы сделать то же самое, а затем сохраняет (register
) вывод вreboot_required.
переменная. Значение этой переменной будет запрошено в следующей задаче.Задача 8: Перезагрузите компьютер, если требуется
Восьмая задача при необходимости перезагрузит сервер:
... - name: Reboot if required ansible.builtin.reboot: when: reboot_required.stat.exists == true
Запрашивая переменную
reboot_required
из задачи 7, эта задача вызывает модульansible.builtin.reboot
для перезагрузки хостов толькокогда
существует/var/run/reboot-required
. Если требуется перезагрузка и перезагружается хост, задача помечается какизмененная
. В противном случае Ansible отмечает его какпропущенный
в обзоре игры.Полный файл playbook для текущего обслуживания будет выглядеть следующим образом:
- hosts: ongoing port: "{{ ssh_port }}" remote_user: "{{ create_user }}" become: true vars_files: - vars/default.yml - secret vars: ansible_become_pass: "{{ password }}" tasks: - name: update cache ansible.builtin.apt: update_cache: yes - name: Update all installed packages ansible.builtin.apt: name: "*" state: latest - name: Make sure NTP service is running ansible.builtin.systemd: state: started name: systemd-timesyncd - name: UFW - Is it running? ansible.builtin.command: ufw status register: ufw_status - name: UFW - Enable UFW and deny incoming traffic community.general.ufw: state: enabled when: "'inactive' in ufw_status.stdout" - name: Remove dependencies that are no longer required ansible.builtin.apt: autoremove: yes - name: Check if reboot required ansible.builtin.stat: path: /var/run/reboot-required register: reboot_required - name: Reboot if required ansible.builtin.reboot: when: reboot_required.stat.exists == true
Закончив просмотр файла, сохраните и закройте его.
Примечание. Вы можете добавлять новые задачи или изменять существующие задачи в playbook. Однако изменение файла YAML может привести к его повреждению, поскольку YAML чувствителен к пробелам, поэтому будьте осторожны, если вы решите отредактировать какой-либо аспект файла. Чтобы узнать больше о работе с плейбуками Ansible, следуйте нашей серии статей о том, как писать плейбуки Ansible.
Теперь вы можете запустить файл. Сначала проверьте синтаксис:
- ansible-playbook --syntax-check --ask-vault-pass ongoing.yml
Вам будет предложено ввести пароль хранилища, который вы создали на шаге 5. Если после успешной аутентификации нет ошибок с синтаксисом YAML, вывод будет таким:
Outputplaybook: ongoing.ymlТеперь вы можете запустить файл с помощью следующей команды:
- ansible-playbook --ask-vault-pass ongoing.yml
Вам будет предложено ввести пароль хранилища. После успешной аутентификации контроллер Ansible войдет на каждый хост как
sammy
(или указанное вами имя пользователя) для выполнения задач в playbook. Вместо запуска командыssh -p 5995 sammy@host_ip_address
на каждом сервере отдельно, Ansible подключается к узлам заданный группойcongoing
в/etc/ansible/hosts
, а затем выполняет задачи в playbook.Если команда завершится успешно, будет напечатан следующий вывод:
OutputPLAY RECAP ***************************************************************************************************** host1 : ok=7 changed=2 unreachable=0 failed=0 skipped=2 rescued=0 ignored=0 host2 : ok=7 changed=2 unreachable=0 failed=0 skipped=2 rescued=0 ignored=0 host3 : ok=7 changed=2 unreachable=0 failed=0 skipped=2 rescued=0 ignored=0В отличие от сводки воспроизведения для первоначальной настройки сервера, в этой сводке воспроизведения отмечены две задачи, которые были
пропущены
, поскольку условие, установленное для каждой задачи с параметромwhen
, не было выполнено.Вы можете использовать этот плейбук для обслуживания хостов без необходимости входа на каждый хост вручную. Когда вы создаете и устанавливаете приложения на хостах, вы можете добавлять задачи в playbook, чтобы вы также могли управлять этими приложениями с помощью Ansible.
Заключение
В этом руководстве вы использовали Ansible для автоматизации первоначальной настройки нескольких серверов Ubuntu 22.04. Вы также запустили дополнительный сценарий для текущего обслуживания этих серверов. Автоматизация Ansible — это инструмент для экономии времени, когда вам нужно настроить приложение, такое как MinIO, в распределенном или кластерном режиме.
Более подробная информация об Ansible доступна на странице Управление конфигурацией 101: Написание Ansible Playbooks.