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 }}"