Ansible manages remote machines over SSH. No agents needed. You write playbooks in YAML that describe what the target state should be, and Ansible makes it happen.

SSH setup

Generate a key pair on the control node and copy it to your targets:

ssh-keygen -t rsa
ssh-copy-id username@target_host

Inventory

An inventory file lists your hosts and groups them:

# my_inventory.ini
[web]
192.168.1.2

[db]
192.168.1.3

You can also use dynamic inventory scripts that output JSON.

Ad-hoc commands

Run a module directly without a playbook:

ansible web -i my_inventory.ini -m ping

Playbooks

A playbook is a YAML file with one or more plays. Each play targets a group of hosts and runs tasks:

---
- name: Install and start Nginx
  hosts: web
  tasks:
    - name: Install Nginx
      apt:
        name: nginx
        state: present

    - name: Start Nginx
      service:
        name: nginx
        state: started

Run it with:

ansible-playbook -i my_inventory.ini my_playbook.yml

Roles

Roles organise playbooks into reusable components. Generate a role skeleton:

ansible-galaxy init web-server

This creates directories for tasks, vars, templates, handlers, etc. Use it in a playbook:

---
- name: Web Server
  hosts: web
  roles:
    - web-server

Variables

Define variables in playbooks:

vars:
  http_port: 80

Or in roles/web-server/vars/main.yml. Reference them with {{ variable_name }}.

Conditionals and loops

- name: Install Apache on Debian systems
  apt:
    name: apache2
    state: present
  when: ansible_facts['os_family'] == "Debian"

- name: Install multiple packages
  apt:
    name: "{{ item }}"
    state: present
  loop:
    - git
    - vim
    - curl

Templates

Ansible uses Jinja2 for templating. Create a .j2 file:

# nginx.conf.j2
server {
    listen {{ http_port }};
}

Apply it in a task:

- name: Deploy nginx config
  template:
    src: nginx.conf.j2
    dest: /etc/nginx/nginx.conf

Tags and debugging

Tag tasks to run selectively:

- name: Install Nginx
  apt:
    name: nginx
    state: present
  tags: ["web"]
ansible-playbook -i my_inventory.ini playbook.yml --tags "web"

For debugging, use -vvv for verbose output or the debug module to print variables:

- debug:
    var: my_variable