How to use playbook on Ansible
Ansible Playbook - what is it and why its amazing ?
Working with Ansible , you can use Ad-Hoc commands if you want to automate simple task or you will use playbook and roles if you want to automate more complex tasks or series of tasks and keep a certain degree of organization.
Ansible playbook is the ansible orchestration language in Ansible that we will define what we want to do and which state we want on our servers.
A playbook is the term that Ansible uses for a configuration management script.
Basically, it will be a set on instruction we want Ansible to achieve on our servers using the Ansible Module.
There are thousands of modules already present.
It can be simple or very complex. Today, as it’s an brief introduction, we will focus on a simple playbook to change settings of Proxy on our Linux Servers.
Before making our first playbook, let’s focus on the theory.
PLAYBOOK YAML file format
Ansible is using YAML file format.
YAML is a file format easier for humans to read and write, like JSON.
A YAML syntax needs to follow the correct indentation and one needs to be a little careful while writing the syntax. I will recommend you to use YAML IDE or any extension/plugins on your favorite IDE to work with YAML file.
💡 I’m using Visual Studio Code with these extensions or directly Vim but Visual Studio code is free and really good and useful.
- YAML Support by Red Hat - provides YAML support through yaml-language-server with built-in Kubernetes and Kedge syntax support.
- Ansible Syntax Highlighting Extension - YAML & Jinja2 support.
- Visual Studio Code extension for Ansible - provides autocompletion, syntax highlighting.
- The remote SSH extension remote-ssh
You can have a look on this page for further information on best tools and applications to use with Ansible : Ansible Editors
Comments start with a number sign ‘#’ like a lot of programming language as bash, python.
# this is a beautiful comment
⚠️ YAML does not support multi line comments.
Strings and thus paramaters can be quoted or not, it’s not mandatory but I always prefer to do as it’s mandatory in some scenarios like using the {{ braces }} for variables substitution.
- name: "super playbook"
# without quote
- name: second playbook super
debug:
msg: "{{ variable }}"
Booleans are very flexible on Ansible and you can use booleans as below :
- True, true, TRUE, yes, Yes, YES, y, Y, on, On, ON
- False, false, FALSE, No, no, NO, n, N, off, Off, OFF
Module arguments are passed as strings and use Ansible internal conventions, which are:
- yes, on, 1, true
- no, off, 0, false
Ex: YAML Format
---
- name: Update postinstall.sh on template
gather_facts: True
become: True
hosts: template
tasks:
- name: Replace postinstall on /usr/local/bin/
copy:
src: /etc/ansible/playbook/files/PostInstall.sh
dest: /usr/local/bin/PostInstall.sh
backup: yes
validate: ls %s
🔥 I’m trying to follow the ansible convention and use True or False on the playbook and yes and no on module arguments.
Lists in YAML are like arrays in Python, they are delimited with ‘-’ , but you can use as well inline format for lists
---
### Inline list
win_updates_category_names: ['CriticalUpdates', 'SecurityUpdates', 'UpdateRollups', 'FeaturePacks', 'DeveloperKits','Connectors' ]
### lists
win_updates_category_names:
- CriticalUpdates
- SecurityUpdates
- UpdateRollups
Dictionaries are like Dictionaries in python key:value. Playbook are using keyword to configure play and task, or roles and they are mostly Dictionaries.
---
- name: Update postinstall.sh on template
gather_facts: True
become: True
hosts: template
Now that we know more about YAML, let’s focus on the playbook itself and the relation between each entity, play, tasks and hosts.
Terminology of Ansible Playbook
Playbook is a single YAML File ( extension .yml ) and is the script containing one or more play or roles.
Play - Define a set of tasks/instruction to be run on hosts - it’s the link between the tasks and the hosts.
Task - An action to be play on the host using one module - Execute a command - Install a Package - Change a file - Create user and group - And so on…
Let’s see each of them more deeply…
The Playbook
A playbook is a list of plays or roles.
It can contains one or more plays or roles or an import of list of plays from another playbook using the keyword ‘import_playbook’.
It’s the only thing which can be run by the Ansible command : ansible-playbook
The Play
The function of a play is to map a set of tasks defined against a particular host or a group of hosts.
The play always contains :
- a host or a group of hosts, it can be a hostname, all, ungrouped or group name. These are set with the keyword : hosts
- a list of tasks which will use module to be executed on each host. The task are configured using tasks block or a list of roles to be imported. The roles will be cover on the article.
And recommended :
- a name to describe the usage of the play
Optionally few parameters/keyword Ansible play keyword
Few most commons keyword are by example :
# use adhoc command setup to get facts of the hosts
gather_facts: True|False
# to become sudo
become: True|False
# block to define variable
vars:
- user: "superman"
- ntpserver "ntp.superdns.com"
# Location of file where variables are defined
vars_files:
# list of variables to prompt for.
vars_prompt
# list of tags
tags:
- install
# to Enforce check mode ( Dry-run )
check_mode: True
The Tasks
A task is an action, a call to an ansible module. This tasks doesn’t know alone on which hosts it is supposed to run.
Every task must contain a key with the name of a module and a value with the arguments to that module.
The list of tasks should start on the play by the keyword : tasks
Let’s see what we’ve just learn in a playbook which will change proxy for Redhat based and Linux Vms :
The Playbook will contains 2 plays, one play for RedHat Hosts and one play for Debian Hosts
Our Inventory file is a below :
vim servertest.cfg
[redhat]
mt-ce-medcre[6:7]
mt-ce7-repo1
[debian]
mt-ub-graf1
mt-ub-postfix
---
# This is a play and the description
- name: Update proxy for redhat
gather_facts: True
become: True
hosts: redhat
vars:
- oldproxy: ["10.89.20.30", "super-proxy.vodafone.com"]
- newproxy: "amazing-proxy.vodafone.mt"
tasks:
# this is a task
- name: gathering distribution facts
# this is a module
debug:
msg: System {{ inventory_hostname }} - {{ ansible_os_family }} - {{ ansible_distribution }} - {{ansible_distribution_major_version }}
# this is another task
- name: get dns information
# this is another module
shell: cat /etc/resolv.conf
register: dns
- name: print DNS information
debug: msg={{ dns.stdout_lines }}
- name: "Change Proxy settings for redhat vms"
replace:
dest: /etc/yum.conf
regexp: '{{ item }}'
replace: '{{ newproxy }}'
backup: yes
with_items:
- "{{ oldproxy }}"
- name: Update proxy for debian
gather_facts: true
become: yes
hosts: debian
vars:
- oldproxy: ["10.89.20.30", "super-proxy.vodafone.com"]
- newproxy: "amazing-proxy.vodafone.mt"
tasks:
- name: gathering distribution facts
debug:
msg: System {{ inventory_hostname }} - {{ ansible_os_family }} - {{ ansible_distribution }} - {{ansible_distribution_major_version }}
- name: get dns information
shell: cat /etc/resolv.conf
register: dns
- name: print DNS information
debug: msg={{ dns.stdout_lines }}
- name: "Change Proxy settings for Ubuntu vms"
replace:
dest: /etc/apt/apt.conf
regexp: '{{ item }}'
replace: '{{ newproxy }}'
backup: yes
with_items:
- "{{ oldproxy }}"
Something important to notice is that each play are link with different hosts groups as the package manager is different if it’s debian or redhat based machines ( by default, apt and yum package manager ).
Let’s launch this playbook and change the proxy use by the package manager of our Vms.
ansible-playbook updateproxypackagemanager.yml -i servertest.cfg
Then, you will see the result/state of each tasks and finally the result of the recap :
< PLAY RECAP >
------------
\ ^__^
\ (oo)\_______
(__)\ )\/\
||----w |
|| ||
mt-ce-medcre6 : ok=5 changed=2 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
mt-ce-medcre7 : ok=5 changed=2 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
mt-ce7-repo1 : ok=5 changed=2 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
mt-ub-graf1 : ok=5 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
mt-ub-postfix : ok=5 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
This end our article about the Playbook. Next time, we will speak about roles and notify/handlers.
< It is the end until the next episode... >
------------
\ ^__^
\ (- -)\_______
(__)\ )\/\
||---- w |
|| ||