S3 Buckets Policies for multiple buckets using for-each

I have to attach bucket policy to 10+ buckets. Creating 10+ buckets is not a problem but attacing a policy that the buckets can only be accessed if someone is accessing from vpc endpoints is a challenge( for me). I am pretty sure that experts like @apparentlymart can do some magic by combining aws_s3_bucket_policy with for_each or for

Appreciate your help. Thanks !

creating buckets ( not a problem)

variable "s3_bucket_name" {
  type    = "list"
  default = ["Test_1","Test_2","Test_3"]
}

resource "aws_s3_bucket" "b" { 
  count         = "${length(var.s3_bucket_name)}"
    bucket        = "${var.s3_bucket_name[count.index]}"
    acl           = "private"
    force_destroy = "true"
    }        

But how do I attach the policy dynamically. It will be dumb if I have to type the bucket policy 10+ times. Here is what I am showing for two buckets

resource "aws_s3_bucket_policy" "p1" {
  bucket = "${aws_s3_bucket.b.id}"

  policy = <<POLICY
{
  "Version": "2012-10-17",
  "Id": "MYBUCKETPOLICY",
  "Statement": [
    {
      "Sid": "IPAllow",
      "Effect": "Deny",
      "Principal": "*",
      "Action": "s3:*",
      "Resource": "arn:aws:s3:::Test_1"
      "Condition": {
         "IpAddress": {"aws:SourceIp": "8.8.8.8/32"}
      }
    }
  ]
}
POLICY
}




resource "aws_s3_bucket_policy" "p2" {
  bucket = "${aws_s3_bucket.b.id}"

  policy = <<POLICY
{
  "Version": "2012-10-17",
  "Id": "MYBUCKETPOLICY",
  "Statement": [
    {
      "Sid": "IPAllow",
      "Effect": "Deny",
      "Principal": "*",
      "Action": "s3:*",
      "Resource": "arn:aws:s3:::Test_2"
      "Condition": {
         "IpAddress": {"aws:SourceIp": "8.8.8.8/32"}
      }
    }
  ]
}
POLICY
}

Just bumping it again.
Wishing to get some help this time :cry:

Hi @Jim420,

I think something like this would do it:

variable "s3_bucket_names" {
  type    = set(string)
  default = ["Test_1","Test_2","Test_3"]
}

resource "aws_s3_bucket" "b" {
  for_each = var.s3_bucket_names

  bucket = each.key
  # ... and all of your other settings
}

resource "aws_s3_bucket_policy" "p1" {
  for_each = aws_s3_bucket.b

  bucket = each.key
  policy = jsonencode({
    Version = "2012-10-17"
    Id      = "MYBUCKETPOLICY",
    Statement = [
      {
        Sid       = "IPAllow"
        Effect    = "Deny"
        Principal = "*"
        Action    = "s3:*"
        Resource  = each.value.arn
        Condition = {
          IpAddress = {
            "aws:SourceIp": "8.8.8.8/32"
          }
        }
      }
    ]
  })
}

Note that because the policy’s for_each is over the bucket resource itself, in that block each.key is the bucket name and each.value is the object representing each bucket. That means I was able to use each.value.arn to access the ARN of each bucket as generated by the provider itself.