Ansible
- https://docs.ansible.com/intro_inventory.html
- https://docs.ansible.com/playbooks_best_practices.html
- https://galaxy.ansible.com
- https://www.azavea.com/blogs/labs/2014/10/creating-ansible-roles-from-scratch-part-1
- https://ryandlane.com/blog/2014/08/04/moving-away-from-puppet-saltstack-or-ansible/
- https://docs.ansible.com/ansible/latest/user_guide/intro_patterns.html: Targeting hosts
- https://docs.ansible.com/ansible/latest/user_guide/playbooks_variables.html#variable-precedence-where-should-i-put-a-variable
- https://zwischenzugs.com/2021/08/27/five-ansible-techniques-i-wish-id-known-earlier
Modules
- https://docs.ansible.com/ansible/latest/collections/ansible/builtin/#modules
- https://docs.ansible.com/ansible/latest/modules/apt_module.html
- https://docs.ansible.com/ansible/latest/modules/apt_repository_module.html
- https://docs.ansible.com/ansible/latest/modules/sysctl_module.html
- https://docs.ansible.com/ansible/latest/modules/user_module.html
See also
- Molecule: testing of Ansible roles
Examples
Generate a copy block for a given file
Not perfect because the output is json, but json is yaml and easy enough to fix up quickly.
## stat -c '{"copy": {"src": "SOURCE_FILE_NAME", "dest": "%n", "mode": "0%a", "owner": "%U", "group": "%G"}}' /etc/logrotate.d/backup | jq .
{
"copy": {
"src": "SOURCE_FILE_NAME",
"dest": "/etc/logrotate.d/backup",
"mode": "0644",
"owner": "root",
"group": "root"
}
}
Show a list of installed modules
ansible-doc --list
Run a playbook and prompt for sudo password
ansible-playbook --ask-become-pass -i inventory/hosts.yaml create_users.yaml
Run an ad-hoc command
You can run one-off ad-hoc commands by passing a module and args to the module.
ansible localhost \
-m get_url \
-a "mode=755
url=https://github.com/bcicen/ctop/releases/download/v0.7.1/ctop-0.7.1-linux-amd64
dest=/usr/local/bin/ctop
checksum=sha256:38cfd92618ba2d92e0e1262c0c43d7690074b4b8dc77844b654f8e565166b577
owner=root
group=root"
Validate and inspect your inventory file
This command parses your inventory and group_vars and outputs a json data structure if no syntax faults are found.
ansible-inventory -i inventory/hosts.yml --list
Use arbitrary groups in static inventory file
$ nl -w 2 -s ' ' -ba inventory/example.yml
1 all:
2 hosts:
3 client:
4 ansible_host: 192.168.1.2
5 server:
6 ansible_host: 192.168.2.3
7
8 linux:
9 hosts:
10 server:
11
12 windows:
13 hosts:
14 client:
15
16 california:
17 hosts:
18 client:
19 server:
$ ansible-inventory -i inventory/example.yml --graph
@all:
|--@california:
| |--client
| |--server
|--@linux:
| |--server
|--@windows:
| |--client
Merge multiple inventory files
The below example gives higher precedence to the later files.
## cat foo.yml
all:
hosts:
client:
ansible_host: 192.168.1.2
service_hostname: hostname-from-file-1
server:
ansible_host: 192.168.2.3
file_number: one
## cat bar.yml
all:
hosts:
client:
ansible_host: 10.1.2.3
server:
ansible_host: 10.2.3.4
file_number: two
## ansible-inventory -i foo.yml -i bar.yml --list | json-to-yaml.py
_meta:
hostvars:
client:
ansible_host: 10.1.2.3
service_hostname: hostname-from-file-1
server:
ansible_host: 10.2.3.4
file_number: two
all:
children:
- ungrouped
ungrouped:
hosts:
- client
- server
Show all resolved variables for a given inventory host
This wisll show all host vars, including variables resolved from all the different variable locations.
ansible -i inventory target_hostname -m debug -a "var=hostvars[inventory_hostname]"
Gather all facts and save them to files
This will create a directory called facts
and save results as one json file per host.
ansible -i inventory target_group_or_hostname -m gather_facts --tree host_facts
Generate an deterministic random number
This is similar to the Puppet fqdn_rand()
function, which is really useful to splay cron jobs. Splaying cron jobs avoids the thundering herd problem by spreading the jobs out over time with deterministic randomness.
---
## defaults/main.yml
demo_cron_minute: "{{ 59 | random(seed=inventory_hostname) }}"
demo_cron_hour: "{{ 23 | random(seed=inventory_hostname) }}"
See also: https://docs.ansible.com/ansible/latest/user_guide/playbooks_filters.html#randomizing-data
Simple ansible playbook
This may be useful for testing syntax and experimenting with ansible modules.
---
## playbook.yml
- name: A local play
hosts: localhost
connection: local
gather_facts: no
tasks:
- name: Run cmd
shell: /bin/date
register: cmd_out
- debug:
var: cmd_out.stdout
ansible-playbook -i localhost playbook.yml
Slightly more complicated example:
## playbook.yml
## run with: ansible-playbook -i localhost playbook.yml
- name: A local play
hosts: localhost
connection: local
gather_facts: no
vars:
region: test_region
subnets:
- subnet_name: Public_2a
subnet_cidr: 192.168.100.0/26
subnet_az: "{{ region }}_a"
- subnet_name: Public_2b
subnet_cidr: 192.168.100.64/26
subnet_az: "{{ region }}_b"
- subnet_name: Private_2a
subnet_cidr: 192.168.100.128/26
subnet_az: "{{ region }}_a"
- subnet_name: Private_2b
subnet_cidr: 192.168.100.192/26
subnet_az: "{{ region }}_b"
tasks:
- name: Run cmd
shell: echo "{{ item.subnet_name }} {{ item.subnet_cidr }} {{ item.subnet_az }}"
register: cmd_out
loop: "{{ subnets }}"
- debug:
var: cmd_out
Get a list of failed hosts
{{ ansible_play_hosts_all | difference(ansible_play_hosts) }}
Links
- https://github.com/danielhoherd/ansible-playground: Examples I've made of Ansible techniques
- Ansible Tests with Molecule - https://molecule.readthedocs.io/en/latest/ / https://www.digitalocean.com/community/tutorials/how-to-test-ansible-roles-with-molecule
- Molecule sequence of scenario events - https://molecule.readthedocs.io/en/latest/configuration.html#scenario
- Test-driven infrastructure development with Ansible & Molecule - https://blog.codecentric.de/en/2018/12/test-driven-infrastructure-ansible-molecule/ / https://github.com/jonashackt/molecule-ansible-docker-vagrant
- Testkitchen modules (for Molecule tests): https://testinfra.readthedocs.io/en/latest/modules.html
- https://www.hashicorp.com/resources/ansible-terraform-better-together