Easier to read with cream paper, a tint, more contrast or larger text? Choose your colours and text, once, for every page.

Free lesson

Ansible tags and Vault

After this lesson: I can run part of a role and keep a secret out of plain text.

60 min lesson16 commandsAnsible roles lab: a role, handlers and Vault on one Ubuntu VM

Run part of a role, hide the secrets

An Ansible tag is a label on a task, so you can run only some tasks of a playbook with --tags. Ansible Vault encrypts a file or a value. A password or a key can then sit in a project without anyone being able to read it.

Together they let a team run a small part of a big role and keep secrets out of plain text.

By the end of this lesson

Note

I can run part of a role and keep a secret out of plain text.

Key words

WordWhat it meansExample
Taga label on a task that lets you pick ittags: setup
Always taga tag whose task runs whichever tags you pick
Limita way to run on only some of the hosts--limit south
VaultAnsible's way of keeping a file encrypted
Vault passwordthe password that locks and opens a vault
Encryptscramble a file so it needs the password

The cells students fill in are left blank in this preview.

A tag picks which tasks run

Give a task tags: notice and run the playbook with --tags notice. Ansible starts only the tasks that carry the tag. --skip-tags does the opposite and leaves those tasks out.

A task tagged always runs whichever tags you pick. --list-tasks shows what a run would start, without running anything. --limit works on hosts, not tasks.

Worked example: four tasks and five runs

RunMake the folder (setup)Write the notice (notice)Write the staff list (staff)Say where it ran (always)
No optionsrunsrunsrunsruns
--tags noticeskippedrunsskippedruns
--tags setup,noticerunsrunsskippedruns
--skip-tags staffrunsrunsskippedruns
--tags staff --skip-tags alwaysskippedskippedrunsskipped

The cells students fill in are left blank in this preview.

Make a folder for the tags work

Command
mkdir -p ~/iac-demo/tags

Shown here, not run. Create a free account to press Run and type it into your own lab’s terminal.

Go into it

Command
cd ~/iac-demo/tags

Shown here, not run. Create a free account to press Run and type it into your own lab’s terminal.

Write an inventory of two hosts

Command
printf '%s\n' '[shop]' 'north ansible_connection=local' 'south ansible_connection=local' > hosts.ini

Shown here, not run. Create a free account to press Run and type it into your own lab’s terminal.

Write a playbook with four tagged tasks

Command
printf '%s\n' '---' '- name: Open the shop' '  hosts: shop' '  gather_facts: false' '  tasks:' '    - name: Make the folder' '      ansible.builtin.file:' '        path: /tmp/iac-tags' '        state: directory' '        mode: "0755"' '      tags: setup' '    - name: Write the notice' '      ansible.builtin.copy:' '        content: "Open today\n"' '        dest: /tmp/iac-tags/notice.txt' '        mode: "0644"' '      tags: notice' '    - name: Write the staff list' '      ansible.builtin.copy:' '        content: "Asha and Ben\n"' '        dest: /tmp/iac-tags/staff.txt' '        mode: "0644"' '      tags: staff' '    - name: Say where it ran' '      ansible.builtin.debug:' '        msg: "Finished on {{ inventory_hostname }}"' '      tags: always' > tagged.yml

Shown here, not run. Create a free account to press Run and type it into your own lab’s terminal.

List every tag the playbook uses

Command
ansible-playbook -i hosts.ini tagged.yml --list-tags | grep "TASK TAGS"

Shown here, not run. Create a free account to press Run and type it into your own lab’s terminal.

List what --tags notice would start

Command
ansible-playbook -i hosts.ini tagged.yml --tags notice --list-tasks | grep -E "TAGS: \[[a-z]"

Shown here, not run. Create a free account to press Run and type it into your own lab’s terminal.

Run only the notice task, on one host

Command
ansible-playbook -i hosts.ini tagged.yml --tags notice --limit south | grep -o "Destination directory [^ ]* does not exist" | head -n 1

Shown here, not run. Create a free account to press Run and type it into your own lab’s terminal.

A common mistake

Warning

Many people think --tags runs the tagged task and everything it needs. It does not. A task without the tag is skipped, even the one that makes the folder. Tag the setup task as well, or tag it always.

Run setup and notice on one host

Command
ansible-playbook -i hosts.ini tagged.yml --tags setup,notice --limit south | grep -oE "^[a-z]+: \[[a-z]+\]"

Shown here, not run. Create a free account to press Run and type it into your own lab’s terminal.

Vault encrypts a file with a password

ansible-vault encrypt scrambles a file so it needs a password to read. The first line of the result names the format, so Ansible knows it is a vault.

A playbook can load an encrypted file as normal, if you give --vault-password-file. The password file is kept apart from the project, and never committed with it. The one here is a practice password and protects nothing real.

Write a practice password file

Command
printf '%s\n' 'practice-password-not-a-secret' > practice.pw

Shown here, not run. Create a free account to press Run and type it into your own lab’s terminal.

Write a file with a made-up key

Command
printf '%s\n' 'api_key: pk-demo-not-real' > secrets.yml

Shown here, not run. Create a free account to press Run and type it into your own lab’s terminal.

Encrypt the file in place

Command
ansible-vault encrypt secrets.yml --vault-password-file practice.pw

Shown here, not run. Create a free account to press Run and type it into your own lab’s terminal.

Read the first line of the file

Command
head -n 1 secrets.yml

Shown here, not run. Create a free account to press Run and type it into your own lab’s terminal.

Read it through the vault

Command
ansible-vault view secrets.yml --vault-password-file practice.pw

Shown here, not run. Create a free account to press Run and type it into your own lab’s terminal.

Write a play that loads the encrypted file

Command
printf '%s\n' '---' '- name: Use the key' '  hosts: localhost' '  gather_facts: false' '  vars_files:' '    - secrets.yml' '  tasks:' '    - name: Say how long the key is' '      ansible.builtin.debug:' '        msg: "The key has {{ api_key | length }} characters"' > use.yml

Shown here, not run. Create a free account to press Run and type it into your own lab’s terminal.

Run it with the password file

Command
ansible-playbook -i localhost, -c local use.yml --vault-password-file practice.pw | grep msg

Shown here, not run. Create a free account to press Run and type it into your own lab’s terminal.

Run it with no password

Command
ansible-playbook -i localhost, -c local use.yml 2>&1 | grep -o "no vault secrets found" | head -n 1

Shown here, not run. Create a free account to press Run and type it into your own lab’s terminal.

Choosing tasks by tag in Python

Code: python
# Which tasks would a tag run start?
tasks = [
    {"name": "Make the folder", "tags": ["setup"]},
    {"name": "Write the notice", "tags": ["notice"]},
    {"name": "Say where it ran", "tags": ["always"]},
]
chosen = ["notice"]
for task in tasks:
    run = False
    for tag in task["tags"]:
        if tag in chosen or tag == "always":
            run = True
    if run:
        print("run", task["name"])
    else:
        print("skip", task["name"])
# Change chosen to ["setup", "notice"] and run it again.

About this lab and its source: Ansible roles lab: a role, handlers and Vault on one Ubuntu VM

Teaching a class? Set this module for your students with a teacher guide, marked assignments and a lab for every student.