Automation with AnsibleFind the latest, print-friendly version of this presentation and tutorial materials at
https://christopherdemarco.com/ansible
Copyright © 2017 Christopher DeMarco. All Rights Reserved.
The opinions and mistakes that follow are my own and do not represent my employer, Red Hat, USENIX, or anyone else.
All code samples were believed correct at runtime. Your mileage may vary.
To my grandfather, who taught me how to write.To my father, who taught me why. 2
This tutorial is interactive.Please interrupt me!
Join us on Slack!#m8-ansiblehttp://lisainvite.herokuapp.com/
Who has used Ansible before?
5
Lightweight configuration management
Stop managing your tools, start using them.
Possibly pay Red Hat to help.
6
Agentless
Install and maintain the client.
Strange firewall ports?
Got SSH?
Got Python >= 2.4? (and maybe not even that!)
7
Serverless
Admin SPOF / Yet Another Cluster
Install Ansible, pull configuration codebase, & run locally.
No daemons or databases.
Laptop? Jenkins? On the node itself?
8
Stateless
Ship bytecode to the nodes being configured—load is in the targets, not the controller.
Keep static host inventories in source control.
Generate dynamic host inventories; scripts simply output JSON.
9
Small DSLYAML
Jinja2
Python
10
OTOH
SSH and Python are slow.
YAML is *too* easy.
Ansible is procedural, not declarative.
Ansible’s DSL does not incorporate a general-purpose programming language.
11
There’s lots of infrastructure we can’t demo!
AWS
Google Compute Engine
OpenStack
Azure
Kubernetes
Cisco
F5
NetApp
Windows
. . . 12
Hello Docker
PlaybooksA play consists of tasks.
A groups of plays is called a playbook.
Playbooks are structured as YAML lists and dictionaries.
14
`hosts` and `tasks` are required parameters of the play.
The `tasks` parameter contains a list of modules. (`ping` and `apt`)
`state` is a parameter of a module. `with_items` is a parameter of a task. Do not confuse them!
15
Inventory
Use INI or YAML.
Or use a script for dynamic inventory.
Set variables.
Set groups.
16
Run it! Ansible runs against all hosts in parallel.
Show changes as they’re made, and summarize overall results.
17
Re-run it! Ansible will only do what’s necessary.
18
Now you try it . . .
19
Accessing your lab workstation
Your paper tokens expire.
Do not break your instances.
Everything disappears afterwards.
Beware USENIX Code of Conduct.
Ansible and class materials are installed.
API credentials expire after this session, don’t try anything funny.
20
Code samples are provided.
The first “hello docker” example is in `~/class/1330_hello`.
Background `docker-compose up`, use tmux/screen, or open a second SSH session.
Once you’ve provisioned the container, connect to it and play around.
21
Docker 101~/class/docker_101.md
22
YAML sucks.~/class/yaml_sucks.yml
23
DON’T USE TABS IN YAML!
http://fortunes.exampleLet’s build it.
What do we need to do?
Copy source.
Install requirements.
Set up app.
26
Does it work?This docker-compose configuration exposes tcp/80.
Test with curl.
27
Tag things to skip them.
28
Use the `ansible-playbook --tags=` option to run only selected tags.
Use the `--skip-tags=` option to exclude selected tags.
Separate multiple tags with a comma [and no space].
Use the `ansible-playbook --list-tasks` option to see what tags are defined.
29
Variables
30
Variables can have default values.
Facts are variables discovered automatically by Ansible.
Interpolate variables using Jinja2 syntax.
Use the `debug` module to print.
31
Set variables on the command line with the `-e` argument.
Or define them in inventory.
Or use `include_vars` to load them from a file.
32
Yeah, but Docker . . .Let’s build it on a real host.
Managing / accessing your lab SSH host
Use `~/class/inventory.py` as your Ansible inventory.
Username is `ubuntu`. Password login is not permitted; use the SSH key at `~/.ssh` .
Recreate alpha by running the `~/recreate_alpha.sh` script; don’t forget to remove stale keys from `~/.ssh/known_hosts`.
34
alpha.<your-host>.foam.ninja
Docker vs. a real hostHow do we switch these on?
sudo
initscript/service
35
How do we become a different user?
`become`
`become_user`
Gotcha: `become` applies to the play—not to the task list, or to individual tasks.
36
How do we branch on platform type?
List the available facts: `ansible -m setup -i <inventory> all`.
Use a task’s `when` parameter to restrict its execution.
Gotcha: no Jinja braces in `when`!
37
Point your browser at http://alpha.your-workstation.foam.ninja!
38
It sure is annoying to set `become_bool` in inventory . . .
39
Yeah, but Debian . . .
You can set variables in a play.
`packages` is a dictionary. Index using Python syntax.
The `package` module is cross-platform.
41
Roles
Roles make things modular.Use them as much as possible!
Install and configure an application.
Apply common configuration.
Bundle assets and resources.
Share code.
43
UserlandLet’s build it.
What do we need to do?
Provide my preferred username and shell.
Authenticate using my GitHub keypair.
Portably install the essentials.
Setup a convenience alias in `~/.ssh/config`.
45
Use a role with the `include_role` task.
46
Set `roles_path` in `ansible.cfg`.
`ansible-galaxy init <rolename>`.
Put tasks in `tasks/main.yml`. (Note that this is a task list—like you’d put in a play—not a playbook.) Similarly for `handlers/main.yml`.
Put files/templates in their respective directories, and you can use them within the role without an explicit path.
47
Set role defaults.
Note that my defaults are probably not what you want!
As a role author, it’s your responsibility to set sane defaults.
48
Tasks return data structures.
Provide status, stdout/stderr, etc.
`register` them, then use them like variables.
Output them using `debug`.
49
Work locally. `delegate_to: localhost`
50
Let’s set a login password. How can we store it securely?
51
Keep secrets in `ansible-vault`.
Use the `import_vars` task to pull vars into the current play.
`ansible-vault [create | edit | view]`
It’s encrypted, therefore safe to store in version control.
`ansible-playbook --ask-vault-pass`
52
Gotcha!sshd doesn’t permit password logins!
53
HandlersHandlers `register` listeners.
Tasks can `notify` handlers.
Put a handler in a play, or in the `handlers` list of a role.
54
Use third-party roles.
55
But are they any good?
http://galaxy.ansible.com
`ansible-galaxy install user.role`
Gotcha! `ansible-galaxy` ignores `ansible.cfg` and installs to ~/.ansible/roles` unless you set `ANSIBLE_ROLES_PATH`.
Check them into source control?
Read them!
OK for prototyping . . . but you’ll probably rewrite ‘em . . .
56
Keep things organized.
Playbooks go in the top level.
Directories for inventory, roles, variables, etc.
`roles_path`
Use version control!
Manage third-party modules!
57
Password-protect fortunes.Let’s build it.
Templates
59
`template` is just another module. Syntax is basically like `copy`.
Use the familiar variable interpolation syntax—including filters.
Wrap Python code with `{% %}`.
What do we need to do?
Install Apache2.
Template the config.
Enable the config and modules, restart `apache2`.
Set up htpasswd.
60
The Apache template is simple with just a single variable expansion.
61
The htpasswd template shows an inline Python code block, and a filter.
62
Automate tmuxinator.
63
Because this is a bogus example, we need to limit execution to localhost.
The magic `ansible_env` variable is a dictionary containing the env vars of the host *on which the play was run*.
The `delegate_to` parameter specifies which host will run the task.
64
`groups` is a variable like any other.
Note that interpolation braces are not required within a Python block.
`hostvars` lets you reference an arbitrary host’s variables!
65
Jevgr phfgbz svygref.
66
Write plugins in Python. Each plugin implements a class whose `filters` method returns a function implementing the actual filter.
Put your Python in a `filter_plugins/` directory adjacent to your playbook or inside your role.
67
Documentation tourBeware the bright light . . .
breakreturn at 1530
Grouping and limiting
Inventory groups can include other groups.
Variables are inherited via group membership.
71
Group membership can use complex pattern syntax.
Limit what will be operated on with the `-l` argument to `ansible-playbook`, or in a play’s `hosts` attribute.
Use the same pattern syntax on the command line or in playbooks.
72
73
Dynamic inventory
74
Let’s build it.
Dynamic inventory: AWS
75
Scale
77
Use `strategy: free` to keep hosts from waiting for each other.
78
Use the default strategy with the `serial` directive to define batches of hosts.
Melt your laptop.
Set `forks` in `ansible.cfg` to scale the number of remote connections.
79
Gotchas
Gotcha! Install & setup
Install your OS’s package.
Scatter stuff all over your machine?
How stale is the version?
81
Instead, run from a git repo.
https://github.com/ansible/ansible.git But don’t commit it to your source control!
Better yet, use a git submodule.
82
But you’ll need a virtualenv.
http://docs.python-guide.org/en/latest/dev/virtualenvs/
Prefer OS packages for the various virtualenv methods; don’t `pip install` system-wide.
83
84
Gotcha! SSH details
Use SSH-specific variables in inventory and on the command line.
`host_key_checking`
`remote_port`
`remote_user`
`ssh_args`
`--extra-vars @aws.var`
85
Gotcha!It won’t work?
Can’t auth? Can’t sudo?
Use `-vvvv` to watch the SSH stream.
Is SSH doing what you expect?
86
Gotcha!So many `.retry`!
`retry_files_enabled`
`retry_files_save_path`
87
Gotcha!YAML parsing
88
Gotcha!YAML parsing
89
Gotcha!Interpolation
90
Gotcha!Firewall
91
Gotcha!No Python!
92
Gotcha!Python3
:-\
93
Gotcha!GitHub keysThou shalt not transport thine public key.
94
Gotcha!GitHub keys(cont.)
95
Gotcha!`sudo` password?!
Add the `-K` flag to make Ansible prompt for a sudo password.
Store the `ansible_become_pass` variable in Vault.
96
Gotcha!JSON
97
Gotcha!Variable precedence!
Don’t get into a position where you need to know this! KISS!
Defaults are lowest priority: role defaults and inventory vars.
Then facts, play vars, task vars.
Then include_vars.
Then set facts.
Then `-e` extra vars.
Basically, the narrowest scope wins.
98
Q & A
Thank you.Lab systems are being destroyed now.
Please fill out your surveys.