Что такое Ansible? Это ПО с открытым исходным кодом, которое автоматизирует поставку программного обеспечения, управление конфигурацией и развёртывание приложений. Ansible помогает DevOps-специалистам автоматизировать сложные задачи.
Примечание Вы читаете улучшенную версию некогда выпущенной нами статьи.Ключевые особенности программы Ansible
- Безагентное. В клиенте не установлено программное обеспечение или агент, который общается с сервером.
- Идемпотентное. Независимо от того, сколько раз вы вызываете операцию, результат будет одинаковым.
- Простое и расширяемое. Программа Ansible написанa на Python и использует YAML для написания команд. Оба языка считаются относительно простыми в изучении.
Установка и запуск
# ubuntu
sudo apt-get install ansible
#mac-OS
brew install ansible
Инструкцию по установке на другие ОС можно найти здесь.
Структура Ansible
Модули
Это небольшие программы, выполняющие определённую работу на сервере. Например, вместо запуска этой команды:
sudo apt-get install htop
Мы можем использовать модуль apt и установить htop:
- name: Install htop
apt: name=htop
Использование модуля даст вам возможность узнать, установлен он или нет.
Плагины
Ansible поставляется с несколькими удобными плагинами, и вы можете легко написать свой собственный.
Инвентаризация хостов
Чтобы предоставить перечень хостов, нам нужно обозначить список, находящийся в файле инвентаризации. Он напоминает содержание файла hosts.
В простейшем виде он может содержать одну строку:
35.178.45.231 ansible_ssh_user=ubuntu
Playbooks
Ansible playbooks — это способ отправки команд на удалённые компьютеры с помощью скриптов. Вместо того, чтобы индивидуально использовать команды для удалённой настройки компьютеров из командной строки, вы можете настраивать целые сложные среды, передавая скрипт одной или нескольким системам.
group_vars
Файл содержит набор переменных, например имя пользователя и пароль базы данных.
Роли
Это способ сгруппировать несколько задач в один контейнер, чтобы эффективно автоматизировать работу с помощью понятной структуры каталогов.
Обработчики
Представляют собой списки задач, которые на самом деле не отличаются от обычных задач, на которые ссылается глобально уникальное имя и которые оповещаются уведомителями. Если ничто не уведомляет обработчик, он не будет запускаться. Независимо от того, сколько задач уведомляет обработчик, он запускается только один раз, после того как все задачи завершены.
Теги
Если у вас playbook с большим объёмом, может быть полезно иметь возможность запускать только определённую часть его конфигурации.
Демо «Реальное приложение»
Цель этой демонстрации — установить приложение Laravel в VPS. Для этого используем Lightsail.
Последовательность действий для создания и запуска Laravel APP:
-
- Создайте экземпляр Ubuntu Lightsail.
- Установите зависимости Ansible на ваш VPS.
- Добавьте SSH-ключи в Git.
- Выполните сборку хостов и ansible.cfg.
- Определите роль в Ansible.
- Определите обработчик.
- Установите модули PHP.
- Установите Nginx.
- Добавьте default-конфигурацию Nginx.
- Добавьте переменные для управления учётными данными БД, хоста, URL-адресом источника GitHub и переменными .env.
- Используйте Ansible-Vault.
- Создайте базу данных MySql, имя пользователя и пароль.
- Клонируйте кодовую базу в ваш VPS.
- Сгенерируйте .env.
- Создайте playbook.
Рассмотрим каждый пункт подробнее.
Создание экземпляра Ubuntu Lightsail
Перейдите на панель управления Lightsail и нажмите «Создать экземпляр».
Выберите свою любимую ОС.
Выберите «Добавить скрипт запуска», который запускается после создания вашего экземпляра. Не забудьте получить SSH-ключ.
Установка зависимостей Ansible на нашем VPS
Добавьте эти sh-команды для установки зависимостей:
sudo add-apt-repository ppa:deadsnakes/ppa -y
sudo apt-get update
sudo apt-get install -y python2.7 python3 python-pip
Теперь у нас есть готовый экземпляр, перейдём к построению Ansible Project.
Добавление SSH-ключей в Git
Вы должны добавить свой сервер id_rsa.pub к своим ключам GitHub SSH, войдя в свой сервер.
# Подключитесь к вашему серверу через SSH и запустите
ssh-keygen
sudo chmod -R 644 .ssh/id_rsa
cat .ssh/id_rsa.pub
# Добавьте результат команды в аккаунт Git
# github settings=> SSH keys => Add new Key
# bitbucket settings=> ssh-keys => Add new Key
Сборка хостов и ansible.cfg
hosts.ini
[aws]
# Ваш IP сервера
127.0.0.39
ansible.cfg
[defaults]
hostfile = hosts.ini
# configure log dir
log_path= logs/ansible-log.log
Определение роли в Ansible
Используем модуль Ping, чтобы убедиться, что хост работает, после чего нужно обновить все пакеты и установить два модуля: git и htop.
---
- ping: ~
###
- name: Update apt packages
apt:
update_cache: yes
##
- name: Install GIT VCS
apt:
name: git
state: latest
##
- name: Install htop
apt: name=htop
Определение обработчика
---
- name: Restart PHP-FPM
service:
name: php{{php_version}}-fpm
state: restarted
####
- name: Restart Nginx
service:
name: nginx
state: restarted
Установка модулей PHP
Чтобы вызвать обработчик, мы должны использовать notify: Restart PHP-FPM, имена обработчиков должны быть уникальными.
В этом руководстве мы определили php как тег, поэтому, например, если вы хотите запустить только эту задачу из своего playbook, вам необходимо выполнить её с —tags = ”php”, которая будет исполнять только её.
---
- name: Install PHP {{php_version}} PPA Repo
apt_repository:
repo: 'ppa:ondrej/php'
tags:
- php
##
- name: Install PHP {{php_version}}
apt: name=php{{php_version}} state=latest
##
- name: Install PHP packages
become: true
apt:
name: "{{ item }}"
state: latest
with_items:
- php{{php_version}}-curl
- php{{php_version}}-fpm
- php{{php_version}}-intl
- php{{php_version}}-mysql
- php{{php_version}}-xml
- php{{php_version}}-mbstring
notify: Restart PHP-FPM
tags:
- php
Установка Nginx
- name: Install Nginx web server
apt:
name: nginx
state: latest
notify: Restart Nginx
tags:
- nginx
###
- name: Update nginx config files
become: true
template:
src: templates/nginx.conf
dest: "/etc/nginx/sites-available/default"
tags:
- nginx
notify: Restart Nginx
###
- name: link nginx config
become: true
file:
src: "/etc/nginx/sites-available/default"
dest: "/etc/nginx/sites-enabled/default"
state: link
tags:
- nginx
notify: Restart Nginx
Добавление default-конфигурации Nginx
server {
listen 80 default_server;
listen [::]:80 default_server ipv6only=on;
server_name {{ server_name }};
root {{ app_work_dir }}public;
location / {
try_files $uri $uri/ /index.php?$args;
index index.php index.html index.htm;
}
if (!-d $request_filename) {
rewrite ^/(.*)/$ /$1 permanent;
}
location = /favicon.ico {
access_log off;
log_not_found off;
}
location ~ \.php$ {
try_files $uri $uri/ /index.php?$args;
index index.php index.html index.htm;
fastcgi_pass unix:/var/run/php/php{{php_version}}-fpm.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME {{app_work_dir}}public$fastcgi_script_name;
fastcgi_param APPLICATION_ENV testing;
fastcgi_param PATH /usr/bin:/bin:/usr/sbin:/sbin;
fastcgi_intercept_errors on;
include fastcgi_params;
}
}
vars.yml
---
##@ref https://docs.ansible.com/ansible/latest/user_guide/playbooks_best_practices.html#variables-and-vaults
ansible_ssh_user: "ubuntu"
current_user: "ubuntu"
server_name: "app_name"
repo_git_url: "app_github_url"
ansible_ssh_private_key_file: "ssh_dir"
php_version: 7.2
app_work_dir: /var/www/app_name/
#mysql config
mysql_host: "mysql_host"
mysql_db: app_name
mysql_user: sql_user
mysql_pass: sql_pass
#other config
cache_driver: file
session_driver: file
app_env: production
app_debug: false
app_key: "your_app_key"
app_name: "app_name"
app_url: "your_app_url"
Примечание: Рекомендуется использовать ansible-vault для шифрования и дешифрования переменных.
Как использовать Ansible-Vault
Создайте секретный файл хранилища, содержащий ключ шифрования, который шифрует ваши переменные.
touch .vault_pass.txt
echo 'YOUR_CONFIG_PASS' > .vault_pass.txt
Чтобы зашифровать переменные, используйте:
ansible-vault encrypt group_vars/vars.yml --vault-password-file .vault_pass.txt
Чтобы расшифровать переменные, используйте:
ansible-vault decrypt group_vars/vars.yml --vault-password-file .vault_pass.txt
Создание базы данных MySql, имени пользователя и пароля
- mysql_user:
name: "{{mysql_user}}"
password: "{{mysql_pass}}"
priv: '*.*:ALL'
state: present
tags:
- mysql-db
##
- name: Create APP DB database
mysql_db: name="{{mysql_db}}" state=present login_user="{{mysql_user}}" login_password="{{mysql_pass}}"
mysql_user
и mysql_pass
определены внутри vars.yml.
Клонирование кодовой базы
- name: update repo - pull the latest changes
git:
repo: "{{repo_git_url}}"
dest: "{{app_work_dir}}"
update: yes
version: master
accept_hostkey: yes
key_file: /home/{{current_user}}/.ssh/id_rsa
tags:
- code-deploy
repo_git_url
и app_work_dir
определены внутри vars.yml.
Генерирование .env
Ansible использует шаблонизатор Jinja2 для динамических выражений и доступа к переменным. Создадим файл env.conf.
APP_ENV={{app_env}}
APP_DEBUG={{app_debug}}
APP_KEY={{app_key}}
APP_URL={{app_url}}
APP_NAME={{app_name}}
DB_HOST={{mysql_host}}
DB_DATABASE={{mysql_db}}
DB_USERNAME={{mysql_user}}
DB_PASSWORD={{mysql_pass}}
CACHE_DRIVER={{cache_driver}}
SESSION_DRIVER={{session_driver}}
Определим role
, чтобы переместить этот шаблон в директорию нашего приложения.
---
- name: Copy lara env file
become: true
template:
src: templates/env.conf
dest: "{{app_work_dir}}/.env"
tags:
- env-file
Создание playbook
---
- hosts: aws
#common options between modules
sudo: yes
gather_facts: no
vars_files:
- ./group_vars/vars.yml
roles:
- misc
- php
- mysql
- redis
- nginx
- bootstrap-app
- code-deploy
###
handlers:
- include: handlers/main.yml
Как видно, мы определили aws как хост для этого playbook, и sudo yes даёт нам возможность выполнять команду как пользователю sudo. У нас есть vars_files, где мы храним наши vars. Мы установили roles, каждая role выполняет определённую задачу. И, наконец, у нас есть handlers, которые содержат все обработчики проекта.
Запуск playbook
#ansible-playbook playbookName
ansible-playbook code-deploy.yml
# Запуск с конкретными тегами
ansible-playbook playbook.yml --tags="env-files,php"
# Если вы используете ansible-vault
ansible-playbook code-deploy.yml --vault-password-file .vault_pass.txt
Полная структура проекта
├── ansible.cfg
├── code-deploy.yml
├── files
│ └── dump.sql
├── group_vars
│ └── vars.yml
├── handlers
│ └── main.yml
├── hosts.ini
├── logs
│ └── ansible-log.log
├── roles
│ ├── bootstrap-app
│ │ └── tasks
│ │ └── main.yml
│ ├── code-deploy
│ │ ├── tasks
│ │ │ ├── config-files.yml
│ │ │ └── main.yml
│ │ └── templates
│ │ └── env.conf
│ ├── misc
│ │ └── tasks
│ │ └── main.yml
│ ├── mysql
│ │ └── tasks
│ │ ├── config.yml
│ │ └── main.yml
│ ├── nginx
│ │ ├── tasks
│ │ │ └── main.yml
│ │ └── templates
│ │ └── nginx.conf
│ ├── php
│ │ └── tasks
│ │ └── main.yml
│ └── redis
│ └── tasks
│ └── main.yml
├── scripts
│ ├── install_composer.sh
│ └── startup.sh
└── site.yml
Дополнительные материалы для начинающих изучать Ansible
- Репозиторий на GitHub, который содержит полный исходный код.
- Этот сайт запущен и работает с использованием этой кодовой базы.
- Советы по использованию Ansible playbooks.
- Описание архитектуры программы Ansible.
- Статья «How to Use Ansible to Automate Initial Server Setup on Ubuntu».
- О других инструментах сисадмина и DevOps читайте в нашей подборке.
Вадим Сычёв
Перевод статьи «Ansible In Action»