HTML Diff
0 added 0 removed
Original 2026-01-01
Modified 2026-03-10
1 <p>В<a>предыдущей статье</a>мы рассмотрели структуру Ansible и определили последовательность действий при создании и запуске Laravel APP. Также создали экземпляр Ubuntu Lightsail, определили роли, добавили SSH-ключи, установили зависимости. Пришла пора закончить начатое.</p>
1 <p>В<a>предыдущей статье</a>мы рассмотрели структуру Ansible и определили последовательность действий при создании и запуске Laravel APP. Также создали экземпляр Ubuntu Lightsail, определили роли, добавили SSH-ключи, установили зависимости. Пришла пора закончить начатое.</p>
2 <h2>Устанавливаем PHP-модули</h2>
2 <h2>Устанавливаем PHP-модули</h2>
3 <p>Чтобы в Ansible вызвать обработчик, надо использовать notify: Restart PHP-FPM, причём имена обработчиков должны быть уникальны.</p>
3 <p>Чтобы в Ansible вызвать обработчик, надо использовать notify: Restart PHP-FPM, причём имена обработчиков должны быть уникальны.</p>
4 <p>В нашем руководстве php определён как тег, поэтому, к примеру, если захотите запустить из своего playbook лишь эту задачу, надо будет выполнить её с -tags = ”php”, которая станет исполнять лишь её.</p>
4 <p>В нашем руководстве php определён как тег, поэтому, к примеру, если захотите запустить из своего playbook лишь эту задачу, надо будет выполнить её с -tags = ”php”, которая станет исполнять лишь её.</p>
5 --- - 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<h2>Устанавливаем Nginx</h2>
5 --- - 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<h2>Устанавливаем Nginx</h2>
6 - 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<h2>Добавляем default-конфигурацию Nginx</h2>
6 - 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<h2>Добавляем default-конфигурацию Nginx</h2>
7 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; } }<h2>Теперь vars.yml</h2>
7 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; } }<h2>Теперь vars.yml</h2>
8 --- ##@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"<p>Тут следует отметить, что для шифрования и дешифрования переменных рекомендуется использовать ansible-vault.</p>
8 --- ##@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"<p>Тут следует отметить, что для шифрования и дешифрования переменных рекомендуется использовать ansible-vault.</p>
9 <h2>Применение Ansible-Vault</h2>
9 <h2>Применение Ansible-Vault</h2>
10 <p>Для использования Ansible-Vault нужно создать секретный файл хранилища, в котором будет ключ шифрования, шифрующий ваши переменные.</p>
10 <p>Для использования Ansible-Vault нужно создать секретный файл хранилища, в котором будет ключ шифрования, шифрующий ваши переменные.</p>
11 touch .vault_pass.txt echo 'YOUR_CONFIG_PASS' &gt; .vault_pass.txt<p>Для того, чтобы зашифровать переменные:</p>
11 touch .vault_pass.txt echo 'YOUR_CONFIG_PASS' &gt; .vault_pass.txt<p>Для того, чтобы зашифровать переменные:</p>
12 ansible-vault encrypt group_vars/vars.yml --vault-password-file .vault_pass.txt<p>Для того, чтобы расшифровать:</p>
12 ansible-vault encrypt group_vars/vars.yml --vault-password-file .vault_pass.txt<p>Для того, чтобы расшифровать:</p>
13 ansible-vault decrypt group_vars/vars.yml --vault-password-file .vault_pass.txt<h2>Создаём БД MySql, имя пользователя и пароль</h2>
13 ansible-vault decrypt group_vars/vars.yml --vault-password-file .vault_pass.txt<h2>Создаём БД MySql, имя пользователя и пароль</h2>
14 - 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}}"<p>Обратите внимание, что mysql_user и mysql_pass определены внутри vars.yml.</p>
14 - 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}}"<p>Обратите внимание, что mysql_user и mysql_pass определены внутри vars.yml.</p>
15 <h2>Клонируем кодовую базу</h2>
15 <h2>Клонируем кодовую базу</h2>
16 - 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<p>Тут app_work_dir и repo_git_url определены внутри vars.yml.</p>
16 - 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<p>Тут app_work_dir и repo_git_url определены внутри vars.yml.</p>
17 <h2>Генерируем .env</h2>
17 <h2>Генерируем .env</h2>
18 <p>Для доступа к переменным и динамических выражений Ansible использует шаблонизатор Jinja2. Создаём файл env.conf:</p>
18 <p>Для доступа к переменным и динамических выражений Ansible использует шаблонизатор Jinja2. Создаём файл env.conf:</p>
19 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}}<p>Теперь нужно определить role, дабы переместить данный шаблон в директорию приложения.</p>
19 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}}<p>Теперь нужно определить role, дабы переместить данный шаблон в директорию приложения.</p>
20 --- - name: Copy lara env file become: true template: src: templates/env.conf dest: "{{app_work_dir}}/.env" tags: - env-file<h2>Создаём playbook</h2>
20 --- - name: Copy lara env file become: true template: src: templates/env.conf dest: "{{app_work_dir}}/.env" tags: - env-file<h2>Создаём playbook</h2>
21 --- - 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<p>Нами был определён aws как хост для playbook, а sudo yes даёт возможность выполнять команду как sudo-пользователю. Также у нас есть vars_files, где хранятся наши vars. Ещё мы установили roles, а каждая role выполняет конкретную задачу. Кроме того, у нас есть handlers, содержащие все обработчики проекта.</p>
21 --- - 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<p>Нами был определён aws как хост для playbook, а sudo yes даёт возможность выполнять команду как sudo-пользователю. Также у нас есть vars_files, где хранятся наши vars. Ещё мы установили roles, а каждая role выполняет конкретную задачу. Кроме того, у нас есть handlers, содержащие все обработчики проекта.</p>
22 <h2>Запускаем playbook</h2>
22 <h2>Запускаем playbook</h2>
23 #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<h2>Посмотрим на полную структуру проекта</h2>
23 #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<h2>Посмотрим на полную структуру проекта</h2>
24 ├── 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<h2>Полезные материалы</h2>
24 ├── 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<h2>Полезные материалы</h2>
25 <p>Если захотите повторить всё шаг за шагом, вам помогут следующие материалы: • исходный код на<a>GitHub</a>; • запущенный с его помощью<a>сайт</a>; • советы для работы с<a>Ansible playbooks</a>; •<a>Описание Ansible-архитектуры</a>.</p>
25 <p>Если захотите повторить всё шаг за шагом, вам помогут следующие материалы: • исходный код на<a>GitHub</a>; • запущенный с его помощью<a>сайт</a>; • советы для работы с<a>Ansible playbooks</a>; •<a>Описание Ansible-архитектуры</a>.</p>
26 <p><em>Источник - "<a>Ansible In Action</a>".</em></p>
26 <p><em>Источник - "<a>Ansible In Action</a>".</em></p>
27  
27