forked from infra/ansible
🤖 docs: Add AGENTS.md with project conventions for AI coding agents
Without guardrails, AI tools generate PRs that ignore Fedora Infra's conventions — wrong file extensions (`.yaml` vs `.yml`), missing `vars_files` triplets, broken idempotency, relative paths instead of the required hardcoded `/srv/web/infra/ansible/` layout, and suggestions to "fix" intentional patterns like the `vars/all/*.yaml` exception or the `fedora_messaging_callback.py` custom plugin. AGENTS.md gives AI agents the same context a new human contributor would get from reading README.md, CONVENTIONS, STYLEGUIDE, and `.ai_review/project.md` — but in a single file that AI tools automatically load before generating code. This means AI-assisted PRs should arrive already following our linting rules, architectural patterns (OpenShift app vs group playbook), staging/prod conventions (`_stg` group_vars, `env`/`env_suffix`), and tag discipline. The file also includes the Fedora AI-Assisted Contribution Policy requirements, ensuring AI agents prompt contributors to include the Assisted-by: commit message trailer and respect the project's rules on accountability, transparency, and human-final review. The net effect is fewer round-trips in review: maintainers spend less time explaining the same conventions repeatedly and can focus review on whether the change is correct, not whether it follows the style guide. Assisted-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com> Signed-off-by: Justin Wheeler <jwheel@redhat.com>
This commit is contained in:
parent
3e60b00464
commit
5c766e21a0
1 changed files with 108 additions and 0 deletions
108
AGENTS.md
Normal file
108
AGENTS.md
Normal file
|
|
@ -0,0 +1,108 @@
|
|||
# AGENTS.md
|
||||
|
||||
This file provides guidance to AI coding agents when working with code in this repository.
|
||||
|
||||
## Project Overview
|
||||
|
||||
Ansible automation for the entire Fedora Project infrastructure. Manages hundreds of bare-metal hosts, VMs, and OpenShift 4 applications across production and staging environments. The control host is **batcave01** (`/srv/web/infra/ansible` public, `/srv/private/ansible` private).
|
||||
|
||||
Repository is hosted at https://forge.fedoraproject.org/infra/ansible
|
||||
|
||||
## Linting
|
||||
|
||||
Run yamllint on changed files:
|
||||
```sh
|
||||
yamllint path/to/file.yml
|
||||
```
|
||||
|
||||
Run ansible-lint on changed files:
|
||||
```sh
|
||||
ansible-lint path/to/file.yml
|
||||
```
|
||||
|
||||
CI runs both linters on changed files only (Forgejo Actions on `quay.io/fedora/fedora:latest`). The `community.zabbix` collection is installed before ansible-lint runs.
|
||||
|
||||
### Linting configuration
|
||||
|
||||
- **yamllint** (`.yamllint.yaml`): 2-space indentation (warning level), line-length disabled, octal values forbidden, truthy values restricted to `true/false/yes/no`, templates directories ignored.
|
||||
- **ansible-lint** (`.ansible-lint`): Runs in offline mode. Skipped rules: `yaml`, `role-name[path]`, `var-naming[no-role-prefix]`, `no-changed-when`, `ignore-errors`. Uses `mock_modules` and `mock_roles` to pass syntax checks without all dependencies.
|
||||
|
||||
## Architecture
|
||||
|
||||
### Directory structure
|
||||
|
||||
- `playbooks/groups/` — One playbook per service group (multi-host). Filename should be descriptive.
|
||||
- `playbooks/hosts/` — One playbook per unique host. Filename MUST be `FQDN.yml`.
|
||||
- `playbooks/openshift-apps/` — ~60 OCP4 application deployments.
|
||||
- `playbooks/manual/` — Admin-only playbooks, never run by cron.
|
||||
- `playbooks/include/` — Shared playbook fragments (proxy, virt, cert).
|
||||
- `roles/` — 134 roles. Flat structure with some namespacing (`openshift/`, `openshift-apps/`, `awx/`, `rabbit/`).
|
||||
- `roles/base/` — Applied to ALL managed hosts. Changes here have maximum blast radius.
|
||||
- `inventory/` — Host definitions, `group_vars/` (150 files), `host_vars/`, and `zzz-inventory.config` (constructed inventory plugin, loads last due to `zzz-` prefix).
|
||||
- `vars/all/` — Fedora release cycle variables. Changed every ~6 months during branching/release. Incorrect values break builds across the entire infrastructure.
|
||||
- `vars/global.yml` — Global vars (paths, SSL, base packages).
|
||||
- `tasks/` — Reusable task snippets included in playbooks.
|
||||
- `library/` — Custom Ansible modules (`delete_old_oci_images.py`, `virt_boot`, etc.).
|
||||
- `callback_plugins/` — Custom callbacks (`fedora_messaging_callback.py`, `logdetail.py`). Don't suggest replacing these.
|
||||
- `main.yml` — Master playbook importing all group/host playbooks. Used with `-t tag` to run specific tags across all hosts. Nightly `--check --diff` cron runs all playbooks.
|
||||
|
||||
### Two main deployment patterns
|
||||
|
||||
**OpenShift app pattern** (dominant for new services):
|
||||
1. Playbook in `playbooks/openshift-apps/<app>.yml` targets `os_control[0]:os_control_stg[0]`
|
||||
2. Uses composable `openshift/*` roles: `project`, `object`, `keytab`, `secret-file`, `imagestream`, `route`, `rollout`
|
||||
3. App templates in `roles/openshift-apps/<app>/templates/`
|
||||
4. Uses `gather_facts: false` (runs `oc` commands on control node, not on apps)
|
||||
|
||||
**Group playbook pattern** (traditional VM services):
|
||||
1. Playbook in `playbooks/groups/<group>.yml` with `hosts:` matching inventory group
|
||||
2. Must include standard vars_files (see below)
|
||||
|
||||
### Staging vs Production
|
||||
|
||||
Same inventory, not separate inventories. Staging hosts use `_stg` suffixed group_vars files. Controlled by:
|
||||
- `env` — `"production"` or `"staging"`
|
||||
- `env_suffix` — `""` for prod, `".stg"` for staging
|
||||
|
||||
## Fedora AI-Assisted Contribution Policy
|
||||
|
||||
This repository is part of the Fedora Project and subject to the [Fedora AI-Assisted Contributions Policy](https://docs.fedoraproject.org/en-US/council/policy/ai-contribution-policy/). Key requirements:
|
||||
|
||||
- **Accountability**: The human contributor is always the author and is fully accountable for the entirety of AI-assisted contributions. All submissions must meet project standards for quality, license compliance, and utility.
|
||||
- **Transparency**: Use of AI tools MUST be disclosed when the significant part of the contribution is taken from a tool without changes. For git contributions, use an `Assisted-by:` commit message trailer (e.g., `Assisted-by: ChatGPTv5` or `Assisted-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>`).
|
||||
- **No AI-only judgments**: AI MUST NOT be used as the sole or final arbiter for substantive or subjective judgments on contributions, nor for evaluating a person's standing in the community. Automated objective validation (CI/CD, testing, linting) is permitted.
|
||||
|
||||
When generating commit messages, always include the `Assisted-by:` trailer naming the specific AI model and version used.
|
||||
|
||||
## Coding Conventions
|
||||
|
||||
### Required vars_files in all group/host playbooks
|
||||
```yaml
|
||||
vars_files:
|
||||
- /srv/web/infra/ansible/vars/global.yml
|
||||
- "{{ private }}/vars.yml"
|
||||
- /srv/web/infra/ansible/vars/{{ ansible_distribution }}.yml
|
||||
```
|
||||
These hardcoded paths are the production layout on batcave01. Do not make them relative or configurable.
|
||||
|
||||
### Style rules
|
||||
- Use `.yml` not `.yaml` for file extensions. Exception: `vars/all/*.yaml` is historical — don't "fix" this.
|
||||
- Add `.j2` extension to all Jinja2 templates. A `.yml` file in `templates/` without `.j2` won't render Jinja expressions.
|
||||
- 2-space YAML indentation. Line length is not enforced.
|
||||
- Prefer readable multi-line module args over single-line `module: name=x arg=y` format.
|
||||
- Standard tags: `packages` (installs/removes packages), `config` (installs config files).
|
||||
- `build` and `rollout` tags use `never` to prevent accidental execution.
|
||||
- All playbooks must be **idempotent** — they can be run at any time by the nightly cron.
|
||||
|
||||
### Common pitfalls
|
||||
- Forgetting to update multiple files in `vars/all/` together during release transitions (e.g., branching requires `FedoraBranched.yaml`, `00-FedoraCycleNumber.yaml`, `FedoraBranchedBodhi.yaml`, and `Frozen.yaml`).
|
||||
- Breaking idempotency — generates noise in nightly `--check --diff` and masks real drift.
|
||||
- OpenShift apps must target `os_control[0]:os_control_stg[0]`, not all control nodes.
|
||||
|
||||
### Domain terminology
|
||||
- **batcave01** — Ansible control host
|
||||
- **FAS/IPA** — Fedora Account System (identity provider)
|
||||
- **Koji** — Build system (VM-based, not OpenShift)
|
||||
- **Bodhi** — Update management (runs on OpenShift)
|
||||
- **dist-git/src.fedoraproject.org** — Package source repositories
|
||||
- **fedora-messaging/RabbitMQ** — AMQP message bus connecting services
|
||||
Loading…
Add table
Add a link
Reference in a new issue