Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Allow CloudFront to access an S3 bucket with an origin access identity

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 
}
like image 223
Obivan Avatar asked May 17 '18 11:05

Obivan


People also ask

What is Origin Access Identity in CloudFront?

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.

How do I add origin to CloudFront?

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.

Does S3 bucket need to be public for CloudFront?

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.


1 Answers

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 
}
like image 112
ydaetskcoR Avatar answered Nov 12 '22 09:11

ydaetskcoR