Status: Accepted
Date: 2026-01-25
Application teams need to provision AWS resources (SQS, RDS, S3, SNS, DynamoDB, ElastiCache) for their services. Currently there is no standardized process for:
- Requesting and provisioning resources in a self-service manner
- Maintaining consistency across environments and regions
- Ensuring governance without creating bottlenecks
- Resources within each
service-xyz-infra- Decentralized, each team manages its own Terraform - Centralized repository with inline modules - One repo with all Terraform code
- Centralized repository + Versioned modules - Separation between definitions and modules
Adopt two separate repositories:
platform-terraform-aws-modules/- Reusable and versioned Terraform modulesplatform-terraform-aws-projects-resources/- Resource definitions per service (uses the modules)
Provisioning flow via Backstage:
- Developer requests resource via form in Backstage
- Backstage creates PR in
platform-terraform-aws-projects-resourcesusing versioned module - PR goes through approval (manual for PROD)
- GitHub Actions executes
terraform applyafter merge
- Versioned modules: Ensures consistency, testability, and controlled upgrades
- Centralized: Facilitates auditing, governance, and visibility of all resources
- Self-service via Backstage: Developer experience without depending on tickets
- PR-based: Audit trail, code review, GitOps compliance
- Separation of concerns: Platform Team maintains modules, App Teams define resources
platform-terraform-aws-modules/
├── modules/
│ ├── sqs/
│ ├── sns/
│ ├── rds/
│ ├── s3/
│ ├── dynamodb/
│ ├── elasticache/
│ └── secrets-manager/
├── examples/
└── tests/
Versioning: Git tags (v1.0.0, v1.1.0, etc.)
platform-terraform-aws-projects-resources/
├── {account}/
│ └── {env}/
│ └── {region}/
│ └── {resource-type}/
│ └── {service-name}/
│ ├── main.tf
│ └── terraform.tfvars
Example: helpdev-prod/prod/us-east-1/sqs/payment-api/order-events.tf
┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ Developer │────▶│ Backstage │────▶│ GitHub PR │────▶│ Approval │
│ Request │ │ Form │ │ + tf plan │ │ (manual) │
└─────────────┘ └─────────────┘ └─────────────┘ └──────┬──────┘
│
▼
┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ Service │◀────│ External │◀────│ Secrets │◀────│ GitHub │
│ Consumes │ │ Secrets │ │ Manager │ │ Actions │
└─────────────┘ └─────────────┘ └─────────────┘ │ tf apply │
└─────────────┘
| Environment | Required Approval |
|---|---|
| HML | 1 team approval |
| PROD | 2 approvals including Platform Team |
| RDS (any) | DBA Team approval |
| Secrets | Security Team approval |
Positive:
- Self-service for developers
- Tested and standardized modules
- Complete audit trail via Git
- Governance via CODEOWNERS
Negative:
- Module maintenance by Platform Team
- Learning curve for Terraform
- Approval latency for PROD (mitigated: clear process)
| Resource | Module | Use Cases |
|---|---|---|
| SQS | sqs/ |
Message queues, DLQ |
| SNS | sns/ |
Pub/sub, notifications |
| RDS | rds/ |
PostgreSQL, MySQL |
| S3 | s3/ |
Storage, backups |
| DynamoDB | dynamodb/ |
NoSQL, sessions |
| ElastiCache | elasticache/ |
Redis, Memcached |
| Secrets Manager | secrets-manager/ |
Application secrets |