This post is to help me page ansible back into memory if it has been moved to long term storage.
an automation tool. Ansible is agentless, meaning:
- you only have to install and run ansible on the control node.
- you must have connectivity from ansible to the things you are trying to control (automation targets).
- *nix -SSH
- Windows - winrm
- Cloud and other stuff - API
Ansible is pretty flexible. For any given thing, you can do or describe it several different ways, e.g. describe it on the command line, in a file, in a database that gets read, etc. So, in the example, don't assume any of these things are necessarily set in stone.
Ansible is run from the command line of the control node with either ansible or ansible-playbook. Both of those commands take the option -i <path to inventory files>
A yaml file describing the desired state of the automation target. The file consists of:
- hosts - directive specifies an inventory group to which to apply plays
- variables - These variables for convenience, not parameterization. That is, use them when you don't want to have to dig through the playbook and update things in all the various places they get used, e.g., like a path variable. It's best if you don't use these variables for something you change for each automation target
- plays - see below
- handler - see below
Plays are for organization.
They group tasks (see below). The tasks are executed in order unless the sequence is altered with one of the flow control directives.
Each play is named because helps
- force commenting
- lable sections of output/logs
- organize sections of a playbook
Tasks generally result in discrete actions in on the automation target.
Tasks are named, for the same reason plays are named.
Tasks call a module, usually in the format
<module>: <directive 1>=<value> <directive 2>=<value>
Handlers are like tasks in that they direct an action. Unlike tasks, handlers:
- are executed after all other tasks in a playbook
- are only executed if running the playbook resulted in a change
Handlers are useful for things like restarting a service when a change was made to its configuration.
The inventory is how ansible describes which host/automation targets to work on. The inventory can be files or generated dynamically. The main focus of the inventory is to group hosts.
Inventory Files -
While you can specify variables in inventory files, but best practice is to separate variables out into separate files.
Inventory files are the only ansible file than can be a non-yaml format, that is the INI format.
Groups are a way to manage multiple hosts similarly A group can consist of hosts or of other groups. In an inventory file, a group of groups uses the children keyword. Look up the syntax. Hosts can belong to multiple groups. If they belong to a nested group, they are members of both the parent and the child group. That is the, the parent is a union of children.
When specifying hosts in calls to ansible or ansible-playbook, you can do fun stuff like excluding from groups, the intersection of groups, etc. See patterns.
There are two default groups: all and ungrouped
Variables are a way to change ansible's behavior for a given task.
Variables can be declared in so many different places that the documentation has a long list of precedence. The documentation says it's more important to know where you should declare a variable than to worry about order of precedence. The documentation then goes on to begrudgingly document the order of precedence in excruciating detail and completely omits a description of the best place to declare variables.
Variable names must be letters, numbers, and _. The name must contain at least one letter. note: no hypen (-). Don't use two leading and trailing underscores, like __name__, or you will run afoul of reserved python keywords.
Two major types of variables apply to
- individual hosts- called host_vars or host variables groups. Usually declared in a file called /etc/ansible/host_vars/hostname.yaml
- groups- called group_vars or group variables. Usually declared in a file called /etc/ansible/group_vars/groupname.yaml
When you run ansible against a host or group, it looks up the applicable variables in the host and group variable files, as well as a number of other places. The value is then used when a playbook references the variable using the Jinja2 system. E.g.
Jinja2 has filters which are a way to apply functions to manipulate the value of the variable. There are lots of string and integer manipulation functions.
A task can output a value that you can register, i.e. declare, for use by subsequent tasks.
Best practice for organization
By default, all your playbooks, inventories, variables, etc. are rooted in the directory /etc/ansible. I can't see when that would ever be practical, but I guess they had to have some default. Instead, people generally just choose some directory as the root, like say specific to the client they are working on. Then they make all their ansible calls with -i /path/to/that/root.
Within that directory, the structure is as follows. This deviates a bit from what ansible says is the standard because I think making names more explicit is useful: hosts-inventory.yaml # the inventory file. note, this can be .yaml, .yml, no extension. group_vars/one_file_per_group.yaml host_vars/one_file_per_host.yaml site-playbook.yaml # master playbook that calls are the child playbooks group1-playbook.yaml # playbook for group 1 group2-playbook.yaml