Ansible - Variables
- letter, number, underscore, start with letter
- use with Jinja2 templating system
- “ansible allows Jinja2 loops and conditionals in templates, but in playbooks we do not use them”
Basic Variable Use
Defining a variable:
- hosts: webservers
vars:
http_port: 80
Using a variable in a template:
This is the report.
Listening on port {{ http_port }}
In a playbook:
template:
src=settings.cfg.j2
dest={{ remote_install_path }}/settings.cfg
In a playbook:
tasks:
- name: create a virtual host file for {{ vhost }}
template:
src: somefile.j2
dest: /etc/httpd/conf.d/{{ vhost }}
Registered Variables
- only in mem and only for current playbook run
Register a variable and print it:
- name: Get Uptime and Register
ansible.builtin.shell: /usr/bin/uptime
register: result
- name: Print Var
ansible.builtin.debug:
var: result
- name: Print Var
ansible.builtin.debug:
msg: This is it: {{ result }}
Perform action conditionally based on result of a registered variable:
- shell: /usr/bin/test_check
register: result
ignore_errors: True
- shell: /usr/bin/bar
when: result.rc == 5
Checking results with a registered variable:
tasks:
- shell: cat /etc/motd
register: motd_contents
- shell: echo "motd contains the word hi"
when: motd_contents.stdout.find('hi') != -1
Use registered variable in a loop if it is a list or converted to a list:
- name: retrieve the list of home directories
command: ls /home
register: home_dirs
- name: add home dirs to the backup spooler
file:
path: /mnt/bkspool/{{ item }}
src: /home/{{ item }}
state: link
loop: "{{ home_dirs.stdout_lines }}"
# same as loop: "{{ home_dirs.stdout.split() }}"
Check if empty:
- name: list contents of directory
command: ls mydir
register: contents
- name: check contents for emptiness
debug:
msg: "Directory is empty"
when: contents.stdout == ""
External Variables File
Reference vars file in playbook:
- hosts: all
remote_user: root
vars:
favcolor: blue
vars_files:
- /vars/external_vars.yml
Vars file example:
---
somevar: somevalue
password: magic
a: 1
b: 2
c: 3
list1:
- apple
- banana
- toast
var1: "test"
Prompt for Variables
You can prompt for variables. This can be done for passwords. You would probably be better off just specifying “-kKb” on the command line.
---
- name: A Test Playbook
hosts: all
become: true
vars_prompt:
- name: ansible_password
prompt: "Enter password"
private: yes
- name: ansible_become_password
prompt: "Enter sudo password"
private: yes
tasks:
- name: First Test
command: "uname -a"
Vars on Commandline:
ansible-playbook release.yml -e "version=1.23.45 other_variable=foo"
ansible-playbook release.yml --extra-vars "version=1.23.45 other_variable=foo"
Use JSON if you want values other than strings:
ansible-playbook release.yml --extra-vars '{"version":"1.23.45","other_variable":"foo"}'
Vars from JSON or YAML file:
ansible-playbook release.yml --extra-vars "@some_file.json"
Unsafe variables:
var1: !unsafe 'this variable has {{ characters that should not be treated as a jinja2 template'
Unsafe / raw section of a template:
NOTE - Ignore the slashes in this example. This page was generated with markdown. I’m using these exact same tags to contain this code block and I couldn’t get that to work right with these tags …..
\{% raw %\} ... \{% endraw %\}
Common Magic Variables
hostvars | vars on other host |
groups | all hosts and groups in inventory |
group_names | group names for current host |
inventory_hostname | hostname as shown in inventory |
inventory_hostname_short | hostname as shown in inventory ( just the host part ) |
ansible_play_hosts | hosts in the play |
ansible_play_batch | hosts in current batch of play |
ansible_playbook_python | python path used to run ansible commandline |
inventory_dir | host file dir |
inventory_file | host file |
playbook_dir | playbook base dir |
role_path | current role path name |
Ex, all IPs in a group:
{% for host in groups['app_servers'] %}
{{ hostvars[host]['ansible_facts']['eth0']['ipv4']['address'] }}
{% endfor %}
YAML Anchors and Aliases
« merge operator &jvm_opts # anchor *jvm_opts # alias
---
...
vars:
app1:
jvm: &jvm_opts
opts: '-Xms1G -Xmx2G'
port: 1000
path: /usr/lib/app1
app2:
jvm:
<<: *jvm_opts
path: /usr/lib/app2
Another example:
vars:
webapp:
version: &my_version 1.0
custom_name:
- "ToDo_App"
- *my_version