Ansible Playbooks: Study Guide
Ansible Playbooks: Study Guide
Ansible Playbooks: Study Guide
Study Guide
Stosh Oldham
[email protected]
February 6, 2019
Contents
Playbook Basics 1
Using run_once . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
Playbook Basics
Using YAML for Ansible Playbooks
• The goal of this section is to cover YAML specifics with regard to Ansible Playbooks.
• Be sure to check out Linux Academy’s YAML Essentials course for greater detail on YAML.
• Best practice dictates that YAML files open with 3 hyphens, ---, and end with 3 periods, ..., as ob-
served below.
---
concentration: DevOps
# List of courses
courses:
- Ansible
- Openshift
- Configuration Management
- Containerized Application Development
...
• List members start with a single hyphen followed by a space. Each list item should be at the same
indentation level. See the course list above.
• Dictionaries are key value pairs that are designated with a colon and a space.
• Example:
• There are two characters that can be used to indicate a multi-line value: | or >
• Example:
ports: |
9001
9002
9003
• Is interpreted as follows:
9001
9002
9003
1
Ansible Playbooks Linux Academy
• Example:
Ports: >
9001
9002
9003
• When to Quote:
• If a colon ends a line or is followed by a space, the values should be wrapped in double quotes.
• Special characters meant to be literals and should always be wrapped in double quotes. YAML Special
characters are [ ] { } : > |
• It should be noted that variables in Ansible are an exception to the special character rule.
• As Ansible variables are indicated with curly braces, {{ variable }}, they must be wrapped in
double quotes to prevent interpretation as a dictionary.
• Example: port: "{{ web_port }}"
• Booleans are automatically converted in Ansible, thus allowing one to use yes, no, true, false, etc.
• This means if you want something like a literal “yes” or “false”, you must use double quotes.
• Writing a Playbook:
2
Ansible Playbooks Linux Academy
• remote_user — System user to execute the play (if not the current user).
• become — If yes, Ansible will escalate permission to the become_user using become_method.
• gather_facts — Whether or not facts should be gathered (default: yes).
• Example:
---
- hosts: webservers
become: yes
remote_user: ansible
gather_facts: yes
• This section contains a list of modules that will be executed against the target(s).
• Each task maps to the use of an Ansible module.
• Example:
---
- hosts: webservers
become: yes
remote_user: ansible
gather_facts: yes
tasks:
- name: ensure httpd is installed
package:
name: httpd
state: latest
• Best Practices:
3
Ansible Playbooks Linux Academy
• This command executes the playbook site.yml using the inventory stored in the file production.
• Notable options:
• -K — (note capital) Asks for the become password.
• -k — (note lowercase) Asks for the connect password.
• -C — Run in check mode which is an effective dry run of the provided playbook.
• Tasks are presented in list form (each list element starts with a hyphen -) beginning with the name
property.
• The name property is simply a plain English statement describing what the task does.
• If applicable, each argument that is provided to the module follows line by line in the format argument:
value.
• Example:
tasks:
- name: install elinks
package:
name: elinks
state: latest
• Best Practices:
4
Ansible Playbooks Linux Academy
• foobar
• foo_bar
• foo5
• foo-bar
• 1foobar
• foo.bar
• Example:
colors:
- red
- blue
- yellow
5
Ansible Playbooks Linux Academy
person:
name: sam
age: 4
favorite_color: green
• Playbook Example:
---
- hosts: webservers
become: yes
vars:
target_service: httpd
target_state: started
tasks:
- name: Ensure target service is at target state
service:
name: "{{ target_service }}"
state: "{{ target_state }}"
• It is good practice to wrap variable names or statements containing variable names in double quotes.
• Variables may also be stored in files and included using the vars_file directive.
# file: /home/ansible/web_vars.ini
target_service: httpd
target_state: started
• Example Playbook:
6
Ansible Playbooks Linux Academy
---
- hosts: webservers
become: yes
vars_files:
/home/ansible/web_vars.ini
tasks:
- name: Ensure target service is at target state
service:
name: "{{ target_service }}"
state: "{{ target_state }}"
- hosts: all
tasks:
- shell: cat /etc/motd
register: motd_contents
• Module parameters
• src — Template file to use.
• dest — Where the resulting file should be on the target host.
• validate — A command that will validate a file before deployment.
• Can also manipulate result file properties (owner, permissions, etc).
• Example:
---
- hosts: webservers
tasks:
- name: ensure apache is at the latest version
yum: name=httpd state=latest
7
Ansible Playbooks Linux Academy
• The filter parameter takes regex to allow you to prune fact output.
• The keyword gather_facts may be set in playbook to change fact gathering behavior.
- shell: /usr/bin/bar
when: foo_result.rc == 5
8
Ansible Playbooks Linux Academy
• Example:
• Example:
• Example:
9
Ansible Playbooks Linux Academy
• Example:
• The calls made in the notify section correspond to handler definitions within the play.
• A handler may be defined similarly to tasks:
• Example:
handlers:
- name: restart memcached
service:
name: memcached
state: restarted
listen: "restart cache service"
• By tagging a play or task, you may run a playbooks in such a way as to only run plays or tasks with a
particular tag.
• Example:
tasks:
- name: install software
yum:
name: "{{ item }}"
10
Ansible Playbooks Linux Academy
state: installed
loop:
- httpd
- memcached
tags:
- packages
• You specify which tags to run or not run via arguments to the ansible-playbook command.
• Run certain tag CLI syntax: ansible-playbook all playbook.yml --tags "pacakges"
• rekey to change the password of an already encrypted file: ansible-vault rekey <file>
• encrypt_string will encrypt a string: ansible-vault encrypt_string 'encrypted text goes here'
• The primary use case for vaults is for encrypting variable files to protect sensitive information such
as passwords.
• It is also possible to encrypt task files or even arbitrary files such as binaries if desired.
• The ansible-vault password file is simply a file that contains a password. There is no special format-
ting.
• The recommended way to provide a vault password from the CLI is to use --vault-id.
• --vault-id may be passed a vault file or a prompt flag (–vault-id@prompt) to collect credentials
to unencrypt a target vault.
• Prior to –vault-id, Ansible could only take a single vault password for a playbook.
11
Ansible Playbooks Linux Academy
• Multiple Vault IDs may be provided and Ansible will try each sequentially to unencrypt as needed.
• Vault IDs also allow for the application of labels to encrypted strings.
• Example:
• ansible-vault encrypt_string --vault-id test@my-vault-file 'some secret text' > file.txt
• The label ‘test’ is applied using the password from the vault file my-vault-file.
• In order for Ansible to use the vault-id during playbook execution you must pass --vault-id
test@my-vault-file with the ansible-playbook command.
• Example:
• Let us say you have a playbook called site.yml that makes use of the vault file.txt.
• In order for Ansible to access the file.txt vault, you must specify the password file for the
vault using the correct vault id.
• Run: ansible-playbook --vault-id test@my-vault-file site.yml
• Using this command, Ansible will try the password from my-vault-file on any string labeled
with ‘test’ before trying any other passwords or vault files.
• You may also specify @prompt instead of label@password_file to have Ansible prompt for the
password.
• Labels are not strictly required.
• You may use only a password file.
• Generally, this is not ideal but may have niche use cases.
• Note: Password files may also be executable (such as a python script).
• Note: when debugging plays, it is possible that sensitive information may be displayed in verbose
logs.
• You can set no_log for a module to censor log output to avoid accidentally exposing sensitive
information during play execution.
• When set for a task, playbooks will not halt on that task failing.
12
Ansible Playbooks Linux Academy
- debug:
msg: "System {{ inventory_hostname }} has uuid {{ ansible_product_uuid }}"
• Error handling may also be dealt with using block groups in Ansible.
tasks:
- name: Attempt and gracefully roll back demo
block:
- debug:
msg: 'I execute normally'
13
Ansible Playbooks Linux Academy
- command: /bin/false
- debug:
msg: 'I never execute, due to the above task failing'
rescue:
- debug:
msg: 'I caught an error'
- command: /bin/false
- debug:
msg: 'I also never execute :-('
always:
- debug:
msg: "this always executes"
• By default, all playbook block tasks ran against a single host use a single SSH session.
• Ansible provides the async feature to allow an operation to run asynchronously such that the
status may be checked.
• This can prevent interruption from SSH timeouts for long running operations.
• You may configure a few key values for an asynchronous task:
• A timeout for an operation (default is unlimited).
• A poll value for who often Ansible should check back.
• Note: A poll value of 0 will have Ansible not check back on a task.
• Example:
14
Ansible Playbooks Linux Academy
- hosts: webservers
tasks:
- name: take out of load balancer pool
command: /usr/bin/take_out_of_pool {{ inventory_hostname }}
delegate_to: 127.0.0.1
• In the example, the task, ‘take out of load balancer pool’, would be ran specifically on 127.0.0.1 an
no other host in webservers.
• You may also use DNS names over IP addresses if preferred.
• Delegating to localhost may also be expressed in shorthand using local_action: <module_name>
[arg1=val1] ... [argN=valN] for a given task.
• Parallelism in playbooks:
15
Ansible Playbooks Linux Academy
Using run_once
• There are scenarios where a specific task needs to be ran only a single time in a given playbook and
not on each host.
• Example:
• This may be leveraged with delegate_to for greater control over which host executes the command.
• It should also be noted that when used with serial that run_once will execute for each serial batch.
base_directory/
<role 1>
tasks/
handlers/
files/
tempaltes/
vars/
defaults/
meta
<role 2>
tasks/
defaults/
meta/
16
Ansible Playbooks Linux Academy
• With the exception of templates and files, each directory must include a main.yml if that directory is
being used.
• Files in the tasks, templates, and files directories may be referenced without path within the role.
---
- hosts: webservers
roles:
- common
- role: foo_app_instance
vars:
dir: '/opt/a'
app_port: 5000
- role: foo_app_instance
vars:
dir: '/opt/b'
app_port: 5001
• When a role is called in a playbook, Ansible looks for the role definition in ${PWD}/roles/<role_name>
• If ${PWD}/roles does not contain the sought role, then /etc/ansible/roles is checked.
• The default role location may be changed in ansible.cfg.
• The full path to a role may also be specified with the role keyword to use a non-default path.
• Example:
---
- hosts: webservers
roles:
- role: '/path/to/my/roles/common'
• A role with a given set of parameters will only be applied once even if called multiple times in a
play.
• If a role is called with different parameters, it will be ran again.
• A role may have allow_duplicates: true defined in meta/main.yml within the role.
• This will also allow the role to be applied more than once.
• Roles may have dependent roles defined in meta/main.yml using the dependencies keyword.
• Parameters may also be included in the dependency list.
• Dependent roles are applied prior to the role dependent on them.
17
Ansible Playbooks Linux Academy
• There are three primary ways (aside from conventional variable use such as inventory) to inter-
act with variables within a role: vars directory, defaults directory, and parameters.
• Each way has a different level of precedence.
• The vars directory defined within the role has the highest level of precedence. (it will override
inventory variables as well)
• The defaults directory has the lowest level of precedents and provides a ‘default’ value.
• Parameters are passed inline to the role and sit between vars and defaults in terms of prece-
dents.
• Example of passing a parameter
roles:
- role: apache
vars:
http_port: 8080
18