Nath
Nath

Reputation: 71

terraform cloudfront distribution origin - how to update s3 bucket policy

While creating cloudfront distribution through aws console, we have an option to choose an origin access identity and also, let it update the bucket policy.

I am trying to look for similar options in terraform so that I don't have to manually manage the s3 bucket read permissions for cloudfront origin access identity.

I have checked https://www.terraform.io/docs/providers/aws/r/cloudfront_distribution.html but couldn't find any reference to such option.

Please let me know if I missed checking something on the page.

Upvotes: 7

Views: 5510

Answers (3)

Youcef LAIDANI
Youcef LAIDANI

Reputation: 59950

Instead you can just create aws_s3_bucket_policy like this:

resource "aws_s3_bucket_policy" "cloudfront_s3_bucket_policy" {
  bucket = aws_s3_bucket.bucket.id
  policy = jsonencode({
    Version = "2008-10-17"
    Id      = "PolicyForCloudFrontPrivateContent"
    Statement = [
      {
        Sid    = "AllowCloudFrontServicePrincipal"
        Effect = "Allow"
        Principal = {
          Service = "cloudfront.amazonaws.com"
        }
        Action   = "s3:GetObject"
        Resource = "${aws_s3_bucket.bucket.arn}/*"
        Condition = {
          StringEquals = {
            "AWS:SourceArn" = aws_cloudfront_distribution.distribution.arn
          }
        }
      }
    ]
  })
}

This gives me the same policy proposed by CloudFront.

Upvotes: 2

Chad
Chad

Reputation: 778

After reading the responses here and doing some reading and tests on my end, I found that the following achieves the effect we want. Assuming you already have your Cloudfront distribution somewhere:

resource "aws_s3_bucket" "my-cdn-s3" {
  bucket = "my-cdn"
}

resource "aws_cloudfront_origin_access_identity" "my-oai" {
  comment = "my-oai"
}

resource "aws_s3_bucket_policy" "cdn-cf-policy" {
  bucket = aws_s3_bucket.my-cdn-s3.id
  policy = data.aws_iam_policy_document.my-cdn-cf-policy.json
}

data "aws_iam_policy_document" "my-cdn-cf-policy" {
  statement {
    sid = "1"
    principals {
      type        = "AWS"
      identifiers = [aws_cloudfront_origin_access_identity.my-cdn-oai.iam_arn]
    }

    actions = [
      "s3:GetObject"
    ]

    resources = [
      "${aws_s3_bucket.my-cdn-s3arn}/*"
    ]
  }
}

We would then get this in the bucket's policy, which I have copied from a non-Terraform creation of CF and S3.

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "1",
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::cloudfront:user/CloudFront Origin Access Identity XXXXXXXXX"
            },
            "Action": "s3:GetObject",
            "Resource": "arn:aws:s3:::my-cdn/*"
        }
    ]
}

Let me know if I left anything out.

Upvotes: 2

Don
Don

Reputation: 574

I don't think you missed anything on that page. But, you also need to look at this page:
https://www.terraform.io/docs/providers/aws/r/s3_bucket.html .
This page covers more detail on setting up S3 buckets. Note the policy line in the Static Website Hosting section. You can add a line like

policy = "${file("policy.json")}"

and then you can write whatever policy you need into the policy.json file, which then will be included and thereby allow you to avoid needing to manually configure permissions in the console.

Upvotes: 0

Related Questions