Buy

Tagging Tasks

Sometimes - especially when debugging - you just want to run only some of your playbook. Because... our playbook is getting so awesome... that, honestly, it takes some serious time to run!

For example, in my VM, I'm going to change the permissions on the var/ directory:

sudo chmod -R 555 var/

Definitely use sudo. Then, I'll remove the cache files:

sudo rm -rf var/cache/*

If you try the page now, it explodes! Ok, I don't expect my permissions to suddenly change like this under normal conditions. But, suppose that we had just hit this permission error for the first time and then added the "Fix var permissions" task. In that case, we would know that re-running the entire playbook should fix things.

But... couldn't we run just this one task? Yep! And a great way to do that is via tags.

Below the task, add tags, and then permissions:

176 lines ansible/playbook.yml
---
- hosts: vb
... lines 3 - 10
tasks:
... lines 12 - 144
- name: Fix var directory permissions
... lines 146 - 150
tags:
- permissions
... lines 153 - 176

Now, from the command line, tell Ansible to only execute tasks with this tag: -t permissions:

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

It still goes through its setup but then... yep! Only one task! Refresh the page. Permissions fixed!

Tagging for Deployment

Here's another example. Right now, our playbook has tasks for two separate jobs. Some tasks setup the server - making sure PHP, Nginx and other stuff is installed and configured. But others are really more about code deployment: making sure the project directory exists, cloning the code, installing composer dependencies, and setting up the database.

In the future - when we make changes to the code - we might want to just deploy that code... without going through all the server setup tasks. Let's add a new tag - deploy - to every step involved in deployment. See the task that creates the project directory? Yep, give it the deploy tag. Add it to "Checkout Git Repository" and also to the three tasks that install Composer:

195 lines ansible/playbook.yml
---
- hosts: vb
... lines 3 - 10
tasks:
... lines 12 - 111
- name: Create project directory and set its permissions
... lines 113 - 119
tags:
- deploy
- name: Checkout Git repository
... lines 124 - 127
tags:
- deploy
- name: Download Composer
... line 132
tags:
- deploy
- name: Move Composer globally
... lines 137 - 138
tags:
- deploy
- name: Set permissions on Composer
... lines 143 - 146
tags:
- deploy
- name: Install Composer's dependencies
... lines 151 - 153
tags:
- deploy
... lines 156 - 195

Actually, this is debatable: you might consider Composer as a "Server setup" task, not deployment. It's up to you.

Keep going! I'll add the task to everything that I want to run for each code update. It's not an exact science:

195 lines ansible/playbook.yml
---
- hosts: vb
... lines 3 - 10
tasks:
... lines 12 - 111
- name: Create project directory and set its permissions
... lines 113 - 119
tags:
- deploy
- name: Checkout Git repository
... lines 124 - 127
tags:
- deploy
- name: Download Composer
... line 132
tags:
- deploy
- name: Move Composer globally
... lines 137 - 138
tags:
- deploy
- name: Set permissions on Composer
... lines 143 - 146
tags:
- deploy
- name: Install Composer's dependencies
... lines 151 - 153
tags:
- deploy
- name: Fix var directory permissions
... lines 158 - 162
tags:
- permissions
- deploy
# Symfony console commands
- name: Create DB if not exists
... line 169
tags:
- deploy
- name: Execute migrations
... line 174
tags:
- deploy
- name: Load data fixtures
... line 179
tags:
- deploy
... lines 182 - 195

Let's see if it works! In the virtual machine, I'm going to manually edit a file:

vim app/Resources/views/default/index.html.twig

Let's add a few exclamation points to be really excited. Then hit escape, :wq to save. In the browser, that won't show up immediately - because we're in Symfony's prod environment. But if you add app_dev.php to the URL... yep! "Filter by Tag!".

By the way, going to app_dev.php only works because I've already modified some security logic in that file to allow me to access it:

33 lines web/app_dev.php
... lines 1 - 10
// This check prevents access to debug front controllers that are deployed by accident to production servers.
// Feel free to remove this, extend it, or make something more sophisticated.
if (isset($_SERVER['HTTP_CLIENT_IP'])
|| isset($_SERVER['HTTP_X_FORWARDED_FOR'])
|| !(in_array(@$_SERVER['REMOTE_ADDR'], ['127.0.0.1', 'fe80::1', '::1', '192.168.33.1']) || php_sapi_name() === 'cli-server' || strpos($_SERVER['REMOTE_ADDR'], '192.168.') === 0)
) {
header('HTTP/1.0 403 Forbidden');
exit('You are not allowed to access this file. Check '.basename(__FILE__).' for more information.');
}
... lines 20 - 33

Ok, back in our local machine, run the playbook... this time with -t deploy:

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

Oh, much, much faster! Try the browser! Code deployed! You can also use --skip-tags if you want to get crazy and do the opposite:

ansible-playbook ansible/playbook.yml -i ansible/hosts.ini --skip-tags deploy

Next, let's talk about how we can "fix" the fact that some tasks say "Changed" every time we run them. Eventually, this will help us speed up our playbook.

Leave a comment!

  • 2017-05-22 Victor Bocharsky

    Hey Jian,

    Good question :) Actually, as Ryan said, this is debatable: you might consider Composer as a "Server setup" task, not deployment. It's up to you. But yeah, there's no a good reason to do it, especially if you're installing Composer globally. But it makes more sense if you do not want to install composer globally, i.e. just download composer.phar, use it and then remove it from the server at all. So fell free to remove deploy tag from tasks which install Composer and move it globally.

    Cheers!

  • 2017-05-19 jian su

    Hi guys: why would you tags deploy for Move Compose globally when you just want to deploy your new code to server? Is this a one time thing when you install composer? I think most of time u just need to run composer install when you deploy ur new code to server.