Kahibaro
Discord Login Register

6.3.1 Ansible basics

What Ansible Is (in Practice)

Ansible is a configuration management and automation tool that connects to your systems (usually over SSH) and applies the state you describe in YAML files (called playbooks).

Key properties:

At a very high level, you:

  1. Have a control node (where Ansible is installed).
  2. Define an inventory (what machines to manage).
  3. Write playbooks (what to do on those machines).
  4. Run ansible or ansible-playbook to apply changes.

This chapter focuses on hands‑on basics: inventories, modules, ad‑hoc commands, and simple playbooks.


Installing Ansible (for Learning)

On a typical Linux workstation:

  sudo apt update
  sudo apt install ansible
  sudo dnf install ansible

A very distribution‑agnostic way is using pip (Python package manager):

python3 -m pip install --user ansible

You can confirm installation with:

ansible --version

You only need Ansible installed on the control node. Managed hosts just need:

The Ansible Inventory

The inventory is how Ansible knows what systems to manage.

By default, Ansible looks at /etc/ansible/hosts, but you can pass any file with -i.

Simple INI-Style Inventory

Example inventory.ini:

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

Explanation:

You can test connectivity with:

ansible -i inventory.ini all -m ping

Common inventory host variables:

Example with host‑specific variables:

[webservers]
web1 ansible_host=192.0.2.10 ansible_user=ubuntu
web2 ansible_host=192.0.2.11 ansible_user=ubuntu

YAML Inventory (Basic Idea)

Inventory can also be YAML. A minimal example:

all:
  children:
    webservers:
      hosts:
        web1:
          ansible_host: 192.0.2.10
        web2:
          ansible_host: 192.0.2.11
    dbservers:
      hosts:
        db1:
          ansible_host: 192.0.2.20
  vars:
    ansible_user: devops

Format choice is mostly preference at the beginner level; INI style is simpler to start with.


Ansible Modules and Ad-Hoc Commands

Modules are small units of work that Ansible executes on target hosts. Everything you do with Ansible uses modules under the hood.

You can run a single module without a playbook using ad‑hoc commands:

ansible <pattern> -i inventory.ini -m <module> -a "<arguments>"

Where:

Common Beginner Modules

  ansible all -i inventory.ini -m ping
  ansible webservers -i inventory.ini -m command -a "uptime"
  ansible webservers -i inventory.ini -m shell -a "df -h /"
  ansible webservers -i inventory.ini -m copy \
    -a "src=/tmp/index.html dest=/var/www/html/index.html owner=www-data group=www-data mode=0644"
  ansible webservers -i inventory.ini -m file \
    -a "path=/var/www/html state=directory owner=www-data mode=0755"
  ansible webservers -i inventory.ini -m apt \
    -a "name=nginx state=present update_cache=yes" --become

--become tells Ansible to use privilege escalation (like sudo).

Ad‑hoc commands are excellent for trying modules and doing quick, one‑off changes.


Your First Playbook

For anything more than quick actions, you write a playbook: a YAML file describing:

Example: a simple playbook to install and start Nginx on Debian/Ubuntu web servers:

webserver.yml:


- name: Configure web servers
  hosts: webservers
  become: yes
  tasks:
    - name: Ensure apt cache is updated
      apt:
        update_cache: yes
        cache_valid_time: 3600
    - name: Ensure nginx is installed
      apt:
        name: nginx
        state: present
    - name: Ensure nginx is running and enabled
      service:
        name: nginx
        state: started
        enabled: yes

Run it with:

ansible-playbook -i inventory.ini webserver.yml

Concepts illustrated:

Ansible output will show tasks as:

Basic Playbook Syntax Rules

A few essentials to avoid common beginner mistakes:

  - name: Ensure nginx is installed
    apt:
      name: nginx
      state: present
  - name: Print a message
    debug:
      msg: "User: {{ ansible_user }}"

If in doubt, use ansible-lint or yamllint (optional tools) to validate syntax.


Variables (Very Basic Use)

Variables let you avoid repeating values and make playbooks reusable.

Where they commonly show up in “basics”:

  [webservers]
  web1 http_port=80
  web2 http_port=8080

Then in a playbook, you can use:

  - name: Show HTTP port
    debug:
      msg: "This host uses port {{ http_port }}"
  - name: Install a package
    hosts: webservers
    become: yes
    vars:
      web_package: nginx
    tasks:
      - name: Ensure web package is installed
        apt:
          name: "{{ web_package }}"
          state: present

Key syntax:

Idempotence and “Desired State”

Ansible’s power is in expressing state, not just commands. For example:

  - name: Install nginx with command
    shell: "apt-get install -y nginx"

Running this multiple times may be slow, and Ansible cannot easily tell if something changed.

  - name: Ensure nginx is installed
    apt:
      name: nginx
      state: present

Here:

The goal: describe the final state you want, not step‑by‑step shell commands, whenever possible.


Using `--check` and `--diff` (Dry Runs)

When you’re learning, it’s useful to see what Ansible would change:

  ansible-playbook -i inventory.ini webserver.yml --check
  ansible-playbook -i inventory.ini webserver.yml --diff

Not all modules perfectly support --check, but it’s still a valuable sanity check before touching many systems.


Basic Troubleshooting Tips

If something goes wrong:

  1. Increase verbosity:
   ansible-playbook -i inventory.ini webserver.yml -vv

-v, -vv, -vvv give progressively more detail.

  1. Check SSH connectivity:
   ansible all -i inventory.ini -m ping -vv
  1. Verify Python is available on target hosts
    Many modules need Python on the managed host (usually /usr/bin/python3).
  2. Inspect failed task
    Read the “msg” field in the failure output; it often includes the underlying command error.

A Minimal Workflow to Practice

  1. Create a test inventory (inventory.ini) with one or two Linux VMs.
  2. Test connectivity with:
   ansible all -i inventory.ini -m ping
  1. Run a simple ad‑hoc command:
   ansible all -i inventory.ini -m command -a "hostname"
  1. Write a tiny playbook to:
    • Install a package
    • Create a directory
    • Copy a small file
  2. Run with --check first, then without, and observe ok vs changed.

This is enough to get comfortable with the basics so you can move on to more advanced topics like structured roles, complex variables, and integration into larger DevOps pipelines.

Views: 119

Comments

Please login to add a comment.

Don't have an account? Register now!