It is used for automation of configuration processes. You inform Ansible what is the DESIRED state and Ansible will try to achieve it, no matter what the CURRENT state is. Example: you want to have a file in a spcified location with a specified content. There ar ea few possible starting points:
- the file does not exist - Ansible will create it
- the file exist, but has a different content - Ansible will update the file
- the file exists and has the right contnet - Ansible will do nothing
Manual -> Automation
Evolution of automation:
- Manual setup
- Writing scripts (.sh, .ps, etc.)
- Using Ansible ad-hoc
- Writing Ansible playbooks
Difference between scripting and Ansible is that in a script we need to say exactly what to do and cover various cases. Ansible takes care of these difficulties. We just say what we want to have in the end and not how to do that.
Ansible relies on modules. There are many of them for various operations (like for file operations, macOS setup, specific device setup, etc.).
Most modules are idempotent, some are not.
Every module can have some return values (i.e. a
file module returns SHA
checksum of the file afer modifications, owner of the file and other things).
ansible-doc command is useful, i.e.
ansible-doc copy gives information about
ansible command allows to run one chosen module with specified inputs.
--dry-run allows to see what the result would be without doing any actual
Playbooks are defined in YAML files and contain tasks that should be done.
We can have many “plays” in the same file:
The task’s parameters can be defined in multiple ways, like the two homebrew tasks above.
Plays can have tags, which allow to limit the plays that we want to execute from
a given file (
A task can have a condition (
when: ansible_os_family == 'RedHat' will run the task only if the host’s OS is in the Red Hat family.
Task can have a
ignore_errors: yes to not stop the play if it fails.
Tasks can store their outputs in variables with
register: my-variable There is
a task that prints these variabes, it’s called
debug: var=my-variable. Outputs are in JOSN format and we are able to
specific subset of it (
Command to run a playbook
-v flag shows more info. It can be added multiple times to increase verbosity
Although Ansible can work just with localhost, it is also suitable to configure multiple hosts. They are referred to as INVENTORY.
Inventory can be defined as a set of files in a chosen directory. They can be grouped under various labels. This helps us to target subsets of our inventory. “all” group is the top level group, contains all of the hosts.
We can use both ad-hoc commnands and playbooks agains inventory. Example of an ad-hoc command:
In the case above, I’d run the command agains hosts that are in the “docker-containers” group (docker containers can be hosts!).
ansible-inventory command manages inventory.
--list shows all hosts in our inventory.
We can use various connection types to reach hosts. For example, we could use
local connection to create some docker containers on our localhost (with
docker_container module) and then, use the
docker connection to do
something on these containers.
Noramlly, there is a central Manager Node that runs the playbooks on the hosts
(push model). Ansible can also work in a different fashion. Each host can use
ansible-pull which connects to some VCS, pulls playbooks and runs them on the
Galaxy enables community to share ROLES and COLLECTIONS (kind of Roles V2). These are constructs that sit between a module and a playbook.
Galaxy is like a package source for Ansible (same as .NET and NuGet or Node.JS and npm)