diff --git a/deploying-php-ansible-ansistrano/README.rst b/deploying-php-ansible-ansistrano/README.rst new file mode 100644 index 0000000..65c5d66 --- /dev/null +++ b/deploying-php-ansible-ansistrano/README.rst @@ -0,0 +1,4 @@ +Working with Workspace +###################### + +https://www.oliverdavies.uk/talks/working-with-workspace diff --git a/deploying-php-ansible-ansistrano/images/.gitkeep b/deploying-php-ansible-ansistrano/images/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/deploying-php-ansible-ansistrano/images/after-deploy-1.png b/deploying-php-ansible-ansistrano/images/after-deploy-1.png new file mode 100644 index 0000000..2acb2b3 Binary files /dev/null and b/deploying-php-ansible-ansistrano/images/after-deploy-1.png differ diff --git a/deploying-php-ansible-ansistrano/images/after-provision-1.png b/deploying-php-ansible-ansistrano/images/after-provision-1.png new file mode 100644 index 0000000..cc61210 Binary files /dev/null and b/deploying-php-ansible-ansistrano/images/after-provision-1.png differ diff --git a/deploying-php-ansible-ansistrano/images/after-provision-2.png b/deploying-php-ansible-ansistrano/images/after-provision-2.png new file mode 100644 index 0000000..67a6f2e Binary files /dev/null and b/deploying-php-ansible-ansistrano/images/after-provision-2.png differ diff --git a/deploying-php-ansible-ansistrano/images/ansible.png b/deploying-php-ansible-ansistrano/images/ansible.png new file mode 100644 index 0000000..c72d308 Binary files /dev/null and b/deploying-php-ansible-ansistrano/images/ansible.png differ diff --git a/deploying-php-ansible-ansistrano/images/ansistrano-flow.png b/deploying-php-ansible-ansistrano/images/ansistrano-flow.png new file mode 100644 index 0000000..519adaf Binary files /dev/null and b/deploying-php-ansible-ansistrano/images/ansistrano-flow.png differ diff --git a/deploying-php-ansible-ansistrano/images/ansistrano.png b/deploying-php-ansible-ansistrano/images/ansistrano.png new file mode 100644 index 0000000..2954d3d Binary files /dev/null and b/deploying-php-ansible-ansistrano/images/ansistrano.png differ diff --git a/deploying-php-ansible-ansistrano/images/ansistrano2.png b/deploying-php-ansible-ansistrano/images/ansistrano2.png new file mode 100644 index 0000000..0104e7f Binary files /dev/null and b/deploying-php-ansible-ansistrano/images/ansistrano2.png differ diff --git a/deploying-php-ansible-ansistrano/images/composer.png b/deploying-php-ansible-ansistrano/images/composer.png new file mode 100644 index 0000000..bb95a49 Binary files /dev/null and b/deploying-php-ansible-ansistrano/images/composer.png differ diff --git a/deploying-php-ansible-ansistrano/images/drupalcon/contribution.jpg b/deploying-php-ansible-ansistrano/images/drupalcon/contribution.jpg new file mode 100644 index 0000000..ed5a478 Binary files /dev/null and b/deploying-php-ansible-ansistrano/images/drupalcon/contribution.jpg differ diff --git a/deploying-php-ansible-ansistrano/images/drupalcon/feedback.jpg b/deploying-php-ansible-ansistrano/images/drupalcon/feedback.jpg new file mode 100644 index 0000000..8795c55 Binary files /dev/null and b/deploying-php-ansible-ansistrano/images/drupalcon/feedback.jpg differ diff --git a/deploying-php-ansible-ansistrano/images/drupalcon/site.png b/deploying-php-ansible-ansistrano/images/drupalcon/site.png new file mode 100644 index 0000000..c2d9b07 Binary files /dev/null and b/deploying-php-ansible-ansistrano/images/drupalcon/site.png differ diff --git a/deploying-php-ansible-ansistrano/images/druplicon.png b/deploying-php-ansible-ansistrano/images/druplicon.png new file mode 100644 index 0000000..b2cc145 Binary files /dev/null and b/deploying-php-ansible-ansistrano/images/druplicon.png differ diff --git a/deploying-php-ansible-ansistrano/images/logo-acquia.png b/deploying-php-ansible-ansistrano/images/logo-acquia.png new file mode 100644 index 0000000..d7939c9 Binary files /dev/null and b/deploying-php-ansible-ansistrano/images/logo-acquia.png differ diff --git a/deploying-php-ansible-ansistrano/images/logo-digital-ocean.png b/deploying-php-ansible-ansistrano/images/logo-digital-ocean.png new file mode 100644 index 0000000..3d3c707 Binary files /dev/null and b/deploying-php-ansible-ansistrano/images/logo-digital-ocean.png differ diff --git a/deploying-php-ansible-ansistrano/images/logo-linode.png b/deploying-php-ansible-ansistrano/images/logo-linode.png new file mode 100644 index 0000000..22daa66 Binary files /dev/null and b/deploying-php-ansible-ansistrano/images/logo-linode.png differ diff --git a/deploying-php-ansible-ansistrano/images/logo-pantheon.png b/deploying-php-ansible-ansistrano/images/logo-pantheon.png new file mode 100644 index 0000000..e1f7ee7 Binary files /dev/null and b/deploying-php-ansible-ansistrano/images/logo-pantheon.png differ diff --git a/deploying-php-ansible-ansistrano/images/logo-platformsh.png b/deploying-php-ansible-ansistrano/images/logo-platformsh.png new file mode 100644 index 0000000..8dd8fc7 Binary files /dev/null and b/deploying-php-ansible-ansistrano/images/logo-platformsh.png differ diff --git a/deploying-php-ansible-ansistrano/images/logo-vultr.png b/deploying-php-ansible-ansistrano/images/logo-vultr.png new file mode 100644 index 0000000..edef64e Binary files /dev/null and b/deploying-php-ansible-ansistrano/images/logo-vultr.png differ diff --git a/deploying-php-ansible-ansistrano/images/site.png b/deploying-php-ansible-ansistrano/images/site.png new file mode 100644 index 0000000..7173f99 Binary files /dev/null and b/deploying-php-ansible-ansistrano/images/site.png differ diff --git a/deploying-php-ansible-ansistrano/images/techs.png b/deploying-php-ansible-ansistrano/images/techs.png new file mode 100644 index 0000000..525ab7a Binary files /dev/null and b/deploying-php-ansible-ansistrano/images/techs.png differ diff --git a/deploying-php-ansible-ansistrano/images/vagrant.png b/deploying-php-ansible-ansistrano/images/vagrant.png new file mode 100644 index 0000000..8636216 Binary files /dev/null and b/deploying-php-ansible-ansistrano/images/vagrant.png differ diff --git a/deploying-php-ansible-ansistrano/main.style b/deploying-php-ansible-ansistrano/main.style new file mode 100644 index 0000000..6c35205 --- /dev/null +++ b/deploying-php-ansible-ansistrano/main.style @@ -0,0 +1,136 @@ +pageSetup: + firstTemplate: coverPage + height: 18cm + margin-bottom: 0cm + margin-gutter: 0cm + margin-left: 0cm + margin-right: 0cm + margin-top: 0cm + size: null + spacing-footer: 2mm + spacing-header: 2mm + width: 32cm + +pageTemplates: + coverPage: + frames: [] + [12%, 10%, 76%, 75%] + showFooter: false + showHeader: false + + titlePage: + alignment: TA_CENTER + frames: [] + [8%, 8%, 85%, 65%] + showFooter: true + showHeader: false + + standardPage: + frames: [] + [3%, 3%, 92%, 92%] + showFooter: true + showHeader: false + + imagePage: + alignment: TA_CENTER + frames: [] + [12%, 10%, 76%, 80%] + showFooter: true + showHeader: false + + outputPage: + frames: [] + [8%, 10%, 82%, 65%] + showFooter: false + showHeader: false + +linkColor: #24608a + +fontsAlias: + stdMono: Inconsolata-Regular + stdMonoBold: Inconsolata-Regular + stdMonoItalic: Inconsolata-Regular + +styles: + normal: + fontSize: 24 + leading: 32 + textColor: #383745 + + bodytext: + alignment: TA_LEFT + + heading: + fontSize: 20 + spaceAfter: 16 + textColor: #24608a + + heading1: + parent: heading + alignment: TA_LEFT + + title: + fontSize: 300% + parent: heading + + bullet-list: + commands: [] + [LEFTPADDING, [0, 0], [1, -1], 10] + [RIGHTPADDING, [0, 0], [1, -1], 0] + [VALIGN, [0, 0], [-1, -1], TOP] + colWidths: ["20", null] + textColor: #aaaaaa + + bullet-list-item: + spaceBefore: 14 + spaceAfter: 0 + + titleslideinfo: + alignment: TA_CENTER + fontSize: 140% + parent: normal + + footer: + alignment: TA_RIGHT + fontName: stdMono + fontSize: 20 + textColor: #24608a + rightIndent: 16 + spaceBefore: 0 + + literal: + backColor: white + fontName: stdMono + + code: + backColor: white + borderWidth: 0 + fontSize: 19 + leading: 22 + parent: literal + spaceBefore: 4 + + blockquote: + parent: normal + fontName: stdItalic + leading: 36 + + attribution: + parent: normal + textColor: #66666 + + centred: + alignment: TA_CENTER + parent: normal + + centredtitle: + alignment: TA_CENTER + fontName: stdBold + fontSize: 48 + leading: 64 + parent: heading + + small: + fontSize: 90% + parent: normal + diff --git a/deploying-php-ansible-ansistrano/slides.rst b/deploying-php-ansible-ansistrano/slides.rst new file mode 100644 index 0000000..2f2aac0 --- /dev/null +++ b/deploying-php-ansible-ansistrano/slides.rst @@ -0,0 +1,1040 @@ +.. footer:: @opdavies + +Deploying PHP with Ansible, Ansible Vault, and Ansistrano +######################################################### + +| + +.. class:: titleslideinfo + +Oliver Davies, Inviqa + +.. raw:: pdf + + TextAnnotation "Full stack Developer and Systems Administrator" + TextAnnotation "Organiser of PHP South Wales" + +.. page:: imagePage + +.. image:: images/techs.png + :width: 14cm + +.. page:: standardPage + +Things we'll be looking at +========================== + +- **Ansible** crash course +- Keeping secrets with **Ansible Vault** +- Deployments with **Ansistrano** + +.. page:: imagePage + +.. image:: images/logo-acquia.png + :width: 12cm + +| + +.. image:: images/logo-platformsh.png + :width: 12cm + +| + +.. image:: images/logo-pantheon.png + :width: 12cm + +.. page:: + +.. image:: images/logo-digital-ocean.png + :width: 6cm + +| + +.. image:: images/logo-linode.png + :width: 6cm + +| + +.. image:: images/logo-vultr.png + :width: 8cm + +.. page:: standardPage + +What is Ansible? +================ + +.. class:: text-lg + +Ansible is an open-source **software provisioning**, **configuration management**, and **application-deployment** tool. + +| + +https://en.wikipedia.org/wiki/Ansible_(software) + +.. page:: + +What is Ansible? +================ + +- CLI tool +- Configured with YAML +- Agentless, connects via SSH +- Jinja2 for templating +- Executes ad-hoc remote commands +- Installs software packages +- Performs deployment steps +- Batteries included + + +.. raw:: pdf + + TextAnnotation "- Written in Python but configured with Yaml." + TextAnnotation "Drupal, Symfony and a lot of other projects use YAML." + TextAnnotation "Nothing needed on the server, other than Python." + TextAnnotation "First-party modules (SSH keys, file and directory management, package repositories, stopping/starting/restarting services, DO/Linode/AWS integration)." + +.. page:: + +Why Ansible? +============ + +- Familiar syntax (Drupal 8, Symfony, Sculpin) +- Easily readable +- No server dependencies +- Easy to add to an existing project +- Includes relevant modules (Git, Composer) +- Idempotency, resulting in cleaner scripts + +.. page:: titlePage + +.. class:: centredtitle + +Hosts / Inventories + +.. page:: standardPage + +hosts.ini +========= + +.. code:: ini + + [webservers] + 192.168.33.10 + + [webservers:vars] + ansible_ssh_port=22 + ansible_ssh_user=opdavies + +.. raw:: pdf + + TextAnnotation "Vagrant IP address." + TextAnnotation "Supports wildcards and ranges" + +hosts.yml +========= + +.. code-block:: yaml + + --- + all: + children: + webservers: + hosts: + 192.168.33.10: + vars: + ansible_ssh_port: 22 + ansible_ssh_user: opdavies + +.. raw:: pdf + + TextAnnotation "My prefered format." + TextAnnotation "More consistency across the project, easier to copy variables from other places such as playbooks." + +.. page:: titlePage + +.. class:: centredtitle + +Ad-hoc Commands + +.. page:: + +.. class:: centredtitle + +``ansible all -i hosts.yml +-m ping`` + +.. raw:: pdf + + TextAnnotation "Single ad-hoc command." + TextAnnotation "-i = inventory" + TextAnnotation "-m = module" + +.. page:: standardPage + +.. code:: json + + webservers | SUCCESS => { + "ansible_facts": { + "discovered_interpreter_python": "/usr/bin/python" + }, + "changed": false, + "ping": "pong" + } + +.. page:: titlePage + +.. class:: centredtitle + +``ansible all -i hosts.yml +-m command +-a "git pull --chdir=/app"`` + +.. raw:: pdf + + TextAnnotation "Update a codebase using "git pull"" + TextAnnotation "-a = (additional) arguments" + TextAnnotation "--chdir = change directory" + +.. page:: + +.. class:: centredtitle + +``ansible all -i hosts.yml +-m git +-a "repo=https://github.com +/opdavies/dransible +--chdir=/app"`` + +.. raw:: pdf + + TextAnnotation "Same example, but using the core "Git" module" + +.. page:: titlePage + +.. class:: centredtitle + +Playbooks + +.. page:: standardPage + +.. code-block:: yaml + + --- + - hosts: webservers + + vars: + git_repo: https://github.com/opdavies/dransible + project_root_dir: /app + + tasks: + - name: Update the code + git: + repo: '{{ git_repo }}' + dest: '{{ project_root_dir }}' + +.. raw:: pdf + + TextAnnotation "YAML file" + TextAnnotation "Collection of multiple tasks" + TextAnnotation "Can add and use variables" + +.. page:: titlePage + +.. class:: centredtitle + +``ansible-playbook main.yml +-i hosts.yml`` + +.. raw:: pdf + + TextAnnotation "How do we run a playbook?" + TextAnnotation "Use the ansible-playbook command and specify the name of the playbook." + +.. page:: titlePage + +.. class:: centredtitle + +Roles: configuring a LAMP stack + +.. page:: standardPage + +requirements.yml +================ + +.. code-block:: yaml + + --- + - src: geerlingguy.apache + - src: geerlingguy.composer + - src: geerlingguy.mysql + - src: geerlingguy.php + - src: geerlingguy.php-mysql + +.. raw:: pdf + + TextAnnotation "Requirements file for Ansible roles" + TextAnnotation "Typically requirements.yml" + TextAnnotation "Pulled from Ansible Galaxy" + TextAnnotation "Equivilent to composer.json/Packagist in PHP" + +.. page:: titlePage + +.. class:: centredtitle + +``ansible-galaxy install +-r requirements.yml`` + +.. page:: standardPage + +.. code-block:: yaml + + # playbook.yml + + --- + - hosts: webservers + + roles: + - geerlingguy.apache + - geerlingguy.mysql + - geerlingguy.php + - geerlingguy.php-mysql + - geerlingguy.composer + +.. raw:: pdf + + TextAnnotation "How do we use them?" + TextAnnotation "Add them to the playbook under 'roles'." + TextAnnotation "Ordering matters here!" + TextAnnotation "If these were ordered alphabetically then Composer install would fail because it would run before PHP is installed." + +.. page:: + +.. code-block:: yaml + + # playbook.yml + + --- + vars: + apache_vhosts: + - servername: dransible + documentroot: /app/web + +.. raw:: pdf + + TextAnnotation "configuring the Apache role to install virtual hosts." + +.. page:: + +.. code-block:: yaml + + # playbook.yml + + --- + vars: + php_version: 7.4 + php_packages_extra: + - libapache2-mod-php{{ php_version }} + - libpcre3-dev + +.. raw:: pdf + + TextAnnotation "configuring PHP." + +.. page:: + +.. code-block:: yaml + + # playbook.yml + + --- + vars: + mysql_databases: + - name: main + + mysql_users: + - name: user + password: secret + priv: main.*:ALL + +.. raw:: pdf + + TextAnnotation "configuring MySQL databases and users." + +.. page:: titlePage + +.. class:: centredtitle + +``ansible-playbook provision.yml +-i hosts.yml`` + +.. page:: standardPage + +.. code-block:: + + 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] + +.. page:: + +.. code-block:: + + 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 + +.. page:: + +.. image:: images/after-provision-1.png + :width: 24cm + +.. raw:: pdf + + TextAnnotation "IP address of server, Apache is installed and running." + +.. page:: + +.. image:: images/after-provision-2.png + :width: 24cm + +.. raw:: pdf + + TextAnnotation "No application code on the server yet." + +.. page:: titlePage + +.. class:: centredtitle + +Basic deployment + +.. page:: standardPage + +.. class:: small + +.. code-block:: 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 + +.. raw:: pdf + + TextAnnotation "Using file module to create the directory" + TextAnnotation "Using synchronize module/rsync to upload the files" + TextAnnotation "Using Composer module to install dependencies. There are other possible values." + +.. page:: titlePage + +.. class:: centredtitle + +``ansible-playbook deploy.yml +-i hosts.yml`` + +.. page:: standardPage + +.. image:: images/after-deploy-1.png + :width: 24cm + +.. page:: standardPage + +Disadvantages +============= + +- Sensitive data stored in plain text +- Single point of failure +- No ability to roll back + +.. page:: titlePage + +.. class:: centredtitle + +Keeping secrets with Ansible Vault + +.. page:: standardPage + +.. code-block:: yaml + + --- + vars: + mysql_databases: + - name: main + + mysql_users: + - name: user + password: secret + priv: main.*:ALL + +.. page:: + +.. code-block:: yaml + + # provision_vault.yml + + --- + vault_database_name: main + vault_database_user: user + vault_database_password: secret + +.. page:: titlePage + +.. class:: centredtitle + +``ansible-vault encrypt +provision_vault.yml`` + +.. class:: centredtitle + +``New Vault password: +Confirm New Vault password: +Encryption successful`` + +.. page:: standardPage + +.. code-block:: + + $ANSIBLE_VAULT;1.1;AES256 + 63656632326165643137646334343537396533656565313032363262623962393861666438393539 + 6366336638316133373061306332303761383565343035330a373637373830356430353630356161 + 32313831663039343733343539636365386333303862363635323138346137666166356639323338 + 3264636538356634390a343766353661386666376362376439386630363664616166643364366335 + 62373530393933373830306338386539626565313364643133666131613138383431353638636334 + 39376437633462373934313236363662633832643138386433646230313465383337373031373137 + 61353963623364393134386335373731356337366464633531656435383161656435313530363234 + 37373865393839616534353165656463313961333532363537383263343364646534333032336337 + 3235 + +.. page:: + +.. code-block:: yaml + + # provision_vars.yml + + --- + database_name: '{{ vault_database_name }}' + database_user: '{{ vault_database_user }}' + database_password: '{{ vault_database_password }}' + +.. page:: + + +.. code-block:: yaml + + # provision.yml + + --- + vars_files: + - vars/provision_vault.yml + - vars/provision_vars.yml + + vars: + mysql_databases: + - '{{ database_name }}' + + mysql_users: + - name: '{{ database_user }}' + password: '{{ database_password }}' + priv: '{{ database_name }}.*:ALL' + +.. page:: titlePage + +.. class:: centredtitle + +``ansible-playbook deploy.yml +-i hosts.yml +--ask-vault-pass`` + +.. page:: +.. class:: centredtitle + +``ansible-playbook deploy.yml +-i hosts.yml +--vault-password-file secret.txt`` + +.. page:: +.. class:: centredtitle + +Better deployments with Ansistrano + +.. page:: standardPage + +.. image:: images/ansistrano.png + :width: 24cm + +.. page:: + +Features +======== + +- Multiple release directories +- Shared paths and files +- Customisable +- Multiple deployment strategies +- Multi-stage environments +- Prune old releases +- Rollbacks + +.. page:: + + +.. code-block:: yaml + + # requirements.yml + + --- + - src: ansistrano.deploy + - src: ansistrano.rollback + +.. raw:: pdf + + TextAnnotation "to install Ansistrano, add the additional roles to the requirements.yml file" + +.. page:: + + +.. code-block:: yaml + + # deploy.yml + + --- + - hosts: all + + roles: + - ansistrano.deploy + +.. raw:: pdf + + TextAnnotation "add to roles within the playbook" + +.. page:: + +.. code-block:: yaml + + # deploy.yml + + --- + vars: + project_deploy_dir: /app + + ansistrano_deploy_to: '{{ project_deploy_dir }}' + ansistrano_deploy_via: git + ansistrano_git_branch: master + ansistrano_git_repo: 'git@github.com:opdavies/dransible' + +.. page:: +.. code-block:: + + 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) + +.. page:: + +.. code-block:: + + 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 + +.. page:: + +.. code-block:: + + 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 + +.. page:: + +.. code-block:: + + 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 + +.. page:: + + +.. code-block:: yaml + + # rollback.yml + + --- + - hosts: all + + roles: + - ansistrano.rollback + + vars: + ansistrano_deploy_to: '{{ project_deploy_dir }}' + +.. page:: titlePage + +.. class:: centredtitle + +``ansible-playbook rollback.yml +-i hosts.yml`` + +.. page:: + +.. class:: centredtitle + +Customising Ansistrano: +Build Hooks + +.. page:: imagePage + +.. image:: images/ansistrano-flow.png + :width: 18cm + +.. raw:: pdf + + TextAnnotation "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." + +.. page:: standardPage + +.. code-block:: yaml + + # 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 }}/bin/drush' + +.. page:: + + +.. code-block:: yaml + + # deploy/after-update-code.yml + + --- + - name: Install Composer dependencies + composer: + command: install + working_dir: '{{ ansistrano_release_path.stdout }}' + +.. page:: + + +.. code-block:: yaml + + # deploy/after-symlink-shared.yml + + --- + - name: Run database updates + command: > + {{ release_drush_path }} + --root {{ release_web_path }} + updatedb + +.. page:: + +.. code-block:: yaml + + # deploy/after-symlink.yml + + --- + - name: Rebuild Drupal cache + command: > + {{ release_drush_path }} + --root {{ release_web_path }} + cache-rebuild + +.. page:: titlePage + +.. class:: centredtitle + +Demo + +.. page:: + +.. class:: centredtitle + +Generating settings files per deployment + +.. page:: standardPage + +.. code-block:: yaml + + # deploy_vars.yml + --- + drupal_settings: + - drupal_root: /app/web + 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 + +.. page:: + +.. code-block:: jinja + + {# templates/settings.php.j2 #} + + {% 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 %} + +.. page:: + + +.. code-block:: yaml + + # tasks/main.yml + + --- + - 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 + +.. page:: titlePage + +.. class:: centredtitle + +Multiple environments development, test, production + +.. page:: standardPage + +.. code-block:: yaml + + # vars.yml + + --- + vars: + 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 + +.. page:: + +.. code-block:: yaml + + # hosts.yml + + --- + production: + children: + hosts: + webservers: + ansible_ssh_host: 192.168.33.10 + ansible_ssh_port: 22 + + project_deploy_path: /app + git_branch: production + + drupal_hash_salt: '{{ vault_drupal_hash_salt }}' + drupal_install: false + + drupal_settings: + # ... + +.. page:: + +.. code-block:: yaml + + # hosts.yml + + --- + staging: + children: + hosts: + webservers: + ansible_ssh_host: 192.168.33.10 + ansible_ssh_port: 22 + + project_deploy_path: /app-staging + git_branch: staging + + drupal_hash_salt: '{{ vault_drupal_hash_salt }}' + drupal_install: true + + drupal_settings: + # ... + +.. page:: titlePage + +.. class:: centredtitle + +``ansible-playbook deploy.yml +-i hosts.yml +--limit staging`` + +.. page:: + +.. class:: centredtitle + +``ansible-playbook deploy.yml +-i hosts.yml +--limit production`` + +.. page:: standardPage + +Thanks! +======= + +References: + +- https://oliverdavies.link/ansible-repos +- https://docs.ansible.com +- https://www.ansistrano.com +- https://symfonycasts.com/screencast/ansistrano + +| + +Me: + +* https://www.oliverdavies.uk diff --git a/workspace.yml b/workspace.yml index 4a88bbd..52017f6 100644 --- a/workspace.yml +++ b/workspace.yml @@ -34,7 +34,7 @@ command('pdf generate '): | command('pdf watch '): | #!bash|= cd ={ input.argument('talk') } - passthru nodemon -e rst,style,txt -x "={ @('rst2pdf.command') }" + passthru nodemon -e rst,style,txt,jpg,png -x "={ @('rst2pdf.command') }" command('thumbnail '): env: