Ansible в действии. Часть 2 | OTUS
⚡ Открываем подписку на курсы!
Проходите параллельно 3 онлайн-курса в месяц по цене одного.
Подробнее

Курсы

Программирование
Flutter Mobile Developer Подготовка к сертификации Oracle Java Programmer (OCAJP)
-8%
Алгоритмы и структуры данных
-12%
Web-разработчик на Python
-11%
Архитектура и шаблоны проектирования
-14%
JavaScript Developer. Basic Супер-интенсив «СУБД в высоконагруженных системах»
-18%
iOS-разработчик. Базовый курс
-23%
Разработчик на Spring Framework
-23%
Python Developer. Basic
-16%
C# ASP.NET Core разработчик
-18%
Разработчик программных роботов (RPA) на базе UiPath и PIX
-6%
Android Developer. Basic
-10%
C++ Developer. Professional Разработчик C# AWS для разработчиков Software Architect Unity Game Developer. Basic Разработчик голосовых ассистентов и чат-ботов Backend-разработка на Kotlin React.js Developer Разработчик Node.js Нереляционные базы данных Супер - интенсив по паттернам проектирования Супер - интенсив по Kubernetes Advanced Fullstack JavaScript developer
Инфраструктура
PostgreSQL
-10%
IoT-разработчик
-12%
Administrator Linux. Professional
-11%
Базы данных
-19%
Administrator Linux.Basic
-18%
Супер-интенсив «СУБД в высоконагруженных системах»
-18%
Разработчик программных роботов (RPA) на базе UiPath и PIX
-6%
Сетевой инженер AWS для разработчиков Software Architect Reverse-Engineering. Professional CI/CD VOIP инженер Супер-практикум по работе с протоколом BGP Супер - интенсив по паттернам проектирования Супер - интенсив по Kubernetes
Специализации Курсы в разработке Подготовительные курсы
+7 499 938-92-02

Ansible в действии. Часть 2

В предыдущей статье мы рассмотрели структуру Ansible и определили последовательность действий при создании и запуске Laravel APP. Также создали экземпляр Ubuntu Lightsail, определили роли, добавили SSH-ключи, установили зависимости. Пришла пора закончить начатое.

Устанавливаем PHP-модули

Чтобы в Ansible вызвать обработчик, надо использовать 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 =https://cdn.tproger.ru/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

Для использования 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

Тут app_work_dir и repo_git_url определены внутри 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-valut
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

Полезные материалы

Если захотите повторить всё шаг за шагом, вам помогут следующие материалы: • исходный код на GitHub; • запущенный с его помощью сайт; • советы для работы с Ansible playbooks; • Описание Ansible-архитектуры.

Источник — «Ansible In Action».

Не пропустите новые полезные статьи!

Спасибо за подписку!

Мы отправили вам письмо для подтверждения вашего email.
С уважением, OTUS!

Автор
0 комментариев
Для комментирования необходимо авторизоваться