Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

S3 bucket policy invalid principal for cloudfront #10158

Open
Dgadavin opened this issue Sep 19, 2019 · 25 comments
Open

S3 bucket policy invalid principal for cloudfront #10158

Dgadavin opened this issue Sep 19, 2019 · 25 comments
Labels
service/cloudfront Issues and PRs that pertain to the cloudfront service. service/s3 Issues and PRs that pertain to the s3 service. upstream Addresses functionality related to the cloud provider.

Comments

@Dgadavin
Copy link

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.

@ghost ghost added service/cloudfront Issues and PRs that pertain to the cloudfront service. service/s3 Issues and PRs that pertain to the s3 service. labels Sep 19, 2019
@github-actions github-actions bot added the needs-triage Waiting for first response or review from a maintainer. label Sep 19, 2019
@dirgapeter
Copy link

@Dgadavin getting same error, have you found solution? why close?

@Dgadavin Dgadavin reopened this Sep 19, 2019
@Dgadavin
Copy link
Author

Dgadavin commented Sep 19, 2019

@dirgapeter Sorry. I thought I find a solution with cloudfront_access_identity_path but it don't work. Reopen

@dirgapeter
Copy link

Using:

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

for now.

@Dgadavin
Copy link
Author

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

@nodomain
Copy link

Thanks for posting this. And thanks to Google for indexing so fast. Just saved me - I was doubting everything since I did not change anything in my code.

@IronCore864
Copy link

I think there's probably something going on in AWS S3 side.
For some of my buckets, I must use underscore, while for others they still must use spaces.

@nodomain
Copy link

That sucks. I have a huge list of environments that are deployed via batch. I'll open a support ticket.

@bbrunod
Copy link

bbrunod commented Sep 19, 2019

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

@bbrunod
Copy link

bbrunod commented Sep 19, 2019

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

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

@nodomain
Copy link

Thanks for clarification here!

@davetapley
Copy link

davetapley commented Sep 19, 2019

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 🙏

@nodomain
Copy link

@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]
    }
  }
}

@bbrunod
Copy link

bbrunod commented Sep 19, 2019

@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

@dirgapeter
Copy link

dirgapeter commented Sep 19, 2019

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_"

@bbrunod
Copy link

bbrunod commented Sep 19, 2019

And the funny thing is, even if you provide a CanonicalId, aws transforms with... a cloudfront origin access identity with underscores!

@parabolic
Copy link
Contributor

parabolic commented Sep 20, 2019

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.

@IronCore864
Copy link

It seems after using type = "CanonicalUser", the policy created in the bucket is still the old format, but can be with either spaces or underscores. But at least the policy adding is successful now.

geota added a commit to geota/terraform-aws-cloudfront-s3-cdn that referenced this issue Sep 20, 2019
…ng spaces and/or underscores - use CanonicalUser type instead - see: hashicorp/terraform-provider-aws#10158
@simontabor
Copy link

simontabor commented Sep 24, 2019

Using CanonicalUser seems to work but results in a change for every deployment, which makes no sense (although there is a warning about this in the Terraform docs)

Using the replace method seems to work on some distributions, but not all.

@bgpat
Copy link

bgpat commented Oct 7, 2019

I had faced this problem, and workaround by #10158 (comment).
Although I tried to create a new CloudFront distribution today, the API server returns the error MalformedPolicy: Invalid principal.... It looks only to accept the identifier contains not underscores but spaces now.

@DJAlPee
Copy link

DJAlPee commented Oct 17, 2019

We are using multiple AWS accounts (20+) and it seems to be a problem only for "newer" AWS accounts (at least for me).

On old accounts, it only works with aws_cloudfront_origin_access_identity.website_bucket.iam_arn. Replacing the blanks with underscores causes here an invalid principal error.

On new accounts it works only with replace(aws_cloudfront_origin_access_identity.website_bucket.iam_arn, " ", "_"), which is very annoying, if you try to apply the same config on multiple accounts

@aeschright aeschright added the upstream Addresses functionality related to the cloud provider. label Dec 12, 2019
@saschakohnke
Copy link

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

@tsusadivyago
Copy link

This is working for me!
Highlighted the code corrections possibly needed in the documentation.
Reached this conclusion after comparing the policy cdn had updated.

image

@justinretzolk
Copy link
Member

Hey y'all 👋 Thank you for taking the time to file this issue, and for the continued discussion! Given that there's been a number of AWS provider releases since it was initially filed, can anyone confirm whether you're still experiencing this behavior?

@justinretzolk justinretzolk added waiting-response Maintainers are waiting on response from community or contributor. and removed needs-triage Waiting for first response or review from a maintainer. labels Dec 9, 2021
@awendt
Copy link

awendt commented Apr 19, 2022

@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.

@github-actions github-actions bot removed the waiting-response Maintainers are waiting on response from community or contributor. label Apr 19, 2022
@kaye-alvarado
Copy link

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
service/cloudfront Issues and PRs that pertain to the cloudfront service. service/s3 Issues and PRs that pertain to the s3 service. upstream Addresses functionality related to the cloud provider.
Projects
None yet
Development

No branches or pull requests