# Ansible

> Open-source automation platform for configuration management, application deployment, and IT orchestration

- Skill: `ffsshhttiikk/ansible` (Agent Skill)
- Install (CLI): `npx skillmds@latest add ffsshhttiikk/ansible`
- Raw SKILL.md: https://api.skillmd.com/api/skills/ffsshhttiikk/ansible/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: DevOps & Infra
- Author: ffsshhttiikk (https://skillmd.com/u/ffsshhttiikk)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/ffsshhttiikk/ansible

---


# Ansible

## What I Do

I am an open-source automation platform that simplifies configuration management, application deployment, and infrastructure orchestration through human-readable YAML playbooks. I use an agentless architecture with SSH for communication.

## When to Use Me

- Configuration management across servers
- Application deployment automation
- Infrastructure provisioning
- Security compliance automation
- Multi-tier application deployments
- Cloud resource orchestration
- One-time ad-hoc automation tasks

## Core Concepts

- **Playbook**: YAML file defining automation tasks
- **Play**: Collection of tasks for specific hosts
- **Task**: Single unit of work
- **Module**: Reusable unit of automation
- **Inventory**: List of managed hosts
- **Role**: Reusable collection of tasks, handlers, files
- **Handler**: Task triggered by notifications
- **Vault**: Encrypted sensitive data
- **Facts**: System information gathered by Ansible
- **Templates**: Jinja2 templating for configuration files

## Code Examples

**Basic Playbook:**
```yaml
---
- name: Web Server Configuration
  hosts: webservers
  become: yes
  vars:
    http_port: 8080
    app_directory: /opt/myapp
  
  pre_tasks:
    - name: Update apt cache
      apt:
        update_cache: yes
        cache_valid_time: 3600
      when: ansible_os_family == "Debian"
  
  tasks:
    - name: Install required packages
      apt:
        name:
          - nginx
          - python3-pip
          - docker.io
        state: present
        update_cache: yes
    
    - name: Ensure nginx is running
      service:
        name: nginx
        state: started
        enabled: yes
    
    - name: Create application directory
      file:
        path: "{{ app_directory }}"
        state: directory
        owner: www-data
        group: www-data
        mode: '0755'
    
    - name: Deploy application files
      copy:
        src: files/myapp/
        dest: "{{ app_directory }}/"
        owner: www-data
        group: www-data
        mode: '0644'
      notify: Restart nginx
  
  handlers:
    - name: Restart nginx
      service:
        name: nginx
        state: restarted
    
    - name: Reload nginx
      service:
        name: nginx
        state: reloaded

  post_tasks:
    - name: Verify nginx is listening
      wait_for:
        port: "{{ http_port }}"
        timeout: 5
```

**Role-based Playbook:**
```yaml
---
# site.yml
- name: Configure production infrastructure
  hosts: all
  gather_facts: yes
  become: yes
  
  roles:
    - common
    - base_security
    - monitoring
  
- name: Configure application servers
  hosts: app_servers
  become: yes
  
  vars_files:
    - vars/app-secrets.yml
  
  roles:
    - docker
    - application
    - nginx
  
- name: Configure database servers
  hosts: db_servers
  become: yes
  
  roles:
    - postgresql
    - backup

- name: Configure load balancers
  hosts: load_balancers
  become: yes
  
  roles:
    - haproxy
    - ssl_certs
```

**Ansible Role (tasks/main.yml):**
```yaml
---
- name: Ensure Docker is installed
  apt:
    name: docker.io
    state: present
  notify: Start docker service

- name: Add user to docker group
  user:
    name: "{{ deploy_user }}"
    groups: docker
    append: yes

- name: Create Docker configuration directory
  file:
    path: /etc/docker
    state: directory
    mode: '0755'

- name: Configure Docker daemon
  template:
    src: templates/daemon.json.j2
    dest: /etc/docker/daemon.json
    mode: '0644'
    backup: yes
  notify: Restart docker

- name: Ensure Docker service is started
  service:
    name: docker
    state: started
    enabled: yes
```

**Template (templates/daemon.json.j2):**
```json
{
  "storage-driver": "overlay2",
  "log-driver": "json-file",
  "log-opts": {
    "max-size": "100m",
    "max-file": "3"
  },
  "live-restore": true,
  "metrics-addr": "0.0.0.0:9323",
  "experimental": {{ docker_experimental | default('false') }}
}
```

**Dynamic Inventory (aws_ec2.yml):**
```yaml
plugin: aws_ec2
regions:
  - us-east-1
  - us-west-2

filters:
  tag:Environment: production
  tag:Ansible: "true"

hostnames:
  - private-ip-address
  - dns-name
  - private-dns-name

compose:
  ansible_host: public_ip_address if public_ip_address else private_ip_address
  ansible_user: ec2-user if "amazon" in image_id else ubuntu

keyed_groups:
  - key: tags.Environment
    prefix: env_
  - key: tags.Application
    prefix: app_
  - key: instance_type
    prefix: type_
```

**Cloud Provisioning (provision-aws.yml):**
```yaml
---
- name: Provision AWS Infrastructure
  hosts: localhost
  connection: local
  gather_facts: no
  
  vars:
    region: us-east-1
    vpc_cidr: 10.0.0.0/16
    
  tasks:
    - name: Create VPC
      ec2_vpc_net:
        name: production-vpc
        cidr_block: "{{ vpc_cidr }}"
        region: "{{ region }}"
        dns_hostnames: yes
        dns_support: yes
        tags:
          Environment: production
      register: vpc
    
    - name: Create Internet Gateway
      ec2_vpc_igw:
        vpc_id: "{{ vpc.vpc.id }}"
        region: "{{ region }}"
        tags:
          Name: production-igw
      register: igw
    
    - name: Create public subnets
      ec2_vpc_subnet:
        vpc_id: "{{ vpc.vpc.id }}"
        cidr: "{{ item.cidr }}"
        az: "{{ item.az }}"
        region: "{{ region }}"
        tags:
          Name: "{{ item.name }}"
          Type: public
      loop:
        - { name: public-1a, cidr: 10.0.1.0/24, az: us-east-1a }
        - { name: public-1b, cidr: 10.0.2.0/24, az: us-east-1b }
      register: public_subnets
    
    - name: Create private subnets
      ec2_vpc_subnet:
        vpc_id: "{{ vpc.vpc.id }}"
        cidr: "{{ item.cidr }}"
        az: "{{ item.az }}"
        region: "{{ region }}"
        tags:
          Name: "{{ item.name }}"
          Type: private
      loop:
        - { name: private-1a, cidr: 10.0.11.0/24, az: us-east-1a }
        - { name: private-1b, cidr: 10.0.12.0/24, az: us-east-1b }
```

## Best Practices

1. **Use roles for organization** - Modular, reusable automation
2. **Keep playbooks idempotent** - Safe to run multiple times
3. **Use check mode** - Test changes before applying
4. **Implement error handling** - ignore_errors, failed_when
5. **Use tags for selective execution** - Run specific task groups
6. **Encrypt sensitive data** - ansible-vault for secrets
7. **Write descriptive tasks** - Clear names and documentation
8. **Use dynamic inventories** - Auto-discover infrastructure
9. **Gather facts strategically** - Disable when not needed
10. **Test playbooks with molecule** - Validate role behavior

