-
Notifications
You must be signed in to change notification settings - Fork 0
storage module
S3 bucket for rule storage, IAM policies, and optional secrets-based auth.
| File | Purpose |
|---|---|
main.tf |
S3 bucket, encryption, versioning, lifecycle, cross-account policy |
iam.tf |
Read-write and read-only IAM policies |
secrets.tf |
IAM user + Secrets Manager for secrets auth mode |
variables.tf |
Input variables |
outputs.tf |
Module outputs |
Bucket naming: {name_prefix}-rules-{random_hex} (8-char suffix for uniqueness)
| Resource | Purpose |
|---|---|
random_id.bucket_suffix |
4 bytes → 8 hex chars |
aws_s3_bucket |
The rules storage bucket |
aws_s3_bucket_versioning |
Optional (default: enabled). Applies only to module-created buckets; an existing bucket keeps its own versioning configuration (the versioning_enabled output is null then) |
aws_s3_bucket_server_side_encryption_configuration |
AES256 + bucket key |
aws_s3_bucket_public_access_block |
All 4 block options enabled |
aws_s3_bucket_lifecycle_configuration |
Aborts incomplete multipart after 7 days |
- Encryption: AES256 server-side encryption with bucket key enabled
- Public access: Fully blocked (all 4 settings)
-
Transport security: A bucket policy that denies non-TLS requests (
aws:SecureTransport = false) is attached only when the module creates the bucket (create_bucket = true) andcross_account_write_principalsis non-empty. With the default empty list, or when pointing at an existing bucket, no bucket policy is created, so there is no SecureTransport deny. Callers should still use HTTPS endpoints regardless. - Versioning: Enabled by default for rule file history
Two modes controlled by storage.auth:
No IAM user created. ECS task roles get S3 access via IAM Architecture:
-
BRMS task role →
s3_accesspolicy (read/write) -
Agent task role →
s3_read_onlypolicy (read only)
Creates an IAM user with access keys stored in Secrets Manager:
| Resource | Purpose |
|---|---|
aws_iam_user.s3_access |
Dedicated IAM user for S3 |
aws_iam_access_key.s3_access |
Access key pair |
aws_secretsmanager_secret.s3_credentials |
Secret container |
aws_secretsmanager_secret_version |
JSON: access_key_id, secret_access_key, bucket_name, region |
See Secrets Management for how secrets are consumed.
Two policies created for different access levels:
Used by BRMS, full access to manage rule files. Defined as an aws_iam_policy resource with an inline jsonencode policy document (not a separate data source). It references local.bucket_arn, which resolves to the created bucket's ARN or var.storage.existing_bucket_arn when using an existing bucket:
resource "aws_iam_policy" "s3_access" {
name = "${var.name_prefix}-s3-access"
description = "IAM policy for S3 bucket access for GoRules"
policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Sid = "ListBucket"
Effect = "Allow"
Action = [
"s3:ListBucket",
"s3:GetBucketLocation"
]
Resource = local.bucket_arn
},
{
Sid = "ObjectAccess"
Effect = "Allow"
Action = [
"s3:GetObject",
"s3:PutObject",
"s3:DeleteObject",
"s3:GetObjectVersion",
"s3:DeleteObjectVersion"
]
Resource = "${local.bucket_arn}/*"
}
]
})
tags = local.common_tags
}Used by Agent, can only read rules, never modify them. Defined as an aws_iam_policy resource with an inline jsonencode policy document. Like s3_access, it references local.bucket_arn, so it works for both a created bucket and an existing one:
resource "aws_iam_policy" "s3_read_only" {
name = "${var.name_prefix}-s3-read-only"
description = "IAM policy for read-only S3 bucket access for GoRules Agent"
policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Sid = "ListBucket"
Effect = "Allow"
Action = [
"s3:ListBucket",
"s3:GetBucketLocation"
]
Resource = local.bucket_arn
},
{
Sid = "ReadObjects"
Effect = "Allow"
Action = [
"s3:GetObject",
"s3:GetObjectVersion"
]
Resource = "${local.bucket_arn}/*"
}
]
})
tags = local.common_tags
}For multi-environment deployments, the bucket can grant access to other AWS accounts:
storage = {
cross_account_write_principals = [
"123456789012", # Staging account ID
"987654321098" # Production account ID
]
}This creates a bucket policy granting the specified principals bucket-level actions (s3:ListBucket, s3:GetBucketLocation) and object-level actions (s3:GetObject, s3:GetObjectVersion, s3:PutObject, s3:DeleteObject, s3:DeleteObjectVersion). Every grant is conditioned on aws:SecureTransport = true, so cross-account access is allowed only over TLS.
This bucket policy is created only for module-managed buckets (create_bucket = true). When pointing at an existing bucket (create_bucket = false), cross_account_write_principals is ignored: no bucket policy is attached and no error is raised, so you must manage the existing bucket's policy yourself.
-
ECS Module: Receives
bucket_name,bucket_arn, IAM policy ARNs - IAM Architecture: Task roles get S3 policy attachments
- Root Module: Routes bucket name/ARN (created or existing) to ECS
storage = {
create_bucket = true
existing_bucket_arn = null
existing_bucket_name = null
auth = "iam" # or "secrets"
versioning = true
cross_account_write_principals = []
}Set storage = null to disable entirely.