Ansible
Introduction
Ansible is (one of many) orchestration tools. It allows you to control your environment (infrastructure and code) and automate the manual tasks.
Ansible has great integration with multiple operating systems (even Windows) and some hardware (switches, Firewalls, etc). It has multiple tools that integrate with the cloud providers. Almost every noteworthy cloud provider is present in the ecosystem (AWS, Azure, Google, DigitalOcean, OVH, etc…).
But ansible is way more! It provides execution plans, an API, library, and callbacks.
Main pros and cons
Pros
It is an agent-less tool. In most scenarios, it uses ssh as a transport layer. In some way you can use it as ‘bash on steroids’.
It is very easy to start. If you are familiar with the concept of ssh - you already know Ansible (ALMOST).
It executes ‘as is’ - other tools (salt, puppet, chef - might execute in different scenario than you would expect)
Documentation is at the world-class standard!
Writing your own modules and extensions is fairly easy.
Ansible AWX is the open source version of Ansible Tower we have been waiting for, which provides an excellent UI.
Cons
It is an agent-less tool - every agent consumes up to 16MB ram - in some environments, it may be noticeable amount.
It is agent-less - you have to verify your environment consistency ‘on-demand’ - there is no built-in mechanism that would warn you about some change automatically (this can be achieved with reasonable effort)
Official GUI - Ansible Tower - is great but expensive.
There is no ‘small enterprise’ payment plan, however Ansible AWX is the free open source version we were all waiting for.
Neutral
Migration - Ansible <-> Salt is fairly easy - so if you would need an event-driven agent environment - it would be a good choice to start quick with Ansible, and convert to Salt when needed.
Some concepts
Ansible uses ssh or paramiko as a transport layer. In a way you can imagine that you are using a ssh with API to perform your action. The simplest way is to execute remote command in more controlled way (still using ssh). On the other hand - in advanced scope - you can wrap Ansible (use python Ansible code as a library) with your own Python scripts! It would act a bit like Fabric then.
Example
An example playbook to install apache and configure log level
Installation
Your first ansible command (shell execution)
Shell Commands
There are few commands you should know about
ansible
(to run modules in CLI)ansible-playbook
(to run playbooks)ansible-vault
(to manage secrets)ansible-galaxy
(to install roles from github/galaxy)
Module
A program (usually python) that executes, does some work and returns proper JSON output. This program performs specialized task/action (like manage instances in the cloud, execute shell command). The simplest module is called ping
- it just returns a JSON with pong
message.
Example of modules:
Module:
ping
- the simplest module that is useful to verify host connectivityModule:
shell
- a module that executes a shell command on a specified host(s).
Module:
command
- executes a single command that will not be processed through the shell, so variables like$HOME
or operands like|` `;
will not work. The command module is more secure, because it will not be affected by the user’s environment. For more complex commands - use shell module.
Module:
file
- performs file operations (stat, link, dir, …)Module:
raw
- executes a low-down and dirty SSH command, not going through the module subsystem (useful to install python2.7)
Task
Execution of a single Ansible module is called a task. The simplest module is called ping
as you could see above.
Another example of the module that allows you to execute a command remotely on multiple resources is called shell
. See above how you were using them already.
Playbook
Execution plan written in a form of script file(s) is called playbook. Playbooks consist of multiple elements - * a list (or group) of hosts that ‘the play’ is executed against * task(s)
or role(s)
that are going to be executed * multiple optional settings (like default variables, and way more)
Playbook script language is YAML. You can think that playbook is very advanced CLI script that you are executing.
Example of the playbook
This example-playbook would execute (on all hosts defined in inventory) two tasks: * ping
that would return message pong * shell
that execute three commands and return the output to our terminal
Run the playbook with the command:
Note: Example playbook is explained in the next chapter: ‘Roles’
More on ansible concept
Inventory
An inventory is a set of objects or hosts, against which we are executing our playbooks or single tasks via shell commands. For these few minutes, let’s assume that we are using the default ansible inventory (which in Debian based system is placed in /etc/ansible/hosts
).
ansible-roles (a ‘template-playbooks’ with right structure)
You already know that the tasks (modules) can be run via CLI. You also know the playbooks - the execution plans of multiple tasks (with variables and logic).
A concept called role
was introduced for parts of the code (playbooks) that should be reusable.
Role is a structured way to manage your set of tasks, variables, handlers, default settings, and way more (meta, files, templates). Roles allow reusing the same parts of code in multiple playbooks (you can parametrize the role ‘further’ during its execution). Its a great way to introduce object oriented
management for your applications.
Role can be included in your playbook (executed via your playbook).
For remaining examples we would use additional repository
This example installs ansible in virtualenv
so it is independent from the system. You need to initialize it into your shell-context with the source environment.sh
command.
We are going to use this repository with examples: https://github.com/sirkubax/ansible-for-learnXinYminutes
Run the playbook with roles example
Role directory structure
Role Handlers
Handlers are tasks that can be triggered (notified) during execution of a playbook, but they execute at the very end of a playbook. It is the best way to restart a service, check if the application port is active (successful deployment criteria), etc.
Get familiar with how you can use roles in the simpleapacherole example
ansible - variables
Ansible is flexible - it has 21 levels of variable precedence. read more For now you should know that CLI variables have the top priority. You should also know, that a nice way to pool some data is a lookup
Lookups
Awesome tool to query data from various sources!!! Awesome! query from: * pipe (load shell command output into variable!) * file * stream * etcd * password management tools * url
You can use them in CLI too
Register and Conditional
Register
Another way to dynamically generate the variable content is the register
command. Register
is also useful to store an output of a task and use its value for executing further tasks.
Conditionals - when:
You can define complex logic with Ansible and Jinja functions. Most common is usage of when:
, with some variable (often dynamically generated in previous playbook steps with register
or lookup
)
ansible - tags, limit
You should know about a way to increase efficiency by this simple functionality
TAGS
You can tag a task, role (and its tasks), include, etc, and then run only the tagged resources
LIMIT
You can limit an execution of your tasks to defined hosts
Templates
Templates are a powerful way to deliver some (partially) dynamic content. Ansible uses Jinja2 language to describe the template.
Jinja may have some limitations, but it is a powerful tool that you might like.
Please examine this simple example that installs apache2 and generates index.html from the template “playbooks/roles/simpleapacherole/templates/index.html”
Jinja2 CLI
You can use the jinja in the CLI too
In fact - jinja is used to template parts of the playbooks too
Jinja2 filters
Jinja is powerful. It has many built-in useful functions.
ansible-vault
To maintain infrastructure as code you need to store secrets. Ansible provides a way to encrypt confidential files so you can store them in the repository, yet the files are decrypted on-the-fly during ansible execution.
The best way to use it is to store the secret in some secure location, and configure ansible to use them during runtime.
dynamic inventory
You might like to know, that you can build your inventory dynamically. (For Ansible) inventory is just JSON with proper structure - if you can deliver that to ansible - anything is possible.
You do not need to reinvent the wheel - there are plenty of ready to use inventory scripts for the most popular Cloud providers and a lot of in-house popular usecases.
ansible profiling - callback
Playbook execution takes some time. It is OK. First make it run, then you may like to speed things up. Since ansible 2.x there is built-in callback for task execution profiling.
facts-cache and ansible-cmdb
You can pull some information about your environment from another host. If the information does not change - you may consider using a facts_cache to speed things up.
I like to use jsonfile
as my backend. It allows to use another project ansible-cmdb
(project on github) that generates a HTML page of your inventory resources. A nice ‘free’ addition!
Debugging ansible [chapter in progress]
When your job fails - it is good to be effective with debugging.
Increase verbosity by using multiple -v [ -vvvvv]
If variable is undefined -
grep -R path_of_your_inventory -e missing_variable
If variable (dictionary or a list) is undefined -
grep -R path_of_your_inventory -e missing_variable
Jinja template debug
Strange behaviour - try to run the code ‘at the destination’
Infrastructure as code
You already know, that ansible-vault allows you to store your confidential data along with your code. You can go further - and define your ansible installation and configuration as code. See environment.sh
to learn how to install the ansible itself inside a virtualenv
that is not attached to your operating system (can be changed by non-privileged user), and as additional benefit - upgrading version of ansible is as easy as installing new version in new virtualenv. What is more, you can have multiple versions of Ansible present at the same time.
become-user, become
In Ansible - to become sudo
- use the become
parameter. Use become_user
to specify the username.
Note: You may like to execute Ansible with --ask-sudo-pass
or add the user to sudoers file in order to allow non-supervised execution if you require ‘admin’ privileges.
Tips and tricks
–check -C
Always make sure that your playbook can execute in ‘dry run’ mode (–check), and its execution is not declaring ‘Changed’ objects.
–diff -D
Diff is useful to see nice detail of the files changed. It compare ‘in memory’ the files like diff -BbruN fileA fileB
.
Execute hosts with ‘regex’
Host groups can be joined, negated, etc
Tagging
You should tag some (not all) objects - a task in a playbook, all tasks included form a role, etc. It allows you to execute the chosen parts of the playbook.
no_logs: True
You may see, that some roles print a lot of output in verbose mode. There is also a debug module. This is the place where credentials may leak. Use no_log
to hide the output.
Debug module
allows to print a value to the screen - use it!
Register the output of a task
You can register the output (stdout), rc (return code), stderr of a task with the register
command.
Conditionals: when:
Loop: with, with_items, with_dict, with_together
Additional Resources
Ansible Tower - Ansible Tower provides a web UI, dashboard and rest interface to ansible.
Ansible AWX - The Open Source version of Ansible Tower.
Last updated