Skip to main content

Command Palette

Search for a command to run...

Ansible Part 4 - Secrets, Facts and Conditional Tasks

Updated
4 min read
Ansible Part 4 - Secrets, Facts and Conditional Tasks
A
DevOps engineer focused on building, automating, and securing cloud infrastructure. I work with AWS, Docker, Terraform, and CI/CD pipelines to ship scalable and reliable systems. I write about cloud services & architecture, deployment strategies, and real-world DevOps practices.

Secrets - passwords, API keys, credentials. You just can't paste them in YAML and push them to your repo.

System awareness - your playbook might need to behave differently depending on the host.

Conditionals - running a task only when a certain condition is true else skip.

Here, we'll cover it all.


Ansible Vault - Encrypting Secrets

We can add database password directly in a var file, it works, but the moment the file reached the repo, it causes a security problem. Ansible vault is the answer to this, it encrypts the file so you can safely commit it. Only someone with the vault password can read or edit the contents.

Creating a Vault file

ansible-vault create vault.yml

It is completely unreadable without the password.

Working with Vault Files

# View the decrypted contents
ansible-vault view vault.yml

# Edit vault (decrypts, opens editor, re-encrypts on save)
ansible-vault edit vault.yml

# Change the vault password
ansible-vault rekey vault.yml

Using vault variables

Reference the vault file in vars_files exactly like any other var file:

---
- name: using vault
  hosts: redhat
  tasks:
    - name: creating group
      group:
        name: "{{ user_group }}"
        state: present
    - name: creating user
      user:
        name: "{{ user_name }}"
        group: "{{ user_group }}"
        state: present

Ansible needs the vault password to decrypt before it can use those variables.

1. Prompt at runtime:

ansible-playbook vault-playbook.yml --ask-vault-pass

This prompts you for a password before running.

2. Password file:

ansible-playbook vault-playbook.yml --vault-password-file=<pass_file>

pass_file should contain just the password. Useful for automated pipelines. But add it to .gitignore


Incase you ever forget you vault password, the data is gone. There is no way to get it back as it can't be brute-forced. Store it in some secure place.

Ansible Facts

Every time Ansible connects to a managed host, before running any of your tasks, it runs a special task called Gathering Facts. Ansible runs the setup module on each host, which collects a massive amount of system information and stores it as variables you can use anywhere in your playbook.

You can see it using:

ansible redhat -m setup | less

The output is a large JSON object.

Using Facts in a Playbook

You have to reference it like general JSON objects like ansible_facts.<fact_name>:

---
  - name: Using facts
    hosts: redhat
    tasks:
      - name: print IPv4 address
        debug:
          var: ansible_facts.default_ipv4.address

Running this across multiple hosts will print different values for each.


Conditional Statements

Facts become truly powerful when combined with conditionals. The when: keyword lets you run a task only if a condition is true. Basic syntax:

- name: task name
  module:
    args: value
  when: some_condition

Example: You want to install a package, but the module is different (yum vs apt) and maybe the package name differs too. One approach is two separate tasks with conditions.

---
- name: install webserver based on OS
  hosts: all
  tasks:
    - name: install httpd on RedHat
      yum:
        name: httpd
        state: present
      when: ansible_facts.os_family == "RedHat"

    - name: install apache2 on Debian
      apt:
        name: apache2
        state: present
      when: ansible_facts.os_family == "Debian"

You can also combine conditions using operators like:

# Run only on RedHat hosts with more than 2GB RAM
when: ansible_facts.os_family == "RedHat" and ansible_facts.memtotal_mb > 2048

# Run on either hostname
when: ansible_facts.hostname == "web1" or ansible_facts.hostname == "web2"

# Run only if a variable was set
when: db_password is defined

Combining the three (secrets, facts and conditional), and wiring them together into a playbook that makes intelligent decisions per host - all without you hardcoding anything.


Next, we'll dive into Loops and Handlers, till then stay tuned. Keep Balling.