|
| 1 | +<!-- Copyright IBM Corp. 2014, 2026 --> |
| 2 | +<!-- SPDX-License-Identifier: MPL-2.0 --> |
| 3 | + |
| 4 | +# AGENTS.md |
| 5 | + |
| 6 | +This file provides guidance to AI coding agents when working with code in this repository. |
| 7 | + |
| 8 | +## Repository Overview |
| 9 | + |
| 10 | +This is the Go-based Terraform AWS Provider (`github.com/hashicorp/terraform-provider-aws`). It maps AWS API resources to Terraform resources, data sources, ephemeral resources and actions (collectively often referred to as just resources). The primary language is Go; HCL appears in acceptance test configurations and website documentation. |
| 11 | + |
| 12 | +--- |
| 13 | +## Agent Registry |
| 14 | + |
| 15 | +This project uses specialized personas for different tasks. |
| 16 | + |
| 17 | +### Available Personas |
| 18 | + |
| 19 | +- **`@contributor`**: [Contributor Persona](./.agents/contributor.md) - Contributes code in the form of bugfixes, enhancements to existing resources, and new resources. Makes clarifications and corrections to existing documentation. |
| 20 | +- **`@maintainer`**: [Maintainer Persona](./.agents/maintainer.md) - Steward of the project, responsible for both internal and external quality. Reviews contributions. Maintains provider-level features, including new Terraform language constructs. |
| 21 | +- **`@tcm`**: [TCM Persona](./.agents/tcm.md) - Triages incoming GitHub issues and PRs. Engages with community members to answer technical and process questions. Suggests workarounds and alternatives to reported bugs. |
| 22 | + |
| 23 | +### Global Rules |
| 24 | + |
| 25 | +- Always use the requested persona for tasks. |
| 26 | +- If no persona is specified, default to `@contributor`. |
| 27 | +- A persona defines a role with a perspective and responsibilities. |
| 28 | +- Personas may invoke skills. |
| 29 | + |
| 30 | +--- |
| 31 | +## Skills |
| 32 | + |
| 33 | +Skills are loaded from `./.agents/skills`. Each skill supplies step-by-step instructions, code patterns, and guardrails for a specific task. |
| 34 | + |
| 35 | +| Skill | Task | |
| 36 | +|---|---| |
| 37 | + |
| 38 | +--- |
| 39 | +## Global Rules |
| 40 | + |
| 41 | +### Non-negotiables |
| 42 | + |
| 43 | +- Verification is a hard exit criterion for every task. Without it, the task is not done. |
| 44 | +- Prefer the boring, obvious solution. |
| 45 | +- Touch only what you’re asked to touch. |
| 46 | + |
| 47 | +### AI Usage Policy |
| 48 | + |
| 49 | +Per `docs/ai-usage.md`: |
| 50 | +- Disclose AI use in the PR description. |
| 51 | +- Include `🤖🤖🤖` in the PR title if an LLM agent is directly involved in submitting it. |
| 52 | +- The human PR author is fully responsible for all submitted code and must understand it completely. |
| 53 | +- Human reviewers own the final code and must understand it fully. |
| 54 | + |
| 55 | +### Authoritative References |
| 56 | + |
| 57 | +- `GNUmakefile` — canonical list of all targets and variables. |
| 58 | +- `docs/naming.md` — naming rules for resources, files, functions, tests. |
| 59 | +- `docs/error-handling.md` — error handling patterns. |
| 60 | +- `docs/data-handling-and-conversion.md` — flatteners, expanders, AutoFlex. |
| 61 | +- `docs/retries-and-waiters.md` — retry and waiter helpers. |
| 62 | +- `docs/running-and-writing-acceptance-tests.md` — acceptance test patterns. |
| 63 | +- `names/caps.md` — enforced capitalization list for initialisms. |
| 64 | +- `.ci/.golangci*.yml` — golangci-lint configuration. |
| 65 | +- `docs/ai-agent-guides/` — task-specific agent guides (resource identity, list resources, etc.). |
| 66 | + |
| 67 | +### Environment Setup |
| 68 | + |
| 69 | +```bash |
| 70 | +make prereq-go # install the required Go version (see .go-version) |
| 71 | +make tools # install linters and helper binaries (run once) |
| 72 | +make build # compile the provider |
| 73 | +``` |
| 74 | + |
| 75 | +Acceptance tests require Terraform CLI 0.12.31+ and AWS credentials in the environment (`AWS_PROFILE` or `AWS_ACCESS_KEY_ID`/`AWS_SECRET_ACCESS_KEY` plus `AWS_DEFAULT_REGION`). The default acceptance test region is `us-west-2`. |
| 76 | + |
| 77 | +### Common Commands |
| 78 | + |
| 79 | +#### Build |
| 80 | + |
| 81 | +```bash |
| 82 | +make build # build provider binary |
| 83 | +make go-build # CI-style build check |
| 84 | +``` |
| 85 | + |
| 86 | +#### Format and Imports |
| 87 | + |
| 88 | +```bash |
| 89 | +make fmt # fix Go source formatting (gofmt -s) |
| 90 | +make fmt-check # verify formatting |
| 91 | +make fix-imports # fix import ordering (goimports) |
| 92 | +``` |
| 93 | + |
| 94 | +#### Unit Tests |
| 95 | + |
| 96 | +```bash |
| 97 | +make test # all unit tests |
| 98 | +make test PKG=iam # one service package |
| 99 | +make test PKG=iam TESTARGS='-run TestExpandRole$' # one test |
| 100 | +make test TEST=./internal/create # one directory |
| 101 | +``` |
| 102 | + |
| 103 | +#### Acceptance Tests (require AWS credentials, create real resources) |
| 104 | + |
| 105 | +```bash |
| 106 | +make testacc PKG=cloudwatch TESTS=TestAccCloudWatchDashboard_ |
| 107 | +make testacc PKG=iam TESTS=TestAccIAMRole_basic |
| 108 | +make t PKG=iam T=TestAccIAMRole_basic # alias |
| 109 | +``` |
| 110 | + |
| 111 | +#### Linting |
| 112 | + |
| 113 | +```bash |
| 114 | +make golangci-lint PKG=<service> # primary Go linter (preferred over make lint) |
| 115 | +make golangci-lint1 PKG=<service> # faster single-shard run |
| 116 | +make import-lint PKG=<service> # import ordering |
| 117 | +make provider-lint PKG=<service> # provider-specific lint rules |
| 118 | +make testacc-lint PKG=<service> # acceptance test HCL lint |
| 119 | +``` |
| 120 | + |
| 121 | +#### Code Generation |
| 122 | + |
| 123 | +```bash |
| 124 | +make gen # run all generators (required after changing @FrameworkResource/@SDKResource annotations) |
| 125 | +make gen-check # verify generated files are up to date |
| 126 | +``` |
| 127 | + |
| 128 | +#### Pre-PR Quick Fix |
| 129 | + |
| 130 | +```bash |
| 131 | +make quick-fix PKG=<service> # fmt, imports, testacc-lint, semgrep, terraform-fmt, copyright |
| 132 | +make ci-quick # broader CI subset |
| 133 | +``` |
| 134 | + |
| 135 | +### Adding a New Resource or Data Source |
| 136 | + |
| 137 | +Always use `skaff` — do not copy an older resource: |
| 138 | + |
| 139 | +```bash |
| 140 | +make skaff |
| 141 | +skaff resource --name ExampleThing --service example |
| 142 | +``` |
| 143 | + |
| 144 | +After scaffolding: |
| 145 | +1. Fill in the schema and CRUD handlers. |
| 146 | +2. Add `@FrameworkResource("aws_example_thing", name="Example Thing")` annotation. |
| 147 | +3. Run `make gen` to register the resource. |
| 148 | +4. Write at minimum: `basic`, `disappears`, and key argument tests. |
| 149 | + |
| 150 | +Net-new resources must use Terraform Plugin Framework. Existing SDKv2 resources stay SDKv2 unless migration is the explicit task. |
| 151 | + |
| 152 | +### Code Style and Conventions |
| 153 | + |
| 154 | +#### Naming |
| 155 | + |
| 156 | +- Service packages: `internal/service/<serviceidentifier>` — lowercase, no underscores, prefer the shorter AWS SDK/CLI name. |
| 157 | +- Go files: `snake_case.go`; data sources end with `_data_source.go`; tests end with `_test.go`. |
| 158 | +- Main constructors: `Resource<Name>()` and `DataSource<Name>()`. |
| 159 | +- CRUD helpers: `resource<Name>Create`, `resource<Name>Read`, `resource<Name>Update`, `resource<Name>Delete`. |
| 160 | +- Use Go MixedCaps with correct initialisms: `VPCEndpoint`, `ARN`, `IAM`, `URL`, `API`. Never `Id` — always `ID`. |
| 161 | +- Do not include the service name in function/variable names within the service package. |
| 162 | +- Terraform schema attribute names use `snake_case`. |
| 163 | + |
| 164 | +#### Imports |
| 165 | + |
| 166 | +Order: standard library → third-party → local. Enforced by `make import-lint`. |
| 167 | + |
| 168 | +Required aliases: |
| 169 | +- `github.com/hashicorp/terraform-plugin-sdk/v2/helper/id` → `sdkid` |
| 170 | +- `github.com/hashicorp/terraform-plugin-sdk/v2/helper/retry` → `sdkretry` |
| 171 | +- `github.com/hashicorp/terraform-plugin-testing/helper/acctest` → `sdkacctest` |
| 172 | +- `github.com/hashicorp/terraform-provider-aws/internal/types` → `inttypes` |
| 173 | + |
| 174 | +#### Schema |
| 175 | + |
| 176 | +- Prefer `Optional: true` + `Computed: true` for attributes with server-side defaults; avoid provider defaults. |
| 177 | +- Use AWS SDK constants instead of duplicating string values. |
| 178 | +- For Framework resources, use `internal/framework/flex` AutoFlex before writing custom conversion code. |
| 179 | + |
| 180 | +#### Error Handling |
| 181 | + |
| 182 | +- Name error variables `err`; use early returns. |
| 183 | +- Wrap errors: `fmt.Errorf("doing thing: %w", err)`. |
| 184 | +- Use `tfawserr.ErrCodeEquals` / `tfawserr.ErrMessageContains` for AWS API error matching. |
| 185 | +- In SDKv2 `Read`, only call `d.SetId("")` when `!d.IsNewResource()`. |
| 186 | +- Use `internal/retry` for waiters and retries; do not write custom polling loops. |
| 187 | + |
| 188 | +#### Tags |
| 189 | + |
| 190 | +AutoFlex ignores `Tags` by default. Keep tagging logic separate. |
| 191 | + |
| 192 | +#### `nolint` Comments |
| 193 | + |
| 194 | +Must name the specific linter and explain why: `//nolint:staticcheck // reason`. |
| 195 | + |
| 196 | +### Testing Conventions |
| 197 | + |
| 198 | +- Unit tests: `Test<FunctionName>` — no service name, usually no underscores, always call `t.Parallel()`. |
| 199 | +- Acceptance tests: `TestAcc<Service><Resource>_<case>` — e.g., `TestAccIAMRole_basic`, `TestAccIAMRole_tags`. |
| 200 | +- Serialized acceptance helpers: `testAcc<Resource>_<case>` (lowercase `t`, no service name). |
| 201 | +- Acceptance tests use: `acctest.Context(t)`, `acctest.PreCheck`, `acctest.ErrorCheck`, `acctest.ProtoV5ProviderFactories`, destroy checks, and import-state verification. |
| 202 | +- Do not hardcode AMI IDs, regions, partitions, or DNS suffixes — use provider helpers. |
| 203 | +- Place unit tests before acceptance tests in the same file. |
| 204 | + |
| 205 | +### Pre-PR Checklist |
| 206 | + |
| 207 | +1. `make quick-fix PKG=<service>` — auto-fix formatting, imports, HCL, copyright. |
| 208 | +2. `make test PKG=<service>` — unit tests pass. |
| 209 | +3. `make golangci-lint PKG=<service>` — no new lint errors. |
| 210 | +4. `make import-lint PKG=<service>` — import ordering clean. |
| 211 | +5. `make provider-lint PKG=<service>` — provider rules clean. |
| 212 | +6. `make gen` — if annotations or generators were changed; then `make gen-check`. |
| 213 | +7. Acceptance tests — if AWS credentials are available and the change warrants it. |
| 214 | + |
| 215 | +Escalate to `make ci-quick` only when the above are clean or the change is broad. |
0 commit comments