We should redesign the API for the aws-cloudfront construct library. There's a lot we can do in order to make it friendlier, less error-prone and less flat and declarative. At the moment, it's basically "leaking" the low level API provided by CloudFormation.
Furthermore, it would be awesome if one could use Assets
to point to a local directory that includes the web distribution content and have the toolkit do the work of uploading it to S3 and all that.
Internally, maybe take a look at BONESConstructs - it's got a mildly less bad wrapper around this. I can port some of that out if you find it useful
For reference, this is what the current API looks like just to setup a simple SPA/PWA:
const bucket = new s3.Bucket(this, 'WebsiteBucket', {
bucketName: 'pmaddox-website-bucket',
versioned: true,
});
const originId = new cloudfront.cloudformation.CloudFrontOriginAccessIdentityResource(this, 'OriginAccessIdentity', {
cloudFrontOriginAccessIdentityConfig: {
comment: 'A comment to associate with this CloudFront origin access identity',
}
});
const cert = acm.Certificate.import(this, 'ExistingCertificate', {
certificateArn: new acm.CertificateArn('arn:aws:acm:us-east-1:123456789012:certificate/7d3591e4-de7f-45cf-f8f5-7cc3d1732930'),
});
const distribution = new cloudfront.CloudFrontWebDistribution(this, 'WebsiteDistribution', {
aliasConfiguration: {
names: ['my-website.com', 'www.my-website.com'],
acmCertRef: cert.certificateArn,
},
originConfigs: [{
behaviors: [{
isDefaultBehavior: true,
}],
s3OriginSource: {
originAccessIdentity: originId,
s3BucketSource: bucket,
},
}]
})
The new API should improve the linking of S3 buckets to CloudFront distributions, and abstract away the need to explicitly create a CloudFrontOriginAccessIdentityResource
.
It would be really nice if we could tie this in with #605 to handle certificate generation/validation too.
Furthermore, it would be awesome if one could use Assets to point to a local directory that includes the web distribution content and have the toolkit do the work of uploading it to S3 and all that.
馃憤
At a minimum I would recommend making the Cloudfront construct aware of other constructs such as:
elb.LoadBalancer
elbv2.ApplicationLoadBalancer
elbv2.NetworkLoadBalancer
apiGateway.LambdaRestApi
ecs.LoadBalancedFargateService
(add the LB created by this construct)ecs.LoadBalancedEc2Service
(add the LB created by this construct)ecs.FargateService
and ecs.Ec2Service
(lookup the attached LB)s3.Bucket
CloudFront construct should be aware of how to get the domain name / address and potentially even the port from each construct and auto configure the origin details
I imagine an interface like:
const dist = new cloudfront.CloudFrontWebDistribution(this, 'WebsiteDistribution');
const ecsOrigin = dist.addOrigin(this, {
target: myEcsServiceConstruct,
port: 3000
});
const apiOrigin = dist.addOrigin(this, {
target: myApiGatewayConstruct
});
dist.addBehavior(this, {
path: '*',
origin: ecsOrigin
default: true
});
dist.addBehavior(this, {
path: 'api*',
origin: apiOrigin
default: true
});
Hi @eladb, @PaulMaddox, @mindstorms6, @nathanpeck
I'm trying to add policy statements to my bucket, but it fails with the message Invalid principal in policy
.
Any hint on how to reference the OID arn correctly?
const originAccessIdentity = new cloudfront.CfnCloudFrontOriginAccessIdentity(
this,
'PublicSiteOAI',
{
cloudFrontOriginAccessIdentityConfig: {
comment: 'OAI for adac-public-site-bucket'
}
}
);
const bucket = new s3.Bucket(this, 'Bucket', {
blockPublicAccess: s3.BlockPublicAccess.BlockAll,
bucketName: 'public-site-bucket'
});
const distribution = new cloudfront.CloudFrontWebDistribution(
this,
'Cloudfront',
{
comment: 'Public Site Cloudfront',
originConfigs: [
{
behaviors: [{ isDefaultBehavior: true }],
s3OriginSource: {
originAccessIdentity,
s3BucketSource: bucket
}
}
]
}
);
const listBucketPolicy = new iam.PolicyStatement()
.addAction('s3:ListBucket')
.allow()
.addResource(`arn:aws:s3:::${distribution.domainName}`)
.addAwsPrincipal(originAccessIdentity.cloudFrontOriginAccessIdentityId);
listBucketPolicy.sid = 'bucket_policy_site_root';
bucket.addToResourcePolicy(listBucketPolicy);
const getObjectPolicy = new iam.PolicyStatement()
.addAction('s3:GetObject')
.allow()
.addResource(`arn:aws:s3:::${distribution.domainName}/*`)
.addAwsPrincipal(originAccessIdentity.cloudFrontOriginAccessIdentityId);
getObjectPolicy.sid = 'bucket_policy_site_all';
bucket.addToResourcePolicy(getObjectPolicy);
The "love" this module needs was designed in this RFC (https://github.com/aws/aws-cdk-rfcs/issues/171) and implementation of the initial "Developer Preview" version is being tracked via this milestone: https://github.com/aws/aws-cdk/milestone/5.
There is also the overall tracking issue #6490 where high-level feature work can be tracked.
Closing this issue out in favor of the above.
Most helpful comment
For reference, this is what the current API looks like just to setup a simple SPA/PWA:
The new API should improve the linking of S3 buckets to CloudFront distributions, and abstract away the need to explicitly create a
CloudFrontOriginAccessIdentityResource
.It would be really nice if we could tie this in with #605 to handle certificate generation/validation too.
馃憤