terraform-contour-mirror/modules/yc-s3/main.tf
Work fb3b9894d4 feat(yc-s3): use bucket policy instead of folder-level IAM roles
- Remove yandex_resourcemanager_folder_iam_member with storage.editor
- Add yandex_storage_bucket_policy for bucket-level access control
- SA now has access only to its own bucket via bucket policy
- Add role variable (storage.uploader, storage.viewer, storage.editor)
- Add README.md with module documentation
- Remove comments from module files
2026-02-03 13:57:14 +03:00

76 lines
2.0 KiB
HCL

locals {
buckets_map = { for bucket in var.buckets : bucket.name => bucket }
role_actions = {
"storage.uploader" = ["s3:PutObject", "s3:DeleteObject", "s3:GetObject"]
"storage.viewer" = ["s3:GetObject", "s3:ListBucket"]
"storage.editor" = ["s3:*"]
}
}
resource "yandex_iam_service_account" "sa" {
for_each = local.buckets_map
name = "${each.key}-sa"
description = "Service account for ${each.key} bucket (access via bucket policy only)"
}
resource "yandex_iam_service_account_static_access_key" "sa_key" {
for_each = local.buckets_map
service_account_id = yandex_iam_service_account.sa[each.key].id
description = "Static access key for ${each.key} bucket"
}
resource "yandex_storage_bucket" "this" {
for_each = local.buckets_map
bucket = each.key
acl = each.value.acl
folder_id = var.folder_id
dynamic "versioning" {
for_each = try(each.value.versioning.enabled, false) ? [1] : []
content {
enabled = true
}
}
dynamic "cors_rule" {
for_each = try(each.value.cors.enabled, false) ? [1] : []
content {
allowed_headers = try(each.value.cors.allowed_headers, [])
allowed_methods = try(each.value.cors.allowed_methods, [])
allowed_origins = try(each.value.cors.allowed_origins, [])
expose_headers = try(each.value.cors.expose_headers, [])
max_age_seconds = try(each.value.cors.max_age_seconds, 3600)
}
}
}
resource "yandex_storage_bucket_policy" "this" {
for_each = local.buckets_map
bucket = yandex_storage_bucket.this[each.key].bucket
policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Sid = "AllowServiceAccountAccess"
Effect = "Allow"
Principal = {
CanonicalUser = [yandex_iam_service_account.sa[each.key].id]
}
Action = local.role_actions[coalesce(each.value.role, var.default_bucket_role)]
Resource = [
"arn:aws:s3:::${each.key}",
"arn:aws:s3:::${each.key}/*"
]
}
]
})
depends_on = [yandex_storage_bucket.this]
}