terraform-provider-aws: S3 bucket policy invalid principal for cloudfront

Community Note

  • Please vote on this issue by adding a 👍 reaction to the original issue to help the community and maintainers prioritize this request
  • Please do not leave “+1” or “me too” comments, they generate extra noise for issue followers and do not help prioritize the request
  • If you are interested in working on this issue or have submitted a pull request, please leave a comment

Terraform Version

Terraform v0.11.14

  • provider.aws v2.28.1

Affected Resource(s)

aws_cloudfront_origin_access_identity

Terraform Configuration Files

resource "aws_cloudfront_origin_access_identity" "default" {
  comment = "some comment"
}

Expected Behavior

I want to get correct iam_arn output. In docs I see it should be arn:aws:iam::cloudfront:user/CloudFront Origin Access Identity E2QWRUHAPOMQZ but AWS wait something like this arn:aws:iam::cloudfront:user/CloudFront_Origin_Access_Identity_E2QWRUHAPOMQZ

Actual Behavior

* aws_s3_bucket_policy.default: Error putting S3 policy: MalformedPolicy: Invalid principal in policy status code: 400, request id: 91F717DA11D3AD4C, host id: neJZv3+m697Cym14SQnkBaUmDyYWrP7pg/sNyPk7T1PQmaosp8ZqNUytSTPvpxUJKHoXhr4v1oI= When I try to add bucket policy.

About this issue

  • Original URL
  • State: open
  • Created 5 years ago
  • Reactions: 49
  • Comments: 25 (2 by maintainers)

Commits related to this issue

Most upvoted comments

You must provide the canonical user id :

{
    "Version": "2008-10-17",
    "Id": "PolicyForCloudFrontPrivateContent",
    "Statement": [
        {
            "Sid": "1",
            "Effect": "Allow",
            "Principal": {
                "CanonicalUser": "CANONICAL_ID"
            },
            "Action": "s3:GetObject",
            "Resource": "arn:aws:s3:::my_bucket/*"
        }
    ]
}

You can find it in the attribute of the aws_cloudfront_origin_access_identity ressource:

s3_canonical_user_id

@dukedave this is not correct. This worked for me:

data "aws_iam_policy_document" "s3_policy" {
  statement {
    actions   = ["s3:GetObject"]
    resources = ["${aws_s3_bucket.static.arn}/*"]

    principals {
      type        = "CanonicalUser"
      identifiers = [aws_cloudfront_origin_access_identity.origin_access_identity.s3_canonical_user_id]
    }
  }

  statement {
    actions   = ["s3:ListBucket"]
    resources = [aws_s3_bucket.static.arn]

    principals {
      type        = "CanonicalUser"
      identifiers = [aws_cloudfront_origin_access_identity.origin_access_identity.s3_canonical_user_id]
    }
  }
}

Answer from aws : _ The reason for this is that CloudFront updated to a new IAM auth system which does not allow spaces in user names. This means that old OAIs like “arn:aws:iam::cloudfront:user/CloudFront Origin Access Identity EXXXXXXXXXXXX” will now look like this “arn:aws:iam::cloudfront:user/CloudFrontOriginAccessIdentityEXXXXXXXXXXXX”. Users who try to hardcode either underscores or spaces into their bucket policy updates (not using CanonicalIds) will result in malformed principal, like the “invalid policy” error you’re getting. This due to some CloudFront OAI ARN uses spaces in the format and some uses underscores (_) in the ARN format. We recommend using the CanonicalId when updating bucket policy to avoid this error message. To get the canonical ID, you can list the bucket policy or CF OAI and it will return the the AWS user name with the encrypted canonicalId “EXXXXXXXX” back in the output.

So, for example, you can run this: $ aws cloudfront get-cloud-front-origin-access-identity --id <ID>

And it will return your canonical ID which you can add to your bucket policy and hit Save. _

Using:

identifiers = [replace("${aws_cloudfront_origin_access_identity.website_bucket.iam_arn}", " ", "_")]

for now.

Hey guys, any chance that there has something changed again? I tried all the described workarounds here but still always receive the same error message. using Terraform 0.12.21

Error putting S3 policy: MalformedPolicy: Invalid principal in policy

type = "CanonicalUser" works for me too.

with latest terraform and aws provider, just it also causes endless loop:

- AWS           = "arn:aws:iam::cloudfront:user/CloudFront_Origin_Access_Identity_..." -> null..
+ CanonicalUser = "..."

sometimes it is "CloudFront Origin Access Identity ", sometimes “CloudFront_Origin Access_Identity_”

@justinretzolk Yes, I can confirm this is still an issue:

  1. Setting AWS as principal with aws_cloudfront_origin_access_identity.foo.iam_arn is not a solution because the resource assumes there are always spaces which is wrong – some buckets use underscores
  2. Setting CanonicalUser as principal is modified by AWS internally into AWS, resulting in a perpetual diff

Currently, there is no solution to this problem. We’d like to see this fixed.

principals {
      type        = "CanonicalUser"
      identifiers = [aws_cloudfront_origin_access_identity.origin_access_identity.s3_canonical_user_id]
    }

Works like a charm, I guess the docs should be updated. đŸ„‡

Or maybe not
 Now terraform always has a diff from the principal with underscores. I guess I am going with the

identifiers = [replace("${aws_cloudfront_origin_access_identity.website_bucket.iam_arn}", " ", "_")]

solution.

@dukedave

Maybe this regreplace works now, but, as I posted before, for how much time
 :

This means that old OAIs like “arn:aws:iam::cloudfront:user/CloudFront Origin Access Identity EXXXXXXXXXXXX” will now look like this “arn:aws:iam::cloudfront:user/CloudFrontOriginAccessIdentityEXXXXXXXXXXXX”. Users who try to hardcode either underscores or spaces into their bucket policy updates (not using CanonicalIds) will result in malformed principal, like the “invalid policy” error you’re getting

Edit: Disregard this, see below 🎉

~FYI if you are using the iam_policy_document data source approach (i.e. not the Multiple Line Heredoc Syntax approach), then:~

~The CanonicalUser solution presented by bbrunod won’t work because iam_policy_document doesn’t allow CanonicalUser in the principal (it requires (https://www.terraform.io/docs/providers/aws/d/iam_policy_document.html#type) 😞~

~But! The replace("${....}", " ", "_")] solution from dirgapeter does work 🙏~

Good workaround. But I think this should be fix by terraform.

@justinretzolk I’m also encountering this now. Terraform version 1.1.7

Thanks for clarification here!