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 YAML format that can be pasted directly into a vars file.

Encrypting a File with Variables

Let’s encrypt some sensitive database credentials.

  1. 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
  1. 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.

  1. 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
  1. 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
  1. 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!