Home DevOps Introduction to Ansible — Automate Infrastructure Without an Agent

Introduction to Ansible — Automate Infrastructure Without an Agent

⚡ Quick Answer
Managing 100 servers by logging into each one and typing commands is like calling 100 employees individually to give the same instruction. Ansible is like sending one company-wide email that everyone acts on simultaneously. You describe the desired state of your servers in plain English-like YAML, and Ansible connects over SSH and makes it happen — on all servers at once, with no software installed on them.

Before configuration management tools, sysadmins maintained hundreds of servers by hand — logging in, running commands, hoping nothing went wrong. This was error-prone, slow, and impossible to scale. Ansible was built to solve exactly this problem.

What makes Ansible different from Chef and Puppet is that it's agentless. No daemon running on your servers, no certificates to manage, no port to open beyond SSH. Ansible runs from your machine, connects over SSH, executes tasks, and disconnects.

By the end of this article you'll understand Ansible's core concepts — inventory, playbooks, tasks, and modules — and you'll have a working playbook that installs and configures Nginx on a remote server.

Inventory, Playbooks, and Modules — The Three Core Concepts

Ansible has three building blocks. The inventory is a list of servers you want to manage — IP addresses or hostnames, organised into groups. A playbook is a YAML file describing what to do on which servers. A module is a pre-built unit of work — install a package, copy a file, start a service. Ansible ships with thousands of modules covering everything from AWS to Windows registry.

inventory.ini · YAML
1234567891011
# inventory.ini — tell Ansible which servers exist
[webservers]
192.168.1.10  ansible_user=ubuntu  ansible_ssh_private_key_file=~/.ssh/id_rsa
192.168.1.11  ansible_user=ubuntu

[databases]
192.168.1.20  ansible_user=ubuntu

[production:children]  # Group of groups
webservers
databases
▶ Output
# Run ad-hoc command to test connectivity:
ansible webservers -i inventory.ini -m ping

192.168.1.10 | SUCCESS => {"ping": "pong"}
192.168.1.11 | SUCCESS => {"ping": "pong"}
⚠️
Test Connectivity First:Always run ansible all -m ping before running playbooks. If ping fails, fix SSH connectivity before debugging anything else. 90% of Ansible problems are SSH or permissions issues.

Your First Playbook

A playbook is a list of plays. Each play targets a group of servers and runs a list of tasks. Each task calls one Ansible module. The order is: playbook → plays → tasks → modules. Ansible executes tasks top-to-bottom, on all targeted servers in parallel.

nginx_setup.yml · YAML
123456789101112131415161718192021222324252627282930313233343536
---
- name: Configure web servers  # Play name — describes intent
  hosts: webservers             # Target the webservers group from inventory
  become: true                  # Use sudo for privileged operations

  tasks:
    - name: Update apt package cache
      apt:
        update_cache: yes
        cache_valid_time: 3600  # Only update if cache is older than 1 hour

    - name: Install Nginx
      apt:
        name: nginx
        state: present          # 'present' = install, 'absent' = remove, 'latest' = upgrade

    - name: Copy custom Nginx config
      copy:
        src: files/nginx.conf   # File on your local machine
        dest: /etc/nginx/nginx.conf
        owner: root
        group: root
        mode: '0644'
      notify: Restart Nginx     # Trigger handler only if this task changes something

    - name: Ensure Nginx is running and starts on boot
      service:
        name: nginx
        state: started
        enabled: yes

  handlers:  # Only run when notified, and only once even if notified multiple times
    - name: Restart Nginx
      service:
        name: nginx
        state: restarted
▶ Output
ansible-playbook -i inventory.ini nginx_setup.yml

PLAY [Configure web servers] ******************
TASK [Update apt package cache] *** ok: [192.168.1.10]
TASK [Install Nginx] *** changed: [192.168.1.10]
TASK [Copy custom Nginx config] *** changed: [192.168.1.10]
TASK [Ensure Nginx is running] *** ok: [192.168.1.10]
RUNNING HANDLER [Restart Nginx] *** changed: [192.168.1.10]

PLAY RECAP: ok=4 changed=3 unreachable=0 failed=0
🔥
Idempotency:Run this playbook 10 times — the result is the same as running it once. If Nginx is already installed, the install task shows 'ok' not 'changed'. This idempotency is what makes Ansible safe to run repeatedly in CI/CD pipelines.
ToolAgent RequiredLanguageLearning CurveBest For
AnsibleNo (agentless)YAMLLowSimple automation, ad-hoc tasks
ChefYes (chef-client)Ruby DSLHighComplex policy-based config
PuppetYes (puppet agent)Puppet DSLHighLarge enterprise, compliance
TerraformNoHCLMediumInfrastructure provisioning (not config)

🎯 Key Takeaways

  • Ansible is agentless — it connects over SSH, no software needed on managed servers
  • Playbooks are YAML files describing the desired state of your infrastructure
  • Always use dedicated modules (apt, service, copy) over shell — they are idempotent
  • Handlers run once at the end of a play, only if notified — perfect for service restarts

⚠ Common Mistakes to Avoid

  • Mistake 1: Using shell/command modules when a dedicated module exists — ansible.builtin.shell: apt install nginx works but is not idempotent. Use the apt module instead — it checks current state before acting.
  • Mistake 2: Not using become: true for tasks that need sudo — tasks silently fail with permission denied. Add become: true at play level for servers where all tasks need elevated privileges.
  • Mistake 3: Hardcoding passwords in playbooks — use Ansible Vault to encrypt secrets. Run ansible-vault encrypt_string 'mypassword' to get an encrypted value you can safely commit to Git.

Interview Questions on This Topic

  • QWhat does agentless mean in Ansible, and what protocol does it use to connect to servers?
  • QWhat is idempotency and why is it important for configuration management?
  • QWhat is the difference between a task and a handler in an Ansible playbook?
🔥
Naren Founder & Author

Developer and founder of TheCodeForge. I built this site because I was tired of tutorials that explain what to type without explaining why it works. Every article here is written to make concepts actually click.

← PreviousService Mesh — Istio BasicsNext →Ansible Playbooks Explained
Forged with 🔥 at TheCodeForge.io — Where Developers Are Forged