Buy

Organizing with include

Our playbook is a mess: there's just a lot of tasks in one file. Let's get organized!

There are a few "categories" of things in the playbook. One category deals with "Bootstrapping Symfony", like installing the composer dependencies, fixing the var directory permissions and all of our Symfony console commands:

250 lines ansible/playbook.yml
---
- hosts: vb
... lines 3 - 26
tasks:
... lines 28 - 188
- name: Install Composer's dependencies
composer:
working_dir: "{{ symfony_root_dir }}"
no_dev: "{{ 'yes' if ('prod' == symfony_env) else 'no' }}"
tags:
- deploy
when: code_changed
- name: Fix var directory permissions
file:
path: "{{ symfony_var_dir }}"
state: directory
mode: 0777
recurse: yes
changed_when: false
tags:
- permissions
- deploy
# Symfony console commands
- name: Create DB if not exists
command: '{{ symfony_console_path }} doctrine:database:create --if-not-exists'
register: db_create_result
changed_when: "not db_create_result.stdout|search('already exists. Skipped')"
tags:
- deploy
- name: Execute migrations
command: '{{ symfony_console_path }} doctrine:migrations:migrate --no-interaction'
register: db_migrations_result
changed_when: "not db_migrations_result.stdout|search('No migrations to execute')"
tags:
- deploy
when: code_changed
- name: Load data fixtures
command: '{{ symfony_console_path }} hautelook_alice:doctrine:fixtures:load --no-interaction'
when: symfony_env != "prod"
changed_when: false
tags:
- deploy
- name: Clear cache
command: '{{ symfony_console_path }} cache:clear --env={{ symfony_env }}'
changed_when: false
tags:
- deploy
when: code_changed
... lines 237 - 250

Using include()

I'd like to isolate these tasks into their own file. And... there are 2 good ways to do that. The first is.... just to include it. Create a new directory inside ansible called includes/, and inside there, a new file called symfony-bootstrap.yml. Start with the --- on top:

50 lines ansible/includes/symfony-bootstrap.yml
---
... lines 2 - 50

Now, let's move some tasks here! Grab "Install Composer Dependencies" and move it. We also want "Fix var directory permissions" all the way down to the end: "Clear Cache". Delete all of it and paste it into symfony-bootstrap.yml:

50 lines ansible/includes/symfony-bootstrap.yml
---
- name: Install Composer's dependencies
composer:
working_dir: "{{ symfony_root_dir }}"
no_dev: "{{ 'yes' if ('prod' == symfony_env) else 'no' }}"
tags:
- deploy
when: code_changed
- name: Fix var directory permissions
file:
path: "{{ symfony_var_dir }}"
state: directory
mode: 0777
recurse: yes
changed_when: false
tags:
- permissions
- deploy
# Symfony console commands
- name: Create DB if not exists
command: '{{ symfony_console_path }} doctrine:database:create --if-not-exists'
register: db_create_result
changed_when: "not db_create_result.stdout|search('already exists. Skipped')"
tags:
- deploy
- name: Execute migrations
command: '{{ symfony_console_path }} doctrine:migrations:migrate --no-interaction'
register: db_migrations_result
changed_when: "not db_migrations_result.stdout|search('No migrations to execute')"
tags:
- deploy
when: code_changed
- name: Load data fixtures
command: '{{ symfony_console_path }} hautelook_alice:doctrine:fixtures:load --no-interaction'
when: symfony_env != "prod"
changed_when: false
tags:
- deploy
- name: Clear cache
command: '{{ symfony_console_path }} cache:clear --env={{ symfony_env }}'
changed_when: false
tags:
- deploy
when: code_changed

Now that these are in their own file, they should not be indented: so un-indent them twice.

In the playbook, to bring those in - it's really cool: where you would normally put a module, say include: ./includes/symfony-bootstrap.yml:

204 lines ansible/playbook.yml
---
- hosts: vb
... lines 3 - 26
tasks:
... lines 28 - 188
# Bootstrap Symfony app
- include: ./includes/symfony-bootstrap.yml
handlers:
... lines 193 - 204

The tasks will run in a slightly different order than they did before, but it won't make any difference for us. But, to be sure try the playbook with -t deploy:

ansible-playbook ansible/playbook.yml -i ansible/hosts.ini -t deploy

All good! Including a file is the easiest way to organize and re-use tasks. But, there's a better, cooler, more robust, more hipster way. It's called roles.

Leave a comment!