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
aws-cloudfront: easily support Origin Access Identity for S3 buckets #941
Comments
What does it do? Can you link us to some docs? |
Short version: the OAI is an IAM Principal that allows you to lock down the "source bucket" such that only CloudFront requests can hit your bucket (or anything else that policy allows) It's somewhat common to want this - we should make it easier. However, @leepa, we do already have a CanonicalUserPrincipal object: You should be able to drop yours :) I think we should make it a bit easier though to handle static websites :P |
@mindstorms6 doh - I missed that one! No matter and easy to flip to it. I agree though, we should make it easier. |
Oh I see. We generate an "identity" and register it with the distribution, and then we say that this identity can access the bucket. Seems like create the |
Can't the very act of creating an S3 Origin with an Identity 'do the right thing'? The identity just needs a comment so... |
Agreed. Passing the S3 bucket should do all this work. |
I started a early version of L2 OAI construct and would appreciate some feedback: master...workeitel:cloudfront-oai You would use it like: const bucket = new s3.Bucket(stack, 'Bucket', { removalPolicy: cdk.RemovalPolicy.Destroy });
const oai = new cloudfront.CloudFrontOriginAccessIdentity(stack, 'OAI', {
comment: 'Allows CloudFront to reach to the bucket!',
});
bucket.grantRead(oai);
const dist = new cloudfront.CloudFrontWebDistribution(stack, 'Distribution', {
originConfigs: [{
behaviors: [{ isDefaultBehavior: true }],
s3OriginSource: {
s3BucketSource: bucket,
originAccessIdentity: oai,
},
}]
}); or import it:
|
In an ideal world I had imagined something like:
The comment could be auto-generated. Never really seen the comment used for anything - unless people use it to browse the console maybe? If so, I personally think it's better not to have another L2 for this - people use OAI by default if fronting S3 to avoid public buckets anyway. |
@leepa - that's a very valid point, however ability to import an existing OAI might be required in certain environments however (places where application developers are not entitled to create new identities/permissions). |
Hi folks. I ran into this issue evaluating the CDK for use with deploying a basic static website to S3 and then creating the corresponding CloudFront Distribution. What I found is that I can get everything working and even create the OIA however the last option of granting the OIA read access to the bucket is where I fall flat. Here is the code I worked out. The last part where I am adding the bucket policy blows up:
If I take out the policy statement at the bottom I get the CloudFront Dist with an OIA but the OIA cannot access the bucket. I clearly am picking the wrong attribute to pass as the ARN for the principal on the bucket policy. Any thoughts? If I get this working it is a nice work around until you have the CDK supporting the OIA out of the box.
|
FYI, I got this working by changing the policy statement I was creating to this:
To match what the CDK was doing in other parts I added the bucketArn and the bucketArn with /*. I also changed the I created a class to make this easier called |
Example usage: ``` const bucket = new s3.Bucket(stack, 'Bucket'); const oai = new cloudfront.CloudFrontOriginAccessIdentity(stack, 'OAI'); bucket.grantRead(oai); // must be granted explicitly const dist = new cloudfront.CloudFrontWebDistribution(stack, 'Distribution', { originConfigs: [{ behaviors: [{ isDefaultBehavior: true }], s3OriginSource: { s3BucketSource: bucket, originAccessIdentity: oai, }, }] }); ``` It supports the old `originAccessIdentityId` as well: ``` const dist = new cloudfront.CloudFrontWebDistribution(stack, 'Distribution', { originConfigs: [{ behaviors: [{ isDefaultBehavior: true }], s3OriginSource: { s3BucketSource: bucket, originAccessIdentityId: "...", // or oai.name }, }] }); ``` And importing Origin Access Identities: ``` const oai = cloudfront.CloudFrontOriginAccessIdentity.fromName( stack, 'OAIImported', 'AEFASDF234' ); ``` NOTE: while typically the S3CanonicalUserId is used in the policy this value is not available after import so instead the CloudFront Arn is constructed manually. aws#941
Example usage: ``` const bucket = new s3.Bucket(stack, 'Bucket'); const oai = new cloudfront.CloudFrontOriginAccessIdentity(stack, 'OAI'); bucket.grantRead(oai); // must be granted explicitly const dist = new cloudfront.CloudFrontWebDistribution(stack, 'Distribution', { originConfigs: [{ behaviors: [{ isDefaultBehavior: true }], s3OriginSource: { s3BucketSource: bucket, originAccessIdentity: oai, }, }] }); ``` It supports the old `originAccessIdentityId` as well: ``` const dist = new cloudfront.CloudFrontWebDistribution(stack, 'Distribution', { originConfigs: [{ behaviors: [{ isDefaultBehavior: true }], s3OriginSource: { s3BucketSource: bucket, originAccessIdentityId: "...", // or oai.name }, }] }); ``` And importing Origin Access Identities: ``` const oai = cloudfront.CloudFrontOriginAccessIdentity.fromName( stack, 'OAIImported', 'AEFASDF234' ); ``` NOTE: while typically the S3CanonicalUserId is used in the policy this value is not available after import so instead the CloudFront Arn is constructed manually. aws#941
Example usage: ``` const bucket = new s3.Bucket(stack, 'Bucket'); const oai = new cloudfront.CloudFrontOriginAccessIdentity(stack, 'OAI'); bucket.grantRead(oai); // must be granted explicitly const dist = new cloudfront.CloudFrontWebDistribution(stack, 'Distribution', { originConfigs: [{ behaviors: [{ isDefaultBehavior: true }], s3OriginSource: { s3BucketSource: bucket, originAccessIdentity: oai, }, }] }); ``` It supports the old `originAccessIdentityId` as well: ``` const dist = new cloudfront.CloudFrontWebDistribution(stack, 'Distribution', { originConfigs: [{ behaviors: [{ isDefaultBehavior: true }], s3OriginSource: { s3BucketSource: bucket, originAccessIdentityId: "...", // or oai.name }, }] }); ``` And importing Origin Access Identities: ``` const oai = cloudfront.CloudFrontOriginAccessIdentity.fromName( stack, 'OAIImported', 'AEFASDF234' ); ``` NOTE: while typically the S3CanonicalUserId is used in the policy this value is not available after import so instead the CloudFront Arn is constructed manually. aws#941
Example usage: ``` const bucket = new s3.Bucket(stack, 'Bucket'); const oai = new cloudfront.CloudFrontOriginAccessIdentity(stack, 'OAI'); const dist = new cloudfront.CloudFrontWebDistribution(stack, 'Distribution', { originConfigs: [{ behaviors: [{ isDefaultBehavior: true }], s3OriginSource: { s3BucketSource: bucket, originAccessIdentity: oai, }, }] }); ``` And importing Origin Access Identities: ``` const oaiImported = cloudfront.OriginAccessIdentity.fromOriginAccessIdentityName( stack, 'OAIImported', 'AEFASDF234' ); ``` NOTE: while typically the S3CanonicalUserId is used in the policy this value is not available after import so instead the CloudFront Arn is constructed manually. aws#941
Example usage: ``` const bucket = new s3.Bucket(stack, 'Bucket'); const oai = new cloudfront.CloudFrontOriginAccessIdentity(stack, 'OAI'); const dist = new cloudfront.CloudFrontWebDistribution(stack, 'Distribution', { originConfigs: [{ behaviors: [{ isDefaultBehavior: true }], s3OriginSource: { s3BucketSource: bucket, originAccessIdentity: oai, }, }] }); ``` And importing Origin Access Identities: ``` const oaiImported = cloudfront.OriginAccessIdentity.fromOriginAccessIdentityName( stack, 'OAIImported', 'AEFASDF234' ); ``` NOTE: while typically the S3CanonicalUserId is used in the policy this value is not available after import so instead the CloudFront Arn is constructed manually. aws#941
Example usage: ``` const bucket = new s3.Bucket(stack, 'Bucket'); const oai = new cloudfront.CloudFrontOriginAccessIdentity(stack, 'OAI'); const dist = new cloudfront.CloudFrontWebDistribution(stack, 'Distribution', { originConfigs: [{ behaviors: [{ isDefaultBehavior: true }], s3OriginSource: { s3BucketSource: bucket, originAccessIdentity: oai, }, }] }); ``` And importing Origin Access Identities: ``` const oaiImported = cloudfront.OriginAccessIdentity.fromOriginAccessIdentityName( stack, 'OAIImported', 'AEFASDF234' ); ``` NOTE: while typically the S3CanonicalUserId is used in the policy this value is not available after import so instead the CloudFront Arn is constructed manually. #941
Example usage: ``` const bucket = new s3.Bucket(stack, 'Bucket'); const oai = new cloudfront.CloudFrontOriginAccessIdentity(stack, 'OAI'); const dist = new cloudfront.CloudFrontWebDistribution(stack, 'Distribution', { originConfigs: [{ behaviors: [{ isDefaultBehavior: true }], s3OriginSource: { s3BucketSource: bucket, originAccessIdentity: oai, }, }] }); ``` And importing Origin Access Identities: ``` const oaiImported = cloudfront.OriginAccessIdentity.fromOriginAccessIdentityName( stack, 'OAIImported', 'AEFASDF234' ); ``` NOTE: while typically the S3CanonicalUserId is used in the policy this value is not available after import so instead the CloudFront Arn is constructed manually. aws#941
I think the above answers are good. I made two small changes. First, I added one additional policy at the top to disable unencrypted transport. To be honest, I'm not entirely sure it's necessary.
Second, when I did this i'm referring to the OIA as a principal:
rather than using the "canonical user id." This works fine, but I'm wondering if one way is better than the other or if it's just a matter of style. |
Currently it doesn't seem possible to do this without creating a CloudFrontOriginAccessIdentityResource and then creating a 'Canonical User' policy fragment.
Here's the Java version:
The text was updated successfully, but these errors were encountered: