5 minutes
Ansible - Vault and Collections - Part 6
This final part of our foundational guide will cover two important aspects of Ansible: securely managing sensitive data with Ansible Vault and understanding Collections for extending Ansible’s functionality.
Ansible Vault: Securing Sensitive Data
In automation, you often deal with sensitive information like passwords, API keys, private keys, and database credentials. Storing these directly in plain text in your playbooks or variable files is a major security risk. Ansible Vault provides a robust solution for encrypting these sensitive variables and files.
When data is encrypted with Ansible Vault, it can only be decrypted and used by Ansible when the correct vault password is provided.
Key Vault Commands
Ansible Vault uses a single, consistent password to encrypt and decrypt data.
- ansible-vault create <file_name>: Creates a new encrypted file. Ansible will prompt you for a password and then open an editor for you to add content.
- ansible-vault encrypt <file_name>: Encrypts an existing plain-text file.
- ansible-vault decrypt <file_name>: Decrypts an encrypted file back to plain text.
- ansible-vault edit <file_name>: Edits an encrypted file. Ansible will decrypt it for editing and then re-encrypt it upon saving.
- ansible-vault view <file_name>: Views the content of an encrypted file without decrypting it to disk.
- ansible-vault rekey <file_name>: Changes the password for an encrypted file.
- ansible-vault encrypt_string ‘<string_to_encrypt>’ –name <variable_name>: Encrypts a single string and outputs it in a
YAMLformat that can be pasted directly into a vars file.
Encrypting a File with Variables
Let’s encrypt some sensitive database credentials.
- Create a vars file with sensitive data (e.g., group_vars/all/secrets.yml):
# group_vars/all/secrets.yml (will be encrypted)
db_username: admin_user
db_password: MySup3rS3cr3tP@ssword!
api_key: abc123def456ghi789jkl
- Encrypt the file:
ansible-vault encrypt group_vars/all/secrets.yml
You’ll be prompted to enter and confirm a new vault password.
After encryption, if you try to cat ```group_vars/all/secrets.yml````, you’ll see a garbled, encrypted blob.
Using Encrypted Variables in a Playbook
You can use the encrypted variables in your playbooks just like regular variables.
Example Playbook using encrypted variables:
---
# playbooks/use_secrets.yml
- name: Demonstrate using vault secrets
hosts: localhost # Or your target hosts
connection: local # To run tasks on the control node
tasks:
- name: Debug database username
ansible.builtin.debug:
msg: "Database Username: {{ db_username }}"
# In a real scenario, you'd pass these to a module, not debug them directly!
- name: Connect to database (example, not actual module)
ansible.builtin.command: "db_connect --user {{ db_username }} --password {{ db_password }}"
# In a real scenario, use a dedicated database module for security
no_log: true # Prevent sensitive data from appearing in logs
Running Playbooks with Vault Encrypted Files
When running a playbook that uses encrypted files, you need to tell Ansible how to decrypt them.
- Using –ask-vault-pass:
This is the most common method for manual runs. Ansible will prompt you for the vault password.
ansible-playbook -i inventory.ini playbooks/use_secrets.yml --ask-vault-pass
- Using a Vault Password File:
For automation or scripting, you can provide a file containing the vault password. Make sure this file is secured (e.g., 600 permissions) and preferably not version-controlled.
echo "MyVaultPassword123" > ~/.vault_pass.txt
chmod 600 ~/.vault_pass.txt
ansible-playbook -i inventory.ini playbooks/use_secrets.yml --vault-password-file ~/.vault_pass.txt
- Using ANSIBLE_VAULT_PASSWORD_FILE environment variable:
You can set an environment variable pointing to the password file.
export ANSIBLE_VAULT_PASSWORD_FILE=~/.vault_pass.txt
ansible-playbook -i inventory.ini playbooks/use_secrets.yml
Encrypting a Single String (encrypt_string)
Sometimes you just need to encrypt a single variable’s value to paste into a vars file without encrypting the entire file.
ansible-vault encrypt_string 'MySuperSecretValueForAnsible' --name 'my_secret_var'
Output will look something like this:
my_secret_var: !vault |
$ANSIBLE_VAULT;1.1;AES256
61666161663032306233363630653564343164346162646231643265623030383162383236353930
... (rest of encrypted data)
You can copy and paste this directly into any YAML variable file (e.g., group_vars/all.yml or roles/my_role/vars/main.yml). Ansible will automatically decrypt it when the vault password is provided.
Ansible Collections: Modernizing Content
Ansible Collections are the new standard for packaging and distributing Ansible content. They are essentially a structured way to combine modules, plugins, roles, and documentation into a single, shareable unit.
Before Collections, modules were often part of Ansible core, and roles were separate. Collections provide a more modular and extensible way to organize and distribute automation content.
Structure of a Collection
A collection has a defined directory structure:
<namespace>/
└── <collection_name>/
├── playbooks/
├── roles/
├── plugins/
│ ├── modules/
│ ├── lookups/
│ ├── filter_plugins/
│ └── ...
├── meta/
│ └── runtime.yml # Defines dependencies, module_utils, etc.
└── docs/
Why Collections?
- Modularization: Content from specific vendors or communities can be packaged and versioned independently from Ansible core.
- Dependency Management: Collections can declare dependencies on other collections.
- Namespace Isolation: Prevents naming conflicts between different modules or roles.
- Easier Distribution: Published on Ansible Galaxy for easy installation.
Using Modules from Collections
When using a module from a collection, you typically preface the module name with its Fully Qualified Collection Name (FQCN): .<collection_name>.<module_name>.
For example, core modules are now part of the ansible.builtin collection:
- name: Install Nginx package
ansible.builtin.yum: # FQCN for a core module
name: nginx
state: present
If you installed a collection for AWS (e.g., community.aws), you’d use its modules like this:
- name: Create an S3 bucket
community.aws.s3_bucket: # FQCN for a community AWS module
name: my-new-bucket-ansible
state: present
Installing Collections
Collections are typically installed from Ansible Galaxy:
ansible-galaxy collection install community.aws
ansible-galaxy collection install community.mysql:==1.0.0 # Install specific version
This will download the collection to your default collections path (usually ~/.ansible/collections).
Using Roles from Collections
Roles included within a collection can also be referenced by their FQCN:
- name: Deploy Apache using a role from a collection
hosts: webservers
roles:
- community.general.apache # Assuming community.general collection contains an apache role
However, it’s more common to install roles directly from Galaxy that are not necessarily part of a broader collection bundle, as shown in Part 5 (e.g., geerlingguy.apache).
Conclusion
This guide has provided a comprehensive introduction to Ansible, covering installation, inventory management, playbooks, variables, templates, control flow, roles, vault for security, and the modern concept of collections.
Ansible is a vast and powerful tool. To continue your learning, explore:
- Official Ansible Documentation: The ultimate source for module parameters, advanced topics, and best practices.
- Ansible Galaxy: Discover and leverage existing roles and collections.
- Ansible Blog and Community Forums: Stay updated and get help from other users.
- Experimentation: The best way to learn is by doing. Set up a few virtual machines and start automating!
Happy Automating!