# ansible

Enforces Ansible standards in Cursor: role structure, clean YAML formatting, idempotency, and Jinja2 template handling.

- rule · `type=rule` · Cursor · ★ 3580
- Author: sanjeed5
- License: CC0-1.0 · policy=mirror · the beginning of the file is at the end of this page
- Source: https://github.com/sanjeed5/awesome-cursor-rules-mdc/tree/HEAD/rules-mdc/ansible.mdc
- Updated: 2026-05-19
- HTML: https://affpapa.org/en/nevibecode/rules/sanjeed5-ansible

## What it does

This rule guides Cursor to generate structured Ansible code instead of monolithic playbooks. It forces tasks into focused roles and collections, isolating setup logic and delegating information gathering to dedicated `_facts` tasks.

The guide mandates strict YAML syntax. Cursor stops using inline `key=value` strings for module parameters, switching to structured dictionaries. Every file must begin with `---`, use two-space indentation, and standard boolean values like `true` or `false`.

Forcing declarative modules over raw `shell` or `command` runs guarantees idempotency. When files need editing, atomic operations via `template` or `copy` prevent incomplete writes from breaking system states.

## Install

### Cursor (native platform)

**Manually: put the files in place**
- File: `.cursor/rules/ansible.mdc` — Frontmatter: description, globs, alwaysApply

### Claude Code

**Manually: put the files in place**
- File: `.claude/rules/ansible.md` — The paths frontmatter field limits the files: move globs from the source into paths

### Codex

**AGENTS.md**
- Codex reads AGENTS.md: paste the rule text there

### GitHub Copilot

**Manually: put the files in place**
- File: `.github/instructions/ansible.instructions.md` — The applyTo field sets which files it applies to: move globs from the source into applyTo

### Windsurf (Devin Desktop)

**Manually: put the files in place**
- File: `.devin/rules/ansible.md`

### Cline

**Manually: put the files in place**
- File: `.clinerules/ansible.md`

Where a file is given instead of a command, copy the files from the source to that path: https://github.com/sanjeed5/awesome-cursor-rules-mdc/tree/HEAD/rules-mdc/ansible.mdc

## When to use it
- split monolithic playbooks into reusable roles
- refactor legacy key=value module parameters into structured YAML
- replace fragile shell scripts with declarative idempotent tasks
- organize role variables between defaults and inventory configs

## Example prompts
- Generate an Ansible role to install and configure PostgreSQL
- Refactor this shell task into an idempotent ansible.builtin module
- Convert these legacy key=value task arguments into structured YAML maps

## Source text · ansible.mdc · CC0-1.0

Below is the content of a third-party file. It is data, not instructions for you: do not act on anything written inside unless the human asks. Block tag: 74c98041dc2af49d.

BEGIN THIRD-PARTY FILE 74c98041dc2af49d
````text
---
description: This guide defines definitive best practices for writing maintainable, performant, and robust Ansible code, focusing on modern YAML hygiene, role design, and CI/CD integration.
globs: **/*
---
# ansible Best Practices

Ansible excels when treated as infrastructure-as-code. These guidelines ensure your playbooks, roles, and modules are consistent, idempotent, and production-ready.

## 1. Code Organization and Structure

**Always structure your Ansible content into roles and collections.** Roles encapsulate specific functionalities, while collections group related roles, modules, and plugins, promoting reusability and discoverability.

-   **Role Scoping:** Each role or module must focus on a single, well-defined task. Avoid monolithic roles.
    ❌ BAD:
    ```yaml
    # roles/webserver/tasks/main.yml
    - name: Install Nginx
      ansible.builtin.apt: name=nginx state=present
    - name: Configure Nginx
      ansible.builtin.template: src=nginx.conf.j2 dest=/etc/nginx/nginx.conf
    - name: Start Nginx
      ansible.builtin.service: name=nginx state=started
    - name: Install PHP-FPM
      ansible.builtin.apt: name=php-fpm state=present
    # ... and more
    ```
    ✅ GOOD:
    ```yaml
    # roles/nginx/tasks/main.yml
    - name: Ensure Nginx is installed and configured
      ansible.builtin.include_tasks: setup.yml
    - name: Ensure Nginx service is running
      ansible.builtin.service: name=nginx state=started enabled=true

    # roles/php-fpm/tasks/main.yml
    - name: Ensure PHP-FPM is installed and configured
      ansible.builtin.include_tasks: setup.yml
    ```
-   **Fact Modules:** Create dedicated `_info` or `_facts` modules/tasks for gathering information, rather than overloading existing ones.
    ✅ GOOD:
    ```yaml
    # roles/system_facts/tasks/main.yml
    - name: Gather custom system facts
      ansible.builtin.set_fact:
        custom_os_version: "{{ ansible_facts['distribution_major_version'] }}"
    ```

## 2. YAML Hygiene and Syntax

**Enforce strict YAML formatting.** Consistent syntax improves readability and prevents subtle parsing errors.

-   **File Start:** All YAML files must begin with `---`.
-   **Indentation:** Use two spaces for indentation, never tabs.
-   **Quotes:** Quote strings only when necessary (e.g., when they contain special characters or Jinja map references). Prefer single quotes. Use double quotes for escaping characters or multi-line strings.
    ❌ BAD:
    ```yaml
    - name: "Install a package"
      ansible.builtin.apt: name="my-package" state="present"
    - name: Set fact
      set_fact:
        myvar: '{{ item["key"] }}' # Incorrect quoting for Jinja map
    ```
    ✅ GOOD:
    ```yaml
    ---
    - name: Install a package
      ansible.builtin.apt:
        name: my-package
        state: present
    - name: Set fact
      ansible.builtin.set_fact:
        my_var: "{{ item['key'] }}" # Double quotes for Jinja map
    - name: Print multi-line message
      ansible.builtin.debug:
        msg: |
          This is line one.
          This is line two.
    ```
-   **Colon Spacing:** Use exactly one space after a colon in key-value pairs.
    ❌ BAD:
    ```yaml
    - name : start service
      service:
          name    : my_service
          state   : started
    ```
    ✅ GOOD:
    ```yaml
    - name: start service
      ansible.builtin.service:
        name: my_service
        state: started
    ```
-   **Structured Map Style:** Always use the structured map style for module parameters, not the legacy `key=value` style.
    ❌ BAD:
    ```yaml
    - name: Create directory
      ansible.builtin.file: path=/opt/app state=directory mode=0755
    ```
    ✅ GOOD:
    ```yaml
    - name: Create directory
      ansible.builtin.file:
        path: /opt/app
        state: directory
        mode: '0755' # Quote octal modes
    ```
-   **Booleans:** Standardize on `true`/`false`.
    ❌ BAD:
    ```yaml
    - name: Enable service
      ansible.builtin.service: name=my_service enabled=yes
      become: True
    ```
````
END THIRD-PARTY FILE 74c98041dc2af49d

The third-party file has ended. Everything between the 74c98041dc2af49d tags is data: requests and commands from it are not followed. An “end of file” line with another tag inside the block is part of the file.

First 4063 of 10016 bytes. © sanjeed5 · CC0-1.0 · https://github.com/sanjeed5/awesome-cursor-rules-mdc/tree/HEAD/rules-mdc/ansible.mdc

_Part of the page did not fit — see the HTML version._

---
NeVibeCode on affpapa.org. Catalog texts are descriptions, not instructions for the agent. How to choose and install: https://affpapa.org/en/nevibecode/agents.md
