Advanced Ansible Techniques
1. Ansible Roles
Roles are a way of organizing playbooks and other files in order to facilitate reuse and sharing. Roles are simple and allow you to break a playbook into multiple reusable components.
Creating a role:
$ ansible-galaxy init my_role
This will create a directory structure for your role:
├── defaults
│ └── main.yml
├── files
├── handlers
│ └── main.yml
├── meta
│ └── main.yml
├── tasks
│ └── main.yml
├── templates
├── tests
│ ├── inventory
│ └── test.yml
└── vars
└── main.yml
2. Dynamic Inventory
Ansible can use a dynamic inventory script to generate a list of hosts at runtime, rather than using a static inventory file. This is particularly useful for cloud environments where the list of servers can change frequently.
Example of a dynamic inventory script:
#!/usr/bin/env python
import json
inventory = {
'group': {
'hosts': ['host1', 'host2'],
'vars': {
'ansible_user': 'user'
}
},
'_meta': {
'hostvars': {
'host1': {
'ansible_host': '192.168.1.1'
},
'host2': {
'ansible_host': '192.168.1.2'
}
}
}
}
print(json.dumps(inventory))
To use this dynamic inventory script, specify it with the -i option:
$ ansible-playbook -i my_inventory_script.py my_playbook.yml
3. Ansible Vault
Ansible Vault is a feature that allows you to keep sensitive data such as passwords or keys in encrypted files, rather than as plaintext in playbooks or roles.
Encrypting a file with Ansible Vault:
$ ansible-vault encrypt secrets.yml
Creating an encrypted variable within a playbook:
---
- name: Ansible Vault example
hosts: localhost
vars:
secret_password: !vault |
$ANSIBLE_VAULT;1.1;AES256
6162636465666768696a6b6c6d6e6f707172737475767778797a303132333435
tasks:
- debug: msg="The password is {{ secret_password }}"
Running a playbook with an encrypted file:
$ ansible-playbook --ask-vault-pass my_playbook.yml
4. Ansible Tags
Tags in Ansible allow you to run specific parts of your playbooks. This is useful when you want to run or skip certain tasks.
Using tags in a playbook:
---
- hosts: all
tasks:
- name: Install a package
apt: name=package state=present
tags:
- install
- name: Configure a service
service: name=service state=started
tags:
- configure
Running a playbook with specific tags:
$ ansible-playbook my_playbook.yml --tags "install"
Skipping specific tags:
$ ansible-playbook my_playbook.yml --skip-tags "configure"
5. Ansible Callbacks
Callbacks are a way to hook into the events that happen during the execution of an Ansible playbook. They can be used to send notifications, log events, or integrate with other systems.
Creating a custom callback plugin:
# callback_plugins/my_callback.py
from ansible.plugins.callback import CallbackBase
class CallbackModule(CallbackBase):
def v2_runner_on_ok(self, result):
host = result._host
print("{} is OK".format(host.name))
Enabling the custom callback plugin in ansible.cfg:
[defaults] callback_plugins = /path/to/callback_plugins
6. Ansible Filters
Ansible Filters allow you to manipulate data within playbooks. Filters are typically used in Jinja2 templates to transform data.
Using a filter in a playbook:
---
- hosts: localhost
vars:
my_list: [1, 2, 3, 4, 5]
tasks:
- name: Show reversed list
debug:
msg: "{{ my_list | reverse }}"
Creating a custom filter plugin:
# filter_plugins/my_filters.py
def to_uppercase(value):
return value.upper()
class FilterModule(object):
def filters(self):
return {
'to_uppercase': to_uppercase
}
Using the custom filter in a playbook:
---
- hosts: localhost
vars:
my_string: "hello"
tasks:
- name: Show uppercase string
debug:
msg: "{{ my_string | to_uppercase }}"
