Prerequisites
Перед установкой Ansible ознакомьтесь с требованиями к управляющему узлу.Перед использованием Ansible ознакомьтесь с требованиями к управляемым узлам (конечным устройствам,которые вы хотите автоматизировать).Управляющие узлы и управляемые узлы имеют разные минимальные требования.
Требования к узлам управления
Для вашего управляющего узла (машины, на которой работает Ansible) вы можете использовать любую машину с установленным Python 2 (версия 2.7) или Python 3 (версия 3.5 и выше). ansible-core 2.11 и Ansible 4.0.0 сделают Python 3.8 мягкой зависимостью для управляющего узла, но будут работать с вышеупомянутыми требованиями. Для работы ansible-core 2.12 и Ansible 5.0.0 на управляющем узле требуется Python 3.8 или новее. Начиная с ansible-core 2.11, проект будет упакован только для Python 3.8 и новее. Сюда входят Red Hat, Debian, CentOS, macOS, любые BSD и так далее. Windows не поддерживается для управляющего узла, подробнее об этом читайте в блоге Мэтта Дэвиса .
Warning
Обратите внимание,что некоторые плагины,работающие на узле управления,имеют дополнительные требования.Эти требования должны быть перечислены в документации к плагину. При выборе узла управления помните,что любая система управления выигрывает,если она работает рядом с управляемыми машинами.Если вы используете Ansible для управления машинами в облаке,рассмотрите возможность использования машины внутри этого облака в качестве узла управления.В большинстве случаев Ansible будет работать лучше с машины в облаке,чем с машины в открытом Интернете
При выборе узла управления помните,что любая система управления выигрывает,если она работает рядом с управляемыми машинами.Если вы используете Ansible для управления машинами в облаке,рассмотрите возможность использования машины внутри этого облака в качестве узла управления.В большинстве случаев Ansible будет работать лучше с машины в облаке,чем с машины в открытом Интернете.
Warning
Ansible 2.11 сделает Python 3.8 мягкой зависимостью для узла управления,но будет функционировать с вышеупомянутыми требованиями.Ansible 2.12 потребует Python 3.8 или новее для работы на узле управления.Начиная с Ansible 2.11,проект будет упакован только для Python 3.8 и новее.
Управляемые требования к узлам
Хотя вам не нужен демон на ваших управляемых узлах, вам нужен способ для Ansible общаться с ними. Для большинства управляемых узлов Ansible устанавливает соединение по SSH и передает модули с помощью SFTP. Если SSH работает, но SFTP недоступен на некоторых из ваших управляемых узлов, вы можете переключиться на SCP в . Для любого компьютера или устройства, на котором может работать Python, вам также понадобится Python 2 (версия 2.6 или новее) или Python 3 (версия 3.5 или новее).
Warning
Обратите внимание, что к некоторым модулям предъявляются дополнительные требования, которые необходимо удовлетворить на «целевой» машине (управляемом узле). Эти требования должны быть перечислены в документации модуля
Note
- Если у вас включен SELinux на удаленных узлах, вы также захотите установить на них libselinux-python перед использованием каких-либо функций, связанных с копированием / файлом / шаблоном в Ansible. Вы можете использовать или в Ansible, чтобы установить этот пакет в удаленных системах, в которых его нет.
- По умолчанию, прежде чем первый модуль Python в playbook запускается на хосте, Ansible пытается найти подходящий интерпретатор Python на этом хосте. Вы можете переопределить поведение обнаружения, установив для переменной инвентаря конкретный интерпретатор и другими способами. См. Подробности в разделе « .
-
Ansible’s , and the , do not depend on a client side install of Python to run. Technically, you can use Ansible to install a compatible version of Python using the , which then allows you to use everything else. For example, if you need to bootstrap Python 2 onto a RHEL-based system, you can install it as follows:
$ ansible myhost
Configure Nginx
It is not enough to install Nginx we also need to configure it. This involves a couple of steps.
1) Creating a configuration file.
examples/ansible/static_site.cfg
server { listen 80 default_server; listen :80 default_server; root /home/foo/static-site; server_name _; location / { try_files $uri $uri/ =404; } }
2) Putting it /etc/nginx/sites-available/.
3) Creating a symbolic link from /etc/nginx/sites-enabled/ to that file.
4) Creating a directory where we put the pages of the website. For simplicity we are going to create a static web site. Without an application behind it. Just an HTML file and an image.
Locally they look like this:
static-site-src/ index.html ansible-logo.jpg
examples/ansible/static-site-src/index.html
<h1>Welcome to Ansible</h1> <img src="/ansible-logo.jpg" />
On the servers I’d like to put them in the static-site directory of user «foo».
That is in /home/foo/static-site.
5) Tell nginx to reload its configuration files.
2: Установка зависимостей
Теперь нужно установить и настроить несколько пакетов, которые понадобятся для дальнейшей работы: git, nginx, sqlite3, mcrypt и пару пакетов php5-*.
Для начала создайте базовый плейбук php.yml:
Добавьте в него следующие настройки. Первые две строки задают группу хостов, которую нужно использовать (в нашем случае php) и запускают команды с sudo. Остальные строки добавляют модуль с необходимыми пакетами. В случае необходимости вы можете откорректировать список пакетов в зависимости от потребностей приложения.
Сохраните php.yml. Запустите ansible-playbook, чтобы установить эти пакеты на сервер. Добавьте опцию –ask-sudo-pass, если вам нужно ввести пароль пользователя sudo сервера PHP.
The Ansible Playbook to set up Nginx
examples/ansible/nginx.yml
--- - hosts: all tasks: - name: ensure nginx is at the latest version apt: name=nginx state=latest become: yes - name: start nginx service: name: nginx state: started become: yes - name: copy the nginx config file and restart nginx copy: src: /home/foo/static_site.cfg dest: /etc/nginx/sites-available/static_site.cfg become: yes - name: create symlink file: src: /etc/nginx/sites-available/static_site.cfg dest: /etc/nginx/sites-enabled/default state: link become: yes - name: copy the content of the web site copy: src: /home/foo/static-site-src/ dest: /home/foo/static-site - name: restart nginx service: name: nginx state: restarted become: yes
Then I run this command:
$ ansible-playbook -i inventory.cfg --limit 192.168.56.11 nginx.yml
Note, this time I have not supplied the -b flag to become root. Instead for each step where I wanted the command to be executed with sudo I’ve added the become: yes parameter.
The output looked like this:
PLAY ****************************************************************************************** TASK ****************************************************************************** ok: TASK ******************************************************** changed: TASK ********************************************************************************** changed: TASK ************************************************* changed: TASK ******************************************************************************* changed: TASK ************************************************************* changed: TASK ******************************************************************************** changed: PLAY RECAP ****************************************************************************************** 192.168.56.11 : ok=7 changed=6 unreachable=0 failed=0
Then I could go ahead and check
$ curl http://192.168.56.11
That printed:
<h1>Welcome to Ansible</h1> <img src="/ansible-logo.jpg" />
When I visited the http://192.168.56.11/ from my desktop machine, it showed me the web page as I expected it, with the logo of Ansible.
5: Установка приложения с помощью Composer
С помощью инструмента Composer установите PHP-приложение и его зависимости.
Composer предоставляет команду create-project, которая устанавливает все необходимые зависимости и выполняет все действия, описанные в разделе post-create-project-cmd файла composer.json. Это обеспечивает правильную настройку приложения.
Чтобы загрузить Composer в /usr/local/bin/composer, используйте следующую задачу Ansible.
После установки Composer появляется доступ к его модулям. В данном случае нужно указать, где находится проект (с помощью параметра working_dir), а затем запустить команду create-project как пользователь www-data.
Примечание: Задача create-project может занять много времени на свежем сервере, поскольку Composer не сможет использовать кэш файлов и будет загружать всё необходимое самостоятельно.
Откройте php.yml:
В конец плейбука (раздел tasks, перед handlers) добавьте следующие задачи:
Запустите плейбук:
Если сейчас вы снова запустите Ansible, это опять запустит команду composer create-project, Laravel получит новый APP_KEY. Нужно сделать так, чтобы эта задача запускалась только после свежего клонирования. Для этого зарегистрируйте переменную с результатом задачи git clone и проверьте этот результат в задаче composer create-project. Итак, если задача git clone изменилась. Программа запустит задачу composer create-project; если изменений не произошло, эта задача будет пропущена.
Примечание: Модуль composer в некоторых версиях Ansible содержит баг, который выдаёт OK вместо Changed, так как он игнорирует выполненные скрипты, даже если не было установлено никаких зависимостей.
Откройте файл php.yml:
Найдите задачу git clone. Добавьте опцию register, которая будет сохранять результаты этой задачи в переменной cloned:
Найдите задачу composer create-project. Добавьте опцию when, которая проверяет изменения переменной cloned.
Запустите плейбук:
Теперь Composer не будет изменять APP_KEY после каждого запуска.
Enabling the Nginx Site
Cool! Once it’s in that directory, we need to enable it… which means we need to
create a symbolic link from to that file in .
And we already know the perfect module for this: !
Add the new task: «Enable Symfony config template from Nginx available sites».
We still need and use the module:
137 lines
— | |
— hosts: vb | |
… lines 3 — 8 | |
tasks: | |
… lines 10 — 46 | |
— name: Add Symfony config template to the Nginx available sites | |
… lines 48 — 52 | |
— name: Enable Symfony config template from Nginx available sites | |
become: true | |
file: | |
… lines 56 — 137 |
This time, for , copy the line from above. For ,
just change it to :
137 lines
— | |
— hosts: vb | |
… lines 3 — 8 | |
tasks: | |
… lines 10 — 46 | |
— name: Add Symfony config template to the Nginx available sites | |
… lines 48 — 52 | |
— name: Enable Symfony config template from Nginx available sites | |
become: true | |
file: | |
src: «/etc/nginx/sites-available/` server_name `.conf» | |
dest: «/etc/nginx/sites-enabled/` server_name `.conf» | |
state: link | |
… lines 59 — 137 |
To create the symbolic link, use . Earlier we created a directory
with .
The Playbook
Here is the YAML playbook file:
- name: Configure webserver with nginx and tls hosts: webservers become: True vars: key_file: /etc/nginx/ssl/nginx.key cert_file: /etc/nginx/ssl/nginx.crt conf_file: /etc/nginx/sites-available/default server_name: localhost tasks: - name: Install nginx apt: name=nginx update_cache=yes cache_valid_time=3600 - name: create directories for ssl certificates file: path=/etc/nginx/ssl state=directory - name: copy TLS key copy: src=files/nginx.key dest=` key_file ` owner=root mode=0600 notify: restart nginx - name: copy TLS certificate copy: src=files/nginx.crt dest=` cert_file ` notify: restart nginx - name: copy nginx config file template: src=templates/nginx.conf.j2 dest=` conf_file ` notify: restart nginx - name: enable configuration file: dest=/etc/nginx/sites-enabled/default src=` conf_file ` state=link notify: restart nginx - name: copy index.html template: src=templates/index.html.j2 dest=/usr/share/nginx/html/index.html mode=0644 handlers: - name: restart nginx service: name=nginx state=restarted
2: Настройка SSH-доступа к хостам Ansible
Как говорилось выше, Ansible в основном взаимодействует со своими клиентами по SSH. Конечно, он умеет обрабатывать парольную аутентификацию SSH, но проще использовать для этой цели SSH-ключи.
На сервере Ansible используйте команду cat, чтобы отобразить открытые ключи SSH в терминале:
Скопируйте результат в буфер обмена, затем откройте новый терминал и подключитесь в нем к клиенту Ansible по SSH:
Перейдите в сессию пользователя root:
Откройте файл authorized_keys:
Вставьте в файл SSH-ключи, скопированные с сервера, а затем сохраните и закройте файл (CTRL + X, Y, Enter). Затем введите exit, чтобы вернуться в сессию обычного пользователя.
Поскольку для запуска модулей Ansible использует интерпретатор python, который находится в /usr/bin/python, вам нужно установить на хост Python 2 (иначе Ansible не сможет взаимодействовать с ним). Запустите следующие команды:
Закройте подключение к клиенту:
Повторите этот процесс для каждого клиента Ansible.
Создание роли
Роли в Ansible используются для логического разделения плейбука. Они имеют строгий синтаксис и файловую структуру. Таким образом, конфигурация становится более упорядоченной и понятной для дальнейшей поддержки.
И так, для ролей должна быть четкая файловая структура — создаем каталоги:
mkdir -p /etc/ansible/roles/nginx/tasks
mkdir -p /etc/ansible/roles/epel/tasks
* в данном случае мы создали каталоги nginx, epel и tasks внутри каталога roles. В ansible это означает, что мы создали роли с названием nginx и epel, а файл main.yml, который мы поместим в каталоги tasks будет описывать задачи данных ролей.
Создаем файл с описанием задач для роли nginx:
vi /etc/ansible/roles/nginx/tasks/main.yml
—— name: Install Nginx Web Server on RedHat Family yum: name=nginx state=latest when: ansible_os_family == «RedHat» notify: — nginx systemd
— name: Install Nginx Web Server on Debian Family apt: name=nginx state=latest when: ansible_os_family == «Debian» notify: — nginx systemd
* где
- — — начало файла YAML;
- name — название для роли (может быть любым);
- yum/apt — используемый модуль для установки приложения;
- yum/apt name — название пакета, которое мы устанавливаем;
- yum/apt state — состояние пакета, которое должно контролироваться ролью;
- when — условие, при котором данная роль будет выполняться;
- notify — обработчик, который будет вызван в случае успешного выполнения задачи. При необходимости, можно задать несколько обработчиков;
* В данном примере мы создали простую задачу для роли по развертыванию nginx. На системы RPM установка выполняется с помощью модуля yum, на deb — apt. Версия должна быть последней (latest); после установки пакета, необходимо разрешить автозапуск сервиса и запустить его.* при установке пакетов также следует учитывать, что некоторые могут иметь разные названия в разных системах. Например, Apache в RMP-системах называется httpd, в deb — apache2.
Создаем файл с описанием задач для роли epel:
vi /etc/ansible/roles/epel/tasks/main.yml
—— name: Install EPEL Repo yum: name=epel-release state=present
Обратите внимание, что в плейбуке выше мы задействовали notify, но не задали handlers — в качестве примера, мы вынесем его в отдельный файл:
mkdir /etc/ansible/roles/nginx/handlers
vi /etc/ansible/roles/nginx/handlers/main.yml
—— name: nginx systemd systemd: name: nginx enabled: yes state: started
* handlers — описание обработчика, который может быть вызван с помощью notify; systemd — модуль для управления юнитами systemd; systemd enabled — разрешает или запрещает сервис; systemd state — состояние, которое должно быть у сервиса. В данном примере мы указываем, что у демона nginx должно быть состояние started и разрешен автозапуск (enabled).
Создание нового плейбука Ansible
Затем мы создадим новый плейбук Ansible и настроим переменные, которые мы использовали в предыдущем разделе этого руководства. Откройте новый файл playbook.yml:
Эта книга начинается с определения hosts со значением all и директивы become, которая сообщает Ansible по умолчанию запускать все задачи от имени пользователя root (то же самое, что и вручную запускать команды через sudo). В разделе var этого сценария мы создадим три переменные: server_name, document_root и app_root. Эти переменные используются в шаблоне конфигурации Nginx для настройки домена или IP-адреса, на который будет отвечать этот веб-сервер, а также для указания полного пути к расположению файлов сайта на сервере. В этом примере мы будем использовать переменную ansible_default_ipv4.address, потому что она содержит общедоступный IP-адрес удаленного сервера (но вы, конечно, можете заменить это значение именем хоста вашего сервера, если у него есть доменное имя, правильно настроенное в DNS):
--- - hosts: all become: yes vars: server_name: "` ansible_default_ipv4`.`address `" document_root: /var/www/html app_root: html_demo_site-main tasks:
Можете пока что оставить этот файл открытым. В следующих разделах мы рассмотрим все задачи, которые вам нужно будет включить в этот плейбук, чтобы сделать его полностью функциональной.
4) Install nginx and add extra variables to default config
-hosts: all vars: - my_extra_params: - client_max_body_size 200M # retain defaults and add additional `client_max_body_size` param roles: - role: jdauphant.nginx nginx_http_params: "{{ nginx_http_default_params + my_extra_params }}"
Note: Each site added is represented by a list of hashes, and the configurations
generated are populated in /etc/nginx/site-available/ and linked from /etc/nginx/site-enable/ to /etc/nginx/site-available.
The file name for the specific site configuration is specified in the hash
with the key «file_name», any valid server directives can be added to the hash.
Additional configurations are created in /etc/nginx/conf.d/
Шаг 2. Установите Docker и Docker Compose
AWX поддерживается и может запускаться только как контейнерное приложение с использованием образов Docker, развернутых в кластере OpenShift, кластере Kubernetes или docker-compose. В этом руководстве мы будем использовать Docker, чтобы запустить AWX.
Сначала загрузите файл репозитория Docker в /etc/yum.repos.d/docker-ce.repo и обновите кеш индекса RPM перед установкой Docker.
Запустите и включите Docker Service для запуска при загрузке и проверьте, работает ли он
Группа докеров создана, но в нее не добавляются пользователи. Добавьте своего пользователя в эту группу, чтобы запускать команды докеров без sudo.
Узнайте больше об установке Docker и Docker Compose в руководстве CentOS 8, чтобы установить Docker и docker-compose на ваш сервер Cent0S 8.
Затем мы будем использовать команду pip3, чтобы установить модуль docker-compose и docker python, как показано ниже.
Подтвердите установленную версию..
Теги
В нашем примере нам не довелось использовать теги — еще одну удобную возможность управления запуском плейбука.
Теги позволяют отметить роль и при запуске плейбука запустить именно ее, проигнорировав другие роли. Например, есть такой плейбук:
…
roles:
— role: nginx
tags: web1
— role: apache
tags: web2
* в данном плейбуке есть две роли — одна называется nginx, вторая — apache; для каждой роли мы задали свой тег.
Теперь, чтобы запустить плейбук, но выполнить в нем определенную роль, нам достаточно указать тег:
ansible-playbook —tags web2 /etc/ansible/play.yml -kK
* данная команда запустит плейбук с выполнением только роли с тегом web2 (в нашем примере, apache).
Проверки и условия
В данную группу войдут действия, которые помогут нам ограничить выполнение задач.
1. Проверка на пустую папку.
Задачи сводится к двум операциям:
- получении списка файлов в целевом каталоге (например, с помощью команды ls) и регистрации полученного значения в переменную с помощью register.
- проверка содержимого переменной, которую мы получили на шаге 1 с помощью when.
Пример будет таким:
— name: Register Contents of PGDATA Folder
shell: ls /var/lib/postgresql/11/main
register: pg_contents
— name: Init PostgreSQL DB
shell: /opt/pgpro/std-11/bin/pg-setup initdb
environment:
PGDATA: «/var/lib/postgresql/11/main»
when: pg_contents | length == 0
* в данном примере мы в первой задаче выводим содержимое каталога /var/lib/postgresql/11/main и помещаем его в переменную pg_contents. Во второй задаче мы уже проверяем с помощью when количество строк — если их 0, то тогда выполняем команду initdb
На практике, это важно, так как инициализация базы PostgreSQL при непустом каталоге выводит сообщение об ошибке
О when: https://docs.ansible.com/ansible/latest/user_guide/playbooks_conditionals.html.
2. Проверить, определена ли переменная.
Для этого используется опция is defined (определена) или is not defined (не определена):
when: pgpro is defined
when: pgpro is not defined
* в данном примере мы проверим наличие переменной pgpro. На практике такая проверка имеет значение, так как если мы попробуем выполнить действия с несуществующей переменной, Ansible нам вернет ошибку.
В официальной документации про это сказано в статье о when (ссылка выше).
3. Выполнение команды, если сервис в рабочем состоянии.
Нам необходимо получить информацию о службах с помощью service_facts, после чего можно уже делать проверку с помощью when:
— name: Populate service facts
ansible.builtin.service_facts:
— name: Stop Service If Running One
shell: systemctl stop apache2
when: ansible_facts.services is defined and ansible_facts.services.state == «running»
* в данном примере мы проверим, есть ли служба apache2 и запущена ли она. Если это так, то мы ее останавливаем.
Подробнее о service_facts можно прочитать в документации (ссылка выше в разделе 4. Получить список сервисов).
4. Существует ли файл.
Проверка может быть выполнена с помощью stat:
— name: Register File Stat
stat:
path: /etc/nginx/nginx.conf
register: stat_result
— name: Cat file if exists
shell: cat /etc/nginx/nginx.conf
when: stat_result.stat.exists
* в данном примере будет выполнено чтение файла /etc/nginx/nginx.conf, если он существует.
О stat: https://docs.ansible.com/ansible/latest/collections/ansible/builtin/stat_module.html.
5. Операционная система.
С помощью переменных ansible_os_family и ansible_distribution_major_version мы можем получить информацию об операционной системы, которая работает на целевом компьютере. Это можно использовать для выполнения проверок и задания условий.
а) Проверка по семейству:
— name: Run task1 if OS is Debian
…
when: ansible_os_family == «Debian»
— name: Run task2 if OS is Red Hat
…
when: ansible_os_family == «RedHat»
* в данном примере мы запустим задачу task1 в системах на основе Debian и task2 — на основе RedHat.
— name: Run task1 if OS is Debian 9
…
when: ansible_os_family == «Debian» and ansible_distribution_major_version == «9»
— name: Run task2 if OS is Red Hat 8
…
when: ansible_os_family == «RedHat» and ansible_distribution_major_version == «8»
* в данном примере мы запустим задачу task1 в системах на основе Debian версии 9 и task2 — на основе RedHat версии 8.
Создание шаблона для конфигурации Nginx
Пора создать шаблон Nginx, необходимый для настройки удаленного веб-сервера. Создайте в каталоге ansible-demo новую папку для хранения файлов, не относящихся к плейбуку:
Затем откройте новый файл nginx.conf.j2:
Этот файл шаблона содержит конфигурацию блока server Nginx для нашего статического HTML-сайта. Он использует три переменные: document_root, app_root и server_name. Мы определим эти переменные позже, при создании плейбука. Скопируйте и вставьте в файл шаблона следующее содержимое:
server { listen 80; root ` document_root `/` app_root `; index index.html index.htm; server_name ` server_name `; location / { default_type "text/html"; try_files $uri.html $uri $uri/ =404; } }
Сохраните и закройте файл.