diff --git a/source/deploying-drupal-ansible-ansistrano/demo.mp4 b/source/deploying-drupal-ansible-ansistrano/demo.mp4 new file mode 100644 index 0000000..2441483 Binary files /dev/null and b/source/deploying-drupal-ansible-ansistrano/demo.mp4 differ diff --git a/source/deploying-drupal-ansible-ansistrano/images/drupalcon/contribution.jpg b/source/deploying-drupal-ansible-ansistrano/images/drupalcon/contribution.jpg new file mode 100644 index 0000000..ed5a478 Binary files /dev/null and b/source/deploying-drupal-ansible-ansistrano/images/drupalcon/contribution.jpg differ diff --git a/source/deploying-drupal-ansible-ansistrano/images/drupalcon/feedback.jpg b/source/deploying-drupal-ansible-ansistrano/images/drupalcon/feedback.jpg new file mode 100644 index 0000000..8795c55 Binary files /dev/null and b/source/deploying-drupal-ansible-ansistrano/images/drupalcon/feedback.jpg differ diff --git a/source/deploying-drupal-ansible-ansistrano/images/drupalcon/site.png b/source/deploying-drupal-ansible-ansistrano/images/drupalcon/site.png new file mode 100644 index 0000000..c2d9b07 Binary files /dev/null and b/source/deploying-drupal-ansible-ansistrano/images/drupalcon/site.png differ diff --git a/source/deploying-drupal-ansible-ansistrano/images/logo-acquia.png b/source/deploying-drupal-ansible-ansistrano/images/logo-acquia.png new file mode 100644 index 0000000..233b6b5 Binary files /dev/null and b/source/deploying-drupal-ansible-ansistrano/images/logo-acquia.png differ diff --git a/source/deploying-drupal-ansible-ansistrano/images/logo-digital-ocean.png b/source/deploying-drupal-ansible-ansistrano/images/logo-digital-ocean.png new file mode 100644 index 0000000..90c76b4 Binary files /dev/null and b/source/deploying-drupal-ansible-ansistrano/images/logo-digital-ocean.png differ diff --git a/source/deploying-drupal-ansible-ansistrano/images/logo-linode.png b/source/deploying-drupal-ansible-ansistrano/images/logo-linode.png new file mode 100644 index 0000000..22daa66 Binary files /dev/null and b/source/deploying-drupal-ansible-ansistrano/images/logo-linode.png differ diff --git a/source/deploying-drupal-ansible-ansistrano/images/logo-pantheon.png b/source/deploying-drupal-ansible-ansistrano/images/logo-pantheon.png new file mode 100644 index 0000000..966a3ac Binary files /dev/null and b/source/deploying-drupal-ansible-ansistrano/images/logo-pantheon.png differ diff --git a/source/deploying-drupal-ansible-ansistrano/images/logo-platformsh.png b/source/deploying-drupal-ansible-ansistrano/images/logo-platformsh.png new file mode 100644 index 0000000..7bde895 Binary files /dev/null and b/source/deploying-drupal-ansible-ansistrano/images/logo-platformsh.png differ diff --git a/source/deploying-drupal-ansible-ansistrano/images/site.png b/source/deploying-drupal-ansible-ansistrano/images/site.png new file mode 100644 index 0000000..7173f99 Binary files /dev/null and b/source/deploying-drupal-ansible-ansistrano/images/site.png differ diff --git a/source/deploying-drupal-ansible-ansistrano/slides.md b/source/deploying-drupal-ansible-ansistrano/slides.md index 0301993..10c389a 100644 --- a/source/deploying-drupal-ansible-ansistrano/slides.md +++ b/source/deploying-drupal-ansible-ansistrano/slides.md @@ -1,131 +1,95 @@ -theme: poster, 8 autoscale: true build-lists: true +code: line-height(1.2) header-emphasis: #53B0EB -header: alignment(left) text: alignment(left) -text-emphasis: #53B0EB -code: Monaco, line-height(1.2) +theme: plain jane, 8 -[.header: alignment(center)] +# [fit] **Deploying PHP applications**
using Ansible, Ansible Vault
and Ansistrano - -# [fit] Deploying PHP applications -# [fit] _With Ansible, Ansible Vault and Ansistrano_ +^ Ansible crash course +Basic deployment +Better deployment --- -[.background-color: #FFFFFF] [.build-lists: false] [.header: #111111] -[.text: #111111, alignment(left)] -![right 800%](../images/me-phpnw.png) +![right 500%](../images/me-phpnw-inviqa.jpg) - 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 +- **Senior Software Engineer** at **Inviqa** +- Acquia certified **Drupal 8 Grand Master** +- Open sourcer +- Drupal 7 & 8 **core contributor** - @opdavies - www.oliverdavies.uk -^ Work at Microserve. -Maintain Drupal modules, PHP CLI tools and libraries +^ Maintain Drupal modules, PHP CLI tools and libraries Blog on my website +I work for Inviqa, but this based on my personal and side projects, though I've implemented similar solutions in the past. --- -[.background-color: #FFFFFF] -[.build-lists: false] -[.text: #111111, alignment(left)] +![350% inline](images/logo-platformsh.png) +![150% inline](images/logo-acquia.png) +![130% inline](images/logo-pantheon.png) -![right 100%](../images/microserve-light.png) - -- https://microserve.io -- https://www.drupal.org/microserve -- https://github.com/microserve-io -- https://twitter.com/microserveltd -- https://www.linkedin.com/company/microserve-ltd +^ Large, well-known managed hosting companies +Optimised servers for PHP/Drupal applications +Include some sort of deployment system --- -### _Things we'll be_ -# Looking at +![100%](images/logo-digital-ocean.png) +![30%](images/logo-linode.png) +![30%](https://www.vultr.com/media/media_card_1200x630.png) + +^ More applicable to virtual or dedicated servers with no existing deployment process +Not enough budget for fully-managed, or using internal infrastructure --- -[.background-color: #FFFFFF] +## **What we'll be looking at** - -![10%](images/ansible.png) -![85%](images/vagrant.png) -![325%](images/druplicon.png) -![325%](images/composer.png) - -^ 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 +* Keeping secrets with **Ansible Vault** +* Deployments with **Ansistrano** --- -1. Ansible crash course -1. Initial setup and provisioning -1. Basic deployment setup -1. Using Ansible Vault for variables -1. Adding and configuring Ansistrano +# **What is Ansible?** --- -[.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)] +## Ansible is **open source software** that automates **software provisioning**,
**configuration management**,
and **application deployment**. ![10% right](images/ansible.png) -# What is Ansible? +--- -* YAML -* Batteries included +![10% right](images/ansible.png) + +### **What is Ansible?** + +* CLI tool +* Written in Python +* Configured with YAML * Executes remote commands * Installs software packages * Performs deployment steps +* Batteries included + +^ Written in Python but you don't need to write or know Python to use it --- -[.background-color: #FFFFFF] -[.text: #111111, alignment(left)] - ![10% right](images/ansible.png) -# What is Ansible? +### **What is Ansible?** -* Hosts +* Hosts/Inventories * Commands * Playbooks * Tasks @@ -133,13 +97,9 @@ Ansible is _open source software_
that automates _software provisioning_,
that automates _software provisioning_,
{ + "ansible_facts": { + "discovered_interpreter_python": "/usr/bin/python" + }, + "changed": false, + "ping": "pong" +} +``` + +--- + +# `ansible all `
`-m command `
`-a 'git pull `
`--chdir=/app'` + +--- + +# `ansible all `
`-m git -a 'repo=https://github.com/opdavies/dransible dest=/app`' + +--- + +# **Tasks and Playbooks** --- @@ -187,23 +174,25 @@ ansible all -m command -a 'git pull --chdir=/var/www/app' --- - hosts: all + vars: + git_repo: https://github.com/opdavies/dransible + tasks: - name: Update the code - command: git pull - args: - chdir: /var/www/app + git: + repo: '{{ git_repo }}' + dest: /app + version: master + update: true ``` --- -``` -ansible-playbook playbook.yml -i hosts.ini -``` +# `ansible-playbook `
`ansible/playbook.yml `
`-i hosts.yml` --- -### _Ansible_ -# Roles +# **Roles** ^ Collections of tasks, variables and handlers @@ -220,11 +209,11 @@ ansible-playbook playbook.yml -i hosts.ini - src: geerlingguy.php-mysql ``` +^ Provisioning LAMP stack and Composer + --- -``` -ansible-galaxy -r ansible/requirements.yml install -``` +# `ansible-galaxy -r`
`ansible/requirements.yml install` --- @@ -246,19 +235,6 @@ ansible-galaxy -r ansible/requirements.yml install --- -[.header: alignment(center)] - -## Let's take a look
at the code - ---- - -### _Basic deployment_ -# Ansible - -^ Any questions on Ansible so far? - ---- - ```yaml # ansible/provision.yml @@ -272,37 +248,38 @@ tasks: mysql_user: name: drupal password: secret - priv: '*.*:ALL' + priv: 'mydatabase.*:ALL' state: present ``` --- +# **Basic deployment** + +--- + ```yaml # ansible/deploy.yml tasks: - name: Creating project directory file: - path: /var/www/app + path: /app state: directory - name: Uploading application synchronize: src: "{{ playbook_dir }}/../" - dest: /var/www/app + dest: /app - name: Installing Composer dependencies composer: command: install - working_dir: /var/www/app + working_dir: /app ``` --- -[.background-color: #FFFFFF] -[.text: #111111, alignment(left)] - # Disadvantages * Single point of failure @@ -311,29 +288,11 @@ tasks: --- -### _Keeping secrets_ -# Ansible Vault +# **Keeping secrets:
Ansible Vault** --- -```bash -ansible-vault create ansible/vault.yml -``` - ---- - -``` -$ANSIBLE_VAULT;1.1;AES256 -36656233323539616336393838396137343939623233393338666530313730373233663263633065 -3133633335316364306366333539613936376239383133330a356365666232623537333730663638 -37393264616134613163663762666464373733663737383039316163336263323538393533323266 -3432346662613438330a386435393432323761386137333736363436386466643031386662353933 -30393631386463313265653862633866663530626439623063393934653235666530656462643135 -39366431353762383434663536663761323565616564336131666339653038326333306433326264 -31623539643166626234663736656337633036323837333137343533386165366531626462643662 -66626631663930626266653937323634366231326537626131663662396335393361336635373736 -3435 -``` +# `ansible-vault create`
`ansible/vault.yml` --- @@ -341,22 +300,39 @@ $ANSIBLE_VAULT;1.1;AES256 # ansible/vars/vault.yml --- -vault_app_db_name: mydatabase -vault_app_db_user: drupal -vault_app_db_password: secret +vault_database_name: mydatabase +vault_database_user: drupal +vault_database_password: secret ``` ^ Optional, but easier to see where variables are set --- +``` +$ANSIBLE_VAULT;1.1;AES256 +36656233323539616336393838396137343939623233393338666530313 +73037323366326363306531336333353163643063663335396139363762 +39383133330a35636566623262353733373066363837393264616134613 +16366376266646437373366373738303931616333626332353839353332 +32663432346662613438330a38643539343232376138613733373636343 +63864666430313866623539333039363138646331326565386263386666 +35306264396230633939346532356665306564626431353936643135376 +23834346635366637613235656165643361316663396530383263333064 +33326264316235396431666262346637366563376330363238373331373 +43533386165366531626462643662666266316639306262666539373236 +343662313265376261316636623963353933613366353737363435 +``` + +--- + ```yaml # 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 }}" +database_name: "{{ vault_database_name }}" +database_user: "{{ vault_database_user }}" +database_password: "{{ vault_database_password }}" ``` --- @@ -367,20 +343,21 @@ app_db_password: "{{ vault_app_db_password }}" tasks: - name: Create a database mysql_db: - name: '{{ app_db_name }}' + name: '{{ database_name }}' state: present ``` --- -```bash -ansible-vault edit ansible/vault.yml -``` +# `ansible-vault edit ansible/vault.yml` --- -### _Better deployments_ -# Ansistrano +# `ansible-playbook`
`-i hosts.yml`
`ansible/deploy.yml`
`--ask-vault-pass` + +--- + +# **Better deployments** --- @@ -391,16 +368,6 @@ 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 @@ -444,10 +411,40 @@ Capistrano is an open-source tool for running scripts on multiple servers; its m --- ... vars: - ansistrano_deploy_to: /var/www + project_deploy_dir: /var/www + + ansistrano_deploy_to: '{{ project_deploy_dir }}' ansistrano_deploy_via: git ansistrano_git_branch: master - ansistrano_git_repo: 'git@github.com:foo/bar.git' + ansistrano_git_repo: 'git@github.com:opdavies/dransible' +``` + +--- + +# `ansible-playbook`
`-i hosts.yml`
`ansible/deploy.yml` + +--- + +```bash +vagrant@dransible:/app$ ls -l +total 8 + +lrwxrwxrwx 1 26 Jul 19 00:15 current -> ./releases/20190719001241Z +drwxr-xr-x 5 4096 Jul 22 20:30 releases +drwxr-xr-x 4 4096 Jul 19 00:00 shared +``` + +--- + +``` +vagrant@dransible:/app/releases$ ls -l +total 20 + +drwxr-xr-x 5 4096 Jul 22 20:30 . +drwxr-xr-x 4 4096 Jul 19 00:15 .. +drwxr-xr-x 10 4096 Jul 19 00:02 20190719000013Z +drwxr-xr-x 10 4096 Jul 19 00:14 20190719001241Z +drwxr-xr-x 9 4096 Jul 22 20:30 20190722203038Z ``` --- @@ -462,19 +459,25 @@ Capistrano is an open-source tool for running scripts on multiple servers; its m - ansistrano.rollback vars: - ansistrano_deploy_to: /var/www + ansistrano_deploy_to: '{{ project_deploy_dir }}' ``` --- -### _Customising Ansistrano_ -# Build Hooks +# `ansible-playbook`
`-i hosts.yml`
`ansible/rollback.yml` --- -[.background-color: #FFFFFF] +# **Customising Ansistrano:
Build Hooks** -![inline 125%](images/ansistrano-flow.png) +--- + +![inline 140%](images/ansistrano-flow.png) + +^ Shared = files directory, logs +Before/after symlink shared = run tests +Symlink = 'current' symlink, site is live +Clean up = remove node_modules, database export, sqlite testing DB --- @@ -525,14 +528,162 @@ vars: --- -[.header: alignment(center)] - -# Questions? +![80%](images/drupalcon/site.png) --- -[.header: alignment(center)] +# **Demo** -# Thanks -### _@opdavies_ -### _oliverdavies.uk_ +--- + +# **Questions?** + +--- + +![](images/drupalcon/contribution.jpg) + +--- + +![](images/drupalcon/feedback.jpg) + +^ Please leave feedback via the DrupalCon app, or via Twitter + +--- + +# **Managing data
across deployments** + +--- + +```yaml +# ansible/deploy.yml + +vars: + # ... + ansistrano_shared_paths: + - "{{ drupal_root }}/sites/default/files" +``` + +--- + +``` +vagrant@dransible:/app/shared/web/sites/default/files$ ls -la +total 28 + +drwxrwxrwx 6 4096 Jul 19 00:18 . +drwxr-xr-x 3 4096 Jul 19 00:00 .. +drwxrwxr-x 2 4096 Jul 22 21:24 css +-rwxrwxrwx 1 487 Jul 19 00:02 .htaccess +drwxrwxr-x 2 4096 Jul 19 00:19 js +drwxrwxrwx 3 4096 Jul 19 00:18 php +drwxrwxrwx 2 4096 Jul 19 00:03 styles +``` + +--- + +``` +vagrant@dransible:/app/current/web/sites/default$ ls -la +total 48 +dr-xr-xr-x 2 4096 Jul 19 00:14 . +drwxr-xr-x 3 4096 Jan 22 17:30 .. +-rw-r--r-- 1 6762 Jul 19 00:14 default.services.yml +-rw-r--r-- 1 31342 Jul 19 00:14 default.settings.php +lrwxrwxrwx 1 45 Jul 19 00:14 files -> ../../../../../shared/web/sites/default/files +lrwxrwxrwx 1 35 Jul 19 00:12 settings.php -> /tmp/app/sites/default/settings.php +``` + +--- + +# **Generating Drupal settings
files per deployment** + +--- + +```yaml +# ansible/vars/vault.yml + +--- +vault_database_name: drupal +vault_database_user: drupal +vault_database_password: drupal +vault_hash_salt: dfgiy$fd2!34gsf2*34g74 +``` +--- + +```yaml +# ansible/vars/vars.yml + +--- +database_name: "{{ vault_database_name }}" +database_password: "{{ vault_database_password }}" +database_user: "{{ vault_database_user }}" +hash_salt: "{{ vault_hash_salt }}" +``` + +--- + +```yaml +# ansible/vars/vars.yml + +--- +drupal_settings: + - drupal_root: /tmp/app + sites: + - name: default + settings: + databases: + default: + default: + driver: mysql + host: localhost + database: '{{ database_name }}' + username: '{{ database_user }}' + password: '{{ database_password }}' + hash_salt: '{{ hash_salt }}' + config_directories: + sync: ../config/sync +``` + + +--- + +```php +// templates/settings.php.j2 +// {{ ansible_managed }} + +{% for key, values in item.1.settings.databases.items() %} +{% for target, values in values.items() %} +$databases['{{ key }}']['{{ target }}'] = array( + 'driver' => '{{ values.driver|default('mysql') }}', + 'host' => '{{ values.host|default('localhost') }}', + 'database' => '{{ values.database }}', + 'username' => '{{ values.username }}', + 'password' => '{{ values.password }}', +); + +{% endfor %} +{% endfor %} + +{% if item.1.settings.base_url is defined %} +$base_url = '{{ item.1.settings.base_url }}'; +{% endif %} +``` + +--- + +```yaml +- name: Remove settings.php + file: + path: '{{ ansistrano_release_path.stdout }}/web/sites/{{ item.1.name|default("default")}}/settings.php' + state: absent + with_subelements: + - '{{ drupal_settings }}' + - sites + +- name: Link settings.php + file: + src: '/tmp/app/sites/{{ item.1.name|default("default")}}/settings.php' + dest: '{{ ansistrano_release_path.stdout }}/web/sites/{{ item.1.name|default("default")}}/settings.php' + state: link + with_subelements: + - '{{ drupal_settings }}' + - sites +``` diff --git a/source/images/me-phpnw-inviqa.jpg b/source/images/me-phpnw-inviqa.jpg new file mode 100644 index 0000000..e87e6fc Binary files /dev/null and b/source/images/me-phpnw-inviqa.jpg differ diff --git a/source/images/me-phpnw-inviqa.png b/source/images/me-phpnw-inviqa.png new file mode 100644 index 0000000..dfd59af Binary files /dev/null and b/source/images/me-phpnw-inviqa.png differ