Add support for multiple Terraform state backends#62
Conversation
This change adds backward-compatible support for configuring multiple
Terraform state backends, each with its own set of SSO permission sets.
**Changes:**
- Add `tf_access_additional_backends` map variable for configuring multiple backends
- Each backend creates three permission sets:
- TerraformPlanAccess-{BackendName}
- TerraformApplyAccess-{BackendName}
- TerraformStateAccess-{BackendName}
- Existing single backend variables remain unchanged for backward compatibility
- Backend names are title-cased for permission set names (e.g., "core" -> "Core")
**Use Case:**
Organizations with separate state backends (e.g., core vs platform infrastructure)
can now grant fine-grained SSO access per backend, ensuring proper isolation
while maintaining appropriate access levels (plan/apply/state).
**Example Configuration:**
```hcl
tf_access_additional_backends = {
core = {
bucket_arn = "arn:aws:s3:::example-core-tfstate"
dynamodb_table_arn = "arn:aws:dynamodb:us-east-1:123456789012:table/example-core-tfstate-lock"
role_arn = "arn:aws:iam::123456789012:role/example-core-gbl-root-tfstate"
}
plat = {
bucket_arn = "arn:aws:s3:::example-plat-tfstate"
role_arn = "arn:aws:iam::123456789012:role/example-plat-gbl-root-tfstate"
}
}
```
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
|
Warning Rate limit exceeded
⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout. Please see our FAQ for further information. 📝 WalkthroughWalkthroughThe PR extends Terraform access management by introducing a configurable input variable for additional backends. It generates three new permission set categories (Plan, Apply, State) per backend with corresponding IAM policies, conditionally including DynamoDB permissions, and concatenates these into the module's permission sets list. Changes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Possibly related PRs
Suggested labels
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 3✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
milldr
left a comment
There was a problem hiding this comment.
we dont need to duplicate the policy for each allowed bucket. We can just add the list of allowed resources to each existing policy. Permissions are identitical
ie
# In locals, consolidate the bucket ARNs
locals {
# Combine the primary bucket with any additional backend buckets
tf_access_bucket_arns = compact(concat(
[var.tf_access_bucket_arn],
[for k, v in var.tf_access_additional_backends : v.bucket_arn]
))
# Similarly for DynamoDB tables (filtering out empty/null values)
tf_access_dynamodb_table_arns = compact(concat(
[var.tf_access_dynamodb_table_arn],
[for k, v in var.tf_access_additional_backends : try(v.dynamodb_table_arn, "")]
))
# And for role ARNs
tf_access_role_arns = compact(concat(
[var.tf_access_role_arn],
[for k, v in var.tf_access_additional_backends : v.role_arn]
))
}# In the existing S3 policy statements, change from:
resources = [var.tf_access_bucket_arn]
# To:
resources = local.tf_access_bucket_arns
# And for object-level permissions:
resources = [for arn in local.tf_access_bucket_arns : "${arn}/*"]
I think we do want individual policies because then you can trust certain policies to certain groups for particular buckets. This allows much more fine-grained access controls. |
This change adds backward-compatible support for configuring multiple
Terraform state backends, each with its own set of SSO permission sets.
**Changes:**
- Add `tf_access_additional_backends` map variable for configuring multiple backends
- Each backend creates three permission sets:
- TerraformPlanAccess-{BackendName}
- TerraformApplyAccess-{BackendName}
- TerraformStateAccess-{BackendName}
- Existing single backend variables remain unchanged for backward compatibility
- Backend names are title-cased for permission set names (e.g., "core" -> "Core")
**Use Case:**
Organizations with separate state backends (e.g., core vs platform infrastructure)
can now grant fine-grained SSO access per backend, ensuring proper isolation
while maintaining appropriate access levels (plan/apply/state).
**Example Configuration:**
```hcl
tf_access_additional_backends = {
core = {
bucket_arn = "arn:aws:s3:::example-core-tfstate"
dynamodb_table_arn = "arn:aws:dynamodb:us-east-1:123456789012:table/example-core-tfstate-lock"
role_arn = "arn:aws:iam::123456789012:role/example-core-gbl-root-tfstate"
}
plat = {
bucket_arn = "arn:aws:s3:::example-plat-tfstate"
role_arn = "arn:aws:iam::123456789012:role/example-plat-gbl-root-tfstate"
}
}
```
Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
|
These changes were released in v2.0.1. |
Summary
Add backward-compatible support for configuring multiple Terraform state backends, each with its own set of SSO permission sets.
Problem
Organizations with separate state backends (e.g., core infrastructure vs platform infrastructure) previously had to grant the same SSO permission sets access to all backends. This created security concerns as users/groups would have access to state backends they shouldn't.
Solution
Introduces a new
tf_access_additional_backendsmap variable that allows configuring multiple backends, where each backend creates its own set of three permission sets:TerraformPlanAccess-{BackendName}- Read-only state access with ReadOnlyAccess AWS policyTerraformApplyAccess-{BackendName}- Read/write state access with AdministratorAccess AWS policyTerraformStateAccess-{BackendName}- Read/write state access only (no AWS account permissions)Key Features
✅ Backward compatible - Existing single backend variables (
tf_access_bucket_arn,tf_access_role_arn) continue to work unchanged✅ Flexible DynamoDB - DynamoDB table ARN is optional (supports S3 state locking)
✅ Clear naming - Backend names are title-cased for permission set names (e.g., "core" → "Core", "prod-east" → "ProdEast")
✅ Fine-grained access - Each backend has independent permission sets for granular access control
Example Configuration
This creates permission sets:
TerraformPlanAccess-Core,TerraformApplyAccess-Core,TerraformStateAccess-CoreTerraformPlanAccess-Plat,TerraformApplyAccess-Plat,TerraformStateAccess-PlatImplementation Details
Files Changed:
src/policy-TerraformAccess.tf- Added new variable, locals, and IAM policy documentssrc/main.tf- Wired new permission set lists into module configurationTechnical Approach:
for_eachover the backends map to generate permission sets dynamicallyTesting
Tested in production with two backends (core + plat):
Migration Path
tf_access_additional_backendsto stack configs as needed🤖 Generated with Claude Code
Summary by CodeRabbit