I have made a static website hosting S3 bucket that is served by CloudFront. I would like to restrict bucket access directly only from CloudFront through Origin Access Identity.
I have tried to update the S3 bucket policy but it's showing an error:
Error putting S3 policy: MalformedPolicy: Invalid principal in policy status code: 400, request id
I'm trying to use the following policy:
resource "aws_s3_bucket_policy" "default" {
bucket = "${aws_s3_bucket.default.id}"
policy = <<EOF
{
"Version": "2008-10-17",
"Statement": [
{
"Sid": "2",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::cloudfront:user/CloudFront Origin Access Identity ${aws_cloudfront_origin_access_identity.origin_access_identity.id}"
},
"Action": "s3:*",
"Resource": "arn:aws:s3:::$/*"
}
]
}
EOF
}
An origin access identity is a special CloudFront user that you can associate with Amazon S3 origins, so that you can secure all or just some of your Amazon S3 content. For more information, see Restricting Access to Amazon S3 Content by Using an Origin Access Identity in the Amazon CloudFront Developer Guide.
An origin is the location where content is stored, and from which CloudFront gets content to serve to viewers. To specify an origin: Use S3OriginConfig to specify an Amazon S3 bucket that is not configured with static website hosting.
By default, your Amazon S3 bucket and all the files in it are private—only the Amazon account that created the bucket has permission to read or write the files. If you want to allow anyone to access the files in your Amazon S3 bucket using CloudFront URLs, you must grant public read permissions to the objects.
As mentioned in the [aws_cloudfront_origin_access_identity documentation] 1 the best way to do this is by generating an IAM policy document
with the aws_iam_policy_document
data source and then attaching that directly.
An example would look something like this:
data "aws_iam_policy_document" "s3_policy" {
statement {
actions = ["s3:GetObject"]
resources = ["${module.names.s3_endpoint_arn_base}/*"]
principals {
type = "AWS"
identifiers = ["${aws_cloudfront_origin_access_identity.origin_access_identity.iam_arn}"]
}
}
statement {
actions = ["s3:ListBucket"]
resources = ["${module.names.s3_endpoint_arn_base}"]
principals {
type = "AWS"
identifiers = ["${aws_cloudfront_origin_access_identity.origin_access_identity.iam_arn}"]
}
}
}
resource "aws_s3_bucket" "bucket" {
# ...
policy = "${data.aws_iam_policy_document.s3_policy.json}"
}
If you really want to hand craft the IAM policy as you are in the question then you just need something like this:
resource "aws_s3_bucket_policy" "default" {
bucket = "${aws_s3_bucket.default.id}"
policy = <<EOF
{
"Version": "2008-10-17",
"Statement": [
{
"Sid": "2",
"Effect": "Allow",
"Principal": {
"AWS": "${aws_cloudfront_origin_access_identity.origin_access_identity.iam_arn}"
},
"Action": "s3:*",
"Resource": "${aws_s3_bucket.default.arn}""
}
]
}
EOF
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With