Skip to main content

Defining Group Variables and Protecting Secrets

Group Variables

Back on Defining the Inventory, you may remember that we broke the inventory up into groups. Groups are a convenient way to break hosts up into units like:

  • Operating system
  • Region
  • Category

Using the operating system grouping system, you could define a group for Windows and a group for Linux. This is especially handy, as Ansible uses different protocols to manage each Windows and Linux.

  • Ansible uses WinRM to manage Windows hosts
  • Ansible uses SSH to manage Linux hosts

Also, you may have different credentials to manage each set of hosts.

  • You might have an SSH key for your Linux hosts
  • And, a username and password Windows hosts.

Defining Group Variables

Ansible will search for a group variables file in the following order:

  • The directory relative to the playbook
  • The directory relative to the inventory file

Say you have an inventory file in: ~/.ansible/inventory/main-inventory.ini. And, in that inventory, you have a windows group and a linux group. You'll want to specify your group variables as such:

  • Windows:
    • ~/.ansible/inventory/group_vars/windows.yml
    • This means that any time a host in your inventory belongs to the windows group, it will inherit the variables specified below:
---
ansible_user: user
ansible_password: strongpass
ansible_connection: winrm
ansible_winrm_transport: ntlm
ansible_winrm_server_cert_validation: ignore

  • Linux:
    • ~/.ansible/inventory/group_vars/linux.yml
    • This means that any time a host in your inventory belongs to the linux group, it will inherit the variables specified below:
---
ansible_ssh_private_key_file: /root/ssh-priv-key.pem

What's the Problem Here?

Your group variables could contain sensitive information -- especially obvious in the case of the windows group variables. There is a password stored in cleartext.

Fortunately, Ansible has a solutionc called, "Ansible Vault" to encrypt the contents of files.



Protecting Secrets with Ansible Vault

You can encrypt any file with the ansible-vault command. Its intended use-case is to encrypt files with a password and decrypt them when a playbook is run.

Encrypting Secrets with Ansible Vault

Going back to the windows group example, this is how you can protect your secrets with Ansible Vault.

  • You need to re-arrange your group variables directory a bit:
    • ~/.ansible/inventory/group_vars/windows/vars.yml
      • This is a cleartext file with Jinja2 templating as placeholders when vault.yml is unlocked
    • ~/.ansible/inventory/group_vars/windows/vault.yml
      • This file contains the secrets to be encrypted using ansible-vault

vault.yml

This file will contain the same contents as the group variables before:

ansible_user: user
ansible_password: strongpass
ansible_connection: winrm
ansible_winrm_transport: ntlm
ansible_winrm_server_cert_validation: ignore

Now, encrypt this file using this command:

ansible-vault encrypt ~/.ansible/inventory/group_vars/windows/vault.yml

You will be prompted to enter a password to encrypt the vault file. Keep this password somewhere safe, as you'll need to remember it in order to decrypt the file later whenever this group variables file is used in a playbook.


vars.yml

---
ansible_user: "{{ vault_ansible_user }}"
ansible_password: "{{ vault_ansible_password }}"
ansible_connection: "{{ vault_ansible_connection }}"
ansible_winrm_transport: "{{ vault_ansible_winrm_transport }}"
ansible_winrm_server_cert_validation: "{{ vault_ansible_winrm_server_cert_validation }}"

Notice the {{ variable_name }} syntax. This is called Jinja2 templating. When you run a playbook, here's what should happen.

  • If your playbook references the windows group
    • Ansible Vault will try to decrypt ~/.ansible/inventory/group_vars/windows/vault.yml
    • You will be asked for a password to decrypt the file
    • If successful, the vault.yml file will decrypt and populate the templates in vars.yml
    • Then, the playbook will reference the variables in vars.yml



Automating with Ansible Vault

What happens if you want to script an Ansible Playbook? You'll need some unattended way to decrypt the vault files when your script runs your playbook.

Ansilbe Vault Password File

IMPORTANT: If you decide to use the Ansible Vault password file, you'll want to make sure you adhere to security best practices, keep your system patched, and monitor for abuse. If an attacker is able to compromise your Ansible server and become root, they could read this file and unlock your encrypted files. (You don't have to use a password file. You'll just have to enter your password every time you run a playbook.)

  1. Create an empty file as the user who will run the playbooks
  2. Enter a strong password in it (save the vault pass in a password manager)
  3. Save the file
  4. chmod 600 the file to protect it
  5. Configure your Ansible server to read the file to encrypt/decrypt Vault files
    • Option 1: Environment Variable
      • Put this line in the user's .bashrc file
      • export ANSIBLE_VAULT_PASSWORD_FILE=/path/to/pass_file.txt
    • Option 2: Ansible Config file
      • Edit the user's .ansible.cfg
      • Add this line under [defaults] section
      • vault_password_file = /path/to/pass_file.txt

Now, any time you run ansible-vault encrypt or ansible-vault view, the password file will be used as your default vault password.