Home > front end >  Adding S3 bucket policy to multiple buckets with for_each Terraform module
Adding S3 bucket policy to multiple buckets with for_each Terraform module

Time:01-31

I have the following module which works fine.

Module


resource "aws_s3_bucket" "buckets" {
  bucket        = var.s3_buckets
}

resource "aws_s3_bucket_acl" "buckets" {
  bucket = var.s3_buckets
  acl    = "private"
}

Root module

module "s3_buckets" {
    source     = "./modules/s3"
    for_each = toset([
        "bucket-test1-${var.my_env}",
        "bucket-test2-${var.my_env}",
        ])
    s3_buckets = each.value
}

I would like to add get the following policy to all the buckets in the list. Obviously the count option below does not work.

data "aws_iam_policy_document" "buckets" {
  count  = length(var.s3_buckets)
  statement {
    sid     = "AllowSSlRequestsOnly"
    actions = ["s3:*"]
    effect  = "Deny"
    condition {
      test     = "Bool"
      variable = "aws:SecureTransport"
      values   = ["false"]
    }
    principals {
      type        = "*"
      identifiers = ["*"]
    }
    resources = ["arn:aws:s3:::${var.s3_buckets}"]
  }
}

resource "aws_s3_bucket_policy" "buckets" {
  bucket = var.s3_buckets
  policy   = data.aws_iam_policy_document.buckets[count.index].json
}

I'm thinking that I need another for_each and use a resource for the IAM policy, I have seen an example such as below, but in the current form I'm providing a string instead a set of strings. Any ideas?

resource "aws_s3_bucket_policy" "buckets" {
  for_each = var.s3_buckets

  bucket = each.key
  policy = jsonencode({
    Version = "2012-10-17"
    Id      = "AllowSSlRequestsOnly",
    Statement = [
      {
        Sid       = "AllowSSlRequestsOnly"
        Effect    = "Deny"
        Principal = "*"
        Action    = "s3:*"
        Resource  = each.value.arn
        Condition = {
          Bool = {
            "aws:SecureTransport": "false"
          }
        }
      }
    ]
  })
}

CodePudding user response:

If you are adding the policy inside the module (which you probably are, otherwise it doesn't make much sense to attach the policies outside, since you have full control) - then why do you need to mingle with count() at all? Create the policy and attach to the bucket like:

data "aws_iam_policy_document" "buckets" {
  statement {
    sid     = "AllowSSlRequestsOnly"
    actions = ["s3:*"]
    effect  = "Deny"
    condition {
      test     = "Bool"
      variable = "aws:SecureTransport"
      values   = ["false"]
    }
    principals {
      type        = "*"
      identifiers = ["*"]
    }
    resources = ["arn:aws:s3:::${var.s3_buckets}"]
  }
}

resource "aws_s3_bucket_policy" "buckets" {
  bucket = var.s3_buckets
  policy   = data.aws_iam_policy_document.buckets.json
}

Couple more points:

good luck ☺️

  • Related