vars_prompt & Environment Variables

Keep on Learning!

If you liked what you've learned so far, dive in!
Subscribe to get access to this tutorial plus
video, code and script downloads.

Start your All-Access Pass
Buy just this tutorial for $10.00

We missed a deploy step! We're not clearing Symfony's cache. That sounds like a job for a new task! Call it "Clear Cache". It's easy: we just need to run a command: {{ symfony_console_path }} cache:clear --env=prod:

---
- hosts: vb
... lines 3 - 10
tasks:
... lines 12 - 188
- name: Clear cache
command: '{{ symfony_console_path }} cache:clear --env=prod'
... lines 191 - 206

Easy! Except... that --env=prod part is interesting. Sometimes I might want to deploy our app in the prod environment - like if we're deploying to production. But other times, like if we're deploying to some test machine, I might want to deploy our app in the dev environment.

What I'm saying is: I want that environment to be configurable. And actually, this is important in two places: here, and when installing the Composer dependencies.

Symfony Composer Deps in the prod Environment

Google for "Symfony deploy" to find a page on Symfony.com. Scroll down to a section about installing and updating your vendors. Ah, so it recommends that when you deploy, you use:

composer install --no-dev

That's actually what the composer module tried to do by default. But then we - via a no_dev option - told it to stop that nonsense!

---
- hosts: vb
... lines 3 - 10
tasks:
... lines 12 - 149
- name: Install Composer's dependencies
composer:
... line 152
no_dev: no
... lines 154 - 206

We had to do that because some of the Composer post-install commands in a Symfony app require the packages in the require-dev section.

In reality, this --no-dev flag is not a big deal. But, we can use it... as long as we set an environment variable: SYMFONY_ENV=prod. Yep, those problematic post-install commands are setup to look for this environment variable, and not to do certain things rely on the require-dev dependencies.

So this is our mission: make the environment configurable, use it in the "Clear Cache" task and set a new environment variable.

Prompting for Input?

How? Start at the top: add a new vars_prompt key with name set to symfony_env:

---
- hosts: vb
... lines 3 - 10
vars_prompt:
- name: symfony_env
... lines 13 - 221

Then, prompt: Enter the environment for your Symfony app (prod|dev|test):

---
- hosts: vb
... lines 3 - 10
vars_prompt:
- name: symfony_env
prompt: "Enter the environment for your Symfony app (prod|dev|test)"
... lines 14 - 221

As you're probably guessing, Ansible will now ask us what environment we want to use. Set a default value to prod and private: no - you can set that to yes to obscure passwords as you type them:

---
- hosts: vb
... lines 3 - 10
vars_prompt:
- name: symfony_env
prompt: "Enter the environment for your Symfony app (prod|dev|test)"
default: prod
private: no
... lines 16 - 221

Cool!

Setting an Environment Variable

Next question: how can we use this variable to set an environment variable? How about... an environment key! Yep, setting environment variables is a native task for Ansible. Set SYMFONY_ENV to {{ symfony_env|lower }}:

---
- hosts: vb
... lines 3 - 10
vars_prompt:
- name: symfony_env
... lines 13 - 16
environment:
SYMFONY_ENV: "{{ symfony_env|lower }}"
... lines 19 - 221

This uses the variable we just set... but pipes it through a lower filter... just in case we get crazy and use upper-case letters.

To see what this all looks like, at the top, let's debug some variables. First, debug one called ansible_env:

---
- hosts: vb
... lines 3 - 19
tasks:
- debug:
var: ansible_env
... lines 23 - 221

This is a built-in variable that has a lot of info about the "host" environment - meaning, the machine (or machines) that you're running Ansible against. It should also contain our environment variable.

Let's also debug the symfony_env variable that we set above:

---
- hosts: vb
... lines 3 - 19
tasks:
- debug:
var: ansible_env
- debug:
var: symfony_env
... lines 26 - 221

Oh, and down on the "Clear Cache" task, I forgot to add the tag for deploy:

---
- hosts: vb
... lines 3 - 19
tasks:
... lines 21 - 203
- name: Clear cache
command: '{{ symfony_console_path }} cache:clear --env=prod'
tags:
- deploy
... lines 208 - 221

Change over to your terminal and run the playbook - but take off the -t option so that everything runs:

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

Yes! Right at the start, it asks us for the environment. I'll leave it blank to use prod. Then, hit ctrl+c to quit: we can already see the variables!

First, it printed ansible_env... which has some pretty cool stuff! It has a HOME key for the home directory, PWD for the current directory and other goodies. AND, it has SYMFONY_ENV set to prod. Not surprisingly, the symfony_env variable also prints prod.

Try this again.. but be tricky... with an uppercase PROD:

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

Yep! The environment variable was lowercased, but not the symfony_env variable. That's no surprise... but if we want to guard against this, it will be a problem in a minute when we try to use this in more places... like down on my "Clear Cache" task:

---
- hosts: vb
... lines 3 - 19
tasks:
... lines 21 - 203
- name: Clear cache
command: '{{ symfony_console_path }} cache:clear --env=prod'
... lines 206 - 221

We could keep using the lower filter. But, there's a cooler way: a "pre task".

Leave a comment!

This tutorial is built using an older version of Symfony, but the core concepts of Ansible are still valid. New versions of Ansible may contain some features that we don't use here.

What PHP libraries does this tutorial use?

// composer.json
{
    "require": {
        "php": ">=5.5.9",
        "symfony/symfony": "3.1.*", // v3.1.4
        "doctrine/orm": "^2.5", // v2.7.2
        "doctrine/doctrine-bundle": "^1.6", // 1.6.4
        "doctrine/doctrine-cache-bundle": "^1.2", // 1.3.0
        "symfony/swiftmailer-bundle": "^2.3", // v2.3.11
        "symfony/monolog-bundle": "^2.8", // 2.11.1
        "symfony/polyfill-apcu": "^1.0", // v1.2.0
        "sensio/distribution-bundle": "^5.0", // v5.0.12
        "sensio/framework-extra-bundle": "^3.0.2", // v3.0.16
        "incenteev/composer-parameter-handler": "^2.0", // v2.1.2
        "doctrine/doctrine-migrations-bundle": "^1.2", // v1.2.0
        "snc/redis-bundle": "^2.0", // 2.0.0
        "predis/predis": "^1.1" // v1.1.1
    },
    "require-dev": {
        "sensio/generator-bundle": "^3.0", // v3.0.8
        "symfony/phpunit-bridge": "^3.0", // v3.1.4
        "doctrine/data-fixtures": "^1.1", // 1.3.3
        "hautelook/alice-bundle": "^1.3" // v1.4.1
    }
}