- Variable Overview
- Variable Precedence
- Variable Scope
- Variable Management
- Registered Variables
- Inclusion
- Loops
- Ansible Return Values
|Variable Overview| Variable Precedence| Variable Scope| Variable Management| Registered Variables| Inclusion| Loops| Ansible Return Values|
Variable:
String or number that gets assigned value- Lets you reuse information across:
- Playbooks
- Inventory files
- Tasks and roles
- Jinja2 template files
- Use variables to define:
- Users
- Packages
- Services
- Files
- Archives
Variable Names
must begind with letter, and can include letters, digits, and underscores- You can use
Arrays
to define multiple variables for different users like below
---
users:
bjones:
first_name: Bob
last_name: Jones
home_dir: /users/bjones
acook:
first_name: Anne
last_name: Cook
home_dir: /users/acook
...
- Accssing variables from array can be done as follows:
users.bjones.first_name
- Options for variables in playbooks:
- Define in vars block at beginning of playbook
- hosts: all
vars:
user: joe
home: /home/joe
* Pass as arguments by including file in playbook
include: extra_args.yml
name: joe
group: wheel
|Variable Overview| Variable Precedence| Variable Scope| Variable Management| Registered Variables| Inclusion| Loops| Ansible Return Values|
If Ansible finds variables with same name, uses chain of precedence Ansible 2: Variables evaluated in 16 categories of precedence order
- Role Default Variables:
* Set in roles
vars
directory
[configuration]
users:
- joe
- jane
- bob
- Inventory Variables:
[host_group]
demo.exmample.com ansible_user: joe
- Inventory
group_vars
variables:
[hostgroup:children]
host_group1
host_group2
[host_group:vars]
user: joe
- Inventory
host_vars
variables:
[hostgroup:vars]
user: joe
group_vars
variables defined ingroup_vars
directory:
--
user: joe
host_vars
variables defined inhost_vars
directory:
--
user: joe
- Host facts, i.e facts discoverable by Ansible
- Registered variables, registered with
register
keyword
---
- hosts: all
tasks:
- name: Checking if Sources are Available
shell: echo "This is a test"
register: output
- Variables defined via
set_fact
:
- set_fact:
user: joe
- Variables defined with
-a
or--args
:
ansible-playbook main.yml -a "user=joe"
vars_prompt
variables:
vars:
from: "user"
vars_prompt:
- name: "user"
prompt: "User to create"
- Variables included using
vars_files
:
vars_files:
- /vars/environment.yml
role
andinclude
variables:
---
- hosts: all
roles:
- { role: user, name: 'joe' }
tasks:
- name: Includes the environment file and sets the variables
include: tasks/environment.yml
vars:
package: httpd
state: started
- Block variables
- For tasks defined in
block
statement
- For tasks defined in
tasks:
- block:
- yum: name={{ item }} state=installed
with_items:
- httpd
- memcached
- Task variables
- Only for task itself:
- user: name=joe
extra
variables- Precedence over all other variables
ansible-playbook users.yml -e "user=joe"
|Variable Overview| Variable Precedence| Variable Scope| Variable Management| Registered Variables| Inclusion| Loops| Ansible Return Values| Three levels
Scope | Definition |
---|---|
Global | |
Play | vars , include , include_vars |
Host | ansible_user defines user to connect with on managed host |
- Scopes let you determine best variable placement
- To define variable only for playbook, use vars block
- Variable evaluated when playbook is played:
vars:
user: joe
- To make variable available for host independent of play, define as group variable in inventory file:
[servers]
demo.example.com
[servers:vars]
user: joe
- To enable variable to override playbook, declare as extra:
[user@demo ~]$ ansible-playbook users.yml -e 'user=joe'
|Variable Overview| Variable Precedence| Variable Scope| Variable Management| Registered Variables| Inclusion| Loops| Ansible Return Values|
- Declare playbook variables in various locations:
- In inventory file as host or group variables
- In vars statement as playbook variables
- In register statement
- Passed as arguments using
-a
- Passed as extra arguments using
-e
Example 1: Value Varying by Datacenter
[datacenter1]
demo1.example.com
demo2.example.com
[datacenter2]
demo3.example.com
demo4.example.com
[datacenter1:vars]
package=httpd
[datacenter2:vars]
package=apache
Example 2: Value Varying by Host
[datacenter1]
demo1.example.com package=httpd
demo2.example.com package=apache
[datacenter2]
demo3.example.com package=mariadb-server
demo4.example.com package=mysql-server
[datacenters:children]
datacenter1
datacenter2
Example 3: Default Value that Host Overrides
[datacenter1]
demo1.example.com
demo2.example.com
[datacenter2]
demo3.example.com
demo4.example.com
[datacenters:children]
datacenter1
datacenter2
[datacenters:vars]
package=httpd
[user@demo ~]$ ansible-playbook demo2.exampe.com main.yml -e "package=apache"
|Variable Overview| Variable Precedence| Variable Scope| Variable Management| Registered Variables| Inclusion| Loops| Ansible Return Values|
- To capture command’s output, use
register
statement
---
- name: Installs a package and prints the result
hosts: all
tasks:
- name: Install the package
yum:
name: httpd
state: installed
register: install_result
- debug: var=install_result
[uder@demo ~]$ ansible-playbook playbook.yml
PLAY [Installs a package and prints the result] ****************************
TASK [setup] ***************************************************************
ok: [demo.example.com]
TASK [Install the package] *************************************************
ok: [demo.example.com]
TASK [debug] ***************************************************************
ok: [demo.example.com] => {
"install_result": {
"changed": false,
"msg": "",
"rc": 0,
"results": [
"httpd-2.4.6-40.el7.x86_64 providing httpd is already installed"
]
}
}
PLAY RECAP *****************************************************************
demo.example.com : ok=3 changed=0 unreachable=0 failed=0
|Variable Overview| Variable Precedence| Variable Scope| Variable Management| Registered Variables| Inclusion| Loops| Ansible Return Values|
- Tasks included with
include
executed same as if defined in playbook - Variables included with
include_vars
parsed same as if declared in playbook - Using multiple external files for tasks and variables:
- Lets you build main playbook in modular way
- Facilitates reuse of elements across playbooks
- To import variables, use
include_vars
:
---
- hosts: all
tasks:
- name: Includes the tasks file and defines the variables
include_vars: variables.yml
- name: Debugs the variables imported
debug:
msg: "{{ packages['web_package'] }} and {{ packages.db_package }} have been imported"
[user@prompt ~]$ ansible-playbook playbook.yml
PLAY ***********************************************************************
TASK [setup] ***************************************************************
ok: [demo.example.com]
TASK [Includes the tasks file and defines the variables] *******************
ok: [demo.example.com]
TASK [Debugs the variables imported] ***************************************
ok: [demo.example.com] => {
"msg": "httpd and mariadb-server have been imported"
}
PLAY RECAP *****************************************************************
demo.example.com : ok=3 changed=0 unreachable=0 failed=0
- Variables defined as Python dictionary
- Same methods for accessing values as facts or array-based variables
- Dot notation:
packages.db_package
,packages.web_package
- Bracket notation:
packages['db_package']
,packages['web_package']
- Dot notation:
|Variable Overview| Variable Precedence| Variable Scope| Variable Management| Registered Variables| Inclusion| Loops| Ansible Return Values|
- Loops require use of arrays
- You define array and task that iterates over array
- Loop iterates over values defined in array
- To pass loop as argument, use item keyword
- Enables Ansible to parse array
- Ansible supports number of loop types:
- Simple loops
- List of items Ansible reads and iterates over
- To define simple loop, provide list of items to
with_items
- Simple loops
- yum:
name: "{{ item }}"
state: latest
loop:
- postfix
- dovecot
* Lists of hashes
* Arrays passed as arguments can be list of hashes
* Example: Pass multidimensional array (array with key/pair values) to `user` module
- user:
name: {{ item.name }}
state: present
groups: {{ item.groups }}
loop:
- { name: 'jane', groups: 'wheel' }
- { name: 'joe', groups: 'root' }
|Variable Overview| Variable Precedence| Variable Scope| Variable Management| Registered Variables| Inclusion| Loops| Ansible Return Values|
Value | Description |
---|---|
changed |
|
failed |
|
msg |
|
results |
result per item |
stderr |
raw , shell , command ) |
ansible_facts |
|
warnings |
|
deprecations |
|Roles Overview |Roles in Playbooks |Role Creation |Ansible Galaxy|
Role Uses:
- Enable Ansible to load components from external files:
- Tasks
- Handlers
- Variables
- Associate and reference:
- Static files
- Templates
[user@host roles]$ tree user.example
user.example/
├── defaults
│ └── main.yml
├── files
├── handlers
│ └── main.yml
├── meta
│ └── main.yml
├── README.md
├── tasks
│ └── main.yml
├── templates
├── tests
│ ├── inventory
│ └── test.yml
└── vars
└── main.yml
Subdirectory | Function |
---|---|
defaults |
main.yml contains default values for role variables |
files |
|
handlers |
main.yml contains role handler definitions |
meta |
main.yml defines role information |
tasks |
main.yml contains role task definitions |
templates |
Jinja2 templates referenced by role tasks |
tests |
test.yml playbook |
vars |
main.yml defines role variable values |
|Roles Overview |Roles in Playbooks |Role Creation |Ansible Galaxy|
- Simple to use roles in playbooks
- Example:
---
- hosts: remote.example.com
roles:
- role1
- role2
Order of Execution
- Default: Role tasks execute before tasks of playbooks in which they appear
- To override default, use pre_tasks and post_tasks
- pre_tasks: Tasks performed before any roles applied
- post_tasks: Tasks performed after all roles completed
---
- hosts: remote.example.com
pre_tasks:
- shell: echo 'hello'
roles:
- role1
- role2
tasks:
- shell: echo 'still busy'
post_tasks:
- shell: echo 'goodbye'
|Roles Overview |Roles in Playbooks |Role Creation |Ansible Galaxy|
- Ansible looks for roles in:
roles
subdirectory- Directories referenced by
roles_path
- Located in Ansible configuration file
- Contains list of directories to search
- Each role has directory with specially named subdirectories
- Use in Playbook
- To access role, reference it in roles: playbook section
- Example: Playbook referencing motd role
- No variables specified
- Role applied with default variable values:
[user@host ~]$ cat use-motd-role.yml
---
- name: use motd role playbook
hosts: remote.example.com
user: devops
become: true
roles:
- motd
|Roles Overview |Roles in Playbooks |Role Creation |Ansible Galaxy|
- https://galaxy.ansible.com
- Library of Ansible roles written by Ansible administrators and users
- Archive contains thousands of Ansible roles
- Database helps users identify helpful roles for accomplishing task
- Includes links to documentation and videos for users and developers
|Ansible Vault Overview |Encrypted Files |Playbooks |Python Cryptography |
- File Tasks
- To enable Ansible Vault, use ansible-vault
- Available file tasks:
- Create
- Encrypt
- View
- Edit
- Decrypt
|Ansible Vault Overview |Encrypted Files |Playbooks |Python Cryptography |
Creating a file
- To create encrypted file, use
ansible-vault create FILENAME
- Enter and confirm new vault password:
[student@demo ~]$ ansible-vault create secret.yml
New Vault password: redhat
Confirm New Vault password: redhat
- Default: File opens using vim editor
- To use different editor, set and import
EDITOR
- Example: To use nano editor, set nano:
export EDITOR=nano
- To use different editor, set and import
- Default encryption cipher: Advanced Encryption Standard (AES)
- Shared secret-based
Password File
- To enter password, can reference vault password file
- Replaces standard password input:
[student@demo ~]$ ansible-vault create --vault-password-file=vault-pass secret.yml
Encrypting a File
- To encrypt existing file, use
ansible-vault encrypt FILENAME
- To encrypt more than one file, enter file names as arguments:
[student@demo ~]$ ansible-vault encrypt secret1.yml secret2.yml
New Vault password: redhat
Confirm New Vault password: redhat
Encryption successful
- To save file with new name, use
--output=OUTPUT_FILE
- Available for encrypting single file only
Viewing an Encrypted File
To view file, use ansible-vault view FILENAME
:
[student@demo ~]$ ansible-vault view secret1.yml
Vault password: secret
less 458 (POSIX regular expressions)
Copyright (C) 1984-2012 Mark Nudelman
less comes with NO WARRANTY, to the extent permitted by law.
For information about the terms of redistribution,
see the file named README in the less distribution.
Homepage: http://www.greenwoodsoftware.com/less
my_secret: "yJJvPqhsiusmmPPZdnjndkdnYNDjdj782meUZcw"
- File not opened for editing
Editing an Encrypted File
- To edit file, use
ansible-vault edit FILENAME
:
[student@demo ~]$ ansible-vault edit secret.yml
Vault password: redhat
- Decrypts file to temporary file
- Edit temporary file and save changes
- Content copied to encrypted file
- Temporary file removed
Changing a File Password
- To change vault password, use
ansible-vault rekey FILENAME
- Enter original and new password:
[student@demo ~]$ ansible-vault rekey secret.yml
Vault password: redhat
New Vault password: RedHat
Confirm New Vault password: RedHat
Rekey successful
- Can rekey multiple files sharing same password
- Enter file names as arguments
- To use password file, supply file name to rekey
- To do so, use
--new-vault-password-file
Decrypting a File
- To decrypt file, use
ansible-vault decrypt FILENAME
:
[student@demo ~]$ ansible-vault decrypt secret1.yml --output=secret1-decrypted.yml
Vault password: redhat
Decryption successful
|Ansible Vault Overview |Encrypted Files |Playbooks |Python Cryptography |
- Playbook can use variables encrypted by Ansible Vault
- Variable types:
- Defined in group_vars or host_vars
- Loaded by include_vars or vars_files
- Passed on
ansible-playbook
with-e @file.yml
or-e @file.json
- Defined as role variables and defaults
- Playbook decrypted in memory while running
Variable Example
- To run such playbook, specify:
--ask-vault-pass
--vault-password-file:
[student@demo ~]$ ansible-playbook --ask-vault-pass site.yml
Password File
- Alternative: Provide file location to decrypt vault
- File stores password in plain text or using script
- Password is string stored as single line in file
- To provide file location, use
--vault-password-file=/path/to/vault-password-file
:
[student@demo ~]$ ansible-playbook --vault-password-file=vault-pass site.yml
- Other option: Set vault password file as environmental variable
- To do so, use
ANSIBLE_VAULT_PASSWORD_FILE=~/vault-pass
- To do so, use