In this post, we are going to see examples of Ansible playbook and various different modules and playbook examples with various modules and multiple hosts. We will start with a basic Ansible playbook and learn what is task and play and what is playbook etc.
What is Ansible Playbook
It is a metaphor representing the configuration files of Ansible. It contains a list of tasks (plays) in an order they should get executed against a set of hosts or a single host based on the configuration specified. Playbooks are written in YAML, in an easy human-readable syntax
You can consider ansible ad-hoc commands as shell commands and a playbook as a shell script.
In this Shell script analogy, many shell commands put together in the form of shell script to perform a set of tasks and they also give us benefits like conditional statements, loops, functions etc.
Likewise, Ansible Playbooks are a group of ad-hoc commands with additional programming elements like loops, iterations, conditionals etc.
Before writing a Playbook It is recommended that you have given a glance on the Ansible AD HOC Command how it works and how to execute them. You can read about Ansible AD HOC Command here
Simply put, If Ansible modules are the tools in your workshop, playbooks are your instruction manuals, and your inventory of hosts are your raw material.
If ansible ad hoc is suitable for quick and single task (or) Purpose, ansible playbooks are ideal for projects and automation.
In a single playbook, you can see multiple modules and handlers are organized. In other words, this is called as Orchestration.
As an example. Let us consider you want to install an Apache Web server against multiple hosts. The following playbook would get it done for you.
Ansible Playbook Example
---
- name: Playbook
hosts: webservers
become: yes
become_user: root
tasks:
- name: ensure apache is at the latest version
yum:
name: httpd
state: latest
- name: ensure apache is running
service:
name: httpd
state: started
this simple ansible-playbook example given above is enough to get your Apache installation done and ready. I sense your anger that I just gave a plain text with no explanation of what do they do.
Well, I have explained what each line does
name
Name of the playbook
hosts
A set of hosts usually grouped together as a host group and defined in inventory file
become
To tell ansible this play has to be executed with elevated privileges
become_user
the user name that we want to switch to like compare it with sudo su - user
tasks
set of tasks to execute, All tasks would be defined below this
and then we have two tasks with two modules, the first module is yum
and the second module is service
in the first task with yum the state latest
represents that the forementioned package httpd
should be installed if it is not installed (or) if it is already installed it should be upgraded to the latest version available. If you do not want it to be upgraded if present, You can change it to state: present
On the Second task with service module, we are making sure that the service named httpd
is started and running using the state: started
Ansible would not restart the service if it is already started and running.
Ansible Play vs Ansible Playbook?
To understand the ansible-playbook you have to understand the Ansible Adhoc commands.
Ad hoc commands can run a single, simple task against a set of targeted hosts as a one-time command. The real power of Ansible, however, is in learning how to use playbooks to run multiple, complex tasks against a set of targeted hosts in an easily repeatable manner.
Here is something to take away
A play is an ordered set of tasks which should be run against hosts selected from your inventory.
A playbook is a text file that contains a list of one or more plays to run in order.
In the previously given example, you can see we are running all the tasks against a single host group named webservers
this is called A PLAY.
If I want to run a different set of tasks against different host group. All you need to do is add one more PLAY.
Remember: A Playbook can have many plays destined to run against a different set of host groups
Every Play must contain
- A set of hosts to configure
- A list of tasks to be executed on those hosts
Think of a play as a wire that connects hosts to tasks.
Example Ansible Playbook with multiple hosts and multiple plays.
Here is the ansible playbook with multiple hosts in it. You can see we are working with web and application servers in the same playbook and executing two different plays (set of tasks) respectively.
---
# Play1 - WebServer related tasks
- name: Play Web - Create apache directories and username in web servers
hosts: webservers
become: yes
become_user: root
tasks:
- name: create username apacheadm
user:
name: apacheadm
group: users,admin
shell: /bin/bash
home: /home/weblogic
- name: install httpd
yum:
name: httpd
state: installed
# Play2 - Application Server related tasks
- name: Play app - Create tomcat directories and username in app servers
hosts: appservers
become: yes
become_user: root
tasks:
- name: Create a username for tomcat
user:
name: tomcatadm
group: users
shell: /bin/bash
home: /home/tomcat
- name: create a directory for apache tomcat
file:
path: /opt/oracle
owner: tomcatadm
group: users
state: present
mode: 0755
In the preceding playbook, you could notice that two plays are there and both of them targeted to different host groups.
How to Execute an Ansible Playbook
Ansible playbook can be executed with ansible-playbook
command. like you have ansible
command to execute ad hoc command. This is dedicated for ansible playbooks
Let us see how to execute the preceding playbook and install apache on the webservers
host group
Note*: a host group is a group of hosts and servers mentioned in the ansible inventory file.
➜ Ansible-Examples git:(master) ✗ cat ansible_hosts [webservers] mwivmweb01 mwivmweb02
Here is the customized Ansible inventory file with two hosts grouped as webservers
Here the host group name is webservers
and it is mentioned in the hosts:
directive on the playbook
Given below is the command syntax or sample to run an ansible playbook.
➜ ansible-playbook sampleplaybook.yml -i ansible_hosts
If you have mentioned all the host groups in your default inventory file /etc/ansible/hosts
then you do not have use -i
argument. this is only when you have a customized inventory file like I do.
See this video log for further information on how to execute the playbook in real-time.
How to Dry Run the playbook without making Actual Changes
you can actually run the playbook with Dry Run feature to see what changes would be made to the server without having to perform the actual changes.
to do that. you just have to add -C
to your ansible-playbook startup command
➜ ansible-playbook -C sampleplaybook.yml -i ansible_hosts
How to Perform a Syntax Check on the Playbook
If you quickly want to verify if everything is ok with the playbook. You can perform a Syntax check.
Here is the ansible command line example on how to perform Syntax check on ansible playbook. Refer the video for the practical idea.
➜ ansible-playbook – syntax-check sampleplaybook.yml -i ansible_hosts
How to use Variables in Ansible Playbook
Ansible playbook supports defining the variable in two forms, Either as a separate file with full of variables and values like a properties file. or a Single liner variable declaration like we do in any common programming languages
vars
to define inline variables within the playbook
vars_files
to import files with variables
Let's suppose we want to add a few variables for our webserver like the server name and SSL key file and cert file etc.
it can be done with vars
like this
---
- name: Playbook
hosts: webservers
become: yes
become_user: root
vars:
key_file: /etc/apache2/ssl/mywebsite.key
cert_file: /etc/apache2/ssl/mywebsite.cert
server_name: www.mywebsite.com
tasks:
- name: ensure apache is at the latest version
yum:
name: httpd
state: latest
### SOME MORE TASKS WOULD COME HERE ###
# you can refer the variable you have defined earlier like this #
# "{{key_file}}" (or) "{{cert_file}}" (or) "{{server_name}}" #
##
- name: ensure apache is running
service:
name: httpd
state: started
and the variables can be referred with the jinja2 template later"{{ variable name }}"
If you want to keep the variables in a separate file and import it with vars_files
You have to first save the variables and values in the same format you have written in the playbook and the file can later be imported using vars_files like this
---
- name: Playbook
hosts: webservers
become: yes
become_user: root
vars_files:
- apacheconf.yml
tasks:
- name: ensure apache is at the latest version
yum:
name: httpd
state: latest
### SOME MORE TASKS WOULD COME HERE ###
# you can refer the variable you have defined earlier like this #
# "{{key_file}}" (or) "{{cert_file}}" (or) "{{server_name}}" #
##
- name: ensure apache is running
service:
name: httpd
state: started
the content of the apacheconf.yml
would like like this
key_file: /etc/apache2/ssl/mywebsite.key
cert_file: /etc/apache2/ssl/mywebsite.cert
server_name: www.mywebsite.com
to keep things cleaner and to keep your playbook simple, It is recommended to use separate variable files and when you are creating ansible roles, you would have to use the variable files more than defining it inline.
Example Ansible Playbook to Setup LAMP stack
Linux Apache Mysql/MariaDB PHP is shortly called as LAMP stack and it powers most of the internet websites including Facebook.
So let us look at a Sample Ansible Playbook to install LAMP stack with necessary packages and tools.
So what are going to do in this playbook
- Connect to Remote host and execute the following tasks
- Install all necessary packages like Apache(httpd), mariadb, php
- Installing a firewall and enabling HTTP services
- Start the Apache HTTPD web server.
- Start the MariaDB server
- Download a Sample PHP page from remote URL
- Access the website we have built by accessng the URL
Here is the Ansible Playbook example to setup LAMP Stack
---
- name: Setting up LAMP Website
user: vagrant
hosts: testserver
become: yes
tasks:
- name: latest version of all required packages installed
yum:
name:
- firewalld
- httpd
- mariadb-server
- php
- php-mysql
state: latest
- name: firewalld enabled and running
service:
name: firewalld
enabled: true
state: started
- name: firewalld permits http service
firewalld:
service: http
permanent: true
state: enabled
immediate: yes
- name: Copy mime.types file
copy:
src: /etc/mime.types
dest: /etc/httpd/conf/mime.types
remote_src: yes
- name: httpd enabled and running
service:
name: httpd
enabled: true
state: started
- name: mariadb enabled and running
service:
name: mariadb
enabled: true
state: started
- name: copy the php page from remote using get_url
get_url:
url: "https://www.middlewareinventory.com/index.php"
dest: /var/www/html/index.php
mode: 0644
- name: test the webpage/website we have setup
uri:
url: http://{{ansible_hostname}}/index.php
status_code: 200
Ansible playbook Examples - Sample Ansible Playbooks
I have written various Ansible playbooks and I have listed most of them here for your easy access. these articles would have a lot of playbook examples specific to modules and to a single topic.
-
Archive module examples - Ansible
-
Ansible Unarchive module examples
-
Shell module examples
-
Ansible Copy module examples
-
Ansible + Vagrant Playbook for provisioning Apache
-
Ansible Copy SSH Keys between remote servers example
-
How to copy files between remote hosts with ansible
-
Ansible changed_when and failed_when in playbook
-
Ansible Command Module Playbook examples
-
How to use GIT with Ansible playbook
-
Template module examples - Ansible
-
Lookup module examples - Ansible
-
How to read and process JSON file with ansible example
-
Ansible apt module examples
-
Ansible Find module examples
-
How to Process JSON Data with JSON_Query ansible
-
Ansible AWS EC2 Example playbook
-
Ansible async Poll examples
-
How to download file from URL with ansible playbook
-
Ansible lineinfile - How to add, replace, update line in file with ansible
-
Ansible replace module - how to replace texts in ansible
-
How to wait_for task to be completed in playbook example
-
Add users to EC2 instances with SSH Access – Ansible automated
-
Weblogic JMS Queue Creation with Ansible and WLST
-
Ansible inventory_hostname and ansible_hostname example playbook
-
Ansible FirewallD Example Playbook
-
Ansible How to connect using Bastion host
-
Ansible Playbook to find EC2 instances using EFS file system
-
Ansible Playbook to Delete OLD log files in Windows - Ansible Windows
-
Playbook to Find and Replace Default HTML in IIS - Ansible Windows
-
Ansible Windows Example - How to use Ansible with Windows
-
Ansible Select Attr Example - How to Filter Dictionary and Select Items
-
Ansible Map Function Examples - How to Filter List and Dictionaries
-
Ansible Split Function Examples - With String, List and Dictionary
-
Ansible S3 module Examples - How to use ansible aws_s3 module
-
Ansible Copy files Local to Remote
-
Ansible PRE tasks and POST Tasks Introduction and Examples
-
Ansible List Examples - How to create and append items to list
-
Ansible playbook to install KAFKA On Ubuntu
-
Ansible Slack example - How to send Slack notifications from Ansible
-
Ansible Retry example - How to retry an ansible task until the Condition is met
-
Find multiple files with patterns and replace them with Ansible
-
Playbook to install Apache Tomcat
-
How to wait for URL to respond with Ansible URI - Web and API automation
-
Ansible URI module examples - for Web and API automation
Conclusion
I hope this article gave you some solid base on what is Ansible playbook and I know you might still have questions. the best way to learn is to explore and practice. So keep writing many playbooks and you can share it with us in the comments or send them to me.
If you want your Playbook to be shared with the world consider uploading it to Ansible Galaxy
If you want your playbook to be published here in DevopsJunction. Share it with us over email or by comment.
Keep Learning.
Cheers,
Sarav AK
Follow me on Linkedin My Profile Follow DevopsJunction onFacebook orTwitter For more practical videos and tutorials. Subscribe to our channel
Signup for Exclusive "Subscriber-only" Content