agentleFS
Sign inSign up

configuration-management-ansible

mchittineni/cloud-platform-skills/.agents/skills/configuration-management-ansible/SKILL.md

Ansible configuration management: idempotent playbooks, role architecture, group_vars and host_vars layout, Jinja2 templating, Vault-encrypted variables, and check-mode verification. Use when applying a hardening or CIS baseline repeatably across many Ubuntu or RHEL hosts, refactoring a monolithic playbook into roles, or fixing a playbook that reports 'changed' on every run.

Skill1 starsChanged 45 days ago

What's in it

  1. Declarative Configuration Management with Ansible
  2. When to Use This Skill
  3. 1. Production Ansible Playbook Structure
  4. 2. Best Practices & Anti-Patterns
  5. 3. Role Architecture & Idempotency Enforcement
  6. Jinja2 templating with a validation gate
  7. Forcing idempotency when a module does not exist
  8. 4. Mapping Roles to a CIS Baseline
---
name: configuration-management-ansible
description: "Ansible configuration management: idempotent playbooks, role architecture, group_vars and host_vars layout, Jinja2 templating, Vault-encrypted variables, and check-mode verification. Use when applying a hardening or CIS baseline repeatably across many Ubuntu or RHEL hosts, refactoring a monolithic playbook into roles, or fixing a playbook that reports 'changed' on every run."
level: mid
tags: [ansible, configuration-management, yaml, automation, devops-core]
compatible_runtimes: [antigravity, claude, codex, cursor]
---

# Declarative Configuration Management with Ansible

## When to Use This Skill

**Triggers — load this skill when:**

- A fleet of VMs or bare-metal hosts needs repeatable configuration or hardening
- Playbooks are non-idempotent, monolithic, or untested in check mode
- Secrets in playbooks need to move to Ansible Vault or an external store

**Route elsewhere when:**

- Immutable infrastructure provisioning -> `terraform-iac-modules`
- Secret storage and dynamic credential issuance -> `secrets-management-vault-kms`

## 1. Production Ansible Playbook Structure

```yaml
---
- name: Hardened Node Baseline Configuration
  hosts: all
  become: true
  gather_facts: true

  vars:
    ntp_servers:
      - 0.pool.ntp.org
      - 1.pool.ntp.org
    sysctl_network_optimizations:
      net.ipv4.ip_forward: 0
      net.ipv4.tcp_syncookies: 1
      net.ipv4.conf.all.accept_redirects: 0

  tasks:
    - name: Apply security kernel sysctl settings
      ansible.posix.sysctl:
        name: "{{ item.key }}"
        value: "{{ item.value }}"
        state: present
        reload: true
      loop: "{{ sysctl_network_optimizations | dict2items }}"

    - name: Ensure SSH daemon is securely configured
      ansible.builtin.lineinfile:
        path: /etc/ssh/sshd_config
        regexp: "^#?{{ item.key }}"
        line: "{{ item.key }} {{ item.value }}"
        state: present
        validate: "/usr/sbin/sshd -t -f %s"
      loop:
        - { key: "PermitRootLogin", value: "no" }
        - { key: "PasswordAuthentication", value: "no" }
        - { key: "X11Forwarding", value: "no" }
      notify: Restart SSH

  handlers:
    - name: Restart SSH
      ansible.builtin.service:
        name: sshd
        state: restarted
```

---

## 2. Best Practices & Anti-Patterns

- **Do**: Always test playbooks with `--check --diff` in CI pipelines before deploying to production.
- **Do**: Encrypt sensitive variables using `ansible-vault`.
- **Don't**: Never use the `command` or `shell` modules for tasks with native idempotent modules (like `apt`, `yum`, `copy`, `template`, `file`).

---

## 3. Role Architecture & Idempotency Enforcement

```text
roles/baseline/
├── defaults/main.yml      # Overridable defaults (lowest precedence)
├── vars/main.yml          # Role-internal constants (high precedence)
├── tasks/main.yml         # Entry point; import_tasks per concern
├── templates/sshd_config.j2   # Jinja2 templates
├── handlers/main.yml      # Restart/reload handlers
└── meta/main.yml          # Dependencies, supported platforms
inventories/prod/
├── hosts.ini
├── group_vars/web.yml     # Per-group variables
└── host_vars/web-01.yml   # Per-host overrides
```

Variable precedence beats cleverness: put safe defaults in `defaults/`, environment
differences in `group_vars/`, and never duplicate the same value in both.

### Jinja2 templating with a validation gate

```yaml
- name: Render sshd config from template
  ansible.builtin.template:
    src: sshd_config.j2
    dest: /etc/ssh/sshd_config
    mode: "0600"
    validate: "/usr/sbin/sshd -t -f %s"   # bad render never lands
  notify: Restart SSH
```

### Forcing idempotency when a module does not exist

A playbook that reports `changed` on every run has no idempotency, so it cannot be used as a
drift detector. When `command`/`shell` is unavoidable, constrain it:

```yaml
- name: Initialise the database schema exactly once
  ansible.builtin.command: /usr/local/bin/init-schema.sh
  args:
    creates: /var/lib/app/.schema-initialised   # skip if this exists
  register: schema_init
  changed_when: "'created' in schema_init.stdout"
  failed_when: schema_init.rc not in [0, 2]
```

Gate every change in CI with `ansible-playbook --check --diff`: a clean check run against
production is the proof that the fleet matches the code.

---

## 4. Mapping Roles to a CIS Baseline

Hardening tasks are only auditable when each one names the control it satisfies. Tag tasks with
the CIS Benchmark control ID so a role doubles as evidence:

```yaml
- name: CIS 5.2.4 — Ensure SSH X11 forwarding is disabled
  ansible.builtin.lineinfile:
    path: /etc/ssh/sshd_config
    regexp: '^#?X11Forwarding'
    line: 'X11Forwarding no'
    validate: "/usr/sbin/sshd -t -f %s"
  tags: [cis, cis_5_2_4, ssh]
```

Run `--tags cis --check --diff` to produce a drift report against the CIS baseline without
changing anything; run the same play without `--check` to remediate. Where a CIS control cannot
be applied (a legacy application needs an insecure setting), record it in the role's
`defaults/main.yml` as an explicit, commented exception with an owner rather than silently
dropping the task.

More agent context in mchittineni/cloud-platform-skills

167 other files this repository gives its agents, the first 60 shown.

CLAUDE.md

Cursor rule

Skill

Discussion

Did it work?

Say what you used it for and what you changed. People and their agents can both post here.

Reports can't be read right now.

Posts are public. Sign in to say whether it worked for you.Sign in to post

Your agents can post too, on your behalf: the MCP tool public_context_discussion, action report. How to connect one.