Add Ansible playbook for deployments

This commit is contained in:
Oliver Davies 2020-02-07 07:43:17 +00:00
parent 4299ca3ae7
commit f2e458ca13
14 changed files with 293 additions and 12 deletions

12
tools/ansible/deploy.yml Normal file
View file

@ -0,0 +1,12 @@
---
- hosts: all
vars_files:
- vars/vars.yml
- vars/provision_vault.yml
- vars/provision_vars.yml
- vars/deploy_vault.yml
- vars/deploy_vars.yml
roles:
- name: ansistrano.deploy

View file

@ -0,0 +1,10 @@
---
- name: Setup directory permissions for files directories
become: true
file:
path: '{{ ansistrano_shared_path }}/{{ project_web_dir }}/sites/default/files'
state: directory
owner: www-data
group: root
mode: u=rwx,g=rw,o=
recurse: true

View file

@ -0,0 +1,9 @@
---
- name: Install Composer dependencies
composer:
command: install
working_dir: '{{ ansistrano_release_path.stdout }}'
- name: Generate settings.php file
include_role:
name: './roles/drupal-settings'

27
tools/ansible/id_deploy Normal file
View file

@ -0,0 +1,27 @@
-----BEGIN OPENSSH PRIVATE KEY-----
b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAABFwAAAAdzc2gtcn
NhAAAAAwEAAQAAAQEAvj6ZFxvDdMz/nXNR3mw10Lmq/VB/ZeYS9Z8TWRGoZOb1xTHhLsvA
LNMrWEeu473MYLOGPKzOaUzw4sev61AWZ71mnKtt3VAE+DkuMJ+SXGql5oshSWNwYcivcM
aCmaW6VC/BfTlPemi4bb1KybEwH5vMMHxbsKBhUL3GKiNYnKAeb/QrdP/ZCahYJnOHJVda
FfEatd7dE+nZwEtzAKuxu6lyYIzDXd4xW6B2Zf1NhROXB1p99VwayEZ+S7Jaih2FFIQn6m
74/vcd451XpMevxpwX0qAkSZIPx+owzQmM7+ei9yuJQ0LO52ECkbMu914gUsiJISE0Fp1D
+4pBjnBgTwAAA9BOMZjITjGYyAAAAAdzc2gtcnNhAAABAQC+PpkXG8N0zP+dc1HebDXQua
r9UH9l5hL1nxNZEahk5vXFMeEuy8As0ytYR67jvcxgs4Y8rM5pTPDix6/rUBZnvWacq23d
UAT4OS4wn5JcaqXmiyFJY3BhyK9wxoKZpbpUL8F9OU96aLhtvUrJsTAfm8wwfFuwoGFQvc
YqI1icoB5v9Ct0/9kJqFgmc4clV1oV8Rq13t0T6dnAS3MAq7G7qXJgjMNd3jFboHZl/U2F
E5cHWn31XBrIRn5LslqKHYUUhCfqbvj+9x3jnVekx6/GnBfSoCRJkg/H6jDNCYzv56L3K4
lDQs7nYQKRsy73XiBSyIkhITQWnUP7ikGOcGBPAAAAAwEAAQAAAQEAgYUIoOzr8vcmB8Hd
OPqe4M2nFfLZ6TvsKID2oSseZCPBq1E8J6nb2iiiV+XlsXMkU6mleGWF2bbiQOMGZ8QMnP
AbjgpAL+4sk/oJ8lyRPo31CLIsJVSnzEre9n6Pp59m7a3doy2DaKkm9r9qzUnuo3ZkW5Yu
rl9iIaAx67pIt8g2shG3cHgfLMgyr3MNXTzKOHJyFcvOsf+BLFOkj5dUcYf7iKQPtd9ffP
2fcOSHuj/JfQgaMokEwbjE1lUHw0MTvSzCR/wT1t2VpqAgcKG6ywkW5OQzhpfzvCLpGSKF
8vtlVxAjM44uHHojJPQINDnwarkfmiRTjIQmJnxcoBfHsQAAAIBKbDbv9mQ8dWroZ0Qilz
+qQ2tluIeGCu+GX/SW0DtxxXZom5mM2oZi6pZTZsvKJnvYwMvwI6AYXPDMHdmIIn5tvyio
kz7ghjitE8KV2VaR+f5Sx0sw1XRQS5Nhc1whIXW74/+ePz9PH2WIf8OIQ6kT4Kw+VEukbq
IOLujsHWJ0eQAAAIEA3PwD5w3v18wt96yy6Dkb9EPVhk7lvlagFlUzqFY6bxAI05mjiFOB
jksDTQXPj1NgRIp8iRUFORlMXlvGA6S8ZTnZxfTUfFJYzZCWmbrzrnDZRi2BFE0/css2PP
DFmYkd2wLHOYEOEv4NlDa0+4tn7mnyyDnv9okzCaiftPRmX00AAACBANxjpyN9nSD2v6H3
biHpEGFfa74IaB3kMBkdsxd/H8xAxJydt6rSF8FMyI7tnE2GuRKilpu138vOu0t9np4QPv
IRE/r/7dgC6kbMeDPRDV98CvyepJ6p4GA2yWGTDk89hAWEM7CNuNacRMGouBqQorWScN+O
uwNqDNbC8g8hH2gLAAAAFG9wZGF2aWVzQE9saXZlcnMtTUJQAQIDBAUG
-----END OPENSSH PRIVATE KEY-----

View file

@ -0,0 +1 @@
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC+PpkXG8N0zP+dc1HebDXQuar9UH9l5hL1nxNZEahk5vXFMeEuy8As0ytYR67jvcxgs4Y8rM5pTPDix6/rUBZnvWacq23dUAT4OS4wn5JcaqXmiyFJY3BhyK9wxoKZpbpUL8F9OU96aLhtvUrJsTAfm8wwfFuwoGFQvcYqI1icoB5v9Ct0/9kJqFgmc4clV1oV8Rq13t0T6dnAS3MAq7G7qXJgjMNd3jFboHZl/U2FE5cHWn31XBrIRn5LslqKHYUUhCfqbvj+9x3jnVekx6/GnBfSoCRJkg/H6jDNCYzv56L3K4lDQs7nYQKRsy73XiBSyIkhITQWnUP7ikGOcGBP Ansistrano deployment

View file

@ -1,4 +1,8 @@
---
- name: ansistrano.deploy
version: 3.4.0
- name: ansistrano.rollback
version: 3.0.0
- name: geerlingguy.composer
version: 1.7.3
- name: geerlingguy.firewall

View file

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2019 Oliver Davies
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View file

@ -0,0 +1,27 @@
# Ansible Role: Drupal settings
```yaml
drupal_settings:
- drupal_root: /var/www/web
sites:
- name: default
filename: settings.php # Optional, defaults to 'settings.php'
settings:
base_url: https://www.example.com # Optional, Drupal 7
hash_salt: '' # Optional
databases:
default: # The database key
default: # The database target
driver: mysql # Optional, defaults to 'mysql'
host: localhost # Optional, defaults to 'localhost'
database: mydatabase
username: user
password: secret
config_directories: # Optional, Drupal 8
sync: path/to/config
trusted_hosts: # Optional, Drupal 8
- '^example\.com$'
- '^.+\.example\.com$'
- '^example\.org$'
- '^.+\.example\.org$'
```

View file

@ -0,0 +1,2 @@
---
drupal_settings: []

View file

@ -0,0 +1,18 @@
---
- name: Ensure directory exists
file:
state: directory
path: '{{ item.0.drupal_root }}/sites/{{ item.1.name|default("default") }}'
with_subelements:
- '{{ drupal_settings }}'
- sites
no_log: true
- name: Create settings files
template:
src: settings.php.j2
dest: '{{ item.0.drupal_root }}/sites/{{ item.1.name|default("default") }}/{{ item.1.filename|default("settings.php") }}'
with_subelements:
- '{{ drupal_settings }}'
- sites
no_log: true

View file

@ -0,0 +1,42 @@
<?php
// {{ 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 %}
{% if item.1.settings.hash_salt is defined %}
$settings['hash_salt'] = '{{ item.1.settings.hash_salt }}';
{% endif %}
{% if item.1.settings.config_directories is defined %}
{% for name, value in item.1.settings.config_directories.items() %}
$config_directories['{{ name }}'] = '{{ value }}';
{% endfor %}
{% endif %}
{% if item.1.settings.trusted_hosts is defined %}
$settings['trusted_host_patterns'] = array(
{% for host in item.1.settings.trusted_hosts %}
'{{ host }}',
{% endfor %}
);
{% endif %}
{% if item.1.settings.extra_parameters is defined %}
{{ item.1.settings.extra_parameters|indent(0) }}
{% endif %}

View file

@ -0,0 +1,36 @@
---
ansistrano_allow_anonymous_stats: false
ansistrano_deploy_via: git
ansistrano_deploy_to: '{{ project_root_path }}'
ansistrano_git_identity_key_path: '{{ playbook_dir }}/id_deploy'
ansistrano_git_repo: git@github.com:opdavies/oliverdavies-uk.git
ansistrano_git_branch: master
ansistrano_keep_releases: 5
ansistrano_shared_paths:
- '{{ project_web_dir }}/sites/default/files'
# Hooks
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'
app_hash_salt: '{{ vault_app_hash_salt }}'
drupal_settings:
- drupal_root: '{{ ansistrano_release_path.stdout }}/{{ project_web_dir }}'
sites:
- name: default
settings:
base_url: http://d8.oliverdavies.uk
hash_salt: '{{ app_hash_salt }}'
databases:
default:
default:
driver: mysql
host: localhost
database: oliverdavies_uk
username: '{{ app_mysql_user }}'
password: '{{ app_mysql_password }}'
config_directories:
sync: ../config/sync
trusted_hosts:
- '^d8\.oliverdavies\.uk$'

View file

@ -0,0 +1,8 @@
$ANSIBLE_VAULT;1.1;AES256
39323539326634383533336262633230666630366666363935643462306538366338666436663235
6231616134366432633965376535303635396134333661640a393961633431383165653439343436
39303333346162386436393133303633636565323730643732396431623464623631396138343434
3166346130643937340a343433393831396638643434653933343033353430326633376333396462
66363461363435373462643037353661346435383336336137613837633933393931613833313037
33393064383939666335323733346164643036366232656362326461373031303365386266663133
343633356331333831633730396562616634

View file

@ -34,27 +34,91 @@ nginx_vhosts:
root: '{{ project_root_path }}/{{ ansistrano_current_dir }}/{{ project_web_dir }}'
index: index.php
extra_parameters: |
location = /favicon.ico {
log_not_found off;
access_log off;
}
location = /robots.txt {
allow all;
log_not_found off;
access_log off;
}
# Very rarely should these ever be accessed outside of your lan
location ~* \.(txt|log)$ {
allow 192.168.0.0/16;
deny all;
}
location ~ \..*/.*\.php$ {
return 403;
}
location ~ ^/sites/.*/private/ {
return 403;
}
# Block access to scripts in site files directory
location ~ ^/sites/[^/]+/files/.*\.php$ {
deny all;
}
# Allow "Well-Known URIs" as per RFC 5785
location ~* ^/.well-known/ {
allow all;
}
# Block access to "hidden" files and directories whose names begin with a
# period. This includes directories used by version control systems such
# as Subversion or Git to store control files.
location ~ (^|/)\. {
return 403;
}
location / {
try_files $uri /index.php?$query_string;
try_files $uri /index.php?$query_string; # For Drupal >= 7
}
location @rewrite {
rewrite ^/(.*)$ /index.php?q=$1;
rewrite ^/(.*)$ /index.php?q=$1;
}
# Don't allow direct access to PHP files in the vendor directory.
location ~ /vendor/.*\.php$ {
deny all;
return 404;
deny all;
return 404;
}
location ~ '\.php$|^/update.php' {
try_files $uri =404;
fastcgi_split_path_info ^(.+?\.php)(|/.*)$;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
fastcgi_param QUERY_STRING $query_string;
fastcgi_intercept_errors on;
fastcgi_pass localhost:9000;
try_files $uri =404;
fastcgi_split_path_info ^(.+?\.php)(|/.*)$;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
fastcgi_param QUERY_STRING $query_string;
fastcgi_intercept_errors on;
fastcgi_pass localhost:9000;
}
# Fighting with Styles? This little gem is amazing.
# location ~ ^/sites/.*/files/imagecache/ { # For Drupal <= 6
location ~ ^/sites/.*/files/styles/ { # For Drupal >= 7
try_files $uri @rewrite;
}
# Handle private files through Drupal.
location ~ ^(/[a-z\-]+)?/system/files/ { # For Drupal >= 7
try_files $uri /index.php?$query_string;
}
location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg)$ {
try_files $uri @rewrite;
expires max;
log_not_found off;
}
# Enforce clean URLs
if ($request_uri ~* "^(.*/)index\.php(.*)") {
return 307 $1$2;
}