Pawel Krupa (@paulfantom)
Ansible is capable of handling many powerful automation tasks with the flexibility to adapt to many environments and workflows. With Ansible, users can very quickly get up and running to do real work.
It's a simple automation language that can perfectly describe an IT application infrastructure in Ansible Playbooks.
It's an automation engine that runs Ansible Playbooks.
Ansible Tower is an enterprise framework for controlling, securing and managing your Ansible automation with a UI and RESTful API.
CROSS PLATFORM – Linux, Windows, UNIX Agentless support for all major OS variants, physical, virtual, cloud and network
HUMAN READABLE – YAML Perfectly describe and document every aspect of your application environment
PERFECT DESCRIPTION OF APPLICATION Every change can be made by playbooks, ensuring everyone is on the same page
VERSION CONTROLLED Playbooks are plain-text. Treat them like code in your existing version control.
DYNAMIC INVENTORIES Capture all the servers 100% of the time, regardless of infrastructure, location, etc.
ORCHESTRATION THAT PLAYS WELL WITH OTHERS – HP SA, Puppet, Jenkins, RHNSS, etc. Homogenize existing environments by leveraging current toolsets and update mechanisms.
COMMUNICATION IS THE KEY TO DEVOPS.
Ansible is the first automation language
that can be read and written across IT.
Ansible is the only automation engine
that can automate the entire application lifecycle
and continuous delivery pipeline.
Ansible comes bundled with hundreds of modules for a wide variety of automation tasks
THE MOST POPULAR OPEN-SOURCE AUTOMATION COMMUNITY ON GITHUB
http://ansible.com/community
# the most common and preferred way of
# installation
$ sudo pip install ansible
# you will need the EPEL repo configured on
# CentOS, RHEL, or Scientific Linux
$ sudo yum install ansible
# you will need the PPA repo configured on
# Debian or Ubuntu
$ sudo apt-get install ansible
Modules are bits of code transferred to the target system and executed to satisfy the task declaration.
http://docs.ansible.com/
# List out all modules installed
$ ansible-doc -l
...
copy
cron
...
# Read documentation for installed module
$ ansible-doc copy
> COPY
The [copy] module copies a file on the local box to remote locations. Use the [fetch] module to copy files from remote locations to the local
box. If you need variable interpolation in copied files, use the [template] module.
* note: This module has a corresponding action plugin.
Options (= is mandatory):
...
If Ansible doesn’t have a module that suits your needs there are the “run command” modules:
/bin/sh
so you can use pipes etc. Be careful.
NOTE: Unlike standard modules, run commands have no concept of desired state and should only be used as a last resort.
Inventory is a collection of hosts (nodes) with associated data and groupings that Ansible can connect and manage.
10.42.0.2
10.42.0.6
10.42.0.7
10.42.0.8
10.42.0.100
host.example.com
[control]
control ansible_host=10.42.0.2
[web]
node-[1:3] ansible_host=10.42.0.[6:8]
[haproxy]
haproxy ansible_host=10.42.0.100
[all:vars]
ansible_user=vagrant
ansible_ssh_private_key_file=~/.vagrant.d/insecure_private_key
An ad-hoc command is a single Ansible task to perform quickly, but don’t want to save for later.
# check all my inventory hosts are ready to be
# managed by Ansible
$ ansible all -m ping
# collect and display the discovered facts
# for the localhost
$ ansible localhost -m setup
# run the uptime command on all hosts in the
# web group
$ ansible web -m command -a "uptime"
Facts are bits of information derived from examining a host systems that are stored as variables for later use in a play.
$ ansible localhost -m setup
localhost | success >> {
"ansible_facts": {
"ansible_default_ipv4": {
"address": "192.168.1.37",
"alias": "wlan0",
"gateway": "192.168.1.1",
"interface": "wlan0",
"macaddress": "c4:85:08:3b:a9:16",
"mtu": 1500,
"netmask": "255.255.255.0",
"network": "192.168.1.0",
"type": "ether"
},
Ansible can work with metadata from various sources and manage their context in the form of variables.
The order in which the same variable from different sources will override each other.
Tasks are the application of a module to perform a specific unit of work.
tasks:
- name: httpd package is present
yum:
name: httpd
state: latest
- name: latest index.html file is present
copy:
src: files/index.html
dest: /var/www/html/
- name: restart httpd
service:
name: httpd
state: restarted
This example shows the task list of an Ansible playbook.
Handlers are special tasks that run at the end of a play if notified by another task when a change occurs.
If a configuration file gets changed notify a service restart task that it needs to run.
Normal tasks run sequentially; handler tasks run on notification of a change and will only run once at the end of a play.
For more information see Handler Tasks.
tasks:
- name: httpd package is present
yum:
name: httpd
state: latest
notify: restart httpd
- name: latest index.html file is present
copy:
src: files/index.html
dest: /var/www/html/
handlers:
- name: restart httpd
service:
name: httpd
state: restarted
Here is our previous example with a few slight modifications that have bene highlighted.
In this version of our example, we add a notify
keyword to the first task to trigger a handler task if it returns "changed" as being true. The third tasks now is under a "handlers" section that signifies that the handler task will run on notification at the end of the play of change occurs during the first task.
Plays are ordered sets of tasks to execute against host selections from your inventory. A playbook is a file containing one or more plays.
Playbooks are text files that contain one or more plays that are expressed in YAML. A play defines target hosts and a task list that are executed sequentially (i.e top to bottom) to achieve a certain state on those hosts.
For more details see the Playbook page in the Ansible documenation.
---
- name: install and start apache
hosts: web
become: yes
vars:
http_port: 80
tasks:
- name: httpd package is present
yum:
name: httpd
state: latest
- name: latest index.html file is present
copy:
src: files/index.html
dest: /var/www/html/
- name: httpd is started
service:
name: httpd
state: started
Here we can see an example of a simple but complete Ansible play. The slides that follow will explore each of these parts and what they do.
---
- name: install and start apache
hosts: web
become: yes
vars:
http_port: 80
tasks:
- name: httpd package is present
yum:
name: httpd
state: latest
- name: latest index.html file is present
copy:
src: files/index.html
dest: /var/www/html/
- name: httpd is started
service:
name: httpd
state: started
Every play and each task in it can be assigned a name that describes its objective in the automation workflow and is output during execution.
It's best practice to always name your plays and tasks. Adding name with a human-meaningful description better communicates the intent to users when running a play.
---
- name: install and start apache
hosts: web
become: yes
vars:
http_port: 80
tasks:
- name: httpd package is present
yum:
name: httpd
state: latest
- name: latest index.html file is present
copy:
src: files/index.html
dest: /var/www/html/
- name: httpd is started
service:
name: httpd
state: started
The Ansible play host selector defines which nodes in the inventory the automation is targetting.
In this example, a single group of "web" is being targetted. Ansible supports targetting intersections, unions and filters of multiple groups or hosts though.
For more details see the host selector Patterns page in the Ansible documenation.
---
- name: install and start apache
hosts: web
become: yes
vars:
http_port: 80
tasks:
- name: httpd package is present
yum:
name: httpd
state: latest
- name: latest index.html file is present
copy:
src: files/index.html
dest: /var/www/html/
- name: httpd is started
service:
name: httpd
state: started
Ansible allows you to "become" another user or with elevated rights to execute a task or an entire play (shown above). This is done using existing privilege escalation tools, which you probably already use or have configured, like sudo (the default), su, pfexec, doas, pbrun, dzdo, ksu and others.
For more details see the Privilege Escalation page in the Ansible documenation.
---
- name: install and start apache
hosts: web
become: yes
vars:
http_port: 80
tasks:
- name: httpd package is present
yum:
name: httpd
state: latest
- name: latest index.html file is present
copy:
src: files/index.html
dest: /var/www/html/
- name: httpd is started
service:
name: httpd
state: started
Variables are used to store metadata for each host drawing from numerous sources. Here we see another one of those sources, a variable "http_port" that has been embedded in a play.
Recalling the previous variable precedence slide, play variables are number 7 in Ansible's the precedence chain.
---
- name: install and start apache
hosts: web
become: yes
vars:
http_port: 80
tasks:
- name: latest httpd package is present
yum:
name: httpd
state: latest
- name: latest index.html file is present
copy:
src: files/index.html
dest: /var/www/html/
- name: httpd is started
service:
name: httpd
state: started
Here we see modules, such as yum, being applied to a to perform a unit of automation such as to assure the latest httpd package is present on a host.
To demonstrate how an Ansible, open an SSH session to your control host and run the playbook in examples/apache-simple-playbook
. That example playbook is essentially the same one we just examined.
Don't forget to reverse what this playbook does before continuing to not interfere with later demos and workshops.
This assignment provides a quick introduction to playbook structure to give them a feel for how Ansible works, but in pratice is too simplistic to be useful.
See workshops/simple_playbook
in the Ansible Lightbulb repo.
Note: If your time is limited, this is a workshop you can skip. We'll cover this and more topics in the next workshop.
Here are some more essential playbook features that you can apply:
We only have covered the most essential capabiltites of what can be done with a playbook so far.
Here we list a few more though this is still far from all there is. There's many other powerful playbook features for handling less common though vital automation workflows. No need to learn everything at once. You can start small and pick up more features over time as you need them.
Ansible embeds the Jinja2 templating engine that can be used to dynamically:
Templates are a vital feature provided by the Jinja2 template engine, a powerful piece of software independent of Ansible. Ansible makes this usage as seamless and transparent as possible. Most will not realize they are doing templating when they develop plays with Ansible.
We don't show any specific template examples at the moment because we'll have plenty of opportunity to see templates in action as we cover other topics.
In all actuality, what is covered here only touches upon a few of its most basic features. To go deeper see these docs:
Loops can do one task on multiple things, such as create a lot of users, install a lot of packages, or repeat a polling step until a certain result is reached.
- yum:
name: "{{ item }}"
state: latest
with_items:
- httpd
- mod_wsgi
This example demonstrates a basic loop with with_items
. The loop sets a variable called "item", a template variable courtesy of the embedded Jinja2 template engine, with the list value that is in context.
There are many different and specialized types of task loops to work with. See the Loops documentation to go deeper.
Ansible supports the conditional execution of a task based on the run-time evaluation of variable, fact, or previous task result.
- yum:
name: httpd
state: latest
when: ansible_os_family == "RedHat"
Conditionals are another instance of Jinja2 in action within Ansible plays themselves. In the provided example "ansible_os_family" is a fact variable Ansible will set.
There are other forms of conditional clauses, but when
is usually all that is needed.
NOTE: Conditional clauses are consdered to be raw Jinja2 expression without double curly braces.
Tags are useful to be able to run a subset of a playbook on-demand.
- yum:
name: "{{ item }}"
state: latest
with_items:
- httpd
- mod_wsgi
tags:
- packages
- template:
src: templates/httpd.conf.j2
dest: /etc/httpd/conf/httpd.conf
tags:
- configuration
In the provided example, if the playbook were run with --tags "packages"
the yum task would execute and the template task would be skipped. If the playbook were run with --tags "configuration"
the opposite would happen. Without a --tags
both tasks would execute like normal.
Tags can be seen as a simple though specialized form of conditional statement designed to enable the execution of a subset tasks. Tags are a bit more than simple boolean flags though. To dig deeper see the playbook Tags documentation.
Blocks cut down on reptitive task directives, allow for logical grouping of tasks and even in play error handling.
- block:
- yum:
name: "{{ item }}"
state: latest
with_items:
- httpd
- mod_wsgi
- template:
src: templates/httpd.conf.j2
dest: /etc/httpd/conf/httpd.conf
when: ansible_os_family == "RedHat"
In the provided example we use a block to group two tasks that are to be conditional executed if a host is running a Red Hat family linux using one conditional clause. In practice, we could have copied the when
clause onto each task and gotten same result. Using a block, there is less clutter thereby less to maintain and nothing to keep in sync. The utility of using a block increases the more tasks and clauses are in use.
Blocks have a play in error handling and automating roll backs that we won't get into here given the scope of that topic.
See the documentation on blocks to dig deeper.
The simple playbook we examined gave us a sense of the structure of a playbook and how they work, but in reality was too simlistic to be practical. Here we look at a basic playbook that it more complete to what users will commonly do with Ansible.
Walk thru the site.yml playbook in examples/apache-basic-playbook
and note the added logic and its function. Then, run the playbook on the control host.
Don't forget to reverse what this playbook does before continuing to not interfere with later demos and workshops.
In this workshop assignment students are tasked with developing their first complete playbook. The assignment approximates the tasks they will typical need to take in order to deploy and configure a single application service using Nginx.
See workshops/basic_playbook/
in the Ansible Lightbulb repo.
Tip: Don't rush this workshop. Give students ample time to do this workshop themselves to completion. This workshop covers the essential concepts and features of effectively automation with Ansible and builds up their core skills for further exploration.
Roles are a packages of closely related Ansible content that can be shared more easily than plays alone.
Roles are closely related Ansible content that are organized into a pre-defined directory structure, making them easier to reuse and share among groups.
site.yml
roles/
common/
files/
templates/
tasks/
handlers/
vars/
defaults/
meta/
apache/
files/
templates/
tasks/
handlers/
vars/
defaults/
meta/
This slide shows an example file system with a top-level playbook (site.yml) and two sample roles (common and apache) embedded in the project. Notice how the file structure under each role are similar to what we find in a play. Role deconstruct the content we'd put in a play and package it up in such a way that it is portable and easily shared and reused.
# site.yml
---
- hosts: web
roles:
- common
- apache
This slide shows the site.yml playbook using the roles in our example project. Notice that it is much more concise than what we've seen.
http://galaxy.ansible.com
Ansible Galaxy is a hub for finding, reusing and sharing Ansible content.
Jump-start your automation project with content contributed and reviewed by the Ansible community.
Ansible Galaxy refers to the Galaxy website, a hub for finding, downloading, and sharing community developed roles. Downloading roles from Galaxy is a great way to jumpstart your automation projects.
Galaxy also refers to a command line tool, ansible-galaxy
, for installing, creating and managing roles from the Galaxy website or directly from a git based SCM. You can also use it to create a new role, remove roles, or perform tasks on the Galaxy website.
Walk thru the site.yml playbook and the contents of roles/apache
in examples/apache-role
. Note how the tasks, variables and handlers from the basic Ansible playbook we've been examined and have been refactored into a role.
Run the playbook on the control host. Notice anything different? Other than a few subtle display changes, you shouldn't. What's important is how roles let you better organize, share and reuse Ansible content that will be vital as the scope and sophistication of your automation accelerates.
Here students are tasked with refactoring their previous work from the Practical Playbook workshop into a role and modifying their playbook accordingly. We intentioinally avoid introducing any new tasks or functionality otherwise. The objective here is to focus students specifically on how roles are structured and develop.
You should emphasize the value of roles in better organizing playbooks as they grow in sophistication and making Ansible automation more portable and reusable than a basic playbook.
See workshops/roles
in the Ansible Lightbulb repo.