Ansible collections - ansible.builtin vs ansible.legacy
How to take advantage of different behavior of the synthetic collections with all the critical Ansible modules and plugins.
What is the “ansible.builtin” Ansible collection? What is the “ansible.legacy” collection? Today we’re going to talk about Ansible’s most essential modules and plugins and how we can use them in our everyday Playbook. I’m Luca Berton, Ansible Automation Expert, and welcome to today’s lesson.
What is ansible.builtin collection?
The “ansible.builtin” collection refers to modules & plugins shipped with ansible-core. Technically is a synthetic collection, virtually constructed by the core engine.
What is ansible.legacy collection?
The “ansible.legacy” collection is a superset of “ansible.builtin” with ‘custom’ plugins in the configured paths and adjacent directories. We use the “ansible.legacy” when we don’t specify any Ansible collection in our playbook. Technically is a synthetic collection, virtually constructed by the core engine.
Links
- https://docs.ansible.com/ansible/latest/reference_appendices/faq.html#what-is-the-difference-between-ansible-legacy-and-ansible-builtin-collections
- https://docs.ansible.com/ansible/latest/reference_appendices/config.html#default-action-plugin-path
The Best Resources For Ansible
Certifications
- Coursera Pro - Unlimited access to 7,000+ world-class courses, hands-on projects, and job-ready certificate programs—all included in your subscription
Video Course
Printed Book
-
Ansible For VMware by Examples
-
Ansible for Kubernetes by Example
-
Hands-on Ansible Automation
-
Red Hat Ansible Automation Platform
eBooks
- Ansible by Examples: 200+ Automation Examples For Linux and Windows System Administrator and DevOps
- Ansible Cookbook: A Comprehensive Guide to Unleashing the Power of Ansible via Best Practices, Troubleshooting, and Linting Rules with Luca Berton
- Terraform By Example: A Practical Approach for Beginners to Learn Cloud Infrastructure with Terraform
- Ansible For Windows By Examples: 50+ Automation Examples For Windows System Administrator And DevOps
- Ansible For Linux by Examples: 100+ Automation Examples For Linux System Administrator and DevOps
- Ansible Linux Filesystem By Examples: 40+ Automation Examples on Linux File and Directory Operation for Modern IT Infrastructure
- Ansible For Security by Examples: 100+ Automation Examples to Automate Security and Verify Compliance for IT Modern Infrastructure
- Ansible Tips and Tricks: 10+ Ansible Examples to Save Time and Automate More Tasks
- Ansible Linux Users & Groups By Examples: 20+ Automation Examples on Linux Users and Groups Operation for Modern IT Infrastructure
- Ansible For PostgreSQL by Examples: 10+ Examples To Automate Your PostgreSQL database
- Ansible For Amazon Web Services AWS By Examples: 10+ Examples To Automate Your AWS Modern Infrastructure
- Ansible Automation Platform By Example: A step-by-step guide for the most common user scenarios
Demo
Live demo about “ansible.builtin” vs. “ansible.legacy” collections. Let’s jump in a quick demo to demonstrate the difference between the “ansible.builtin” vs. “ansible.legacy” collections. I’m going to create a custom “debug” module that prints the extra text “foo” when used with the “msg” parameter. Let’s see the different results when we execute with “ansible.builtin”, “ansible.legacy” or without specifying any collections. The code is the following.
common code
- inventory (localhost)
localhost ansible_connection=local
- ansible.cfg
[defaults]
action_plugins = plugins/action
- plugins/action/debug.py
# Copyright 2012, Dag Wieers <[email protected]>
# Copyright 2016, Toshio Kuratomi <[email protected]>
#
# This file is part of Ansible
#
# Ansible is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Ansible is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Ansible. If not, see <http://www.gnu.org/licenses/>.
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
from ansible.errors import AnsibleUndefinedVariable
from ansible.module_utils.six import string_types
from ansible.module_utils._text import to_text
from ansible.plugins.action import ActionBase
class ActionModule(ActionBase):
''' Print statements during execution '''
TRANSFERS_FILES = False
_VALID_ARGS = frozenset(('msg', 'var', 'verbosity'))
def run(self, tmp=None, task_vars=None):
if task_vars is None:
task_vars = dict()
validation_result, new_module_args = self.validate_argument_spec(
argument_spec={
'msg': {'type': 'raw', 'default': 'Hello world!'},
'var': {'type': 'raw'},
'verbosity': {'type': 'int', 'default': 0},
},
mutually_exclusive=(
('msg', 'var'),
),
)
result = super(ActionModule, self).run(tmp, task_vars)
del tmp # tmp no longer has any effect
# get task verbosity
verbosity = new_module_args['verbosity']
if verbosity <= self._display.verbosity:
if new_module_args['var']:
try:
results = self._templar.template(new_module_args['var'], convert_bare=True, fail_on_undefined=True)
if results == new_module_args['var']:
# if results is not str/unicode type, raise an exception
if not isinstance(results, string_types):
raise AnsibleUndefinedVariable
# If var name is same as result, try to template it
results = self._templar.template("{{" + results + "}}", convert_bare=True, fail_on_undefined=True)
except AnsibleUndefinedVariable as e:
results = u"VARIABLE IS NOT DEFINED!"
if self._display.verbosity > 0:
results += u": %s" % to_text(e)
if isinstance(new_module_args['var'], (list, dict)):
# If var is a list or dict, use the type as key to display
result[to_text(type(new_module_args['var']))] = results
else:
result[new_module_args['var']] = results
else:
result['msg'] = (new_module_args['msg'] + "foo")
# force flag to make debug output module always verbose
result['_ansible_verbose_always'] = True
else:
result['skipped_reason'] = "Verbosity threshold not met."
result['skipped'] = True
result['failed'] = False
return result
ansible.builtin code
- ansible.builtin.yml
---
- name: debug module demo
hosts: all
vars:
fruit: "apple"
tasks:
- name: Builtin
ansible.builtin.debug:
msg: "{{ fruit }}"
ansible.builtin execution
$ ansible-playbook -i inventory ansible.builtin.yml
PLAY [debug module demo] ****************************************************************
TASK [Gathering Facts] ******************************************************************
ok: [localhost]
TASK [Builtin] **************************************************************************
ok: [localhost] => {
"msg": "apple"
}
PLAY RECAP ******************************************************************************
localhost : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
ansible.legacy code
- ansible.legacy.yml
---
- name: debug module demo
hosts: all
vars:
fruit: "apple"
tasks:
- name: Legacy
ansible.legacy.debug:
msg: "{{ fruit }}"
ansible.legacy execution
$ ansible-playbook -i inventory ansible.legacy.yml
PLAY [debug module demo] ****************************************************************
TASK [Gathering Facts] ******************************************************************
ok: [localhost]
TASK [Legacy] ***************************************************************************
ok: [localhost] => {
"msg": "applefoo"
}
PLAY RECAP ******************************************************************************
localhost : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
ansible.vanilla code
- ansible.vanilla.yml
---
- name: debug module demo
hosts: all
vars:
fruit: "apple"
tasks:
- name: Vanilla
debug:
msg: "{{ fruit }}"
ansible.legacy execution
$ ansible-playbook -i inventory ansible.vanilla.yml
PLAY [debug module demo] ****************************************************************
TASK [Gathering Facts] ******************************************************************
ok: [localhost]
TASK [Vanilla] **************************************************************************
ok: [localhost] => {
"msg": "applefoo"
}
PLAY RECAP ******************************************************************************
localhost : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
Recap
Now you know more about the “ansible.builtin” and the “ansible.legacy” collections. This is a great foundation for your Ansible Playbook onward. Subscribe to the YouTube channel, Medium, and Website, X (formerly Twitter) to not miss the next episode of the Ansible Pilot.
Academy
Learn the Ansible automation technology with some real-life examples in my
My book Ansible By Examples: 200+ Automation Examples For Linux and Windows System Administrator and DevOps
Donate
Want to keep this project going? Please donate