I'm trying to create an S3 bucket using Terraform, but keep getting Access Denied errors.
I have the following Terraform code:
resource "aws_s3_bucket" "prod_media" {
bucket = var.prod_media_bucket
acl = "public-read"
}
resource "aws_s3_bucket_cors_configuration" "prod_media" {
bucket = aws_s3_bucket.prod_media.id
cors_rule {
allowed_headers = ["*"]
allowed_methods = ["GET", "HEAD"]
allowed_origins = ["*"]
expose_headers = ["ETag"]
max_age_seconds = 3000
}
}
resource "aws_s3_bucket_acl" "prod_media" {
bucket = aws_s3_bucket.prod_media.id
acl = "public-read"
}
resource "aws_iam_user" "prod_media_bucket" {
name = "prod-media-bucket"
}
resource "aws_s3_bucket_policy" "prod_media_bucket" {
bucket = aws_s3_bucket.prod_media.id
policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Principal = "*"
Action = [
"s3:*",
]
Effect = "Allow"
Resource = [
"arn:aws:s3:::${var.prod_media_bucket}",
"arn:aws:s3:::${var.prod_media_bucket}/*"
]
},
{
Sid = "PublicReadGetObject"
Principal = "*"
Action = [
"s3:GetObject",
]
Effect = "Allow"
Resource = [
"arn:aws:s3:::${var.prod_media_bucket}",
"arn:aws:s3:::${var.prod_media_bucket}/*"
]
},
]
})
}
resource "aws_iam_user_policy" "prod_media_bucket" {
user = aws_iam_user.prod_media_bucket.name
policy = aws_s3_bucket_policy.prod_media_bucket.id
}
resource "aws_iam_access_key" "prod_media_bucket" {
user = aws_iam_user.prod_media_bucket.name
}
Whenever I run terraform apply
I get the following error:
╷
│ Error: error creating S3 bucket ACL for prod-media-8675309: AccessDenied: Access Denied
│ status code: 403, request id: XNW2R0KWFYB3KB9R, host id: CuBMdZSaJJgu+0Rprzlptt7oRsjMxBNNHJPhFq98ROGC9l9BUmfmv5YxYZuxf/V3GJBoiGJKJkg=
│
│ with aws_s3_bucket_acl.prod_media,
│ on s3.tf line 18, in resource "aws_s3_bucket_acl" "prod_media":
│ 18: resource "aws_s3_bucket_acl" "prod_media" {
│
╵
╷
│ Error: Error putting S3 policy: AccessDenied: Access Denied
│ status code: 403, request id: XNW60T7SQXW1Y4SV, host id: AyGS46L37yIcI4JwddrjHo4GRF7T9JrnfD8TGNdUhpO5uLOWBbgY3+c4opoQTFc2jRdHtXwkqO8=
│
│ with aws_s3_bucket_policy.prod_media_bucket,
│ on s3.tf line 28, in resource "aws_s3_bucket_policy" "prod_media_bucket":
│ 28: resource "aws_s3_bucket_policy" "prod_media_bucket" {
│
The account running the Terraform has Administrator Access to all resources.
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "*",
"Resource": "*"
}
]
}
Please help identify what is causing this error.
There are few issues in your code:
acl
attribute of aws_s3_bucket
is deprecated and shouldn't be used.aws_s3_bucket_ownership_controls
aws_s3_bucket_public_access_block
depends_on
aws_iam_user_policy
can't use aws_s3_bucket_policy.prod_media_bucket.id
(its not even clear what do you want to accomplish here, so I removed it from the code below).The working code is:
resource "aws_s3_bucket" "prod_media" {
bucket = var.prod_media_bucket
}
resource "aws_s3_bucket_cors_configuration" "prod_media" {
bucket = aws_s3_bucket.prod_media.id
cors_rule {
allowed_headers = ["*"]
allowed_methods = ["GET", "HEAD"]
allowed_origins = ["*"]
expose_headers = ["ETag"]
max_age_seconds = 3000
}
}
resource "aws_s3_bucket_acl" "prod_media" {
bucket = aws_s3_bucket.prod_media.id
acl = "public-read"
depends_on = [aws_s3_bucket_ownership_controls.s3_bucket_acl_ownership]
}
resource "aws_s3_bucket_ownership_controls" "s3_bucket_acl_ownership" {
bucket = aws_s3_bucket.prod_media.id
rule {
object_ownership = "BucketOwnerPreferred"
}
depends_on = [aws_s3_bucket_public_access_block.example]
}
resource "aws_iam_user" "prod_media_bucket" {
name = "prod-media-bucket"
}
resource "aws_s3_bucket_public_access_block" "example" {
bucket = aws_s3_bucket.prod_media.id
block_public_acls = false
block_public_policy = false
ignore_public_acls = false
restrict_public_buckets = false
}
resource "aws_s3_bucket_policy" "prod_media_bucket" {
bucket = aws_s3_bucket.prod_media.id
policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Principal = "*"
Action = [
"s3:*",
]
Effect = "Allow"
Resource = [
"arn:aws:s3:::${var.prod_media_bucket}",
"arn:aws:s3:::${var.prod_media_bucket}/*"
]
},
{
Sid = "PublicReadGetObject"
Principal = "*"
Action = [
"s3:GetObject",
]
Effect = "Allow"
Resource = [
"arn:aws:s3:::${var.prod_media_bucket}",
"arn:aws:s3:::${var.prod_media_bucket}/*"
]
},
]
})
depends_on = [aws_s3_bucket_public_access_block.example]
}