home tools books contact

How to Inject Environment Variables into Ansible Playbooks

Ansible Automation

This tutorial will show you how to inject environment variables into your Ansible playbooks. This allows the playbook to be stored inside a Git repository without exposing secrets.

Example Use Case

Let’s assume we want to write a playbook that creates a TXT DNS record managed by Cloudflare. The Cloudflare Ansible module requires an email address and API token but you don’t want to hard code them in the playbook because it will be stored in a public repository.

The following example will create a TXT record called test with the value hello world in the zone example.com.

- hosts: localhost
  gather_facts: no
  vars:
    cloudflare_email:     "cloudflare@example.com"
    cloudflare_api_token: "mysecureapitokenthatnooneshouldhaveaccessto"
    cloudflare_zone:      "example.com"
  
  tasks:
  - name: create cloudflare TXT record
    cloudflare_dns:
      account_api_token: "{{ cloudflare_api_token }}"
      account_email: "{{ cloudflare_email }}"
      zone: "{{ cloudflare_zone }}"
      record: "test"
      type: TXT
      value: "hello world"
      solo: true
      state: present

Don’t store secrets in playbooks

As you can see in the previous example playbook, the Cloudflare credentials are assigned to the variables and stored in plain text. The problem with this playbook, is we can’t store it in a Git repository because the secrets will be exposed to the public.

To get round this we need to tell Ansible to pull these variables from the environment using the lookup plugin. We can do that be making the following changes to the Cloudflare variables:

  vars:
    cloudflare_email:     "{{ lookup('env','CF_EMAIL') }}"
    cloudflare_api_token: "{{ lookup('env','CF_API_TOKEN') }}"
    cloudflare_zone:      "example.com"

Assign environment varibles

If you are running the playbook on your local machine, you can assign the environment variables before running the ansible-playbook command like shown in the example below:

export CF_EMAIL=<your_cloudflare_email>
export CF_API_TOKEN=<your_cloudflare_api_token>
ansible-playbook main.yml

Tip

When running the playbooks from your local machine, having to remember the secrets and running the export commands each time is tedious.

To make life a little easier, you can store them in a file outside the Git repo. For example, ~/.secrets/cloudflare. Then you can run source ~/.secrets/cloudflare before the ansible-playbook command, or run them from a bash script:

#!/bin/bash
source ~/.secrets/cloudflare
ansible-playbook main.yml

This bash script can also be added to the Git repo.

Conclusion

This tutorial demonstrated how you can use the lookup plugin to import secrets from the environment into variables in Ansible playbooks. This will allow you to store your playbooks in a public Git repository and use automation tools like Jenkins to assign the secrets before the Ansible playbook is run.

Written by: Tony Mackay