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
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.
Apologies for bumping an old topic, but I have a question along similar lines to this. I essentially want to do the same thing but rather than using jsonencode on an inline policy, I want to use the json render from a data source. The reason for this is readability as the policy required for my usecase is extensive and I keep it in it’s own file.
Error: each.value cannot be used in this context
on data.tf line 133, in data "aws_iam_policy_document" "s3_bucket_policy":
133: "arn:aws:s3:::${each.value.id}/*",
A reference to "each.value" has been used in a context in which it
unavailable, such as when the configuration no longer contains the value in
its "for_each" expression. Remove this reference to each.value in your
configuration to work around this error.
In order for that to work you’ll need to use the same for_each argument in your data "aws_iam_policy_document" "s3_bucket_policy" block so that you can generate a separate policy document for each bucket.
As you noted this is an old topic, so if you have some more questions about that I’d invite you to start a new topic where we can hopefully see a more complete subset of your configuration and then I should be able to give you some more specific advice.
Hey, my apologies for responding to an old topic. I am trying to do something similar with attaching bucket policies to s3 buckets, but am getting an error. I cannot figure out why this error is coming. Below is how I am creating the buckets, bucket policies, and the errors:
resource "aws_s3_bucket" "dest_buckets" {
for_each = var.s3_bucket_names
bucket = "${each.key}-replica"
acl = "private"
force_destroy = "true"
versioning {
enabled = true
}
}
resource "aws_s3_bucket_policy" "dest_policy" {
for_each = aws_s3_bucket.dest_buckets
bucket = each.key
policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Effect = "Allow"
Action = "s3:GetBucketVersioning"
Resource = each.value.arn
Principal = "arn:aws:iam::account-id:role/Replication-Role"
},
{
Effect = "Allow"
Action = "s3:PutBucketVersioning"
Resource = each.value.arn
Principal = "arn:aws:iam::account-id:role/Replication-Role"
},
{
Effect = "Allow"
Action = "s3:ReplicateObject"
Resource = "${each.value.arn}/*"
Principal = "arn:aws:iam::account-id:role/Replication-Role"
},
{
Effect = "Allow"
Action = "s3:ReplicateDelete"
Resource = "${each.value.arn}/*"
Principal = "arn:aws:iam::account-id:role/Replication-Role"
}
]
}
)
}
Error: Error putting S3 policy: BucketRegionError: incorrect region, the bucket is not in 'us-east-2' region at endpoint ''
status code: 301, request id: , host id:
on s3.tf line 28, in resource "aws_s3_bucket_policy" "dest_policy":
28: resource "aws_s3_bucket_policy" "dest_policy" {
Error: Error putting S3 policy: AccessDenied: Access Denied
status code: 403, request id: A4BDA2A2818CE3C7, host id: BlVmLX44pl7itNWbfxKe0wnA0UxlGrH6b9HIQC0i09sk5NLl1jgSGrNZjEkHVhQeU2YN3lgi4ec=
on s3.tf line 28, in resource "aws_s3_bucket_policy" "dest_policy":
28: resource "aws_s3_bucket_policy" "dest_policy" {
Hey @apparentlymart apologies for bumping the old topic. I have a similar kind of question but bit different like i have one policy which implies on single bucket and another policy which implies to all bucket. Now how i use single code for both situations as every time my single policy replace by second policy.