hashicorp/terraform-provider-aws
The AWS Provider enables Terraform to manage AWS resources.
Mixed signals — read the receipts
no tests detected; no CI workflows detected
Has a license, tests, and CI — clean foundation to fork and modify.
Documented and popular — useful reference codebase to read through.
No critical CVEs, sane security posture — runnable as-is.
- ⚠No CI workflows detected
- ⚠No test directory detected
- ✓Last commit today
- ✓14 active contributors
- ✓Distributed ownership (top contributor 19% of recent commits)
- ✓MPL-2.0 licensed
What would improve this?
- →Use as dependency Mixed → Healthy if: add a test suite
Computed from maintenance signals — commit recency, contributor breadth, bus factor, license, CI, tests
Informational only. RepoPilot summarises public signals (license, dependency CVEs, commit recency, CI presence, etc.) at the time of analysis. Signals can be incomplete or stale. Not professional, security, or legal advice; verify before relying on it for production decisions.
Embed the "Forkable" badge
Paste into your README — live-updates from the latest cached analysis.
[](https://repopilot.app/r/hashicorp/terraform-provider-aws)Paste at the top of your README.md — renders inline like a shields.io badge.
▸Preview social card
This card auto-renders when someone shares https://repopilot.app/r/hashicorp/terraform-provider-aws on X, Slack, or LinkedIn.
Ask AI about hashicorp/terraform-provider-aws
Grounded in the actual source code. Pick a starter question or write your own.
Onboarding doc
Onboarding: hashicorp/terraform-provider-aws
Generated by RepoPilot · 2026-06-24 · Source
🎯Verdict
WAIT — Mixed signals — read the receipts
- Last commit today
- 14 active contributors
- Distributed ownership (top contributor 19% of recent commits)
- MPL-2.0 licensed
- ⚠ No CI workflows detected
- ⚠ No test directory detected
<sub>Computed from maintenance signals — commit recency, contributor breadth, bus factor, license, CI, tests</sub>
⚡TL;DR
The AWS Provider is a Terraform plugin written in Go that allows users to declare, provision, and manage AWS infrastructure resources through Terraform's HCL language. It translates Terraform configurations into AWS API calls, supporting 100+ AWS services from EC2 and S3 to RDS and Lambda, enabling infrastructure-as-code workflows on AWS. Monolithic single-service structure: internal/provider/ contains the main provider logic organized by AWS service (internal/service/ec2/, internal/service/s3/, etc.). Each service has resource and data_source files with schema definitions, CRUD operations, and validation. Tests sit alongside implementations (internal/service//resource__test.go). .archive/changelog/ tracks all changes by PR number.
👥Who it's for
DevOps engineers, infrastructure teams, and Terraform users who need to manage AWS resources programmatically via IaC. Contributors include HashiCorp maintainers and community members extending support for new AWS services and features.
🌱Maturity & risk
Production-ready and actively developed. The repository shows consistent contribution patterns with archived changelogs tracking releases, a clear quarterly roadmap (ROADMAP.md), and organized test infrastructure. This is the official, widely-trusted AWS provider used in thousands of production deployments.
Low risk for end-users but moderate complexity for contributors. The codebase is large (77MB+ of Go code) requiring deep AWS API knowledge. Risk factors: provider must track AWS API changes constantly, changelog archive suggests high release velocity meaning potential for breaking changes, and single resource type changes can have cascading effects on dependent configurations.
Active areas of work
Active development across multiple AWS services. The archived changelog shows ongoing work on features, bug fixes, and new resource support. The quarterly roadmap (ROADMAP.md) provides visibility into planned work. Recent activity visible in the changelog archive (PR 12645, 12642, etc.) indicates continuous feature additions and maintenance.
🚀Get running
git clone https://github.com/hashicorp/terraform-provider-aws.git
cd terraform-provider-aws
make build
Verify the Makefile exists in root for build targets. Requires Go installed (version specified in go.mod, not listed here).
Daily commands:
make build # Builds the provider binary
make test # Runs unit tests
make testacc # Runs acceptance tests (requires AWS credentials)
The Makefile (present in file list) contains all standard targets. Provider binary installs to ~/.terraform.d/plugins/ after build.
🗺️Map of the codebase
.actrc— GitHub Actions configuration; defines the CI/CD pipeline and build/test environment for all contributors.archive/changelog— Changelog directory tracking all historical releases and feature additions; essential reference for understanding versioning practices and breaking changes
🧩Components & responsibilities
- Provider Registry Component (terraform-plugin-sdk/v2) — Registers all resources and data sources; Terraform CLI uses this to discover available operations
- Failure mode: Missing or incorrectly named resources cause Terraform to fail at plan time with 'resource type not found'
- Resource CRUD Handlers (Go, AWS SDK for Go) — Implement Create, Read, Update, Delete logic for each resource; translate Terraform schema to AWS API calls
- Failure mode: Bugs in CRUD logic cause resource drift, failed deployments, or data loss
- Schema Definition (terraform-plugin-sdk/v2 schema package) — Define resource attributes, validation rules, and computed fields; exposes contract to Terraform users
- Failure mode: Incomplete or incorrect schema causes type errors, validation failures, or missing attributes in state
- Acceptance Test Framework (terraform-plugin-sdk/v2 helper/resource) — Execute tests against real AWS environment; verify resource lifecycle and state management
- Failure mode: Tests fail on AWS API changes or environment issues; slow feedback loop masks bugs
- Error Handling & Retry Logic (AWS SDK retry middleware, custom error mapping) — Handle AWS API errors, throttling, and transient failures; retry with exponential backoff
- Failure mode: Insufficient retry logic causes spurious failures; poor error messages prevent troubleshooting
🔀Data flow
Terraform configuration file (.tf)→Terraform CLI— User defines resource blocks with provider-specific argumentsTerraform CLI→AWS Provider (gRPC)— CLI invokes provider binary; sends resource schema requests and plan/apply operationsAWS Provider→AWS SDK for Go— Provider translates Terraform operations to AWS SDK API callsAWS SDK for Go→AWS API (HTTPS)— SDK marshals requests and sends to AWS endpoint; receives JSON responsesAWS API→AWS Provider— Returns resource state, IDs, attributes, and error detailsAWS Provider→Terraform state file— Provider returns mapped resource state for Terraform to persist
🛠️How to make changes
Add Support for a New AWS Resource
- Create a new resource definition file in the appropriate AWS service package (e.g., ec2, s3, rds). Follow the naming convention: internal/service/{service}/resource_{resource_name}.go (
internal/service/*/resource_*.go) - Implement the resource schema with Create, Read, Update, Delete operations matching Terraform's ResourceData interface (
internal/service/*/resource_*.go) - Register the new resource in the provider's resource map within internal/provider/provider.go (
internal/provider/provider.go) - Add corresponding acceptance test file following naming convention: internal/service/{service}/resource_{resource_name}_test.go (
internal/service/*/resource_*_test.go) - Create changelog entry in .changelog directory documenting the new resource feature (
.changelog/*.md)
Fix a Bug in an Existing Resource
- Locate the resource file in internal/service/{service}/resource_{resource_name}.go and identify the bug in the CRUD operation (
internal/service/*/resource_*.go) - Write or update an acceptance test in the corresponding _test.go file to reproduce the bug (
internal/service/*/resource_*_test.go) - Implement the fix in the resource file and verify the test now passes (
internal/service/*/resource_*.go) - Add a changelog entry documenting the bug fix with the issue/PR number (
.changelog/*.md)
Add a New Attribute to an Existing Resource
- Open the resource file internal/service/{service}/resource_{resource_name}.go and add the new attribute to the Schema map (
internal/service/*/resource_*.go) - Implement field mapping in the Create/Read/Update functions to handle the new attribute from the AWS API response (
internal/service/*/resource_*.go) - Update or add acceptance tests to validate the new attribute is properly created, read, and updated (
internal/service/*/resource_*_test.go) - Create a changelog entry documenting the new attribute addition (
.changelog/*.md)
🔧Why these technologies
- Go — Terraform plugin SDK is written in Go; provider must be implemented in Go to interface with the framework
- AWS SDK for Go — Provides type-safe bindings to all AWS API operations; required for resource operations
- Terraform Plugin SDK v2 — Framework for implementing provider resources, data sources, and configuration; handles Terraform protocol communication
- GitHub Actions — CI/CD platform for running acceptance tests, linting, and releasing provider versions
⚖️Trade-offs already made
-
Monorepo structure with 600+ files across 200+ AWS services
- Why: Consolidates all AWS resources in a single provider for unified versioning and deployment
- Consequence: Large build times, slower test cycles, difficulty in isolating service-specific changes
-
Acceptance tests run against real AWS (not mocked)
- Why: Guarantees provider behavior matches actual AWS API behavior; prevents false negatives
- Consequence: Tests are slow, require AWS credentials, incur AWS costs, and depend on API availability
-
Changelog entries created per PR instead of auto-generated
- Why: Maintains human-readable, curated release notes with context and impact
- Consequence: Manual overhead; risk of missing or duplicate entries if not enforced
🚫Non-goals (don't propose these)
- Does not provide real-time change notifications or streaming API updates
- Does not handle AWS authentication or credential management (relies on AWS SDK defaults)
- Does not provide local resource state simulation; all operations are against live AWS
- Does not provide cross-AWS-account resource management orchestration
📊Code metrics
- Avg cyclomatic complexity: ~6.5 — Average resource implements 4–5 CRUD functions with error handling, state mapping, and AWS API interactions; monorepo spans 200+ services with varying API complexity
- Largest file:
internal/service/ec2/resource_*.go (estimated)(2,500 lines) - Estimated quality issues: ~35 — Large monorepo with inconsistent patterns across services; manual field mapping prone to errors; insufficient test coverage for edge cases; legacy code in older services not refactored
⚠️Anti-patterns to avoid
- Hardcoded AWS region or account assumptions (High) —
internal/service/*/resource_*.go (various): Resources assuming a single region or account instead of reading from provider config; breaks multi-region deployments - Polling without max retries or timeout (High) —
internal/service/*/resource_*.go (resource Read functions): Infinite retry loops waiting for resource state; can hang indefinitely if AWS API enters bad state - Manual field mapping without struct tags (Medium) —
internal/service/*/resource_*.go (Create/Read functions): Manual d.Set() calls instead of leveraging reflection; error-prone and hard to maintain - Insufficient error wrapping or context (Medium) —
internal/service/*/resource_*.go (various): Returning raw AWS SDK errors without wrapping; makes debugging difficult for users
🔥Performance hotspots
Acceptance test suite (all _test.go files)(I/O and external dependency) — Sequential test execution against live AWS API; 100+ tests can take 1–2 hours; AWS API rate limits and throttling cause intermittent failuresLarge monorepo build (600 files)(Compilation and artifact generation) — Building entire provider binary even for single-service changes; incremental compilation not easily parallelizable in GoState refresh on Read operations(API call overhead) — Every terraform refresh or read triggers an AWS API call; no client-side caching; high latency for users with large state files
🪤Traps & gotchas
AWS credentials required: acceptance tests (make testacc) need AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, AWS_REGION. Test environment isolation: acceptance tests create real AWS resources and will fail without cleanup; use TF_ACC=true flag carefully. Service implementation pattern: each service must follow exact schema + CRUD method signature or plugin protocol breaks. changelog PR numbers: .archive/changelog/ files use PR numbers as filenames (10036.txt, etc.) which are not directly mappable without PR metadata. Resource naming: resource and data source files must match exact terraform resource name format (underscores, not hyphens).
🏗️Architecture
💡Concepts to learn
- Terraform Plugin Protocol (gRPC) — The AWS provider communicates with Terraform core via gRPC; understanding request/response lifecycle is critical for debugging provider behavior and understanding schema validation
- Schema-Driven Resource Definition — Every AWS resource in this provider is defined through terraform-plugin-sdk's Schema object which validates input, generates docs, and controls CRUD operations; mastering schema is the primary task
- Acceptance Testing (TF_ACC) — Provider tests actually create and destroy AWS resources; understanding the test framework's resource lifecycle, state inspection, and cleanup is essential for writing reliable tests
- State Locking and Drift Detection — Terraform tracks resource state to detect changes; provider's Read() function must accurately reflect AWS reality or drift goes undetected, causing plan inconsistencies
- API Idempotency and Retries — AWS APIs can fail transiently; provider must implement retry logic and ensure operations are idempotent so re-applies don't cause errors or duplicate resources
- Terraform Plan, Apply, Refresh Cycle — The provider implements Read/Create/Update/Delete operations that map to this cycle; understanding which operation fires when is critical for correct resource behavior
- Flattening and Expanding (AWS SDK ↔ Terraform Schema) — AWS API responses must be flattened into Terraform schema format and vice versa; this data transformation is error-prone and appears throughout internal/service//resource_.go
🔗Related repos
hashicorp/terraform-provider-azurerm— Official Azure provider following identical plugin architecture and schema patterns; reference for cross-cloud provider designhashicorp/terraform-provider-google— Official Google Cloud provider with same terraform-plugin-sdk dependency; comparison for multi-cloud resource patternshashicorp/terraform— Core Terraform engine that loads and executes this provider; understanding plugin protocol is essentialaws/aws-sdk-go— Official AWS SDK for Go vendored in this provider; required to understand API call semantics and error typeshashicorp/terraform-plugin-sdk— The framework this provider is built on; contains resource schema definitions, CRUD interfaces, and testing utilities
🪄PR ideas
To work on one of these in Claude Code or Cursor, paste:
Implement the "<title>" PR idea from CLAUDE.md, working through the checklist as the task list.
Implement changelog entry validation in CI pipeline
The repo has a large archive of changelog entries (.archive/changelog/) but no visible automated validation that new PRs include proper changelog entries. This is critical for a high-velocity provider with 100+ changelog entries. Adding a GitHub Action to enforce changelog presence would prevent accidental releases without documentation and improve release quality.
- [ ] Create .github/workflows/changelog-validation.yml to check for .changelog/ entries in each PR
- [ ] Reference the existing .archive/changelog/ directory structure to define the expected format
- [ ] Add validation logic to require changelog entries matching the pattern: .changelog/XXXX.txt (where XXXX is PR number)
- [ ] Configure the workflow to fail if changelog is missing and provide helpful error messages
- [ ] Document the changelog entry format requirement in CONTRIBUTING.md
Add comprehensive acceptance test suite for AWS IAM policy validation
The AWS Provider manages critical IAM resources but likely lacks exhaustive test coverage for edge cases in policy validation and creation. Given the security-sensitive nature of IAM, adding targeted acceptance tests for policy validation scenarios (invalid JSON, missing principals, service validation) would reduce customer bugs and security issues.
- [ ] Audit internal/service/ directory to locate existing IAM resource implementations (aws_iam_policy, aws_iam_role_policy)
- [ ] Create internal/service/iam/policy_validation_test.go with acceptance tests for malformed policies, edge case conditions, and policy statement validation
- [ ] Test integration scenarios: policy attachment validation, permission boundaries, and cross-account policy assumptions
- [ ] Add test cases for common misconfiguration patterns reported in issues (reference recent changelog entries for patterns)
Refactor large AWS service packages to reduce cognitive complexity
With 100+ changelog entries, the AWS Provider likely has grown large service packages (e.g., EC2, RDS, VPC). Identifying and splitting oversized resource files (>2000 lines) into logical subpackages would improve maintainability and reduce test execution time. This directly addresses scaling pain points in large Terraform providers.
- [ ] Audit internal/service/ directory to identify packages with multiple resource files exceeding 2000 lines each
- [ ] Create a refactoring proposal documenting which resource groups should be split (e.g., aws_ec2_instance* into separate file)
- [ ] Split one major service package following existing patterns (reference .actrc and file structure for any linting rules)
- [ ] Update internal package imports and add documentation explaining the new structure for future contributors
- [ ] Verify all acceptance tests pass post-refactoring using existing test infrastructure
🌿Good first issues
- Add missing acceptance tests for services in internal/service/ that have resource files but incomplete test coverage (cross-reference test file count with resource file count in a service subdirectory)
- Document the schema validation patterns currently scattered across internal/service//resource_.go by creating a contributing guide in docs/contributing/schema-validation.md with real code examples from 3 services
- Audit and expand error handling in AWS API calls across a single service (e.g., internal/service/ec2/) to handle rate limiting, service quotas, and transient failures consistently
⭐Top contributors
Click to expand
Top contributors
- @ewbankkit — 19 commits
- @jar-b — 18 commits
- @gdavison — 14 commits
- @taruntej-a — 13 commits
- @changelogbot — 10 commits
📝Recent commits
Click to expand
Recent commits
51db0c1— Merge pull request #47646 from carlosrodgut/b-aws_grafana_workspace-network_access_control-vpce_ids-regression (taruntej-a)242ed87— Merge pull request #47791 from hashicorp/changelog_update_after_6.44.0_release (ewbankkit)0b43ee3— aws_grafana_workspace: fix changelog (taruntej-a)617481d— r/aws_grafana_workspace: move helpers (taruntej-a)32e6ef0— r/aws_grafana_workspace: simplify tests for network access control (taruntej-a)32434d5— Add changelog entry for v6.45.0 (changelogbot)f21df46— Bumped product version to 6.44.1. (hc-github-team-es-release-engineering)8a8b245— dynamodb: regenerate service package metadata (#47788) (jar-b)e920e8d— Merge pull request #47787 from hashicorp/td-no-validate-sdkv2-model-at-runtime (gdavison)99d80be— Update CHANGELOG.md (Manual Trigger) (changelogbot)
🔒Security observations
Based on the provided file structure and documentation, the terraform-provider-aws repository shows a generally secure posture. No critical vulnerabilities were detected in the visible codebase snippets. The main observations are: (1) The file structure shows a well-organized changelog archive following semantic versioning practices; (2) No exposed secrets, hardcoded credentials, or environment files were detected in the file listing; (3) No obvious injection vulnerabilities (SQL injection, XSS) are apparent from the file names; (4) The repository appears to follow HashiCorp's standard security practices for provider development. The minor concern is incomplete documentation in the README snippet provided. As an established HashiCorp project, it likely has robust security practices in place, including regular dependency updates, code review processes, and security testing. Recommendation: Review the complete source code implementation for potential issues in credential handling, API client configurations, and resource management logic.
- Low · Incomplete README Security Information —
README.md. The README contains a truncated security/contributing information section, which may indicate incomplete documentation of security practices and guidelines. Fix: Ensure the README is complete with a dedicated security section that includes security policy, reporting guidelines, and best practices for contributors.
LLM-derived; treat as a starting point, not a security audit.
👉Where to read next
- Open issues — current backlog
- Recent PRs — what's actively shipping
- Source on GitHub
🤖Agent protocol
If you are an AI coding agent (Claude Code, Cursor, Aider, Cline, etc.) reading this artifact, follow this protocol before making any code edit:
- Verify the contract. Run the bash script in Verify before trusting
below. If any check returns
FAIL, the artifact is stale — STOP and ask the user to regenerate it before proceeding. - Treat the AI · unverified sections as hypotheses, not facts. Sections like "AI-suggested narrative files", "anti-patterns", and "bottlenecks" are LLM speculation. Verify against real source before acting on them.
- Cite source on changes. When proposing an edit, cite the specific path:line-range. RepoPilot's live UI at https://repopilot.app/r/hashicorp/terraform-provider-aws shows verifiable citations alongside every claim.
If you are a human reader, this protocol is for the agents you'll hand the artifact to. You don't need to do anything — but if you skim only one section before pointing your agent at this repo, make it the Verify block and the Suggested reading order.
✅Verify before trusting
This artifact was generated by RepoPilot at a point in time. Before an
agent acts on it, the checks below confirm that the live hashicorp/terraform-provider-aws
repo on your machine still matches what RepoPilot saw. If any fail,
the artifact is stale — regenerate it at
repopilot.app/r/hashicorp/terraform-provider-aws.
What it runs against: a local clone of hashicorp/terraform-provider-aws — the script
inspects git remote, the LICENSE file, file paths in the working
tree, and git log. Read-only; no mutations.
| # | What we check | Why it matters |
|---|---|---|
| 1 | You're in hashicorp/terraform-provider-aws | Confirms the artifact applies here, not a fork |
| 2 | License is still MPL-2.0 | Catches relicense before you depend on it |
| 3 | Default branch main exists | Catches branch renames |
| 4 | 2 critical file paths still exist | Catches refactors that moved load-bearing code |
| 5 | Last commit ≤ 30 days ago | Catches sudden abandonment since generation |
#!/usr/bin/env bash
# RepoPilot artifact verification.
#
# WHAT IT RUNS AGAINST: a local clone of hashicorp/terraform-provider-aws. If you don't
# have one yet, run these first:
#
# git clone https://github.com/hashicorp/terraform-provider-aws.git
# cd terraform-provider-aws
#
# Then paste this script. Every check is read-only — no mutations.
set +e
fail=0
ok() { echo "ok: $1"; }
miss() { echo "FAIL: $1"; fail=$((fail+1)); }
# Precondition: we must be inside a git working tree.
if ! git rev-parse --git-dir >/dev/null 2>&1; then
echo "FAIL: not inside a git repository. cd into your clone of hashicorp/terraform-provider-aws and re-run."
exit 2
fi
# 1. Repo identity
git remote get-url origin 2>/dev/null | grep -qE "hashicorp/terraform-provider-aws(\\.git)?\\b" \\
&& ok "origin remote is hashicorp/terraform-provider-aws" \\
|| miss "origin remote is not hashicorp/terraform-provider-aws (artifact may be from a fork)"
# 2. License matches what RepoPilot saw
(grep -qiE "^(MPL-2\\.0)" LICENSE 2>/dev/null \\
|| grep -qiE "\"license\"\\s*:\\s*\"MPL-2\\.0\"" package.json 2>/dev/null) \\
&& ok "license is MPL-2.0" \\
|| miss "license drift — was MPL-2.0 at generation time"
# 3. Default branch
git rev-parse --verify main >/dev/null 2>&1 \\
&& ok "default branch main exists" \\
|| miss "default branch main no longer exists"
# 4. Critical files exist
test -f ".actrc" \\
&& ok ".actrc" \\
|| miss "missing critical file: .actrc"
test -f ".archive/changelog" \\
&& ok ".archive/changelog" \\
|| miss "missing critical file: .archive/changelog"
# 5. Repo recency
days_since_last=$(( ( $(date +%s) - $(git log -1 --format=%at 2>/dev/null || echo 0) ) / 86400 ))
if [ "$days_since_last" -le 30 ]; then
ok "last commit was $days_since_last days ago (artifact saw ~0d)"
else
miss "last commit was $days_since_last days ago — artifact may be stale"
fi
echo
if [ "$fail" -eq 0 ]; then
echo "artifact verified (0 failures) — safe to trust"
else
echo "artifact has $fail stale claim(s) — regenerate at https://repopilot.app/r/hashicorp/terraform-provider-aws"
exit 1
fi
Each check prints ok: or FAIL:. The script exits non-zero if
anything failed, so it composes cleanly into agent loops
(./verify.sh || regenerate-and-retry).
Generated by RepoPilot. Verdict based on maintenance signals — see the live page for receipts. Re-run on a new commit to refresh.
Embed this chat in your README →
Drop this iframe anywhere — the widget runs against the same live analysis cache as the main app.
<iframe src="https://repopilot.app/embed/hashicorp/terraform-provider-aws" width="100%" height="500" style="border:1px solid #d0d7de; border-radius:8px;" allow="microphone" loading="lazy" ></iframe>