8.6 KiB
theme: poster, 8 autoscale: true build-lists: true header-emphasis: #53B0EB header: alignment(left) text: alignment(left) text-emphasis: #53B0EB code: Monaco, line-height(1.2)
[.header: alignment(center)]
[fit] Deploying PHP applications
[fit] With Ansible, Ansible Vault and Ansistrano
[.background-color: #FFFFFF] [.build-lists: false] [.header: #111111] [.text: #111111, alignment(left)]
- Full Stack Web Developer & System Administrator
- Senior Developer at Microserve
- Part-time freelancer
- Acquia certified Drupal 8 Grand Master
- Drupal 7 & 8 core contributor
- Symfony, Laravel, Sculpin
- @opdavies
- www.oliverdavies.uk
^ Work at Microserve. Maintain Drupal modules, PHP CLI tools and libraries Blog on my website
[.background-color: #FFFFFF] [.build-lists: false] [.text: #111111, alignment(left)]
- https://microserve.io
- https://www.drupal.org/microserve
- https://github.com/microserve-io
- https://twitter.com/microserveltd
- https://www.linkedin.com/company/microserve-ltd
[.header: #FFFFFF, line-height(0.7), League Gothic]
Things we'll be
Looking at
[.background-color: #FFFFFF]
^ Ansible - software provisioning and deployment tool Vagrant - used for managing virtual machines. Used instead of a real server Drupal Composer - required by Drupal 8 to pull in dependencies (e.g. Symfony)
- Ansible crash course
- Initial setup and provisioning
- Basic deployment setup
- Using Ansible Vault for variables
- Adding and configuring Ansistrano
[.background-color: #FFFFFF] [.text: #111111, alignment(left)]
When should I use this?
- Dedicated hosting: probably has this already
- Shared hosting: probably not flexible enough
- VPS or dedicated server
What is
Ansible?
[.background-color: #FFFFFF] [.text: #111111] [.footer: https://en.wikipedia.org/wiki/Ansible_(software)]
Ansible is open source software
that automates software provisioning,
configuration management,
and application deployment.
[.background-color: #FFFFFF] [.text: #111111, alignment(left)]
What is Ansible?
- YAML
- Batteries included
- Executes remote commands
- Installs software packages
- Performs deployment steps
[.background-color: #FFFFFF] [.text: #111111, alignment(left)]
What is Ansible?
- Hosts
- Commands
- Playbooks
- Tasks
- Roles
[.background-color: #FFFFFF] [.text: #111111, alignment(left)]
Why Ansible?
- Familiar syntax
- Easily readable
- No server dependencies
- Easy to add to an existing project
- Includes relevant modules (e.g. Composer)
Ansible
Hosts
# hosts.ini
[dransible]
192.168.33.10
Ansible
Commands
ansible all -m ping
ansible all -m command -a 'git pull --chdir=/var/www/app'
Ansible
[fit] Tasks and Playbooks
# playbook.yml
---
- hosts: all
tasks:
- name: Update the code
command: git pull
args:
chdir: /var/www/app
ansible-playbook playbook.yml -i hosts.ini
Ansible
Roles
^ Collections of tasks, variables and handlers
# requirements.yml
---
- src: geerlingguy.apache
- src: geerlingguy.composer
- src: geerlingguy.mysql
- src: geerlingguy.php
- src: geerlingguy.php-mysql
ansible-galaxy -r ansible/requirements.yml install
# playbook.yml
---
- hosts: all
roles:
- geerlingguy.apache
- geerlingguy.mysql
- geerlingguy.php
- geerlingguy.php-mysql
- geerlingguy.composer
^ Role order matters!
[.header: alignment(center)]
Let's take a look
at the code
Basic deployment
Ansible
^ Any questions on Ansible so far?
# ansible/provision.yml
tasks:
- name: Create a database
mysql_db:
name: mydatabase
state: present
- name: Add the database user
mysql_user:
name: drupal
password: secret
priv: '*.*:ALL'
state: present
# ansible/deploy.yml
tasks:
- name: Creating project directory
file:
path: /var/www/app
state: directory
- name: Uploading application
synchronize:
src: "{{ playbook_dir }}/../"
dest: /var/www/app
- name: Installing Composer dependencies
composer:
command: install
working_dir: /var/www/app
[.background-color: #FFFFFF] [.text: #111111, alignment(left)]
Disadvantages
- Single point of failure
- No ability to roll back
- Sensitive data stored in plain text
Keeping secrets
Ansible Vault
ansible-vault create ansible/vault.yml
$ANSIBLE_VAULT;1.1;AES256
36656233323539616336393838396137343939623233393338666530313730373233663263633065
3133633335316364306366333539613936376239383133330a356365666232623537333730663638
37393264616134613163663762666464373733663737383039316163336263323538393533323266
3432346662613438330a386435393432323761386137333736363436386466643031386662353933
30393631386463313265653862633866663530626439623063393934653235666530656462643135
39366431353762383434663536663761323565616564336131666339653038326333306433326264
31623539643166626234663736656337633036323837333137343533386165366531626462643662
66626631663930626266653937323634366231326537626131663662396335393361336635373736
3435
# ansible/vars/vault.yml
---
vault_app_db_name: mydatabase
vault_app_db_user: drupal
vault_app_db_password: secret
^ Optional, but easier to see where variables are set
# ansible/vars/vars.yml
---
app_db_name: "{{ vault_app_db_name }}"
app_db_user: "{{ vault_app_db_user }}"
app_db_password: "{{ vault_app_db_password }}"
# ansible/provision.yml
tasks:
- name: Create a database
mysql_db:
name: '{{ app_db_name }}'
state: present
ansible-vault edit ansible/vault.yml
Better deployments
Ansistrano
^ Just another role, specifically for deployments Ansible port of Capistrano
[.background-color: #FFFFFF] [.text: #111111, alignment(center)]
Capistrano is an open-source tool for running scripts on multiple servers; its main use is deploying web applications.
It automates the process of making a new version of an application available on one or more web servers, including supporting tasks such as changing databases.
[.background-color: #FFFFFF] [.text: #111111, alignment(left)]
Features
- Multiple release directories
- Shared paths and files
- Customisable
- Multiple deployment strategies
- Multi-stage environments
- Prune old releases
- Rollbacks
^ rsync, Git, SVN etc
# ansible/requirements.yml
---
...
- ansistrano.deploy
- ansistrano.rollback
# ansible/deploy.yml
---
- hosts: all
roles:
- ansistrano.deploy
# ansible/deploy.yml
---
...
vars:
ansistrano_deploy_to: /var/www
ansistrano_deploy_via: git
ansistrano_git_branch: master
ansistrano_git_repo: 'git@github.com:foo/bar.git'
# ansible/rollback.yml
---
- hosts: all
roles:
- ansistrano.rollback
vars:
ansistrano_deploy_to: /var/www
Customising Ansistrano
Build Hooks
[.background-color: #FFFFFF]
# ansible/deploy.yml
vars:
...
ansistrano_after_symlink_shared_tasks_file: "{{ playbook_dir }}/deploy/after-symlink-shared.yml"
ansistrano_after_symlink_tasks_file: "{{ playbook_dir }}/deploy/after-symlink.yml"
ansistrano_after_update_code_tasks_file: "{{ playbook_dir }}/deploy/after-update-code.yml"
release_web_path: "{{ ansistrano_release_path.stdout }}/web"
release_drush_path: "{{ ansistrano_release_path.stdout }}/vendor/bin/drush"
# ansible/deploy/after-update-code.yml
---
- name: Install Composer dependencies
composer:
command: install
working_dir: '{{ ansistrano_release_path.stdout }}'
# ansible/deploy/after-symlink-shared.yml
---
- name: Run database updates
command: '{{ release_drush_path }} --root {{ release_web_path }} updatedb'
# ansible/deploy/after-symlink.yml
---
- name: Clear Drupal cache
command: '{{ release_drush_path }} --root {{ release_web_path }} cache-rebuild'
[.header: alignment(center)]
Questions?
[.header: alignment(center)]