Introduction
Ansible playbooks become more powerful, dynamic, and reusable when leveraging variables. One of the most flexible ways to use variables in Ansible is through the --extra-vars
(or -e
) command-line option. This guide will show you how to effectively use extra variables in your Ansible playbooks
Why Use Extra Variables??
Extra variables offer several advantages:
- Make playbooks more dynamic and reusable
- Avoid hardcoding values that change frequently
- Pass environment-specific configurations
- Enable single playbook use across different scenarios
- Simplify playbook maintenance
The Problem with Hardcoding
Let’s examine a common anti-pattern: hardcoding values directly in playbooks.
Example of Hardcoded Playbook
---
- name: Copy File Playbook
gather_facts: no
hosts: webserver
tasks:
- name: Copy file
copy:
dest: /home/justgeek/file.txt
src: /home/justgeek/file.txt
Issues with Hardcoding:
- Limited reusability
- Requires playbook modification for each use case
- Increases risk of errors
- Makes version control more complicated
- Reduces automation capabilities
Using Extra Variables
Step 1: Modify the Playbook
First, update your playbook to use variables instead of hardcoded values:
---
- name: Copy File Playbook
gather_facts: no
hosts: "{{ target_hosts | default('webserver') }}"
tasks:
- name: Copy file
copy:
dest: "/home/justgeek/{{ filename }}"
src: "/home/justgeek/{{ filename }}"
Step 2: Run with Extra Variables
Now you can pass variables when executing the playbook:
# Basic usage with single variable
ansible-playbook playbook.yml -i inventory.yml --extra-vars "filename=newfile.txt"
# Multiple variables
ansible-playbook playbook.yml -i inventory.yml --extra-vars "filename=newfile.txt target_hosts=production"
# Using JSON format
ansible-playbook playbook.yml -i inventory.yml --extra-vars '{"filename":"newfile.txt","target_hosts":"production"}'
# Using YAML file
ansible-playbook playbook.yml -i inventory.yml --extra-vars "@vars.yml"
Here is the sample @vars.yml
file.
# vars.yml
target_hosts: webserver
dest_path: /home/justgeek
source_path: /home/source
filename: test.txt
copy_enabled: true
Advanced Usage Examples
1. Multiple Variable Types
---
- name: Advanced Copy Playbook
gather_facts: no
hosts: "{{ target_hosts }}"
tasks:
- name: Copy file with specific permissions
copy:
dest: "/{{ dest_path }}/{{ filename }}"
src: "/{{ source_path }}/{{ filename }}"
mode: "{{ file_mode | default('0644') }}"
owner: "{{ file_owner | default('ansible') }}"
group: "{{ file_group | default('ansible') }}"
2. Using Variables with Conditionals
---
- name: Conditional Copy Playbook
gather_facts: no
hosts: "{{ target_hosts }}"
tasks:
- name: Copy file if enabled
copy:
dest: "/{{ dest_path }}/{{ filename }}"
src: "/{{ source_path }}/{{ filename }}"
when: copy_enabled | default(true) | bool
Conditionals Play book can be ran as
ansible-playbook playbook.yml -i inventory.yml --extra-vars "target_hosts=webserver dest_path=/home/justgeek source_path=/home/source filename=test.txt copy_enabled=true"
Conclusion
Using extra variables in Ansible playbooks significantly improves their flexibility and reusability. By following these patterns and best practices, you can create more maintainable and robust automation solutions.
Remember to:
- Avoid hardcoding values whenever possible
- Document your variables clearly
- Provide sensible defaults
- Use variable validation where appropriate
- Consider using variable files for complex deployments
These practices will help you create more efficient and maintainable Ansible automation workflows.