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
| Word | What it means | Example |
|---|---|---|
| Tag | a label on a task that lets you pick it | tags: setup |
| Always tag | a tag whose task runs whichever tags you pick | |
| Limit | a way to run on only some of the hosts | --limit south |
| Vault | Ansible's way of keeping a file encrypted | |
| Vault password | the password that locks and opens a vault | |
| Encrypt | scramble 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
| Run | Make the folder (setup) | Write the notice (notice) | Write the staff list (staff) | Say where it ran (always) |
|---|---|---|---|---|
| No options | runs | runs | runs | runs |
| --tags notice | skipped | runs | skipped | runs |
| --tags setup,notice | runs | runs | skipped | runs |
| --skip-tags staff | runs | runs | skipped | runs |
| --tags staff --skip-tags always | skipped | skipped | runs | skipped |
The cells students fill in are left blank in this preview.
Make a folder for the tags work
mkdir -p ~/iac-demo/tagsShown here, not run. Create a free account to press Run and type it into your own lab’s terminal.
Go into it
cd ~/iac-demo/tagsShown 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
printf '%s\n' '[shop]' 'north ansible_connection=local' 'south ansible_connection=local' > hosts.iniShown 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
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.ymlShown 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
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
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
ansible-playbook -i hosts.ini tagged.yml --tags notice --limit south | grep -o "Destination directory [^ ]* does not exist" | head -n 1Shown 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
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
printf '%s\n' 'practice-password-not-a-secret' > practice.pwShown 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
printf '%s\n' 'api_key: pk-demo-not-real' > secrets.ymlShown here, not run. Create a free account to press Run and type it into your own lab’s terminal.
Encrypt the file in place
ansible-vault encrypt secrets.yml --vault-password-file practice.pwShown 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
head -n 1 secrets.ymlShown here, not run. Create a free account to press Run and type it into your own lab’s terminal.
Read it through the vault
ansible-vault view secrets.yml --vault-password-file practice.pwShown 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
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.ymlShown 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
ansible-playbook -i localhost, -c local use.yml --vault-password-file practice.pw | grep msgShown here, not run. Create a free account to press Run and type it into your own lab’s terminal.
Run it with no password
ansible-playbook -i localhost, -c local use.yml 2>&1 | grep -o "no vault secrets found" | head -n 1Shown 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
# 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.