Update slides
This commit is contained in:
parent
9ab929a7c0
commit
fce230f798
Binary file not shown.
After Width: | Height: | Size: 226 KiB |
Binary file not shown.
After Width: | Height: | Size: 58 KiB |
BIN
source/deploying-drupal-ansible-ansistrano/images/logo-vultr.png
Normal file
BIN
source/deploying-drupal-ansible-ansistrano/images/logo-vultr.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 5.8 KiB |
|
@ -3,51 +3,16 @@ build-lists: true
|
||||||
code: line-height(1.2)
|
code: line-height(1.2)
|
||||||
header-emphasis: #53B0EB
|
header-emphasis: #53B0EB
|
||||||
text: alignment(left)
|
text: alignment(left)
|
||||||
theme: plain jane, 8
|
theme: simple, 8
|
||||||
|
|
||||||
# [fit] **Deploying PHP applications** <br>using Ansible, Ansible Vault <br>and Ansistrano
|
# [fit] **Deploying PHP applications** <br>using Ansible, Ansible Vault <br>and Ansistrano
|
||||||
|
|
||||||
^ Ansible crash course
|
^ I work primarily with PHP, and there will be some PHP-isms in this talk (LAMP stack, Composer).
|
||||||
Basic deployment
|
Will be using a Drupal 8 application as the example, but the tools are tool and language agnostic.
|
||||||
Better deployment
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
[.build-lists: false]
|
# [fit] **Deploying ~~PHP~~ applications** <br>using Ansible, Ansible Vault <br>and Ansistrano
|
||||||
[.header: #111111]
|
|
||||||
|
|
||||||
![right 500%](../images/me-phpnw-inviqa.jpg)
|
|
||||||
|
|
||||||
- Full Stack Web Developer & System Administrator
|
|
||||||
- **Senior Software Engineer** at **Inviqa**
|
|
||||||
- Acquia certified **Drupal 8 Grand Master**
|
|
||||||
- Open sourcer
|
|
||||||
- Drupal 7 & 8 **core contributor**
|
|
||||||
- @opdavies
|
|
||||||
- www.oliverdavies.uk
|
|
||||||
|
|
||||||
^ 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.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
![350% inline](images/logo-platformsh.png)
|
|
||||||
![150% inline](images/logo-acquia.png)
|
|
||||||
![130% inline](images/logo-pantheon.png)
|
|
||||||
|
|
||||||
^ Large, well-known managed hosting companies
|
|
||||||
Optimised servers for PHP/Drupal applications
|
|
||||||
Include some sort of deployment system
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
![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
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
@ -59,14 +24,58 @@ Not enough budget for fully-managed, or using internal infrastructure
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
[.build-lists: false]
|
||||||
|
[.header: #111111]
|
||||||
|
|
||||||
|
![right 500%](../images/me-phpnw-inviqa.jpg)
|
||||||
|
|
||||||
|
- Full Stack Software Developer & System Administrator
|
||||||
|
- **Senior Software Engineer** at **Inviqa**
|
||||||
|
- Acquia certified **Drupal 8 Grand Master** and **Cloud Pro**
|
||||||
|
- Open sourcer
|
||||||
|
- Drupal 7 & 8 **core contributor**
|
||||||
|
- @opdavies
|
||||||
|
- www.oliverdavies.uk
|
||||||
|
|
||||||
|
^ Maintain Drupal modules, PHP CLI tools and libraries, Ansible roles
|
||||||
|
Blog on my website
|
||||||
|
I work primarily with Drupal and Symfony
|
||||||
|
I work for Inviqa, but this based on my personal and side projects.
|
||||||
|
I've been using Ansible for a number of years, initially only for provisioning and setting up my laptop, and later for application deployments
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
![350% inline](images/logo-platformsh.png)
|
||||||
|
![150% inline](images/logo-acquia.png)
|
||||||
|
![130% inline](images/logo-pantheon.png)
|
||||||
|
|
||||||
|
^ Large, well-known managed hosting companies
|
||||||
|
Optimised servers for PHP/Drupal applications
|
||||||
|
Include some sort of deployment system
|
||||||
|
This workflow doesn't apply to this scenario
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
![100%](images/logo-digital-ocean.png)
|
||||||
|
![30%](images/logo-linode.png)
|
||||||
|
![30%](images/logo-vultr.png)
|
||||||
|
|
||||||
|
^ More applicable to virtual or dedicated servers with no existing deployment process
|
||||||
|
Not enough budget for fully-managed, or using internal infrastructure
|
||||||
|
This is where the this workflow would be useful
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
# **What is Ansible?**
|
# **What is Ansible?**
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Ansible is **open source software** that automates **software provisioning**, <br>**configuration management**, <br>and **application deployment**.
|
## Ansible is an open-source **software provisioning, configuration management, and application-deployment** tool.
|
||||||
|
|
||||||
![10% right](images/ansible.png)
|
![10% right](images/ansible.png)
|
||||||
|
|
||||||
|
[.footer: https://en.wikipedia.org/wiki/Ansible_(software)]
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
![10% right](images/ansible.png)
|
![10% right](images/ansible.png)
|
||||||
|
@ -76,12 +85,14 @@ Not enough budget for fully-managed, or using internal infrastructure
|
||||||
* CLI tool
|
* CLI tool
|
||||||
* Written in Python
|
* Written in Python
|
||||||
* Configured with YAML
|
* Configured with YAML
|
||||||
* Executes remote commands
|
* Executes ad-hoc remote commands
|
||||||
* Installs software packages
|
* Installs software packages
|
||||||
* Performs deployment steps
|
* Performs deployment steps
|
||||||
* Batteries included
|
* Batteries included
|
||||||
|
|
||||||
^ Written in Python but you don't need to write or know Python to use it
|
^ Written in Python but you don't need to write or know Python to use it
|
||||||
|
Drupal, Symfony and a lot of other projects use YAML
|
||||||
|
First-party modules (SSH keys, file and directory management, package repositories, stopping/starting/restarting services, DO/Linode/AWS integration)
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
@ -95,6 +106,10 @@ Not enough budget for fully-managed, or using internal infrastructure
|
||||||
* Tasks
|
* Tasks
|
||||||
* Roles
|
* Roles
|
||||||
|
|
||||||
|
^ Hosts: where your managed nodes/hosts are. Can be static or dynamic.
|
||||||
|
Commands: run from a control node onto managed nodes
|
||||||
|
Playbooks and Tasks: YAML representation of a series of commands/steps
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
![10% right](images/ansible.png)
|
![10% right](images/ansible.png)
|
||||||
|
@ -106,10 +121,12 @@ Not enough budget for fully-managed, or using internal infrastructure
|
||||||
* No server dependencies
|
* No server dependencies
|
||||||
* Easy to add to an existing project
|
* Easy to add to an existing project
|
||||||
* Includes relevant modules (e.g. Composer)
|
* Includes relevant modules (e.g. Composer)
|
||||||
|
* Idempotency
|
||||||
|
|
||||||
^ Drupal 8, Symfony, Ansible all use YAML
|
^ Drupal 8, Symfony, Ansible all use YAML
|
||||||
Runs on any server with Python
|
Runs on any server with Python
|
||||||
Plugins into Drupal via CLI apps like Drush and Drupal Console
|
Plugins into Drupal via CLI apps like Drush and Drupal Console
|
||||||
|
Changes are only made when needed (once)
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
@ -124,6 +141,8 @@ Plugins into Drupal via CLI apps like Drush and Drupal Console
|
||||||
192.168.33.10
|
192.168.33.10
|
||||||
```
|
```
|
||||||
|
|
||||||
|
^ Supports wildcards and ranges.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
|
@ -140,11 +159,11 @@ webservers:
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
# `ansible all -m ping`
|
# `ansible all -i hosts.yml -m ping`
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
```
|
```json
|
||||||
webservers | SUCCESS => {
|
webservers | SUCCESS => {
|
||||||
"ansible_facts": {
|
"ansible_facts": {
|
||||||
"discovered_interpreter_python": "/usr/bin/python"
|
"discovered_interpreter_python": "/usr/bin/python"
|
||||||
|
@ -156,11 +175,11 @@ webservers | SUCCESS => {
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
# `ansible all `<br>`-m command `<br>`-a 'git pull `<br>`--chdir=/app'`
|
# `ansible all `<br>`-i hosts.yml `<br>`-m command `<br>`-a 'git pull `<br>`--chdir=/app'`
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
# `ansible all `<br>`-m git -a 'repo=https://github.com/opdavies/dransible dest=/app`'
|
# `ansible all -i hosts.yml`<br>`-m git -a 'repo=https://github.com/opdavies/dransible dest=/app`'
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
@ -170,9 +189,8 @@ webservers | SUCCESS => {
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
# playbook.yml
|
# playbook.yml
|
||||||
|
|
||||||
---
|
---
|
||||||
- hosts: all
|
- hosts: webservers # or 'all'
|
||||||
|
|
||||||
vars:
|
vars:
|
||||||
git_repo: https://github.com/opdavies/dransible
|
git_repo: https://github.com/opdavies/dransible
|
||||||
|
@ -188,11 +206,11 @@ webservers | SUCCESS => {
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
# `ansible-playbook `<br>`ansible/playbook.yml `<br>`-i hosts.yml`
|
# `ansible-playbook `<br>`playbook.yml -i hosts.yml`
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
# **Roles**
|
# **Roles: <br>configuring a LAMP stack**
|
||||||
|
|
||||||
^ Collections of tasks, variables and handlers
|
^ Collections of tasks, variables and handlers
|
||||||
|
|
||||||
|
@ -200,7 +218,6 @@ webservers | SUCCESS => {
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
# requirements.yml
|
# requirements.yml
|
||||||
|
|
||||||
---
|
---
|
||||||
- src: geerlingguy.apache
|
- src: geerlingguy.apache
|
||||||
- src: geerlingguy.composer
|
- src: geerlingguy.composer
|
||||||
|
@ -213,15 +230,14 @@ webservers | SUCCESS => {
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
# `ansible-galaxy -r`<br>`ansible/requirements.yml install`
|
# `ansible-galaxy -r`<br>`requirements.yml install`
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
# playbook.yml
|
# provision.yml
|
||||||
|
|
||||||
---
|
---
|
||||||
- hosts: all
|
- hosts: webservers
|
||||||
|
|
||||||
roles:
|
roles:
|
||||||
- geerlingguy.apache
|
- geerlingguy.apache
|
||||||
|
@ -236,72 +252,171 @@ webservers | SUCCESS => {
|
||||||
---
|
---
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
# ansible/provision.yml
|
# provision.yml
|
||||||
|
---
|
||||||
|
- hosts: webservers
|
||||||
|
# ...
|
||||||
|
|
||||||
tasks:
|
vars:
|
||||||
- name: Create a database
|
apache_vhosts:
|
||||||
mysql_db:
|
- servername: dransible.wip
|
||||||
name: mydatabase
|
documentroot: /app/web
|
||||||
state: present
|
|
||||||
|
|
||||||
- name: Add the database user
|
|
||||||
mysql_user:
|
|
||||||
name: drupal
|
|
||||||
password: secret
|
|
||||||
priv: 'mydatabase.*:ALL'
|
|
||||||
state: present
|
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
# **Basic deployment**
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
# ansible/deploy.yml
|
# provision.yml
|
||||||
|
---
|
||||||
|
- hosts: webservers
|
||||||
|
# ...
|
||||||
|
|
||||||
tasks:
|
vars:
|
||||||
- name: Creating project directory
|
# ...
|
||||||
file:
|
php_version: '7.4'
|
||||||
path: /app
|
php_packages_extra:
|
||||||
state: directory
|
- libapache2-mod-php{{ php_version }}
|
||||||
|
- libpcre3-dev
|
||||||
- name: Uploading application
|
|
||||||
synchronize:
|
|
||||||
src: "{{ playbook_dir }}/../"
|
|
||||||
dest: /app
|
|
||||||
|
|
||||||
- name: Installing Composer dependencies
|
|
||||||
composer:
|
|
||||||
command: install
|
|
||||||
working_dir: /app
|
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
# Disadvantages
|
```yaml
|
||||||
|
# provision.yml
|
||||||
|
---
|
||||||
|
- hosts: webservers
|
||||||
|
# ...
|
||||||
|
|
||||||
* Single point of failure
|
vars:
|
||||||
* No ability to roll back
|
# ...
|
||||||
* Sensitive data stored in plain text
|
mysql_databases:
|
||||||
|
- name: main
|
||||||
|
|
||||||
|
mysql_users:
|
||||||
|
- name: user
|
||||||
|
password: secret
|
||||||
|
priv: main.*:ALL
|
||||||
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
# **Keeping secrets: <br>Ansible Vault**
|
# `ansible-playbook provision.yml -i hosts.yml`
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
# `ansible-vault create` <br>`ansible/vault.yml`
|
```
|
||||||
|
PLAY [Provision the webserver machines] ********************************************************************************
|
||||||
|
|
||||||
|
TASK [Gathering Facts] *************************************************************************************************
|
||||||
|
ok: [webservers]
|
||||||
|
|
||||||
|
TASK [geerlingguy.apache : Include OS-specific variables.] *************************************************************
|
||||||
|
ok: [webservers]
|
||||||
|
|
||||||
|
TASK [geerlingguy.apache : Include variables for Amazon Linux.]
|
||||||
|
skipping: [webservers]
|
||||||
|
|
||||||
|
TASK [geerlingguy.apache : Define apache_packages.] ********************************************************************
|
||||||
|
ok: [webservers]
|
||||||
|
|
||||||
|
TASK [geerlingguy.apache : include_tasks] ******************************************************************************
|
||||||
|
included: /Users/opdavies/.ansible/roles/geerlingguy.apache/tasks/setup-Debian.yml for webservers
|
||||||
|
|
||||||
|
TASK [geerlingguy.apache : Update apt cache.] **************************************************************************
|
||||||
|
changed: [webservers]
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
```
|
||||||
|
TASK [geerlingguy.composer : Ensure composer directory exists.] ********************************************************
|
||||||
|
ok: [webservers]
|
||||||
|
|
||||||
|
TASK [geerlingguy.composer : include_tasks] ****************************************************************************
|
||||||
|
skipping: [webservers]
|
||||||
|
|
||||||
|
TASK [geerlingguy.composer : include_tasks] ****************************************************************************
|
||||||
|
skipping: [webservers]
|
||||||
|
|
||||||
|
RUNNING HANDLER [geerlingguy.apache : restart apache] ******************************************************************
|
||||||
|
changed: [webservers]
|
||||||
|
|
||||||
|
RUNNING HANDLER [geerlingguy.mysql : restart mysql] ********************************************************************
|
||||||
|
changed: [webservers]
|
||||||
|
|
||||||
|
RUNNING HANDLER [geerlingguy.php : restart webserver] ******************************************************************
|
||||||
|
changed: [webservers]
|
||||||
|
|
||||||
|
RUNNING HANDLER [geerlingguy.php : restart php-fpm] ********************************************************************
|
||||||
|
skipping: [webservers]
|
||||||
|
|
||||||
|
PLAY RECAP *************************************************************************************************************
|
||||||
|
webservers : ok=111 changed=32 unreachable=0 failed=0 skipped=78 rescued=0 ignored=0
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
![70%](images/after-provision-1.png)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
![70%](images/after-provision-2.png)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# **Keeping secrets with <br>Ansible Vault**
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
# ansible/vars/vault.yml
|
# provision.yml
|
||||||
|
---
|
||||||
|
- hosts: webservers
|
||||||
|
# ...
|
||||||
|
|
||||||
|
vars:
|
||||||
|
# ...
|
||||||
|
mysql_databases:
|
||||||
|
- name: main
|
||||||
|
|
||||||
|
mysql_users:
|
||||||
|
- name: user
|
||||||
|
password: secret
|
||||||
|
priv: main.*:ALL
|
||||||
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
vault_database_name: mydatabase
|
|
||||||
vault_database_user: drupal
|
[.code-highlight: 11-14]
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
# provision.yml
|
||||||
|
---
|
||||||
|
- hosts: webservers
|
||||||
|
# ...
|
||||||
|
|
||||||
|
vars:
|
||||||
|
# ...
|
||||||
|
mysql_databases:
|
||||||
|
- name: main
|
||||||
|
|
||||||
|
mysql_users:
|
||||||
|
- name: user
|
||||||
|
password: secret
|
||||||
|
priv: main.*:ALL
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# `ansible-vault create` <br>`vault.yml`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
# vars/vault.yml
|
||||||
|
---
|
||||||
|
vault_database_name: main
|
||||||
|
vault_database_user: user
|
||||||
vault_database_password: secret
|
vault_database_password: secret
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -327,8 +442,7 @@ $ANSIBLE_VAULT;1.1;AES256
|
||||||
---
|
---
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
# ansible/vars/vars.yml
|
# vars/vars.yml
|
||||||
|
|
||||||
---
|
---
|
||||||
database_name: "{{ vault_database_name }}"
|
database_name: "{{ vault_database_name }}"
|
||||||
database_user: "{{ vault_database_user }}"
|
database_user: "{{ vault_database_user }}"
|
||||||
|
@ -338,22 +452,58 @@ database_password: "{{ vault_database_password }}"
|
||||||
---
|
---
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
# ansible/provision.yml
|
# provision.yml
|
||||||
|
---
|
||||||
|
mysql_databases:
|
||||||
|
- '{{ database_name }}'
|
||||||
|
|
||||||
tasks:
|
mysql_users:
|
||||||
- name: Create a database
|
- name: '{{ database_user }}'
|
||||||
mysql_db:
|
password: '{{ database_password }}'
|
||||||
name: '{{ database_name }}'
|
priv: '{{ database_name }}.*:ALL'
|
||||||
state: present
|
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
# `ansible-vault edit ansible/vault.yml`
|
# `ansible-vault edit vault.yml`
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
# `ansible-playbook` <br>`-i hosts.yml` <br>`ansible/deploy.yml`<br>`--ask-vault-pass`
|
# `ansible-playbook` <br>`-i hosts.yml` <br>`deploy.yml`<br>`--ask-vault-pass`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# **Basic deployment**
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
# deploy.yml
|
||||||
|
|
||||||
|
tasks:
|
||||||
|
- name: Creating project directory
|
||||||
|
file:
|
||||||
|
path: /app
|
||||||
|
state: directory
|
||||||
|
|
||||||
|
- name: Uploading application
|
||||||
|
synchronize:
|
||||||
|
src: "{{ playbook_dir }}/../"
|
||||||
|
dest: /app
|
||||||
|
|
||||||
|
- name: Installing Composer dependencies
|
||||||
|
composer:
|
||||||
|
command: install
|
||||||
|
working_dir: /app
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# Disadvantages
|
||||||
|
|
||||||
|
* Single point of failure
|
||||||
|
* No ability to roll back
|
||||||
|
* Sensitive data stored in plain text
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
@ -383,10 +533,9 @@ Ansible port of Capistrano
|
||||||
---
|
---
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
# ansible/requirements.yml
|
# requirements.yml
|
||||||
|
|
||||||
---
|
---
|
||||||
...
|
# ...
|
||||||
- ansistrano.deploy
|
- ansistrano.deploy
|
||||||
- ansistrano.rollback
|
- ansistrano.rollback
|
||||||
```
|
```
|
||||||
|
@ -394,7 +543,7 @@ Ansible port of Capistrano
|
||||||
---
|
---
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
# ansible/deploy.yml
|
# deploy.yml
|
||||||
|
|
||||||
---
|
---
|
||||||
- hosts: all
|
- hosts: all
|
||||||
|
@ -406,12 +555,11 @@ Ansible port of Capistrano
|
||||||
---
|
---
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
# ansible/deploy.yml
|
# deploy.yml
|
||||||
|
|
||||||
---
|
---
|
||||||
...
|
# ...
|
||||||
vars:
|
vars:
|
||||||
project_deploy_dir: /var/www
|
project_deploy_dir: /app
|
||||||
|
|
||||||
ansistrano_deploy_to: '{{ project_deploy_dir }}'
|
ansistrano_deploy_to: '{{ project_deploy_dir }}'
|
||||||
ansistrano_deploy_via: git
|
ansistrano_deploy_via: git
|
||||||
|
@ -421,7 +569,59 @@ Ansible port of Capistrano
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
# `ansible-playbook` <br>`-i hosts.yml` <br>`ansible/deploy.yml`
|
# `ansible-playbook` <br>`-i hosts.yml` <br>`deploy.yml`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
```
|
||||||
|
PLAY [webservers] ******************************************************************************************************
|
||||||
|
|
||||||
|
TASK [Gathering Facts] *************************************************************************************************
|
||||||
|
ok: [webservers]
|
||||||
|
|
||||||
|
TASK [ansistrano.deploy : include_tasks] *******************************************************************************
|
||||||
|
|
||||||
|
TASK [ansistrano.deploy : include_tasks] *******************************************************************************
|
||||||
|
included: /Users/opdavies/.ansible/roles/ansistrano.deploy/tasks/setup.yml for webservers
|
||||||
|
|
||||||
|
TASK [ansistrano.deploy : ANSISTRANO | Ensure deployment base path exists] *********************************************
|
||||||
|
ok: [webservers]
|
||||||
|
|
||||||
|
TASK [ansistrano.deploy : ANSISTRANO | Ensure releases folder exists] **************************************************
|
||||||
|
ok: [webservers]
|
||||||
|
|
||||||
|
TASK [ansistrano.deploy : ANSISTRANO | Ensure shared elements folder exists] *******************************************
|
||||||
|
ok: [webservers]
|
||||||
|
|
||||||
|
TASK [ansistrano.deploy : ANSISTRANO | Ensure shared paths exists] *****************************************************
|
||||||
|
ok: [webservers] => (item=web/sites/default/files)
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
```
|
||||||
|
TASK [ansistrano.deploy : Update file permissions] *********************************************************************
|
||||||
|
changed: [webservers]
|
||||||
|
|
||||||
|
TASK [ansistrano.deploy : include_tasks] *******************************************************************************
|
||||||
|
|
||||||
|
TASK [ansistrano.deploy : include_tasks] *******************************************************************************
|
||||||
|
included: /Users/opdavies/.ansible/roles/ansistrano.deploy/tasks/cleanup.yml for webservers
|
||||||
|
|
||||||
|
TASK [ansistrano.deploy : ANSISTRANO | Clean up releases] **************************************************************
|
||||||
|
changed: [webservers]
|
||||||
|
|
||||||
|
TASK [ansistrano.deploy : include_tasks] *******************************************************************************
|
||||||
|
|
||||||
|
TASK [ansistrano.deploy : include_tasks] *******************************************************************************
|
||||||
|
included: /Users/opdavies/.ansible/roles/ansistrano.deploy/tasks/anon-stats.yml for webservers
|
||||||
|
|
||||||
|
TASK [ansistrano.deploy : ANSISTRANO | Send anonymous stats] ***********************************************************
|
||||||
|
skipping: [webservers]
|
||||||
|
|
||||||
|
PLAY RECAP *************************************************************************************************************
|
||||||
|
webservers : ok=33 changed=14 unreachable=0 failed=0 skipped=7 rescued=0 ignored=0
|
||||||
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
@ -449,9 +649,12 @@ drwxr-xr-x 9 4096 Jul 22 20:30 20190722203038Z
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
```yaml
|
# `ansible-playbook` <br>`-i hosts.yml` <br>`rollback.yml`
|
||||||
# ansible/rollback.yml
|
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
# rollback.yml
|
||||||
---
|
---
|
||||||
- hosts: all
|
- hosts: all
|
||||||
|
|
||||||
|
@ -464,10 +667,6 @@ drwxr-xr-x 9 4096 Jul 22 20:30 20190722203038Z
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
# `ansible-playbook` <br>`-i hosts.yml` <br>`ansible/rollback.yml`
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
# **Customising Ansistrano: <br>Build Hooks**
|
# **Customising Ansistrano: <br>Build Hooks**
|
||||||
|
|
||||||
---
|
---
|
||||||
|
@ -482,23 +681,25 @@ Clean up = remove node_modules, database export, sqlite testing DB
|
||||||
---
|
---
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
# ansible/deploy.yml
|
# 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_symlink_shared_tasks_file: "{{ playbook_dir }}/deploy/after-symlink-shared.yml"
|
ansistrano_after_update_code_tasks_file: '{{ playbook_dir }}/deploy/after-update-code.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_web_path: '{{ ansistrano_release_path.stdout }}/web'
|
||||||
release_drush_path: "{{ ansistrano_release_path.stdout }}/vendor/bin/drush"
|
release_drush_path: '{{ ansistrano_release_path.stdout }}/vendor/bin/drush'
|
||||||
```
|
```
|
||||||
|
|
||||||
|
^ Each step has a 'before' and 'after' step
|
||||||
|
Ansistrano allows us to add more things by providing a path to a playbook and adding additional steps.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
# ansible/deploy/after-update-code.yml
|
# deploy/after-update-code.yml
|
||||||
|
|
||||||
---
|
---
|
||||||
- name: Install Composer dependencies
|
- name: Install Composer dependencies
|
||||||
composer:
|
composer:
|
||||||
|
@ -509,8 +710,7 @@ vars:
|
||||||
---
|
---
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
# ansible/deploy/after-symlink-shared.yml
|
# deploy/after-symlink-shared.yml
|
||||||
|
|
||||||
---
|
---
|
||||||
- name: Run database updates
|
- name: Run database updates
|
||||||
command: '{{ release_drush_path }} --root {{ release_web_path }} updatedb'
|
command: '{{ release_drush_path }} --root {{ release_web_path }} updatedb'
|
||||||
|
@ -519,8 +719,7 @@ vars:
|
||||||
---
|
---
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
# ansible/deploy/after-symlink.yml
|
# deploy/after-symlink.yml
|
||||||
|
|
||||||
---
|
---
|
||||||
- name: Clear Drupal cache
|
- name: Clear Drupal cache
|
||||||
command: '{{ release_drush_path }} --root {{ release_web_path }} cache-rebuild'
|
command: '{{ release_drush_path }} --root {{ release_web_path }} cache-rebuild'
|
||||||
|
@ -532,30 +731,12 @@ vars:
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
# **Demo**
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
# **Questions?**
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
![](images/drupalcon/contribution.jpg)
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
![](images/drupalcon/feedback.jpg)
|
|
||||||
|
|
||||||
^ Please leave feedback via the DrupalCon app, or via Twitter
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
# **Managing data <br>across deployments**
|
# **Managing data <br>across deployments**
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
# ansible/deploy.yml
|
# deploy.yml
|
||||||
|
|
||||||
vars:
|
vars:
|
||||||
# ...
|
# ...
|
||||||
|
@ -588,29 +769,27 @@ 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 6762 Jul 19 00:14 default.services.yml
|
||||||
-rw-r--r-- 1 31342 Jul 19 00:14 default.settings.php
|
-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 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
|
-rw-r--r-- 1 35 Jul 19 00:12 settings.php
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
# **Generating Drupal settings <br>files per deployment**
|
# **Generating settings <br>files per deployment**
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
# ansible/vars/vault.yml
|
# vars/vault.yml
|
||||||
|
|
||||||
---
|
---
|
||||||
vault_database_name: drupal
|
vault_database_name: main
|
||||||
vault_database_user: drupal
|
vault_database_user: user
|
||||||
vault_database_password: drupal
|
vault_database_password: secret
|
||||||
vault_hash_salt: dfgiy$fd2!34gsf2*34g74
|
vault_hash_salt: dfgiy$fd2!34gsf2*34g74
|
||||||
```
|
```
|
||||||
---
|
---
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
# ansible/vars/vars.yml
|
# vars/vars.yml
|
||||||
|
|
||||||
---
|
---
|
||||||
database_name: "{{ vault_database_name }}"
|
database_name: "{{ vault_database_name }}"
|
||||||
database_password: "{{ vault_database_password }}"
|
database_password: "{{ vault_database_password }}"
|
||||||
|
@ -621,11 +800,10 @@ hash_salt: "{{ vault_hash_salt }}"
|
||||||
---
|
---
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
# ansible/vars/vars.yml
|
# vars/vars.yml
|
||||||
|
|
||||||
---
|
---
|
||||||
drupal_settings:
|
drupal_settings:
|
||||||
- drupal_root: /tmp/app
|
- drupal_root: /app/web
|
||||||
sites:
|
sites:
|
||||||
- name: default
|
- name: default
|
||||||
settings:
|
settings:
|
||||||
|
@ -642,11 +820,11 @@ drupal_settings:
|
||||||
sync: ../config/sync
|
sync: ../config/sync
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
```php
|
```php
|
||||||
// templates/settings.php.j2
|
// templates/settings.php.j2
|
||||||
|
|
||||||
// {{ ansible_managed }}
|
// {{ ansible_managed }}
|
||||||
|
|
||||||
{% for key, values in item.1.settings.databases.items() %}
|
{% for key, values in item.1.settings.databases.items() %}
|
||||||
|
@ -665,25 +843,106 @@ $databases['{{ key }}']['{{ target }}'] = array(
|
||||||
{% if item.1.settings.base_url is defined %}
|
{% if item.1.settings.base_url is defined %}
|
||||||
$base_url = '{{ item.1.settings.base_url }}';
|
$base_url = '{{ item.1.settings.base_url }}';
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
|
{# ... #}
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
- name: Remove settings.php
|
# tasks/main.yml
|
||||||
|
---
|
||||||
|
- name: Ensure directory exists
|
||||||
file:
|
file:
|
||||||
path: '{{ ansistrano_release_path.stdout }}/web/sites/{{ item.1.name|default("default")}}/settings.php'
|
state: directory
|
||||||
state: absent
|
path: '{{ item.0.drupal_root }}/sites/{{ item.1.name|default("default") }}'
|
||||||
with_subelements:
|
with_subelements:
|
||||||
- '{{ drupal_settings }}'
|
- '{{ drupal_settings }}'
|
||||||
- sites
|
- sites
|
||||||
|
no_log: true
|
||||||
|
|
||||||
- name: Link settings.php
|
- name: Create settings files
|
||||||
file:
|
template:
|
||||||
src: '/tmp/app/sites/{{ item.1.name|default("default")}}/settings.php'
|
src: settings.php.j2
|
||||||
dest: '{{ ansistrano_release_path.stdout }}/web/sites/{{ item.1.name|default("default")}}/settings.php'
|
dest: '{{ item.0.drupal_root }}/sites/{{ item.1.name|default("default") }}/{{ item.1.filename|default("settings.php") }}'
|
||||||
state: link
|
|
||||||
with_subelements:
|
with_subelements:
|
||||||
- '{{ drupal_settings }}'
|
- '{{ drupal_settings }}'
|
||||||
- sites
|
- sites
|
||||||
|
no_log: true
|
||||||
```
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# **Multiple environments**
|
||||||
|
## Dev, test, production
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
mysql_databases:
|
||||||
|
- name: production
|
||||||
|
- name: staging
|
||||||
|
|
||||||
|
mysql_users:
|
||||||
|
- name: production
|
||||||
|
password: '{{ live_db_password }}'
|
||||||
|
priv: '{{ live_db_name }}.*:ALL'
|
||||||
|
|
||||||
|
- name: staging
|
||||||
|
password: '{{ staging_db_password }}'
|
||||||
|
priv: staging.*:ALL
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
# inventories/live.yml
|
||||||
|
---
|
||||||
|
all:
|
||||||
|
hosts:
|
||||||
|
webservers:
|
||||||
|
ansible_ssh_host: 192.168.33.10
|
||||||
|
ansible_ssh_port: 22
|
||||||
|
|
||||||
|
project_deploy_path: /app
|
||||||
|
git_branch: master
|
||||||
|
|
||||||
|
drupal_hash_salt: "{{ vault_drupal_hash_salt }}"
|
||||||
|
drupal_install: true
|
||||||
|
|
||||||
|
drupal_settings:
|
||||||
|
# ...
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
# inventories/staging.yml
|
||||||
|
---
|
||||||
|
all:
|
||||||
|
hosts:
|
||||||
|
webservers:
|
||||||
|
ansible_ssh_host: 192.168.33.10
|
||||||
|
ansible_ssh_port: 22
|
||||||
|
|
||||||
|
project_deploy_path: /app-test
|
||||||
|
git_branch: develop
|
||||||
|
|
||||||
|
drupal_hash_salt: "{{ vault_drupal_hash_salt }}"
|
||||||
|
drupal_install: true
|
||||||
|
|
||||||
|
drupal_settings:
|
||||||
|
# ...
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# `ansible-playbook deploy.yml -i inventories/staging.yml`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# `ansible-playbook deploy.yml -i inventories/live.yml`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# **Questions?**
|
||||||
|
|
Loading…
Reference in a new issue