Kahibaro
Discord Login Register

6.3.1 Ansible basics

Understanding Ansible

Ansible is a configuration management and automation tool that lets you control many Linux systems from one place using simple text files. Instead of logging into each server and running commands manually, you describe the desired state of those systems, and Ansible makes the systems match that description.

Ansible is agentless. This means it does not require special software running on the managed machines. It usually connects over SSH and uses Python on the remote side. For you, this keeps installation and maintenance simple, especially in environments with many servers.

Ansible is designed to be declarative. You normally describe what you want, not how to do every single step. Ansible then chooses the steps and checks whether changes are needed or not. This approach keeps your automation safe to run repeatedly.

Control Node and Managed Nodes

Ansible has two main roles in its architecture. The control node is the machine where you install Ansible and from which you run Ansible commands. The managed nodes are the machines that Ansible configures and manages.

On the control node, you have the Ansible command line tools, your inventory files, and your playbooks. On the managed nodes, you mainly need SSH access and a suitable Python interpreter. When you execute Ansible, the control node connects to managed nodes, runs modules there, and gathers results back.

You can use a regular Linux workstation as a control node. The same machine can also be one of the managed nodes, but in many production environments the control node is separate, for example a dedicated management or bastion host.

Inventory: Describing Your Infrastructure

Ansible needs to know which machines it should manage. This list is called the inventory. At a basic level the inventory is a static text file that lists hostnames or IP addresses, and optionally groups them.

You can define an inventory in INI format like this:

[webservers]
web1.example.com
web2.example.com
[dbservers]
db1.example.com
[all:vars]
ansible_user=admin

The section names in square brackets define host groups. In this example, webservers and dbservers are groups. Groups let you target related servers together, for example all web servers. Group variables under all:vars apply to every host in the inventory.

Ansible also supports inventories written in YAML and dynamic inventories generated by scripts or cloud plugins, but for a beginner static inventories in simple files are often enough to start with.

When you run commands, you point Ansible to a specific inventory file and a group or host in that inventory. The inventory becomes your central map of the infrastructure you control.

Modules: Reusable Building Blocks

Ansible work is mostly done through modules. A module is a small unit of code that performs one type of action. For example, there are modules to manage packages, users, services, files, and many other resources.

When you call a module, you provide arguments that describe the state you want. For example, a package module can install a package by ensuring state=present. A service module can keep a service started and enabled so that it runs after reboot.

You usually do not run modules directly by hand. Instead, you use them inside playbooks or through the ansible command. Ansible sends the module code to the remote host, executes it there, and then removes temporary files, so you do not need to install the modules on the managed nodes.

Many modules are idempotent. This means that if you run them again with the same parameters, they detect that nothing needs to change and leave the system as it is.

Idempotent Ansible modules can be run repeatedly with the same input without causing unwanted additional changes. This property is essential for safe, repeatable automation.

Ad‑hoc Commands with `ansible`

Before you write playbooks, you can use ad‑hoc commands to run a single task against one or more hosts. You use the ansible command, specify a host or group, a module, and some arguments.

For example, to ping all hosts in your inventory using the ping module, you can run:

ansible all -i inventory.ini -m ping

Here all selects all hosts, -i specifies the inventory file, and -m ping selects the ping module. The Ansible ping checks whether Ansible is able to connect and run Python on the remote, not whether ICMP ping is open.

To install a package on all web servers using a package module you might run something like:

ansible webservers -i inventory.ini -m apt -a "name=nginx state=present" --become

The -a option passes arguments to the module. The --become flag asks Ansible to escalate privileges, for example to root, which is often required when changing system packages. The exact module name and arguments depend on the Linux distribution and package manager.

Ad‑hoc commands are useful for quick fixes and checks, but for repeatable and documented changes you will use playbooks instead.

Playbooks: YAML Automation Recipes

Playbooks are where Ansible becomes powerful. A playbook is a YAML file that describes a series of plays. Each play targets some hosts from the inventory and defines tasks that Ansible will run on those hosts.

A minimal playbook might look like this:


- name: Configure web servers
  hosts: webservers
  become: true
  tasks:
    - name: Ensure Nginx is installed
      apt:
        name: nginx
        state: present
    - name: Ensure Nginx is running and enabled
      service:
        name: nginx
        state: started
        enabled: true

At the top level, the playbook is a list. Each item in the list is a play. In this example there is one play that targets the webservers group. Inside the play you set options such as become: true for privilege escalation, and you write a list of tasks.

Each task has a name for readability and uses one module with certain parameters. Ansible runs tasks from top to bottom for each host in the play. If a module finds that the desired state is already met, it usually skips changes but still reports success.

Idempotence and Desired State

Ansible playbooks describe a desired state. A playbook that installs packages, configures services, or creates files should be safe to run as many times as you want, because the underlying modules check before they change anything.

Idempotence is what gives you this safety. For example, if you run the earlier playbook and Nginx is already installed and running, the apt and service tasks will detect this and report that no changes were made.

You should always design your tasks to be idempotent. Avoid commands that blindly append content or restart services without checking. When you need to do something that is not naturally idempotent, many modules offer parameters to help you control when changes happen, or you can use conditions and checks.

Always aim for idempotent playbooks. An idempotent playbook can be applied repeatedly to the same hosts without causing inconsistent or accumulating changes.

Variables and Templates at a Glance

Ansible lets you define variables to avoid repetition and to adapt behavior per host or per group. You can store variables in inventory files, separate variable files, or in playbooks themselves.

A simple example inside a play might look like this:

- hosts: webservers
  vars:
    web_port: 8080
  tasks:
    - name: Show configured port
      debug:
        msg: "Web server will listen on port {{ web_port }}"

The {{ web_port }} syntax uses a templating language called Jinja2. You will see this syntax often when generating configuration files or composing commands dynamically. Templates let you construct content based on variables and simple logic, while keeping your playbooks and configuration files general and reusable.

Handlers and Notifications

Sometimes changes need a follow up action. For example, when you update a service configuration file, you might need to restart that service. Ansible uses handlers for this pattern.

Handlers are special tasks that run only when notified. A normal task can include a notify directive which refers to a handler name. Ansible collects notifications and runs each handler at the end of the play, and only once per host, even if multiple tasks notify the same handler.

A short example looks like this:

- hosts: webservers
  become: true
  tasks:
    - name: Update Nginx configuration
      template:
        src: nginx.conf.j2
        dest: /etc/nginx/nginx.conf
      notify: Restart nginx
  handlers:
    - name: Restart nginx
      service:
        name: nginx
        state: restarted

If the template task actually changes the file, it notifies the handler and the service restarts. If there is no change to the file, the handler does not run. This pattern helps you avoid unnecessary restarts.

Running Playbooks with `ansible-playbook`

To execute a playbook, you use the ansible-playbook command. You point it at the inventory and the playbook file.

A typical run looks like this:

ansible-playbook -i inventory.ini site.yml

Ansible then parses the playbook, connects to the specified hosts, and executes tasks in order. The output shows which tasks ran, which hosts changed, and any failures.

You can limit which hosts receive the play by using the --limit option and you can check what would change without applying it with the --check option. These controls help you test changes and roll them out gradually.

For example:

ansible-playbook -i inventory.ini site.yml --limit web1.example.com --check

This runs the playbook in check mode for a single host, so you can review the planned changes before applying them everywhere.

Roles and Reuse Overview

As your Ansible content grows, managing everything in one playbook becomes hard. Ansible uses roles to help you organize related tasks, templates, variables, and files into reusable units.

A role has a standard directory structure. Inside it you can place tasks, handlers, templates, and other components. Once a role is defined, you can include it in any play with its name.

A play using a role might look like this:

- hosts: webservers
  become: true
  roles:
    - nginx

Here nginx is a role. The role can be shared between projects or teams, and you can download many community roles from Ansible Galaxy.

Roles keep your automation modular, easier to test, and easier to understand, because each role focuses on one component or service.

Summary

Ansible basics center on a simple model. You run Ansible from a control node, describe your infrastructure in an inventory, and use playbooks written in YAML to apply idempotent changes to managed nodes through modules. Variables, templates, handlers, and roles help you keep your automation flexible and reusable. As you expand from simple ad‑hoc commands to structured playbooks and roles, Ansible becomes a reliable tool to manage Linux systems consistently at any scale.

Views: 8

Comments

Please login to add a comment.

Don't have an account? Register now!