diff --git a/README.md b/README.md
index 395b7aa..c7187e5 100644
--- a/README.md
+++ b/README.md
@@ -1,143 +1,21 @@
-# Composer template for Drupal projects
+# Dransible
 
-[![Build Status](https://travis-ci.org/drupal-composer/drupal-project.svg?branch=8.x)](https://travis-ci.org/drupal-composer/drupal-project)
+A demo [Drupal] application for demonstrating PHP application deployment with [Ansible][], [Ansible Vault][] and [Ansistrano][].
 
-This project template provides a starter kit for managing your site
-dependencies with [Composer](https://getcomposer.org/).
+[Ansible]: https://www.ansible.com
+[Ansible Vault]: https://docs.ansible.com/ansible/ansible-vault.html
+[Ansistrano]: https://ansistrano.com
+[Drupal]: https://drupal.org
 
-If you want to know how to use it as replacement for
-[Drush Make](https://github.com/drush-ops/drush/blob/8.x/docs/make.md) visit
-the [Documentation on drupal.org](https://www.drupal.org/node/2471553).
+## Prerequisites
 
-## Usage
+- [Ansible][]
+- [Vagrant][]
+- [VirtualBox][]
 
-First you need to [install composer](https://getcomposer.org/doc/00-intro.md#installation-linux-unix-osx).
+[Vagrant]: https://www.vagrantup.com
+[VirtualBox]: https://www.virtualbox.or
 
-> Note: The instructions below refer to the [global composer installation](https://getcomposer.org/doc/00-intro.md#globally).
-You might need to replace `composer` with `php composer.phar` (or similar) 
-for your setup.
+## Installation
 
-After that you can create the project:
-
-```
-composer create-project drupal-composer/drupal-project:8.x-dev some-dir --stability dev --no-interaction
-```
-
-With `composer require ...` you can download new dependencies to your 
-installation.
-
-```
-cd some-dir
-composer require drupal/devel:~1.0
-```
-
-The `composer create-project` command passes ownership of all files to the 
-project that is created. You should create a new git repository, and commit 
-all files not excluded by the .gitignore file.
-
-## What does the template do?
-
-When installing the given `composer.json` some tasks are taken care of:
-
-* Drupal will be installed in the `web`-directory.
-* Autoloader is implemented to use the generated composer autoloader in `vendor/autoload.php`,
-  instead of the one provided by Drupal (`web/vendor/autoload.php`).
-* Modules (packages of type `drupal-module`) will be placed in `web/modules/contrib/`
-* Theme (packages of type `drupal-theme`) will be placed in `web/themes/contrib/`
-* Profiles (packages of type `drupal-profile`) will be placed in `web/profiles/contrib/`
-* Creates default writable versions of `settings.php` and `services.yml`.
-* Creates `web/sites/default/files`-directory.
-* Latest version of drush is installed locally for use at `vendor/bin/drush`.
-* Latest version of DrupalConsole is installed locally for use at `vendor/bin/drupal`.
-* Creates environment variables based on your .env file. See [.env.example](.env.example).
-
-## Updating Drupal Core
-
-This project will attempt to keep all of your Drupal Core files up-to-date; the 
-project [drupal-composer/drupal-scaffold](https://github.com/drupal-composer/drupal-scaffold) 
-is used to ensure that your scaffold files are updated every time drupal/core is 
-updated. If you customize any of the "scaffolding" files (commonly .htaccess), 
-you may need to merge conflicts if any of your modified files are updated in a 
-new release of Drupal core.
-
-Follow the steps below to update your core files.
-
-1. Run `composer update drupal/core webflo/drupal-core-require-dev symfony/* --with-dependencies` to update Drupal Core and its dependencies.
-1. Run `git diff` to determine if any of the scaffolding files have changed. 
-   Review the files for any changes and restore any customizations to 
-  `.htaccess` or `robots.txt`.
-1. Commit everything all together in a single commit, so `web` will remain in
-   sync with the `core` when checking out branches or running `git bisect`.
-1. In the event that there are non-trivial conflicts in step 2, you may wish 
-   to perform these steps on a branch, and use `git merge` to combine the 
-   updated core files with your customized files. This facilitates the use 
-   of a [three-way merge tool such as kdiff3](http://www.gitshah.com/2010/12/how-to-setup-kdiff-as-diff-tool-for-git.html). This setup is not necessary if your changes are simple; 
-   keeping all of your modifications at the beginning or end of the file is a 
-   good strategy to keep merges easy.
-
-## Generate composer.json from existing project
-
-With using [the "Composer Generate" drush extension](https://www.drupal.org/project/composer_generate)
-you can now generate a basic `composer.json` file from an existing project. Note
-that the generated `composer.json` might differ from this project's file.
-
-
-## FAQ
-
-### Should I commit the contrib modules I download?
-
-Composer recommends **no**. They provide [argumentation against but also 
-workrounds if a project decides to do it anyway](https://getcomposer.org/doc/faqs/should-i-commit-the-dependencies-in-my-vendor-directory.md).
-
-### Should I commit the scaffolding files?
-
-The [drupal-scaffold](https://github.com/drupal-composer/drupal-scaffold) plugin can download the scaffold files (like
-index.php, update.php, …) to the web/ directory of your project. If you have not customized those files you could choose
-to not check them into your version control system (e.g. git). If that is the case for your project it might be
-convenient to automatically run the drupal-scaffold plugin after every install or update of your project. You can
-achieve that by registering `@composer drupal:scaffold` as post-install and post-update command in your composer.json:
-
-```json
-"scripts": {
-    "post-install-cmd": [
-        "@composer drupal:scaffold",
-        "..."
-    ],
-    "post-update-cmd": [
-        "@composer drupal:scaffold",
-        "..."
-    ]
-},
-```
-### How can I apply patches to downloaded modules?
-
-If you need to apply patches (depending on the project being modified, a pull 
-request is often a better solution), you can do so with the 
-[composer-patches](https://github.com/cweagans/composer-patches) plugin.
-
-To add a patch to drupal module foobar insert the patches section in the extra 
-section of composer.json:
-```json
-"extra": {
-    "patches": {
-        "drupal/foobar": {
-            "Patch description": "URL or local path to patch"
-        }
-    }
-}
-```
-### How do I switch from packagist.drupal-composer.org to packages.drupal.org?
-
-Follow the instructions in the [documentation on drupal.org](https://www.drupal.org/docs/develop/using-composer/using-packagesdrupalorg).
-
-### How do I specify a PHP version ?
-
-Currently Drupal 8 supports PHP 5.5.9 as minimum version (see [Drupal 8 PHP requirements](https://www.drupal.org/docs/8/system-requirements/drupal-8-php-requirements)), however it's possible that a `composer update` will upgrade some package that will then require PHP 7+.
-
-To prevent this you can add this code to specify the PHP version you want to use in the `config` section of `composer.json`:
-```json
-"config": {
-    "sort-packages": true,
-    "platform": {"php": "5.5.9"}
-},
-```
+See [installation.md](docs/installation.md)
diff --git a/Vagrantfile b/Vagrantfile
index 09c7339..bc45427 100644
--- a/Vagrantfile
+++ b/Vagrantfile
@@ -8,8 +8,8 @@ Vagrant.configure("2") do |config|
 
   config.vm.provider "virtualbox" do |vb|
     vb.name = 'dransible'
-    vb.memory = 1024
-    vb.cpus = 2
+    vb.memory = 2048
+    vb.cpus = 1
   end
 
   # Set the name of the VM. See: http://stackoverflow.com/a/17864388/100134
@@ -18,8 +18,8 @@ Vagrant.configure("2") do |config|
 
   config.vm.provision "ansible" do |ansible|
     ansible.compatibility_mode = "2.0"
-    ansible.playbook = "ansible/provision.yml"
-    ansible.inventory_path = "ansible/hosts.ini"
+    ansible.playbook = "tools/ansible/provision.yml"
+    ansible.inventory_path = "tools/ansible/hosts.yml"
     ansible.become = true
     ansible.ask_vault_pass = true
   end
diff --git a/ansible.cfg b/ansible.cfg
index 51315b7..370ab6c 100644
--- a/ansible.cfg
+++ b/ansible.cfg
@@ -1,5 +1,5 @@
 [defaults]
-inventory = ./ansible/hosts.ini
+inventory = ./tools/ansible/hosts.yml
 nocows = True
 private_key_file = .vagrant/machines/dransible/virtualbox/private_key
 remote_user = vagrant
diff --git a/ansible/deploy/after-symlink-shared.yml b/ansible/deploy/after-symlink-shared.yml
deleted file mode 100644
index e62c0bd..0000000
--- a/ansible/deploy/after-symlink-shared.yml
+++ /dev/null
@@ -1,3 +0,0 @@
----
-- name: Run database updates
-  command: '{{ release_drush_path }} --root {{ release_web_path }} updatedb'
diff --git a/ansible/deploy/after-symlink.yml b/ansible/deploy/after-symlink.yml
deleted file mode 100644
index 2f2b2b8..0000000
--- a/ansible/deploy/after-symlink.yml
+++ /dev/null
@@ -1,3 +0,0 @@
----
-- name: Clear Drupal cache
-  command: '{{ release_drush_path }} --root {{ release_web_path }} cache-rebuild'
diff --git a/ansible/deploy/after-update-code.yml b/ansible/deploy/after-update-code.yml
deleted file mode 100644
index 6133fba..0000000
--- a/ansible/deploy/after-update-code.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-- name: Install Composer dependencies
-  composer:
-    command: install
-    working_dir: '{{ ansistrano_release_path.stdout }}'
diff --git a/ansible/hosts.ini b/ansible/hosts.ini
deleted file mode 100644
index 121ea91..0000000
--- a/ansible/hosts.ini
+++ /dev/null
@@ -1 +0,0 @@
-dransible ansible_ssh_host=192.168.33.10 ansible_ssh_port=22
diff --git a/ansible/vars/vars.yml b/ansible/vars/vars.yml
deleted file mode 100644
index 7d6bbb0..0000000
--- a/ansible/vars/vars.yml
+++ /dev/null
@@ -1,31 +0,0 @@
----
-apache_vhosts:
-  - servername: dransible
-    documentroot: "{{ app_project_docroot }}"
-
-php_packages:
-  - libapache2-mod-php{{ php_default_version_debian }}
-  - libpcre3-dev
-  - php-apcu
-  - php-sqlite3
-  - php{{ php_default_version_debian }}-cli
-  - php{{ php_default_version_debian }}-common
-  - php{{ php_default_version_debian }}-curl
-  - php{{ php_default_version_debian }}-dev
-  - php{{ php_default_version_debian }}-fpm
-  - php{{ php_default_version_debian }}-gd
-  - php{{ php_default_version_debian }}-imap
-  - php{{ php_default_version_debian }}-json
-  - php{{ php_default_version_debian }}-mbstring
-  - php{{ php_default_version_debian }}-opcache
-  - php{{ php_default_version_debian }}-xml
-
-ansistrano_current_dir: current
-
-app_project_root: /var/www/app
-app_project_subdir: web
-app_project_docroot: "{{ app_project_root }}/{{ ansistrano_current_dir }}/{{ app_project_subdir }}"
-
-app_db_name: "{{ vault_app_db_name }}"
-app_db_user: "{{ vault_app_db_user }}"
-app_db_password: "{{ vault_app_db_password }}"
diff --git a/ansible/vars/vault.yml b/ansible/vars/vault.yml
deleted file mode 100644
index 9348d3d..0000000
--- a/ansible/vars/vault.yml
+++ /dev/null
@@ -1,10 +0,0 @@
-$ANSIBLE_VAULT;1.1;AES256
-36656233323539616336393838396137343939623233393338666530313730373233663263633065
-3133633335316364306366333539613936376239383133330a356365666232623537333730663638
-37393264616134613163663762666464373733663737383039316163336263323538393533323266
-3432346662613438330a386435393432323761386137333736363436386466643031386662353933
-30393631386463313265653862633866663530626439623063393934653235666530656462643135
-39366431353762383434663536663761323565616564336131666339653038326333306433326264
-31623539643166626234663736656337633036323837333137343533386165366531626462643662
-66626631663930626266653937323634366231326537626131663662396335393361336635373736
-3435
diff --git a/docs/images/after-deploy.png b/docs/images/after-deploy.png
new file mode 100644
index 0000000..74ba288
Binary files /dev/null and b/docs/images/after-deploy.png differ
diff --git a/docs/images/before-deploy.png b/docs/images/before-deploy.png
new file mode 100644
index 0000000..a774885
Binary files /dev/null and b/docs/images/before-deploy.png differ
diff --git a/docs/installation.md b/docs/installation.md
new file mode 100644
index 0000000..2b5f031
--- /dev/null
+++ b/docs/installation.md
@@ -0,0 +1,19 @@
+# Installation
+
+1. Run `vagrant up` or `vagrant up --provision` if needed, to start Vagrant and provision the virtual machine using the `tools/ansible/provision.yml` playbook. This will set up a LAMP stack with Apache, MySQL, PHP and Composer.
+
+    If you try loading the site at this point you will see a `The requested URL was not found on this server` message as the site has not yet been deployed.
+
+    ![A browser showing a 'Not Found' error](images/before-deploy.png)
+
+1. Run the deploy playbook to deploy the application code to the virtual machine. The Vault password, which is `dransible`, is stored in `tools/ansible/vault-password.txt` as this is an example project.
+
+    ```
+    ansible-playbook tools/ansible/deploy.yml \
+      -i tools/ansible/hosts.yml \
+      --vault-password-file=tools/ansible/vault-password.txt
+    ```
+
+1. Load `http://dransible` in a browser, and you should see a Drupal 8 website.
+
+    ![A browser showing the front page of a Drupal website](images/after-deploy.png)
diff --git a/ansible/deploy.yml b/tools/ansible/deploy.yml
similarity index 64%
rename from ansible/deploy.yml
rename to tools/ansible/deploy.yml
index 759f55f..ee98c09 100644
--- a/ansible/deploy.yml
+++ b/tools/ansible/deploy.yml
@@ -3,23 +3,23 @@
   become: true
 
   roles:
+    - drupal-settings
     - ansistrano.deploy
 
   vars_files:
+    - vars/vault.yml
     - vars/vars.yml
 
   vars:
+    release_drupal_path: "{{ ansistrano_release_path.stdout }}/web"
+    release_drush_path: "{{ ansistrano_release_path.stdout }}/vendor/bin/drush"
+
     ansistrano_deploy_via: "rsync"
-    ansistrano_deploy_from: "{{ playbook_dir }}/../"
-    ansistrano_deploy_to: "{{ app_project_root }}"
+    ansistrano_deploy_from: "{{ playbook_dir }}/../../"
+    ansistrano_deploy_to: "{{ project_deploy_dir }}"
     ansistrano_keep_releases: 5
     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"
     ansistrano_shared_paths:
-      - "{{ app_project_subdir }}/sites/default/files"
-    ansistrano_shared_files:
-      - "{{ app_project_subdir }}/sites/default/settings.php"
-
-    release_web_path: "{{ ansistrano_release_path.stdout }}/web"
-    release_drush_path: "{{ ansistrano_release_path.stdout }}/vendor/bin/drush"
+      - "{{ project_subdir }}/sites/default/files"
diff --git a/tools/ansible/deploy/after-symlink-shared.yml b/tools/ansible/deploy/after-symlink-shared.yml
new file mode 100644
index 0000000..cc98bc8
--- /dev/null
+++ b/tools/ansible/deploy/after-symlink-shared.yml
@@ -0,0 +1,11 @@
+---
+- name: Fix files directory permissions
+  become: true
+  file:
+    path: '{{ project_deploy_dir }}/shared/web/sites/default/files'
+    state: directory
+    mode: 0775
+    recurse: true
+
+- name: Install Drupal
+  command: '{{ release_drush_path }} --root {{ release_drupal_path }} site-install -y --account-pass=admin123 --site-name="PHP South Wales"'
diff --git a/tools/ansible/deploy/after-symlink.yml b/tools/ansible/deploy/after-symlink.yml
new file mode 100644
index 0000000..ed97d53
--- /dev/null
+++ b/tools/ansible/deploy/after-symlink.yml
@@ -0,0 +1 @@
+---
diff --git a/tools/ansible/deploy/after-update-code.yml b/tools/ansible/deploy/after-update-code.yml
new file mode 100644
index 0000000..bd97d4e
--- /dev/null
+++ b/tools/ansible/deploy/after-update-code.yml
@@ -0,0 +1,22 @@
+---
+- 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
+
+- name: Install Composer dependencies
+  composer:
+    command: install
+    working_dir: '{{ ansistrano_release_path.stdout }}'
diff --git a/tools/ansible/hosts.yml b/tools/ansible/hosts.yml
new file mode 100644
index 0000000..24d88dc
--- /dev/null
+++ b/tools/ansible/hosts.yml
@@ -0,0 +1,5 @@
+all:
+  hosts:
+    dransible:
+      ansible_ssh_host: 192.168.33.10
+      ansible_ssh_port: 22
diff --git a/ansible/provision.yml b/tools/ansible/provision.yml
similarity index 77%
rename from ansible/provision.yml
rename to tools/ansible/provision.yml
index 7520d86..800bb03 100644
--- a/ansible/provision.yml
+++ b/tools/ansible/provision.yml
@@ -16,12 +16,12 @@
   tasks:
     - name: Create a database
       mysql_db:
-        name: '{{ app_db_name }}'
+        name: '{{ database_name }}'
         state: present
 
     - name: Add the database user
       mysql_user:
-        name: '{{ app_db_user }}'
-        password: '{{ app_db_password }}'
+        name: '{{ database_user }}'
+        password: '{{ database_password }}'
         priv: '*.*:ALL'
         state: present
diff --git a/ansible/requirements.yml b/tools/ansible/requirements.yml
similarity index 61%
rename from ansible/requirements.yml
rename to tools/ansible/requirements.yml
index fcccb7b..9e9d2fb 100644
--- a/ansible/requirements.yml
+++ b/tools/ansible/requirements.yml
@@ -1,8 +1,15 @@
 ---
 - src: ansistrano.deploy
+  version: 3.0.1
 - src: ansistrano.rollback
+  version: 3.0.0
 - src: geerlingguy.apache
+  version: 3.0.3
 - src: geerlingguy.composer
+  version: 1.7.3
 - src: geerlingguy.mysql
+  version: 2.9.4
 - src: geerlingguy.php
+  version: 3.7.0
 - src: geerlingguy.php-mysql
+  version: 2.0.2
diff --git a/ansible/rollback.yml b/tools/ansible/rollback.yml
similarity index 69%
rename from ansible/rollback.yml
rename to tools/ansible/rollback.yml
index d6ad7f8..8a2c695 100644
--- a/ansible/rollback.yml
+++ b/tools/ansible/rollback.yml
@@ -9,4 +9,4 @@
     - vars/vars.yml
 
   vars:
-    ansistrano_deploy_to: "{{ app_project_root }}"
+    ansistrano_deploy_to: "{{ project_deploy_dir }}"
diff --git a/tools/ansible/vars/vars.yml b/tools/ansible/vars/vars.yml
new file mode 100644
index 0000000..e15e467
--- /dev/null
+++ b/tools/ansible/vars/vars.yml
@@ -0,0 +1,49 @@
+---
+apache_vhosts:
+  - servername: dransible
+    documentroot: "{{ project_docroot }}"
+
+php_packages:
+  - libapache2-mod-php{{ php_default_version_debian }}
+  - libpcre3-dev
+  - php-apcu
+  - php-sqlite3
+  - php{{ php_default_version_debian }}-cli
+  - php{{ php_default_version_debian }}-common
+  - php{{ php_default_version_debian }}-curl
+  - php{{ php_default_version_debian }}-dev
+  - php{{ php_default_version_debian }}-fpm
+  - php{{ php_default_version_debian }}-gd
+  - php{{ php_default_version_debian }}-imap
+  - php{{ php_default_version_debian }}-json
+  - php{{ php_default_version_debian }}-mbstring
+  - php{{ php_default_version_debian }}-opcache
+  - php{{ php_default_version_debian }}-xml
+
+ansistrano_current_dir: current
+
+project_deploy_dir: /var/www/app
+project_subdir: web
+project_docroot: "{{ project_deploy_dir }}/{{ ansistrano_current_dir }}/{{ project_subdir }}"
+
+database_name: "{{ vault_database_name }}"
+database_password: "{{ vault_database_password }}"
+database_user: "{{ vault_database_user }}"
+hash_salt: "{{ vault_hash_salt }}"
+
+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
diff --git a/tools/ansible/vars/vault.yml b/tools/ansible/vars/vault.yml
new file mode 100644
index 0000000..0a9d2b7
--- /dev/null
+++ b/tools/ansible/vars/vault.yml
@@ -0,0 +1,12 @@
+$ANSIBLE_VAULT;1.1;AES256
+61653737643939333936636566323038316561323033633831656536643733343639356232356538
+3238306433353165626531646366646132626233646561390a386534373066346234373237373865
+64363663323662666261616136663239366634643135386433613639313532653262373932386166
+3736626562653963390a666566643537356436303166356130616530306562303565323637343631
+31333837303166623130353530636366663464346431643837303637343863353764373236303861
+65623364383839623063393466303637653865393031626234366361333261633238383261646233
+31313131393933636236326463313830346534613862333733306265633962663964386638623435
+64323437373262653862383063343436633237353865386539653263623935626431363362363436
+37306338313134383334316232383238663830346231393638353834663730663663626465353862
+34366132653430326230613164333533326463346638393866636465343237613263346232663538
+306164366133323334373862353238343834
diff --git a/tools/ansible/vault-password.txt b/tools/ansible/vault-password.txt
new file mode 100644
index 0000000..59a4e88
--- /dev/null
+++ b/tools/ansible/vault-password.txt
@@ -0,0 +1 @@
+dransible