Ansible Modules - How To Use Them Efficiently (Examples) (2024)

This article delves into Ansible modules, one of the core building blocks of Ansible. In this blog post, we will examine the purpose and usage of modules, along with information on how to build them and best practices.

If you are interested in other Ansible concepts, these Ansible tutorials posted on Spacelift’s blog might be helpful for you.

What Are Ansible Modules?

Modules represent distinct units of code, each one with specific functionality. Basically, they are standalone scripts written for a particular job and are used in tasks as their main functional layer.

We build Ansible modules to abstract complexity and provide end-users with an easier way to execute their automation tasks without needing all the details. This way, some of the cognitive load of more complex tasks is abstracted away from Ansible users by leveraging the appropriate modules.

Here’s an example of a task using the apt package manager module to install a specific version of Nginx.

- name: "Install Nginx to version {{ nginx_version }} with apt module" ansible.builtin.apt: name: "nginx={{ nginx_version }}" state: present

Modules can be executed as well directly from the command line. Here’s an example of running the ping module against all the database hosts from the command line.

ansible databases -m ping

Working With Ansible Modules

A well-designed module provides a predictable and well-defined interface that accepts arguments that make sense and are consistent with other modules. Modules take some arguments as input and return values in JSON format after execution.

Ansible modules should follow idempotency principles, which means that consecutive runs of the same module should have the same effect if nothing else changes. Well-designed modules detect if the current and desired state match and avoid making changes if that’s the case.

We can utilize handlers to control the flow execution of modules and tasks in a playbook. Modules can trigger additional downstream modules and tasks by notifying specific handlers.

As mentioned, modules return data structures in JSON data. We can store these return values in variables and use them in other tasks or display them to the console. Look at the common return values for all modules to get an idea.

For custom modules, the return values should be documented along with other useful information for the module. The command-line tool ansible-doc displays this information.

Here’s an example output of running the ansible-doc command.

ansible-doc apt

Ansible Modules - How To Use Them Efficiently (Examples) (1)

In the latest versions of Ansible, most modules are part of collections, a distribution format that includes roles, modules, plugins, and playbooks. Many of the core modules we use extensively are part of the Ansible.Builtin collection. To find other available modules have a look at the Collection docs.

12 Useful & Common Ansible Modules

In this part, we explore some of the most used and helpful modules, and for each, we provide a working example. The modules in this list are picked based on their popularity within the Ansible community and functionality to perform everyday automation tasks.

Package Manager Modules yum & apt

The apt module is part of ansible-core and manages apt packages for Debian/Ubuntu Linux distributions. Here’s an example that updates the repository cache and updates the Nginx package to the latest version:

- name: Update the repository cache and update package "nginx" to latest version ansible.builtin.apt: name: nginx state: latest update_cache: yes

The yum module is also part of ansible-core and manages packages with yum for RHEL/Centos/Fedora Linux distributions. Here’s the same example as above with the yum module:

- name: Update the repository cache and update package "nginx" to latest version ansible.builtin.yum: name: nginx state: latest update_cache: yes

Service Module

The service module controls services on remote hosts and can leverage different init systems depending on their availability in a system. This module provides a nice abstraction layer for underlying service manager modules. Here’s an example of restarting the docker service:

- name: Restart docker service ansible.builtin.service: name: docker state: restarted

File Module

The file module handles operations to files, symlinks, and directories. Here’s an example of using this module to create a directory with specific permissions:

- name: Create the directory "/etc/test" if it doesnt exist and set permissions ansible.builtin.file: path: /etc/test state: directory mode: '0750'

Copy Module

The Ansible copy module copies files to the remote machine and handles file transfers or moves within a remote system. Here’s an example of copying a file to the remote machine with permissions set:

- name: Copy file with owner and permissions ansible.builtin.copy: src: /example_directory/test dest: /target_directory/test owner: joe group: admins mode: '0755'

Template Module

The template module assists us to template files out to target hosts by leveraging the Jinja2 templating language. Here’s an example of using a template file and some set Ansible variables to generate an Nginx configuration file:

- name: Copy and template the Nginx configuration file to the host ansible.builtin.template: src: templates/nginx.conf.j2 dest: /etc/nginx/sites-available/default

Read more about how to create an Ansible template.

Lineinfile & Blockinfile Modules

The lineinfile module adds, replaces, or ensures that a particular line exists in a file. It’s pretty common to use this module when we need to update a single line in configuration files.

- name: Add a line to a file if it doesnt exist ansible.builtin.lineinfile: path: /tmp/example_file line: "This line must exist in the file" state: present

The blockinfile module inserts, updates, or removes a block of lines from a file. It has the same functionality as the previous module but is used when you want to manipulate multi-line text blocks.

- name: Add a block of config options at the end of the file if it doesn’t exist ansible.builtin.blockinfile: path: /etc/example_dictory/example.conf block: | feature1_enabled: true feature2_enabled: false feature2_enabled: true insertafter: EOF

Cron Module

The cron module manages crontab entries and environment variables entries on remote hosts.

- name: Run daily DB backup script at 00:00 ansible.builtin.cron: name: "Run daily DB backup script at 00:00" minute: "0" hour: "0" job: "/usr/local/bin/db_backup_script.sh > /var/log/db_backup_script.sh.log 2>&1"

Wait_for Module

The wait_for module provides a way to stop the execution of plays and wait for conditions, amount of time to pass, ports to become open, processes to finish, files to be available, strings to exist in files, etc.

- name: Wait until a string is in the file before continuing ansible.builtin.wait_for: path: /tmp/example_file search_regex: "String exists, continue"

💡 You might also like:

  • 44 Ansible Best Practices to Follow
  • How to Manage Ansible More Securely
  • Common Infrastructure Challenges and How to Solve Them

Command & Shell Modules

The command and shell modules execute commands on remote nodes. Their main difference is that the command module bypasses the local shell, and consequently, variables like $HOSTNAME or $HOME aren’t available, and operations like “<”, “&” don’t work. If you need these features, you have to use the shell module.

On the other hand, the remote local environment won’t affect the command module, so its outcome is considered more predictable and secure.

Usually, it’s always preferred to use specialized Ansible modules to perform tasks instead of command and shell. There are cases, though, where you won’t be able to get the functionality that you need from specialized modules, and you will have to use one of these two. Use command and shell with care, and always try to check if there is a specialized module that can serve you better before relying on them.

- name: Execute a script in remote shell and capture the output to file ansible.builtin.shell: script.sh >> script_output.log

Read more about the Ansible shell module.

Building Ansible Modules

For advanced users, there is always the option to develop custom modules if they have needs that can’t be satisfied by existing modules. Since modules always should return JSON data, they can be written in any programming language.

Before jumping into module development, ensure that a similar module doesn’t exist to avoid unnecessary work. Αdditionally, you might be able to combine different modules to achieve the functionality you need. In this case, you might be able to replicate the behavior you want by creating a role that leverages other modules. Another option is to use plugins to enhance Ansible’s basic functionality with logic and new features accessible to all modules.

Next, we will go through an example of creating a custom module that takes as input a string that represents an epoch timestamp and converts it to its human-readable equivalent of type datetime in Python. You can find the code for this tutorial on this repository.

First, let’s create a library directory on the top of our repository to place our custom module. Playbooks with a./library directory relative to their YAML file can add custom ansible modules that can be recognized in the ansible module path. This way, we can group custom modules and their related playbooks.

We create our custom Python module epoch_converter.py inside the library directory. This simple module takes as input the argument epoch_timestamp and converts it to datetime type. We use another argument, state_changed, to simulate a change in the target system by this module.

library/epoch_converter.py

#!/usr/bin/python from __future__ import (absolute_import, division, print_function)__metaclass__ = typeimport datetime DOCUMENTATION = r'''---module: epoch_converter short_description: This module converts an epoch timestamp to human-readable date. # If this is part of a collection, you need to use semantic versioning,# i.e. the version is of the form "2.5.0" and not "2.4".version_added: "1.0.0" description: This module takes a string that represents a Unix epoch timestamp and displays its human-readable date equivalent. options: epoch_timestamp: description: This is the string that represents a Unix epoch timestamp. required: true type: str state_changed: description: This string simulates a modification of the target's state. required: false type: bool author: - Ioannis Moustakis (@Imoustak)''' EXAMPLES = r'''# Convert an epoch timestamp- name: Convert an epoch timestamp epoch_converter: epoch_timestamp: 1657382362''' RETURN = r'''# These are examples of possible return values, and in general should use other names for return values.human_readable_date: description: The human-readable equivalent of the epoch timestamp input. type: str returned: always sample: '2022-07-09T17:59:22'original_timestamp: description: The original epoch timestamp input. type: str returned: always sample: '16573823622' ''' from ansible.module_utils.basic import AnsibleModule def run_module(): # define available arguments/parameters a user can pass to the module module_args = dict( epoch_timestamp=dict(type='str', required=True), state_changed=dict(type='bool', required=False) )  # seed the result dict in the object # we primarily care about changed and state # changed is if this module effectively modified the target # state will include any data that you want your module to pass back # for consumption, for example, in a subsequent task result = dict( changed=False, human_readable_date='', original_timestamp='' )  # the AnsibleModule object will be our abstraction working with Ansible # this includes instantiation, a couple of common attr would be the # args/params passed to the execution, as well as if the module # supports check mode module = AnsibleModule( argument_spec=module_args, supports_check_mode=True )  # if the user is working with this module in only check mode we do not # want to make any changes to the environment, just return the current # state with no modifications if module.check_mode: module.exit_json(**result)  # manipulate or modify the state as needed (this is going to be the # part where your module will do what it needs to do) result['original_timestamp'] = module.params['epoch_timestamp'] result['human_readable_date'] = datetime.datetime.fromtimestamp(int(module.params['epoch_timestamp']))  # use whatever logic you need to determine whether or not this module # made any modifications to your target if module.params['state_changed']: result['changed'] = True  # during the execution of the module, if there is an exception or a # conditional state that effectively causes a failure, run # AnsibleModule.fail_json() to pass in the message and the result if module.params['epoch_timestamp'] == 'fail': module.fail_json(msg='You requested this to fail', **result)  # in the event of a successful module execution, you will want to # simple AnsibleModule.exit_json(), passing the key/value results module.exit_json(**result) def main(): run_module() if __name__ == '__main__': main()

To test our module, let’s create a test_custom_module.yml playbook in the same directory as our library directory.

test_custom_module.yml

- name: Test my new module hosts: localhost tasks: - name: Run the new module epoch_converter: epoch_timestamp: '1657382362' state_changed: yes register: show_output - name: Show Output debug: msg: '{{ show_output }}'

Last stop, let’s execute the playbook to test our custom module. Since we opted to set the state_changed argument, we expect the task state to appear as changed and displayed in yellow.

Ansible Modules - How To Use Them Efficiently (Examples) (2)

If you wish to contribute to an existing Ansible collection or create and publish a new one with your custom modules, look at Distributing collections and Ansible Community Guide, where you can find information on how to configure and distribute Ansible content.

Ansible Modules Best Practices

Use specialized modules over shell or command: Although It might be tempting to use the shell or command module often, it’s considered a best practice to leverage more specific modules for each job. Specialized modules are typically recommended because they implement the concept of desired state and idempotency, have been tested, and fulfill basic standards, like error handling.

Specify arguments when it makes sense: Some module arguments have default values that can be omitted. To be more transparent and explicit, we can opt to specify some of these arguments like the state in our playbook definitions.

Prefer multi-tasks in a module over loops: The most efficient way of defining a list of similar tasks, like installing packages, is to use multiple tasks in a single module.

- name: Install Docker dependencies ansible.builtin.apt: name: - curl - ca-certificates - gnupg2 - lsb-release state: latest

The above method should be preferred over the loop or defining multiple separate tasks using the same module.

Custom modules should be simple and tackle a specific job: If you decide to build your own module, focus on solving a particular problem. Each module should have a concise functionality, be as simple as possible, and perform one thing well. If what you try to achieve goes beyond the scope of a single module, consider developing a new collection.

Custom modules should have predictable parameters: Try to enable others to use your module by defining a transparent and predictable user interface. The arguments should be well-scoped and understandable, and their structures should be as simple as possible. Follow the typical convention of parameter names in lowercase and use underscores as the word separator.

Document and test your custom modules: Every custom module should include examples, explicitly document dependencies, and describe return responses. New modules should be tested thoroughly before releasing. You can create roles and playbooks to test your custom modules and different test cases.

Key Points

We deep-dived into Ansible modules and examined their use and functionality in detail. We discussed best practices and showed practical examples of leveraging the most commonly-used modules. Lastly, we went through a complete example of developing a custom module.

You can also explore how Spacelift’s vibrant ecosystem and excellent GitOps flow can greatly assist you in managing and orchestrating Ansible. By introducing Spacelift on top of Ansible, you can then easily create custom workflows based on pull requests and apply any necessary compliance checks for your organization. Get started on your journey by creating a free trial account.

Thank you for reading, and I hope you enjoyed this article as much as I did.

Automation and Collaboration Layer for Infrastructure as Code

Spacelift is a flexible orchestration solution for IaC development. It delivers enhanced collaboration, automation and controls to simplify and accelerate the provisioning of cloud based infrastructures.

Start free trial

Ansible Modules - How To Use Them Efficiently (Examples) (2024)

FAQs

How do I use Ansible modules? ›

Creating and sharing Ansible modules
  1. Creating a library directory in your repository.
  2. Creating a module file in Python or your preferred programming language within the library directory.
  3. Developing a test playbook in your library directory.
  4. Executing the playbook to test the module.
Feb 12, 2024

When using Ansible What is the proper best practice way to begin a playbook? ›

When running a playbook, Ansible finds the variables in the unencrypted file and all sensitive variables come from the encrypted file. A best practice approach for this is to start with a group_vars/ subdirectory named after the group. Inside of this subdirectory, create two files named vars and vault .

How do I speed up Ansible execution? ›

If you're working with Ansible regularly, especially with complex playbooks, you probably wonder if there is a way for playbooks to run more quickly.
  1. Strategies for reducing the time Ansible takes to execute playbooks are: ...
  2. Setting up Local Infrastructure. ...
  3. Ansible Configuration File. ...
  4. Default Strategy. ...
  5. Disable Fact Caching.

What are the disadvantages of Ansible modules? ›

Ansible, while powerful for data center automation, has limitations. Its statelessness can complicate complex orchestration tasks, and scalability may become an issue with a large number of managed nodes. Real-time monitoring capabilities are limited, and error handling can be challenging for complex scenarios.

What are the most used modules in Ansible? ›

  • yum module. yum module is used to install different packages/software on Redhat based linux flavours. ...
  • apt module. apt package module is used for managing software on debian based linux os. ...
  • package module. ...
  • pip module. ...
  • npm module. ...
  • raw module. ...
  • command module. ...
  • shell module.
Jun 25, 2022

What is the difference between Ansible modules and playbooks? ›

Ansible modules are standalone scripts that can be used inside an Ansible playbook. A playbook consists of a play, and a play consists of tasks. These concepts may seem confusing if you're new to Ansible, but as you begin writing and working more with playbooks, they will become familiar.

Which of the following are Ansible best practices? ›

Ansible Best Practices
  • File System Layout. Organize projects with a consistent file system layout. ...
  • Ansible Configuration. Use ansible. ...
  • Playbook Design and Structure. Use Roles to modularize playbooks. ...
  • Variable Names. Choose descriptive variable names. ...
  • Error Handling in Ansible. ...
  • Ansible Logging. ...
  • Inline Comments. ...
  • READMEs.
Nov 28, 2023

What is the correct order of Ansible playbook execution? ›

Playbook execution. A playbook runs in order from top to bottom. Within each play, tasks also run in order from top to bottom.

What are the main use cases of Ansible? ›

Ansible has various use cases in Provisioning, Configuration Management, Application Deployment, Continuous Deployment, Automation, and Orchestration. So, if you are looking forward to a career in DevOps, IT automation, and managing cloud infrastructure then Ansible is a must-have.

How do I run multiple tasks in Ansible? ›

If you want to run multiple tasks in a playbook concurrently, use async with poll set to 0. When you set poll: 0 , Ansible starts the task and immediately moves on to the next task without waiting for a result. Each async task runs until it either completes, fails or times out (runs longer than its async value).

What is the free strategy of Ansible playbook? ›

In free strategy, the host does not depend on each other to complete tasks for e.g. webserver will not wait to complete the task on sqlserver. Let's consider a case, where the admin has to configure/install an application on a huge list of hosts (might be 100 or 1000).

What is Ansible strategy? ›

Ansible strategy refers to the approach or methodology used by Ansible to execute tasks on the managed nodes. By default, Ansible uses the linear strategy, which executes tasks one by one in the order they are defined in the playbook.

What kind of things Ansible Cannot do? ›

Ansible disadvantages include debugging, performance, complex data structures and control flow. Complex data structures. Many network automation tasks require complex data structures.

What is Ansible not good for? ›

Ansible doesn't inherently track the state of managed systems beyond the execution of tasks. This can be a disadvantage for scenarios requiring detailed state tracking and management, which are better addressed by tools like Terraform.

Why use Terraform instead of Ansible? ›

Both tools serve similar purposes, but they take different techniques and have other functionalities. Ansible is a powerful automation engine that makes configuration management and application deployment easier, whereas Terraform is a tool for building, updating, and versioning infrastructure safely and effectively.

Where do I put Ansible modules? ›

To load your local modules automatically and make them available to all playbooks and roles, add them in any of these locations:
  1. any directory added to the ANSIBLE_LIBRARY environment variable ( $ANSIBLE_LIBRARY takes a colon-separated list like $PATH )
  2. ~/. ansible/plugins/modules/
  3. /usr/share/ansible/plugins/modules/

How do I import modules into Ansible? ›

This module is part of ansible-core and included in all Ansible installations. In most cases, you can use the short module name import_playbook even without specifying the collections keyword. However, we recommend you use the Fully Qualified Collection Name (FQCN) ansible.

How do modules work? ›

In computer hardware, a module is a component that is designed for easy replacement. In computer software, a module is an extension to a main program dedicated to a specific function. In programming, a module is a section of code that is added in as a whole or is designed for easy reusability.

Where do Ansible modules run? ›

A module is a reusable, standalone script that Ansible runs on your behalf, either locally or remotely. Modules interact with your local machine, an API, or a remote system to perform specific tasks like changing a database password or spinning up a cloud instance.

Top Articles
Latest Posts
Article information

Author: Tish Haag

Last Updated:

Views: 5908

Rating: 4.7 / 5 (67 voted)

Reviews: 82% of readers found this page helpful

Author information

Name: Tish Haag

Birthday: 1999-11-18

Address: 30256 Tara Expressway, Kutchburgh, VT 92892-0078

Phone: +4215847628708

Job: Internal Consulting Engineer

Hobby: Roller skating, Roller skating, Kayaking, Flying, Graffiti, Ghost hunting, scrapbook

Introduction: My name is Tish Haag, I am a excited, delightful, curious, beautiful, agreeable, enchanting, fancy person who loves writing and wants to share my knowledge and understanding with you.