Ansible Cheat Sheet

Ansible Concepts Cheat Sheet

Core Components

  • Control Node: The machine where you install Ansible and from which you execute all commands and playbooks.
  • Managed Nodes: The devices (servers, network devices, etc.) that Ansible manages. These are often called hosts.
  • Inventory: A file that contains a list of the managed nodes. It can be a simple static file or a dynamic one generated by a script.
  • Modules: The specific units of code that Ansible executes on the managed nodes. Each module is designed to perform a specific task, like installing a package or copying a file.
  • Tasks: A single action that a module performs. Playbooks are made up of a list of tasks.
  • Playbooks: YAML files that contain a series of plays, which in turn contain a list of tasks to be executed on a group of managed nodes. Playbooks define the desired state of your systems.
  • Roles: A way to group related content, such as tasks, handlers, and variables, into a reusable and shareable structure. Roles help to organize complex playbooks.

Key Terminology

  • Facts: Information gathered about the managed node by Ansible’s setup module. This includes details like the operating system, network configuration, and hardware specifications.
  • Variables: Key-value pairs used to store and reuse data within playbooks. They can be defined in a variety of places, including inventory files, playbooks, or separate variable files.
  • Handlers: Special tasks that are only run when notified by another task. They are typically used for service restart actions.
  • Loops: A way to repeat a task multiple times with different values. This is used to avoid repeating the same task definition for each item.
  • Conditional Statements: Used to run tasks only if a certain condition is met. This allows for flexible and intelligent playbooks that can adapt to different situations.
  • Templates: Files that contain variables and control structures and are processed by the Jinja2 templating engine. They are often used to create configuration files on managed nodes.
  • Ad-hoc Commands: Single-line commands executed from the control node to perform quick, one-off tasks without writing a full playbook.
  • Vault: A feature for encrypting sensitive data, like passwords and API keys, within Ansible.
  • Collections: A standard way to package, share, and distribute Ansible content, including playbooks, roles, modules, and plugins.
  • Plugins: Extend Ansible’s core functionality. Examples include inventory plugins (to gather hosts from a dynamic source) or connection plugins (to connect to managed nodes via different protocols).
  • Tags: A mechanism to label tasks and plays, allowing you to run only specific parts of a playbook.
  • Play: A grouping of tasks that target a specific set of hosts. A playbook can contain one or more plays.

Advanced Concepts

  • Idempotence: A fundamental concept in Ansible. It means that an operation can be applied multiple times without changing the result beyond the initial application. Ansible modules are designed to be idempotent, ensuring that running a playbook repeatedly won’t cause unintended side effects.
  • YAML: The human-readable data serialization language used for writing playbooks, inventory files, and configuration files. It stands for “YAML Ain’t Markup Language” and is known for its simple syntax.
  • Jinja2: The templating engine used by Ansible. It’s used to create dynamic configuration files and other documents by embedding variables, expressions, and control structures within text files.
  • Delegation: The process of running a task on a different host than the one being targeted in the play. This is often used for tasks like managing a load balancer or a database.
  • Connection Plugins: These plugins define how Ansible connects to managed nodes. The default is SSH, but there are others for Windows (winrm), network devices, and more.
  • Lookup Plugins: Used to retrieve data from external sources, such as files, environment variables, or other systems, and use that data in playbooks.
  • Callbacks: Plugins that interact with Ansible’s execution, such as printing custom output or sending notifications to a logging service.
  • Filters: A way to transform data within a playbook. They can be used to manipulate strings, lists, or other variables. A common filter is to_json to convert a variable into JSON format.
  • Facts Cache: A method to save facts gathered from managed nodes to avoid having to re-run the setup module on every execution, which can speed up large-scale playbook runs.
  • Ansible Tower / AWX: A web-based solution that provides a user interface for Ansible. It includes features for role-based access control, scheduling, and centralized logging. AWX is the open-source version of Ansible Tower.
  • Configuration Management: The broader IT discipline that Ansible belongs to. It involves managing the state of a system’s configuration to ensure it is consistent and compliant.

Ansible Directory Structure

/my_ansible_project/
├── playbook.yml            # Main playbook file
├── ansible.cfg             # Optional, but recommended configuration file
├── inventory/
│   ├── production          # Inventory for production environment
│   └── staging             # Inventory for staging environment
├── group_vars/
│   ├── all.yml             # Variables for all hosts
│   ├── web_servers.yml     # Variables for the 'web_servers' group
│   └── database.yml        # Variables for the 'database' group
├── host_vars/
│   ├── server1.yml         # Variables for 'server1' host
│   └── server2.yml         # Variables for 'server2' host
└── roles/
    ├── web_server/         # 'web_server' role
    │   ├── defaults/       # Default variables for the role
    │   │   └── main.yml
    │   ├── handlers/       # Handlers for the role
    │   │   └── main.yml
    │   ├── tasks/          # Main tasks for the role
    │   │   └── main.yml
    │   ├── templates/      # Jinja2 templates for the role
    │   ├── files/          # Static files to copy
    │   └── meta/           # Metadata for the role
    │       └── main.yml
    └── database_server/    # 'database_server' role
        ├── defaults/
        │   └── main.yml
        └── tasks/
            └── main.yml

Explanation of Components

  • playbook.yml: The main entry point for your automation. It calls the roles and defines the high-level logic for your infrastructure.
  • ansible.cfg: A configuration file that can specify the location of your inventory, roles, and other settings.
  • inventory/: A directory to store separate inventory files for different environments (e.g., production, staging).
  • group_vars/ and host_vars/: Directories to store variables specific to host groups or individual hosts. This is a best practice for managing environment-specific configurations.
  • roles/: This directory contains all your reusable roles. Each role is a self-contained unit of automation.
  • Role Directories: A standard role directory has a specific structure:
    • tasks/: Contains the tasks that the role will execute. main.yml is the default file that is run when the role is called.
    • handlers/: Contains handlers, which are tasks that are only triggered when notified.
    • defaults/: Contains default variables for the role. These variables can be overridden by other variables.
    • files/: Contains static files that can be copied to managed hosts.
    • templates/: Contains Jinja2 templates that can be rendered with variables and copied to managed hosts.
    • meta/: Contains metadata about the role, such as its dependencies.

Nodes

What are Ansible Nodes?

Ansible uses the term nodes to refer to the machines it manages. There are two types of nodes in an Ansible setup:

  • Control Node: The machine where Ansible is installed and from which you run all commands and playbooks. It’s the “master” machine that orchestrates the automation.
  • Managed Nodes: The target machines that the control node manages. These are the servers, network devices, or other devices where Ansible performs tasks. They are also commonly called hosts.

Key Characteristics & Workflow

  • Agentless: Unlike other configuration management tools, Ansible doesn’t require any special agent software to be installed on the managed nodes. This simplifies deployment and management.
  • Communication: Communication between the control node and managed nodes is typically done over SSH (Secure Shell) for Linux/Unix systems. For Windows, it uses WinRM (Windows Remote Management).
  • Python Requirement: Managed nodes only need Python (version 2.6+ or 3.5+) to run Ansible modules.
  • Inventory: Managed nodes are defined in an inventory file, which is a list of hosts organized by groups. This file tells Ansible which machines to target.

How it Works

  1. You execute an Ansible command or playbook from the control node.
  2. Ansible connects to the specified managed nodes using SSH or WinRM.
  3. It temporarily copies the necessary modules to the managed node.
  4. The modules execute on the managed node, performing the desired task.
  5. After the task is completed, the modules are removed from the managed node.
  6. Ansible returns the output and status of the task to the control node.

This process is what makes Ansible agentless and a simple and powerful automation tool.

Inventory

An Ansible Inventory is a file or set of files that defines the managed nodes (hosts) that Ansible will interact with. It serves as the primary source of truth for all machines, groups of machines, and associated variables you are managing.

Inventory Types

  • Static Inventory: A simple text file that you manually create and maintain. This is the most common type and is suitable for environments that don’t change frequently.
  • Dynamic Inventory: A script or program that generates a list of hosts on the fly. This is useful for cloud environments (like AWS, Azure, GCP) where hosts are frequently created or destroyed. Ansible provides plugins for many cloud providers.

File Formats & Structure

The inventory can be written in either INI or YAML format.

INI Format (Common)

Hosts are listed under group headings. Host and group-level variables can also be defined.

[web_servers]
server1.example.com
server2.example.com

[database_servers]
db1.example.com
db2.example.com

[all:vars]
ansible_user=ubuntu
  • Groups: Hosts are organized into logical groups, like web_servers or database_servers.
  • Host Variables: Variables specific to a single host can be defined on the same line.
  • Group Variables: Variables that apply to all hosts in a group can be defined under a [group:vars] section.
YAML Format

This format is often preferred for its readability, especially for complex structures.

all:
  hosts:
    server1.example.com:
    server2.example.com:
  children:
    web_servers:
      hosts:
        server1.example.com:
        server2.example.com:
      vars:
        ansible_user: ubuntu
    database_servers:
      hosts:
        db1.example.com:
        db2.example.com:

Best Practices

  • Version Control: Always keep your inventory file in a version control system like Git.
  • Separate Environments: Use separate inventory files or directories for different environments (e.g., production, staging, development).
  • Use Variables: Define host and group variables within the inventory to keep playbooks more generic and reusable. This is a powerful feature for managing environment-specific settings.

Task

An Ansible task is a single, defined action to be executed on a managed node. It is the fundamental building block of a playbook. Each task has a specific goal, such as installing a package, copying a file, or starting a service. Tasks are always executed in the order they appear within a playbook.

Basic Syntax

A task is defined using a module and its arguments. The name is optional but highly recommended for readability and debugging.

- name: This is a descriptive name for the task
  module_name:
    argument1: value
    argument2: value

Key Attributes and Directives

These are common attributes used to control a task’s behavior.

  • name: A human-readable description of the task. Essential for providing context in playbook output.
  • become: A directive to escalate privileges on the managed node (e.g., to run a command as root). The become_user can be specified as well.
  • when: A conditional statement that allows a task to run only if a specific condition is met.
  • with_items (or loop): A loop that iterates through a list of values, allowing the same task to be run multiple times with different input.
  • register: A directive that saves the output of a task into a variable. This variable can then be used in subsequent tasks or conditional statements.
  • notify: Used to notify a handler to run, typically after a task has made a change.

Common Task Examples

Here are some examples of tasks using popular modules.

1. Installing a Package

This task uses the apt module to ensure the nginx package is installed on a managed node.

- name: Install NGINX web server
  apt:
    name: nginx
    state: present

2. Copying a File

This task uses the copy module to move a file from the control node to the managed node.

- name: Copy the NGINX configuration file
  copy:
    src: /path/to/local/nginx.conf
    dest: /etc/nginx/nginx.conf

3. Running a Command with a Condition

This task runs the reboot command only if the reboot_required variable is set to true.

- name: Reboot the server if required
  command: /sbin/reboot
  when: reboot_required

Modules

Ansible modules are the specific units of code that perform a single task on a managed node. They are the core workhorses of Ansible, as they are the part that actually interacts with the system to achieve a desired state. Each module is designed to perform a specific function, such as managing packages, services, files, or users.

How They Work

  1. Execution: When a playbook runs, Ansible transfers the necessary module to the managed node (typically via SSH).
  2. Execution: The module runs on the managed node, using its logic to perform the specified task (e.g., installing a package).
  3. Result: The module returns a JSON-formatted response to the control node, indicating whether it made a change and providing other output details. This result is used to determine if a handler should be notified or if a task needs to be skipped on subsequent runs.
  4. Cleanup: The temporary module file is then removed from the managed node.

This process is what makes Ansible agentless and a simple and powerful automation tool.

Key Characteristics

  • Idempotence: Most modules are designed to be idempotent. This means running a task multiple times will result in the same outcome as running it once. For example, running the apt module to ensure a package is “present” will not reinstall it if it’s already there.
  • Module Library: Ansible ships with a vast library of over 1,000 modules for a wide range of tasks, from low-level system administration to cloud provisioning and network management.
  • Declarative: Modules are designed to be declarative. You describe the state you want to achieve, and the module figures out the steps to get there. For instance, you declare that a file should state: present rather than writing a script to check for its existence first.

Common Module Examples

ModuleDescriptionExample Usage
apt / yumManages packages on Debian/Ubuntu or Red Hat-based systems.- name: Install NGINX <br> apt: name: nginx state: present
serviceManages services.- name: Start NGINX service <br> service: name: nginx state: started
copyCopies a file from the control node to the managed node.- name: Copy config file <br> copy: src: my_config dest: /etc/config
fileManages files, directories, and symlinks.- name: Create a directory <br> file: path: /data/ dir state: directory
commandExecutes a command on the managed node.- name: Run a command <br> command: echo "hello world"

Plugins

Ansible plugins are pieces of code that extend and enrich Ansible’s core functionality. They are a way to customize Ansible’s behavior without modifying the main source code. Plugins run on the control node and enable Ansible to connect to different systems, gather data from external sources, or process information in new ways.

Common Types of Plugins

Plugin TypeDescriptionExample Use Case
InventoryExtends Ansible to get host and group information from dynamic sources like cloud providers (AWS, Azure, GCP), CMDBs, or other external databases.Automatically generate an inventory of all your EC2 instances in AWS.
ConnectionDefines how Ansible connects to managed nodes. The default is SSH, but other plugins exist for different protocols.Connect to Windows machines using WinRM or to network devices via a specific API.
LookupFetches data from external sources and integrates it into a playbook. Sources can include files, environment variables, or other services.Read a list of usernames from a local file to create users on a remote server.
FilterTransforms data into a different format. They are often used with Jinja2 templates.Convert a JSON string to a Python dictionary, or a list of items into a comma-separated string.
CallbackControls the output and logging of a playbook run. They can send notifications to external systems like Slack or a logging service.Send a message to a Slack channel when a playbook run fails.
ActionA special type of module that runs on the control node. Many core modules are actually action plugins.Processes a file before sending it to a remote host, like the template or copy modules.

Filter Plugin

Ansible filter plugins are a type of plugin that extends Ansible’s ability to transform and manipulate data. They run on the control node and are primarily used within Jinja2 templates and expressions to modify data before it is used. They are a powerful way to process variables, format output, and handle complex data structures without requiring external tools or complicated logic in your playbooks.

How They Work

A filter plugin takes data as input, applies a transformation, and returns the modified data. You use them by piping a variable or expression to the filter name.

Example: Basic String Transformation
- name: Convert a string to uppercase
  ansible.builtin.debug:
    msg: "{{ 'hello world' | upper }}"

In this simple example, the upper filter is a built-in filter plugin that converts a string to uppercase. The output would be HELLO WORLD.

Creating a Custom Filter Plugin

While Ansible includes many built-in filters, you can also write your own to perform custom data transformations.

  1. Create the Plugin File: Create a Python file inside a filter_plugins directory within your playbook project or a role.
  2. Define the Filter: The Python file needs to contain a function that takes input and returns the transformed output. The function is then added to a dictionary named FilterModule.
Example Plugin (filter_plugins/my_filters.py)
def my_custom_filter(data):
    # This filter will simply reverse a string
    return data[::-1]

class FilterModule(object):
    def filters(self):
        return {
            'reverse_string': my_custom_filter,
        }
Using the Custom Filter in a Playbook

Once the custom filter plugin is in place, you can use it in any playbook within the same project.

- name: Use the custom filter to reverse a string
  ansible.builtin.debug:
    msg: "{{ 'ansible' | reverse_string }}"

This would output elbisna.

Connection Plugin

A Connection Plugin in Ansible is a piece of code that defines how Ansible communicates with a managed node. It’s the mechanism responsible for transferring modules and commands to the remote host and retrieving the results. Connection plugins run on the control node and are essential for making Ansible a truly “agentless” tool.

How it Works

When you run a playbook or an ad-hoc command, Ansible uses a connection plugin to establish a link to the managed node. The most common connection plugins are:

  • ssh: The default and most widely used plugin. It connects to Linux/Unix machines over the standard SSH protocol. It is the most robust and secure option for these systems.
  • winrm: This plugin is used to connect to Windows servers via the Windows Remote Management protocol.
  • local: This plugin executes tasks on the control node itself, bypassing the need for a remote connection. It’s often used for tasks that don’t need to be run on remote hosts, such as managing local files or using lookup plugins.
  • netconf: Used for managing network devices that support the NETCONF protocol.
Key Characteristics and Usage
  • Agentless: Connection plugins do not require any persistent agent software on the managed nodes. They establish a connection, perform a task, and then disconnect.
  • Configuration: You can specify the connection plugin to use either in your playbook or in the inventory file. For example, to use winrm, you would set ansible_connection: winrm in your inventory.
  • Customization: You can write your own connection plugins to support custom protocols or to interact with devices that don’t use standard SSH or WinRM.

Action Plugin

An Action Plugin is a type of plugin that executes on the control node before the module is called on the managed node. It’s a special kind of plugin that can run tasks that require logic or operations on the control node itself, and then pass the results to the remote module for execution. Many of Ansible’s core modules, like ansible.builtin.copy and ansible.builtin.template, are implemented as action plugins.

How it Works

Action plugins act as an intermediary between the Ansible core and the remote module. They perform several key functions:

  1. Local Operations: An action plugin can perform local tasks on the control node. For example, the template action plugin will process a Jinja2 template file on the control node before sending the final, rendered file to the managed node.
  2. Module Transfer: They handle the transfer of the actual module code to the managed node.
  3. Argument Handling: They can manipulate or validate the arguments passed to the module before execution.
Key Characteristics and Examples
  • Runs on Control Node: Unlike a typical module that runs on the managed node, the action plugin itself runs on the control node.
  • Complex Logic: They are used for tasks with complex logic that cannot be performed directly on the managed node.
  • Built-in Plugins: Many of the most-used Ansible modules are actually action plugins.
PluginWhat it Does
ansible.builtin.copyAction plugin that copies a file from the control node to the managed node.
ansible.builtin.templateProcesses a Jinja2 template file locally on the control node and then sends the rendered file to the managed node.
ansible.builtin.shellTakes a command from the playbook, formats it for the remote shell, and then executes it on the managed node.

Callback Plugin

A Callback Plugin in Ansible is a piece of code that allows you to customize and extend how Ansible’s output is displayed and handled. These plugins run on the control node at key moments during a playbook execution, such as when a task starts, completes, or fails, or when a play finishes. They provide a way to hook into the Ansible process and perform actions like logging, sending notifications, or generating custom reports based on the playbook’s results.

How it Works

Callback plugins are often used for integrations with other systems. They can:

  • Log Results: Send detailed results of a playbook run to a centralized logging system like Splunk or ELK.
  • Send Notifications: Trigger notifications to a team chat service like Slack or to a ticketing system like Jira when a playbook fails or completes.
  • Generate Reports: Create custom reports or summaries of the automation run, which can be useful for auditing and compliance.
Key Characteristics
  • Runs on Control Node: Like other plugins, callback plugins run on the machine from which you are executing Ansible.
  • Event-Driven: They are triggered by specific events during a playbook run.
  • Customizable Output: The default output of Ansible is a callback plugin itself. You can enable or disable other plugins to change how output is displayed.

To use a callback plugin, you typically enable it in your ansible.cfg file by setting the stdout_callback option. You can also specify a plugin directory to use custom ones.

Example Use Case

A common use case is to get a notification in Slack when a production deployment finishes. You would configure a callback plugin to send a message to a specific Slack channel after the playbook completes, providing a summary of the successful deployment. This allows team members to stay informed about automation events without having to monitor the command line output.

Lookup Plugin

A Lookup Plugin is a type of plugin that runs on the control node to retrieve data from external sources.1 It’s a way to pull information into your playbooks from a variety of places, such as files, environment variables, databases, or even other command outputs.2 Lookup plugins are essential for creating dynamic playbooks that don’t rely on static data and can fetch information as needed during an automation run.

How It Works

A lookup plugin operates on the control node to find a value and then returns that value to the playbook. The most common use is to populate a variable. You use the lookup keyword, which takes the name of the plugin and its arguments.3

Example: Looking up a value from a file

The file lookup plugin reads the contents of a file on the control node.4

- name: Read a secret from a local file
  vars:
    my_secret: "{{ lookup('file', '/etc/ansible/secrets/api_key.txt') }}"

- name: Debug the secret variable
  ansible.builtin.debug:
    msg: "The API key is {{ my_secret }}"

In this example, the playbook will read the contents of api_key.txt and assign it to the my_secret variable.

Common Lookup Plugin Examples
PluginDescriptionExample Use
fileReads the contents of a file.Read a single line of text into a variable.
envRetrieves the value of an environment variable.Get a value like HOME or a custom variable set in your shell.
pipeExecutes a command and returns its standard output.Run a local grep command to find a value.
passwordGenerates or retrieves a password.Create a random password for a new user or database.
iniReads values from an INI file.Get configuration settings from a local .ini file.

Playbooks

Ansible playbooks are files written in YAML that define a set of instructions, or “plays,” to be executed on a group of managed nodes. They are the core of Ansible’s automation and are used to orchestrate a series of tasks to achieve a desired state on your systems. Playbooks are declarative, meaning you describe the end state you want, and Ansible figures out how to get there.

Core Components

A playbook is composed of several key elements:

  • Plays: A playbook is a list of one or more plays. Each play is a block that targets a specific group of hosts from the inventory and defines the tasks to be run on them.
  • Hosts: This directive specifies which hosts from your inventory the play will target. It can be a group name (e.g., web_servers), a host name, or all.
  • Tasks: A list of tasks to be executed in the order they are defined. Each task calls an Ansible module to perform a specific action, like installing a package or copying a file.
  • Variables: Playbooks can use variables to store data, making them more flexible and reusable. Variables can be defined within the playbook, in separate files, or in the inventory.
  • Roles: Playbooks often use roles to organize related tasks, handlers, variables, and files into a reusable structure. This is a best practice for managing complex automation projects.

Example Playbook Structure

This example shows a simple playbook that installs and starts the NGINX web server on a group of hosts.

---
- name: Install and configure a web server
  hosts: web_servers
  become: yes
  vars:
    nginx_port: 80

  tasks:
    - name: Ensure NGINX is installed
      ansible.builtin.apt:
        name: nginx
        state: present

    - name: Copy NGINX configuration file
      ansible.builtin.copy:
        src: files/nginx.conf
        dest: /etc/nginx/nginx.conf
      notify: restart nginx

    - name: Ensure NGINX service is running and enabled
      ansible.builtin.service:
        name: nginx
        state: started
        enabled: yes

  handlers:
    - name: restart nginx
      ansible.builtin.service:
        name: nginx
        state: restarted

Play

An Ansible play is a grouping of tasks that are executed on a specific set of hosts from your inventory. It’s a single unit of work within a playbook and is used to define the high-level goal for a set of machines. A playbook can contain one or more plays, each targeting different hosts or performing different roles.

Anatomy of a Play

A play is defined by its target hosts, and all the tasks that follow apply to those hosts.

  • name: An optional but highly recommended descriptive name for the play.
  • hosts: Specifies the group of hosts from your inventory that the play will run on. It can target a group name, a specific hostname, or all.
  • tasks: The list of tasks to be executed on the targeted hosts. The tasks are run sequentially on each host.
  • become: A directive to escalate privileges on the managed nodes within the play. Setting become: yes is the equivalent of using sudo on the control node.
  • vars: A section to define variables that are local to the current play.

Example Play

Here’s an example of a play within a playbook.

---
- name: "This is the first play: configure web servers"
  hosts: web_servers
  become: yes
  vars:
    web_server_port: 80

  tasks:
    - name: Ensure NGINX is installed
      ansible.builtin.apt:
        name: nginx
        state: present
    
    - name: Ensure the web service is running
      ansible.builtin.service:
        name: nginx
        state: started

- name: "This is the second play: configure database servers"
  hosts: database_servers
  become: yes

  tasks:
    - name: Ensure PostgreSQL is installed
      ansible.builtin.apt:
        name: postgresql
        state: present
    
    - name: Ensure the database service is running
      ansible.builtin.service:
        name: postgresql
        state: started

In this example, the playbook contains two plays. The first play targets the web_servers group and performs tasks to install and start a web service. The second play then targets the database_servers group to install and start a database service. This demonstrates how plays divide a playbook into logical, host-specific sections.

Tags

Ansible tags are a way to label tasks, plays, or even roles within your playbooks. They provide a mechanism for running only a specific subset of your automation, which is extremely useful for debugging, testing, or running a targeted part of a large playbook. Instead of running the entire playbook from start to finish, you can use tags to skip irrelevant steps and execute only what’s necessary.

How to Add Tags

You can add a tag to a task, a play, or a role using the tags keyword. You can assign a single tag or a list of tags to any of these elements.

1. Tagging a Task
- name: Install NGINX
  ansible.builtin.apt:
    name: nginx
    state: present
  tags:
    - web
    - install
2. Tagging a Play
---
- name: This is the web servers play
  hosts: web_servers
  tags:
    - web_servers_play
  tasks:
    - name: Ensure NGINX is installed
      ansible.builtin.apt:
        name: nginx
        state: present

How to Use Tags

You use the ansible-playbook command with specific command-line flags to control which tagged tasks are executed.

1. Running Only Specific Tags

To run only the tasks with a given tag, use the --tags or -t flag.

ansible-playbook my_playbook.yml --tags "web, install"

This command would only run tasks that have been tagged with either “web” or “install”.

2. Skipping Specific Tags

To run all tasks except those with a specific tag, use the --skip-tags or -s flag.

ansible-playbook my_playbook.yml --skip-tags "web"

This command would run every task in the playbook except for those tagged with “web”.

3. Special Tags

Ansible has two special tags:

  • always: A task with the always tag will run regardless of what other tags are specified via --tags or --skip-tags. This is useful for cleanup or reporting tasks that should never be skipped.
  • never: A task with the never tag will not run unless you explicitly include it using the --tags flag. This is helpful for tasks that you only want to run on rare occasions, like a full system backup.

Roles

Ansible Roles are a way to organize and reuse automation content. They are a core part of Ansible’s best practices, providing a structured, hierarchical directory of files for a specific function. By using roles, you can group related tasks, handlers, variables, files, and templates into a single, cohesive unit. This makes your playbooks more modular, easier to maintain, and shareable.

Why Use Roles?

  • Reusability: Roles are self-contained, so you can easily use the same role in different playbooks or for different environments.
  • Modularity: They break down complex automation tasks into smaller, manageable units. For example, you can have a role for “web_server,” a role for “database_server,” and a role for “monitoring_agent.”
  • Standardization: They enforce a standard directory structure, which makes it easier for team members to understand and work with a project.
  • Shareability: Roles can be easily shared with others via Ansible Galaxy, a public hub for community-contributed roles.

Standard Role Directory Structure

The structure for a role is strict and helps keep content organized. When you create a role, Ansible expects a specific set of subdirectories.

/roles/
└── my_role/
    ├── defaults/             # Default variables for the role
    │   └── main.yml
    ├── handlers/             # Handlers (tasks that are notified)
    │   └── main.yml
    ├── tasks/                # Main tasks for the role
    │   └── main.yml
    ├── templates/            # Jinja2 templates
    ├── files/                # Static files to be copied
    ├── vars/                 # Other variables
    │   └── main.yml
    └── meta/                 # Metadata about the role (e.g., dependencies)
        └── main.yml

How to Use a Role

You don’t run a role directly. Instead, you call it from within a playbook using the roles directive.

---
- name: Deploy a web server with a single role
  hosts: web_servers
  become: yes
  roles:
    - web_server

Variables

Ansible variables are key-value pairs used to store and reuse data within playbooks. They allow you to write generic playbooks that can be adapted for different environments or configurations without modifying the playbook code itself. This makes your automation more flexible, reusable, and maintainable.

Variable Scope and Precedence

Variables have a specific scope, which determines where they are accessible. Ansible resolves variables based on a set order of precedence. A variable defined with higher precedence will override a variable of the same name defined with a lower precedence.

Here is a simplified order from lowest to highest precedence:

  1. Inventory Variables: Defined in inventory files.
  2. group_vars and host_vars: Files that store variables for specific groups or hosts.
  3. Role Defaults: Defined in the defaults/main.yml file of a role. These have the lowest precedence and are easily overridden.
  4. Role Variables: Defined in the vars/main.yml file of a role.
  5. Playbook Variables: Defined in the vars section of a playbook.
  6. Extra Vars (-e): Variables passed on the command line using the -e flag. These have the highest precedence and are often used to override specific values for a single run.

How to Define Variables

Variables can be defined in a variety of places, depending on their scope.

1. In Inventory

Variables can be defined directly in the inventory file (INI or YAML).

[web_servers]
server1.example.com http_port=8080
server2.example.com http_port=8080
2. In group_vars and host_vars

This is a recommended method for managing environment-specific variables.

File: group_vars/web_servers.yml

---
ansible_user: web_admin
db_host: db1.example.com
3. In a Playbook

Variables can be defined at the playbook level using the vars keyword.

---
- name: Deploy a web server
  hosts: web_servers
  vars:
    ansible_user: deploy_user

  tasks:
    - name: Ensure website is running
      ansible.builtin.command: "{{ ansible_user }} is logged in"

How to Use Variables

To use a variable, you enclose its name in double curly braces, like {{ variable_name }}.

- name: Use the user variable to create a directory
  ansible.builtin.file:
    path: "/home/{{ ansible_user }}/data"
    state: directory

Facts

Ansible facts are pieces of information about the managed nodes that are automatically collected by Ansible during a playbook run. Think of them as a real-time snapshot of a system’s state. They provide a wealth of dynamic data, like the operating system, IP address, network configuration, available memory, and disk space. This information is crucial for writing intelligent and adaptable playbooks.

How They Work

Ansible uses a built-in module called setup to gather facts. By default, Ansible runs this module at the start of every play in a playbook. The collected facts are stored in a variable called ansible_facts. You can then access and use these variables just like any other variable within your tasks, conditionals, and templates.

Example: Accessing a Fact

To use a fact, you can reference it using the ansible_facts dictionary.

  • To get the operating system family: {{ ansible_facts['os_family'] }}
  • To get the default IPv4 address: {{ ansible_facts['default_ipv4']['address'] }}
  • To get the hostname: {{ ansible_facts['hostname'] }}

Key Use Cases

  • Conditional Logic: Use facts to run tasks only when certain conditions are met. This is a powerful way to make playbooks smarter and more efficient. For example, you can install a package using apt on Debian-based systems and yum on Red Hat-based systems.YAML- name: Install a web server ansible.builtin.yum: name: httpd state: present when: ansible_facts['os_family'] == "RedHat" - name: Install a web server ansible.builtin.apt: name: apache2 state: present when: ansible_facts['os_family'] == "Debian"
  • Dynamic Configuration: Facts can populate templates to generate configuration files that are tailored to each specific host.
  • Reporting and Debugging: You can use the debug module to print out facts and help with troubleshooting.

Controlling Fact Gathering

Sometimes, gathering facts can add unnecessary time to a playbook run, especially in large environments. You can control this behavior:

  • Disabling Facts: To disable fact gathering for a specific play, set gather_facts: false.YAML- name: A play without fact gathering hosts: all gather_facts: false tasks: - name: A simple task that does not need facts ansible.builtin.ping:
  • Caching Facts: For a performance boost, especially in large environments, you can configure fact caching. This stores the collected facts so Ansible doesn’t need to re-gather them on every run.

Handlers & Notifier

Ansible handlers are special tasks that only run when they are explicitly notified by another task. They are designed to manage services or perform other actions that are only necessary when a change has been made. For example, if you modify a configuration file, you should restart the service it affects only after the file has been successfully written. Handlers provide a way to trigger such actions conditionally and at the end of a play, ensuring that services are only restarted once, even if multiple tasks have notified them.

How They Work

  1. A task in a playbook makes a change to the managed node (e.g., updates a file, installs a new package).
  2. The task then uses the notify directive to call a handler by name.
  3. Ansible registers this notification but does not run the handler immediately.
  4. After all the tasks in the current play have been completed, Ansible checks for any registered notifications.
  5. If a handler was notified, it will run. Even if multiple tasks notify the same handler, it will only run once. This is a key feature that prevents unnecessary restarts and saves time.

Syntax and Example

Handlers are defined in their own section in a playbook or, more commonly, in a handlers/main.yml file within a role.

Defining a Handler
---
- name: restart webserver
  ansible.builtin.service:
    name: nginx
    state: restarted
Notifying a Handler

You can call the handler by its name using the notify directive in a task.

---
- name: Ensure the NGINX configuration file is correct
  ansible.builtin.template:
    src: templates/nginx.conf.j2
    dest: /etc/nginx/nginx.conf
  notify: restart webserver

Loops

Ansible loops are a way to repeat a single task multiple times with different input values. They allow you to avoid writing redundant code in your playbooks by iterating over lists, dictionaries, or the results of other tasks. This makes your playbooks more concise, readable, and efficient. The most common loop construct is the loop keyword, which replaces the older with_items and other with_ directives.

Basic Loop Syntax

The loop keyword is added to a task and is followed by the list you want to iterate over. Within the task, you can access the current item in the loop using the item variable.

- name: Install a list of packages
  ansible.builtin.apt:
    name: "{{ item }}"
    state: present
  loop:
    - nginx
    - htop
    - git

In this example, the task will run three times, with the item variable taking on the values nginx, htop, and git in each iteration.

Looping Over Dictionaries

You can also loop over a list of dictionaries. In this case, you can access the individual keys of the dictionary.

- name: Create multiple users with specific UIDs
  ansible.builtin.user:
    name: "{{ item.name }}"
    uid: "{{ item.uid }}"
    state: present
  loop:
    - { name: 'john', uid: '1001' }
    - { name: 'jane', uid: '1002' }
    - { name: 'sam', uid: '1003' }

Looping Over Registered Variables

A powerful use of loops is to iterate over the output of a previous task that has been registered into a variable.

- name: Get a list of running services
  ansible.builtin.service_facts:
  register: service_list

- name: Debug a list of services
  debug:
    var: item
  loop: "{{ service_list.ansible_facts.services | dict2items }}"

In this case, the loop iterates over the output of the service_facts module, allowing you to process each service individually.

Common Loop Directives

  • loop: The standard and modern way to loop.
  • loop_control: A directive that allows you to change the variable name from the default item to something more descriptive, or to control batching behavior. For example, loop_control: loop_var: package_name.
  • with_items: The legacy loop directive that is still functional but replaced by the more general loop.
  • with_subelements: A directive for looping over nested data structures.

Conditional Statements

Conditional statements in Ansible are used to control whether a task, play, or other action is executed. They allow you to define logic in your playbooks, ensuring that certain steps are performed only when specific conditions are met. This makes your automation smarter and more adaptable, as it can react dynamically to the state of the managed nodes. The primary keyword for a conditional statement is when.

Basic Syntax and Usage

The when clause is added to a task and is followed by an expression that evaluates to True or False. If the expression is True, the task runs; otherwise, it is skipped.

- name: Install a package only on CentOS servers
  ansible.builtin.yum:
    name: httpd
    state: present
  when: ansible_facts['distribution'] == "CentOS"

In this example, the task will only execute on hosts where the Ansible fact ansible_facts['distribution'] is equal to “CentOS”.

Common Conditional Expressions

You can use various tests and operators within the when clause.

Comparison Operators: Use operators like == (equal to), != (not equal to), > (greater than), and < (less than).

- name: Reboot if kernel version is less than 5.0
  ansible.builtin.reboot:
  when: ansible_facts['kernel'] < "5.0"

Logical Operators: Combine multiple conditions using and, or, and not.

- name: Start NGINX service on port 80 if host is not in production
  ansible.builtin.service:
    name: nginx
    state: started
  when: ansible_facts['default_ipv4']['address'] != '127.0.0.1' and inventory_hostname != 'prod_web_01'

Tests: Use special tests to check for conditions like a variable being defined (is defined), a string containing a substring (in), or a list being empty.

- name: Run a task only if a variable is defined
  ansible.builtin.debug:
    msg: "The user is {{ user_name }}"
  when: user_name is defined

Conditional Statements with Loops

You can apply a conditional statement to a task that contains a loop. The when condition is evaluated once for the entire task.

- name: Install packages only if the OS is Debian
  ansible.builtin.apt:
    name: "{{ item }}"
    state: present
  loop:
    - vim
    - tmux
  when: ansible_facts['os_family'] == 'Debian'

Templates

Ansible templates are files that contain variables and control structures, which are processed by the Jinja2 templating engine. They are a powerful way to generate custom configuration files, scripts, or any other text file on the managed nodes. Instead of creating a separate file for each host’s specific settings, you can use a single template and populate it dynamically with Ansible variables. This makes your automation more flexible and scalable.

How They Work

  1. Creation: You create a template file on the control node, typically with a .j2 extension (e.g., nginx.conf.j2).
  2. Processing: When a playbook runs, Ansible uses the ansible.builtin.template module to process the template file on the control node. It replaces any variables ({{ variable_name }}) and evaluates any control structures ({% for item in list %}) with the specific values for the target managed node.
  3. Deployment: The processed, final file is then copied to the managed node, where it can be used by the application or service.

Jinja2 Syntax

Jinja2 uses a simple syntax with two main delimiters:

  • {{ variable_name }}: Used to print the value of a variable.
  • {% control_structure %}: Used to define control structures like loops and conditionals.
Example Template (nginx.conf.j2)

This template will dynamically set the port and server names based on variables.

server {
    listen {{ http_port }};
    server_name {{ server_name }};

    {% if redirect_to_https %}
    return 301 https://$host$request_uri;
    {% else %}
    root /var/www/html;
    index index.html index.htm;
    {% endif %}

    location / {
        try_files $uri $uri/ =404;
    }
}

Using the Template Module

To use the template in a playbook, you call the ansible.builtin.template module.

- name: Deploy an NGINX configuration from a template
  ansible.builtin.template:
    src: templates/nginx.conf.j2
    dest: /etc/nginx/nginx.conf
  notify: restart nginx

This task will take the nginx.conf.j2 file from the templates/ directory on the control node, process it, and save the final output to /etc/nginx/nginx.conf on the managed node. If the file content changes, it will notify the restart nginx handler.

Filters

Ansible filters are a way to transform or manipulate data within a playbook. They are a core component of the Jinja2 templating engine, which Ansible uses to process variables and templates. Filters allow you to perform various operations on data, such as converting data types, manipulating strings, sorting lists, or extracting specific information. They are used to make data suitable for a specific task or to present it in a desired format.

How to Use Filters

Filters are used with the pipe (|) character within a Jinja2 expression. The data on the left side of the pipe is passed as the first argument to the filter on the right.

Basic Syntax:

{{ some_variable | filter_name }}
Example: Converting a List to a Comma-Separated String

The join filter is a common example. It joins elements of a list into a single string.

- name: Create a variable from a list
  vars:
    my_list:
      - 'item1'
      - 'item2'
      - 'item3'

- name: Display the joined list
  ansible.builtin.debug:
    msg: "The list is: {{ my_list | join(', ') }}"

This would output: The list is: item1, item2, item3.

Common Filter Examples

FilterDescriptionExample
to_jsonConverts a data structure (dictionary or list) into a JSON string.`{{ my_dict
from_jsonParses a JSON string and converts it into a data structure.`{{ my_json_string
defaultProvides a default value if the variable is undefined or an empty string.`{{ my_var
uniqueReturns a list with duplicate items removed.`{{ my_list
listEnsures that a value is treated as a list.`{{ single_value
sortSorts a list in ascending order.`{{ my_list

Vault

Ansible Vault is a feature for encrypting sensitive data, such as passwords, API keys, and other secrets, within your Ansible playbooks and roles. It allows you to store this confidential information in files or variables in a secure, encrypted format that can be safely committed to a version control system like Git. This ensures that your sensitive data remains protected from unauthorized access while still being usable by Ansible during automation runs.

How It Works

Ansible Vault uses a single, shared password to encrypt and decrypt files. You can manage encrypted files using a command-line interface.

1. Encrypting a File

To encrypt a new file or an existing one, use the ansible-vault encrypt command. Ansible will prompt you to enter and confirm a password.

ansible-vault encrypt my_secrets.yml
2. Editing an Encrypted File

To edit an encrypted file, use the ansible-vault edit command. Ansible will prompt for the password, decrypt the file for editing, and then re-encrypt it when you save and exit.

ansible-vault edit my_secrets.yml
3. Viewing an Encrypted File

To view the decrypted contents of a file without editing, use the ansible-vault view command.

ansible-vault view my_secrets.yml

Using Vault Files in Playbooks

To use an encrypted file in a playbook, you simply reference it just like any other variable file. Ansible will automatically handle the decryption during the playbook run.

---
- name: Use a vaulted variable file
  hosts: all
  vars_files:
    - secrets.yml
  tasks:
    - name: Access a vaulted variable
      ansible.builtin.debug:
        msg: "The user is {{ my_vaulted_user }}"

To run a playbook that uses encrypted files, you need to provide the vault password using the --ask-vault-pass or a password file (--vault-password-file).

ansible-playbook playbook.yml --ask-vault-pass

AWX

AWX is the open-source, upstream project from which Ansible Tower (now known as Red Hat Ansible Automation Platform) is built. It provides a web-based user interface, REST API, and task engine for managing your Ansible automation. AWX offers a centralized, visual way to control, schedule, and monitor Ansible jobs, making it an ideal choice for teams that want to adopt a more structured approach to their automation without a commercial license.

Key Features and Benefits

  • Dashboard: A clean, web-based dashboard that provides a real-time overview of your hosts and job statuses.
  • Centralized Control: It allows you to launch playbooks, manage inventories, and handle credentials from a single point, providing better visibility and control.
  • Security and Access Control: You can define users and teams and grant them specific permissions, ensuring that only authorized personnel can run certain playbooks.
  • Job Scheduling: AWX allows you to schedule automated tasks to run at a specific time or on a recurring basis, which is great for routine maintenance jobs.
  • Credential Management: It provides a secure way to store credentials like passwords and SSH keys, so they aren’t exposed in plain text within your playbooks.
  • REST API: It has a robust API that can be used to integrate your automation with other tools in your CI/CD pipeline.

Ansible Tower

Ansible Tower is a web-based, enterprise-grade solution that provides a centralized user interface for managing and controlling your Ansible automation. It sits on top of the core Ansible engine and offers features designed to make automation more scalable, secure, and easier to use for teams. While Ansible itself is a powerful command-line tool, Ansible Tower provides a visual dashboard, simplifying operations and providing a single pane of glass for all your automation activities.

Key Features and Benefits

  • Dashboard: A web-based interface that provides a high-level overview of all your hosts, projects, jobs, and recent activity.
  • Role-Based Access Control (RBAC): Allows you to define which users and teams have permission to run specific playbooks or manage certain resources. This is crucial for security and compliance in a team environment.
  • Job Scheduling: Lets you schedule playbooks to run at specific times or intervals, automating routine tasks like nightly backups or weekly patch deployments.
  • Centralized Logging: Provides a single place to view and search the output of all your Ansible job runs, making it easier to troubleshoot and audit automation tasks.
  • REST API: Offers a powerful API that allows you to integrate Ansible Tower with other tools in your IT ecosystem, like monitoring systems or CI/CD pipelines.
  • Credential Management: Securely stores sensitive credentials (e.g., passwords, SSH keys) in a vault, preventing them from being exposed in plain text.

Ansible Tower vs. AWX

AWX is the open-source upstream project that serves as the foundation for Ansible Tower. While they share the same core code, there are key differences:

  • AWX: The open-source community version, managed by Red Hat and a community of contributors. It has a more rapid release cycle and is generally free to use.
  • Ansible Tower: The commercially supported product from Red Hat. It offers official support, enterprise-grade features, and a more stable release cycle.

For most enterprise and production environments, Ansible Tower (or its successor, Red Hat Ansible Automation Platform) is the chosen solution due to its official support and security features.

Galaxy

Ansible Galaxy is a public hub for finding, sharing, and using community-contributed Ansible content. It is a repository where you can discover and download reusable automation components like roles and collections created by other users. Think of it as a central place for the Ansible community to share and collaborate on content.

How it Works

Ansible Galaxy is integrated with the ansible-galaxy command-line tool, which allows you to manage content directly from your terminal.

1. Finding Content

You can browse the web interface of Ansible Galaxy to search for roles and collections based on keywords, popularity, or use cases.

2. Installing Content

You use the ansible-galaxy command to install a role or collection from the Galaxy hub. The command downloads the content and places it in a standard directory structure on your system, ready to be used by your playbooks.

Installing a Role

ansible-galaxy install geerlingguy.nginx

Installing a Collection

ansible-galaxy collection install community.general
3. Creating and Sharing Content

If you want to share your own automation, you can create a role or collection, and then publish it to Ansible Galaxy using the ansible-galaxy command. This makes it available for others to use and collaborate on.

Key Takeaways

  • Community Hub: It’s the central hub for the Ansible community.
  • Reusable Content: It’s a source of reusable, pre-built roles and collections.
  • Command-Line Tool: The ansible-galaxy CLI tool is used to interact with the hub for installing, managing, and publishing content.

Collections

Ansible Collections are a standard way to package, distribute, and manage Ansible content. They are a significant advancement over the old method of distributing roles and modules individually. A collection can bundle together multiple types of content, including roles, plugins (like inventory, lookup, and filter plugins), and modules, all within a single, versioned package. This makes it easier to share, install, and use related automation content.

Key Components of a Collection

A collection is essentially a directory with a specific structure that includes all the relevant content. The core components are:

  • Roles: Self-contained units of automation.
  • Modules: The individual units of code that perform actions on managed nodes.
  • Plugins: Extend Ansible’s core functionality, such as inventory plugins to gather dynamic host lists or filter plugins to transform data.
  • Playbooks: Can also be included to show how to use the content within the collection.

The structure of a collection looks like this:

<namespace>.<collection_name>/
├── docs/
├── galaxy.yml          # Collection metadata
├── playbooks/
├── plugins/
│   ├── modules/
│   ├── inventory/
│   └── filter/
├── roles/
└── tests/

How to Use Collections

1. Finding and Installing Collections

You can find collections on Ansible Galaxy, the official hub for community-contributed content. You install them using the ansible-galaxy command.

ansible-galaxy collection install <namespace>.<collection_name>
2. Referencing Content in Playbooks

Once a collection is installed, you reference its content using the Fully Qualified Collection Name (FQCN) format: <namespace>.<collection_name>.<content_name>.

  • Calling a Module: To use a module from a collection, you specify its FQCN. For example, community.general.ping.
  • Calling a Role: You can include a role from a collection in your playbook’s roles section.
---
- name: Use a collection to manage a web server
  hosts: all
  roles:
    - community.general.nginx
  tasks:
    - name: Use a collection module
      community.general.ping:

Using collections makes managing dependencies and sharing reusable content much more streamlined than the older method.

Ansible Commands Cheat Sheet

ansible

The ansible command is a powerful tool for running ad-hoc commands, which are single-line tasks executed directly from the command line without a playbook. It’s ideal for quick actions like checking system status or performing a one-off configuration change across multiple servers.

Basic Syntax

ansible <host-pattern> -m <module_name> -a "<module_arguments>" [options]
  • <host-pattern>: The hosts or host groups from your inventory to run the command on (e.g., all, web_servers, db_01).
  • -m <module_name>: The name of the module to execute (e.g., ping, shell, apt).
  • -a "<module_arguments>": Arguments to pass to the module.

Common Command-Line Options

OptionDescription
-i, –inventorySpecifies the inventory file or a comma-separated list of hosts.
-k, –ask-passPrompts for a connection password to connect to the managed hosts.
-b, –becomeRuns the task with elevated privileges (like sudo).
–become-userSpecifies the user to become after privilege escalation (e.g., root).
-K, –ask-become-passPrompts for the sudo password.
-f, –forksSets the number of parallel processes to use, which controls how many hosts are managed at once. The default is 5.
-v, –verboseIncreases the verbosity of the output. Use -vvv for a detailed debug output.
-C, –checkRuns the command in “dry run” mode. No changes will be made, but Ansible will report what would have changed.
-D, –diffShows the differences in files and templates that would be changed in check mode.
–vault-password-fileSpecifies a file that contains the Ansible Vault password.
–limitFurther restricts the host pattern to a specific set of hosts.

Command Examples

Example CommandExplanation
ansible all -m pingTests connectivity to all hosts in the inventory.
ansible web_servers -m command -a "df -h /"Checks the disk space on the root (/) partition for all hosts in the web_servers group.
ansible db_servers -b -K -m apt -a "name=postgresql state=present"Connects to db_servers, prompts for a sudo password, and uses the apt module to install the postgresql package with elevated privileges.
ansible all -m setup --tree /tmp/factsGathers facts from all hosts and saves the JSON output to individual files in the /tmp/facts directory.

ansible-playbook

The ansible-playbook command is the main tool for running Ansible playbooks. It reads a YAML file and orchestrates the automation defined within it. Unlike the simple ansible command, ansible-playbook is used for multi-step, complex, and reusable automation jobs.

Basic Syntax

ansible-playbook <playbook.yml> [options]
  • <playbook.yml>: The path to the playbook file to execute.

Common and Important Options

OptionDescriptionExample
-i, –inventorySpecifies the inventory file to use, overriding the default ansible.cfg setting.ansible-playbook site.yml -i production
-e, –extra-varsSets additional variables at a high precedence, overriding others. Can be a single key=value pair or a path to a YAML file.ansible-playbook deploy.yml -e "port=8080"
-C, –checkRuns in check mode or “dry run” mode. Ansible reports what changes it would make without applying them.ansible-playbook upgrade.yml --check
-D, –diffShows the diff of files and templates that would be changed when used with --check.ansible-playbook config.yml --check --diff
–limitRestricts the playbook’s execution to a specific host or group of hosts from the inventory.ansible-playbook site.yml --limit "db_servers"
–tagsRuns only the tasks or plays that have the specified tag(s).ansible-playbook deploy.yml --tags "nginx,db"
–skip-tagsSkips plays and tasks that have the specified tag(s).ansible-playbook all.yml --skip-tags "backup"
-b, –becomeRuns tasks with elevated privileges (e.g., as root via sudo).ansible-playbook install.yml -b -K
-K, –ask-become-passPrompts for the sudo password.ansible-playbook install.yml -b -K
–start-at-taskStarts the playbook execution at the specified task name, skipping all prior tasks.ansible-playbook long_playbook.yml --start-at-task "configure services"
–list-hostsParses the playbook and inventory and lists the hosts that would be targeted.ansible-playbook my_playbook.yml --list-hosts
–list-tagsLists all tags available in the playbook.ansible-playbook deploy.yml --list-tags
–list-tasksLists all the tasks that would be executed by the playbook.ansible-playbook config.yml --list-tasks
–syntax-checkChecks the playbook for syntax errors without executing any tasks.ansible-playbook my_playbook.yml --syntax-check
–vault-password-fileSpecifies a file that contains the Ansible Vault password.ansible-playbook deploy.yml --vault-password-file ~/.vault_pass
-v, –verboseIncreases the verbosity of output. Use multiple times (e.g., -vvv) for more debug information.ansible-playbook my_playbook.yml -vvv

ansible-vault

The ansible-vault command is used to manage encrypted files and strings within Ansible. It’s a security feature that allows you to store sensitive data like passwords and API keys in a secure, encrypted format, which can be safely stored in version control systems.

Common Actions

The ansible-vault command operates using sub-commands, or “actions,” to perform specific tasks.

ActionDescription
createCreates a new encrypted file and opens it for editing.
editDecrypts an existing encrypted file and opens it for editing. The file is re-encrypted upon saving.
encryptEncrypts an existing plain text file. The original file is overwritten with the encrypted version.
decryptDecrypts an encrypted file back into plain text.
viewViews the decrypted contents of an encrypted file without editing it.
rekeyChanges the encryption password for a vault file without decrypting it first.
encrypt_stringEncrypts a single string and prints the encrypted output to the console. Useful for adding single secrets directly into a playbook or a vars file.

Important Options and Examples

OptionDescriptionExample
--ask-vault-passPrompts for the vault password on the command line.ansible-vault encrypt my_secrets.yml --ask-vault-pass
--vault-password-fileSpecifies a file containing the vault password. Recommended for automated scripts.ansible-vault view my_secrets.yml --vault-password-file ~/.vault_pass
--outputSpecifies the output file for encrypt or decrypt actions.ansible-vault encrypt credentials.txt --output encrypted_credentials.txt
--encrypt-vault-idSpecifies which vault identity to use when encrypting if multiple IDs are defined.ansible-vault encrypt my_file.txt --encrypt-vault-id staging
--nameDefines a variable name for encrypt_string output.ansible-vault encrypt_string --name my_api_key 'my_secret_key'

ansible-inventory

The ansible-inventory command is used to display, verify, and manage your Ansible inventory. It helps you understand how Ansible views your hosts and groups, especially when dealing with dynamic inventories or complex group structures.

Common Actions

The command’s behavior is determined by the action flags you use.

ActionDescriptionExample
--listOutputs the entire inventory as a JSON data structure. This is the most common use case for scripts and external tools.ansible-inventory -i hosts.yml --list
--host <HOST>Shows detailed information (including variables and group memberships) for a specific host.ansible-inventory -i hosts.yml --host web_01
--graphDisplays a text-based graph representation of your inventory, showing the hierarchical relationships between groups and hosts.ansible-inventory -i hosts.yml --graph
–yaml / –json / –tomlSpecifies the output format. By default, --list and --host output in JSON, but you can change it to YAML or TOML.ansible-inventory -i hosts.yml --list --yaml

Important Options

OptionDescriptionExample
-i, –inventorySpecifies the inventory file to use. You can use this flag multiple times to combine inventories.ansible-inventory -i prod.ini -i dev.ini --list
-e, –extra-varsSets additional variables that can be used to influence a dynamic inventory script.ansible-inventory -i my_script.py -e "zone=us-east-1" --list
-l, –limitLimits the inventory output to a specific subset of hosts.ansible-inventory -i hosts.yml --list --limit "web_servers"
–vault-password-fileSpecifies a file containing the password to decrypt any vaulted inventory files or variables.ansible-inventory -i vaulted_vars.yml --list --vault-password-file ~/.vault_pass
-v, –verboseIncreases the verbosity of the output, which can be useful for debugging dynamic inventory scripts.ansible-inventory -i my_script.py -vvv

ansible-galaxy

The ansible-galaxy command is a tool used to manage reusable Ansible content, specifically roles and collections. It simplifies finding, installing, and creating these components from a central hub called Ansible Galaxy.

Common Actions

ActionDescriptionExample
collection initCreates the basic directory structure for a new collection.ansible-galaxy collection init my_namespace.my_collection
collection installInstalls collections from Ansible Galaxy or a local file.ansible-galaxy collection install community.general
collection listLists all collections that are installed on your system.ansible-galaxy collection list
role initCreates the skeleton framework for a new role.ansible-galaxy role init my_webserver_role
role installInstalls one or more roles from Ansible Galaxy.ansible-galaxy role install geerlingguy.nginx
role removeRemoves an installed role from your local system.ansible-galaxy role remove geerlingguy.nginx

Important Options

OptionDescriptionExample
-r, –requirements-fileInstalls roles or collections from a file listing them. This is a common way to manage dependencies.ansible-galaxy install -r requirements.yml
–forceOverwrites an existing role or collection with the newly installed version. Useful for updating.ansible-galaxy collection install my.collection --force
-p, –roles-pathSpecifies the directory to install or search for roles in.ansible-galaxy install geerlingguy.nginx -p /etc/ansible/roles
–collections-pathSpecifies the directory to install or search for collections in.ansible-galaxy collection install community.general --collections-path ~/ansible_collections

ansible-pull

The ansible-pull command is used to set up a “pull” mode for Ansible automation. 🔄 Instead of a central control node pushing playbooks to managed nodes, ansible-pull is a command run on the managed node itself. It clones a Git repository containing playbooks and then runs them locally. This is a common pattern for managing many geographically distributed machines that can’t be easily reached from a central location.

How It Works

ansible-pull automates a simple three-step process on the managed host:

  1. It checks out the specified Git repository.
  2. It runs the specified playbook locally.
  3. It can be configured to run periodically as a cron job, ensuring the host is always in a desired state.

Basic Syntax

ansible-pull -U <repository-url> -C <commit-or-branch> [options]
  • -U <repository-url>: The URL of the Git repository to clone.
  • -C <commit-or-branch>: The branch, tag, or commit to check out.

Common and Important Options

OptionDescriptionExample
-U, --urlSpecifies the URL of the Git repository to pull from.ansible-pull -U https://github.com/my/playbooks.git
--accept-host-keyAutomatically adds the repository’s host key to ~/.ssh/known_hosts if it doesn’t already exist.ansible-pull -U git@github.com:my/playbooks.git --accept-host-key
--checkoutSpecifies the branch, tag, or commit to check out from the repository.ansible-pull -U ... --checkout production
-o, --only-if-changedOnly runs the playbook if the repository has been updated since the last pull.ansible-pull -U ... -o
--cleanDiscards any local modifications in the repository before pulling.ansible-pull -U ... --clean
--fullPerforms a full clone of the repository instead of a shallow one.ansible-pull -U ... --full
-t, --tagsOnly runs the tasks or plays with the specified tag(s) in the playbook.ansible-pull -U ... -t "config,web"
--skip-tagsSkips tasks and plays that have the specified tag(s).ansible-pull -U ... --skip-tags "backup"
-f, --forceForces the playbook to run even if the repository couldn’t be updated.ansible-pull -U ... -f
-v, --verboseIncreases the verbosity of the output. Use multiple times (e.g., -vvv) for more debug information.ansible-pull -U ... -vvv

ansible-config

The ansible-config command is used to inspect and manage Ansible’s configuration settings. ⚙️ It provides a way to view configuration values and their sources without having to manually locate and open the ansible.cfg file. This is useful for debugging and ensuring that Ansible is running with the correct settings.

Common Actions

ActionDescriptionExample
listLists all available configuration settings, including their default values and descriptions.ansible-config list
dumpDumps the current, effective configuration settings, showing which values have been changed from their defaults.ansible-config dump
viewShows the contents of the Ansible configuration file being used, as it’s being interpreted.ansible-config view
initCreates a new ansible.cfg file with all the default options commented out.ansible-config init --disabled > ansible.cfg
getRetrieves the value of a specific configuration setting.ansible-config get inventory

Important Options

OptionDescriptionExample
-c, –configSpecifies a custom path to a configuration file to use for the command.ansible-config dump -c my_custom.cfg
–only-changedUsed with dump to show only the settings that have been explicitly changed from their defaults.ansible-config dump --only-changed
-t, –typeFilters the configuration list or dump to show settings for a specific plugin type (e.g., inventory).ansible-config list --type inventory
–jsonOutputs the configuration in JSON format, which is useful for machine parsing.ansible-config dump --json
–formatSpecifies the output format for various actions. Supported formats include yaml, json, ini, and plain.ansible-config list --format json

ansible-doc

The ansible-doc command is used to view the documentation for Ansible modules and plugins directly from your command line. 📖 It’s the fastest way to get information on a module’s parameters, usage, and return values without an internet connection, as the documentation is stored locally.

Common Actions

ActionDescriptionExample
ansible-doc <module>Displays detailed documentation for a specific module, including its description, parameters, and examples.ansible-doc ping
ansible-doc -lLists all available modules installed on your system.ansible-doc -l
ansible-doc -s <module>Shows a short, single-line “snippet” of a module’s basic usage in a playbook.ansible-doc -s apt
ansible-doc -t <type> -lLists all plugins of a specific type, such as inventory or lookup.ansible-doc -t inventory -l
ansible-doc -t <type> <plugin>Displays detailed documentation for a specific plugin type.ansible-doc -t lookup file

Important Options

OptionDescriptionExample
-j, –jsonFormats the documentation output as a JSON object, which is useful for machine parsing.ansible-doc apt --json
-l, –listLists all available modules or plugins, often used with the -t option.ansible-doc -l
-s, –snippetDisplays a minimal playbook snippet for a module or plugin.ansible-doc -s template
-t, –typeSpecifies the type of plugin you want to document. The default is module, but others include inventory, lookup, connection, etc.ansible-doc -t inventory -l
-F, –list_filesLists plugin names and their source file locations.ansible-doc -F

ansible-console

The ansible-console command provides an interactive shell for running Ansible ad-hoc commands. 💻 It’s an excellent tool for real-time debugging, exploration, and quick testing of modules across multiple hosts without having to write a full playbook.

How It Works

When you start ansible-console, it connects to all hosts in your specified inventory. You can then use a command-line interface to execute modules, apply filters, and interact with the hosts. It’s a faster alternative to repeatedly running ansible commands from your regular shell.

Common Commands within the Console

CommandDescriptionExample
cd <group>Changes the current working group of hosts. You can cd into a specific group name, a single host, or use all to select all hosts.cd web_servers
listShows the hosts currently in the active working set.list
<module> <arguments>Executes a module directly. This is the main function of the console.ping
? or helpDisplays a list of available commands and basic help.?
exitExits the ansible-console session.exit

Important Options

These options are used when you first launch ansible-console to define the environment.

OptionDescriptionExample
-i, –inventorySpecifies the inventory file to use.ansible-console -i hosts.yml
-l, –limitLimits the interactive session to a specific subset of hosts.ansible-console -i hosts.yml --limit "web_servers"
-b, –becomeEnters the session with elevated privileges, prompting for a password if needed.ansible-console -i hosts.yml -b
-u, –userSpecifies the remote user to connect as.ansible-console -i hosts.yml -u ubuntu
-f, –forksSets the number of parallel processes to use during the session.ansible-console -i hosts.yml -f 10
-v, –verboseIncreases the verbosity of the output. Use -vvv for more detailed debug messages.ansible-console -i hosts.yml -vvv

Leave a Comment