Skip to content

Commit

Permalink
Preserving logical names for cachePolicy & originRequestPolicy resour…
Browse files Browse the repository at this point in the history
…ces.
  • Loading branch information
fvsnippets authored and Federico Valido committed Jun 21, 2022
1 parent 3271a4d commit 26d617e
Show file tree
Hide file tree
Showing 2 changed files with 88 additions and 67 deletions.
147 changes: 84 additions & 63 deletions source/constructs/lib/back-end/back-end-construct.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { Policy, PolicyStatement, Role, ServicePrincipal } from '@aws-cdk/aws-ia
import { Code, Function as LambdaFunction, Runtime } from '@aws-cdk/aws-lambda';
import { LogGroup, RetentionDays } from '@aws-cdk/aws-logs';
import { Bucket, IBucket } from '@aws-cdk/aws-s3';
import { ArnFormat, Aws, Construct, Duration, Lazy, Stack } from '@aws-cdk/core';
import { ArnFormat, Aws, Construct, Duration, Lazy, Resource, Stack } from '@aws-cdk/core';
import { CloudFrontToApiGatewayToLambda } from '@aws-solutions-constructs/aws-cloudfront-apigateway-lambda';

import { addCfnSuppressRules } from '../../utils/utils';
Expand Down Expand Up @@ -92,7 +92,75 @@ export class BackEnd extends Construct {

addCfnSuppressRules(imageHandlerLogGroup, [{ id: 'W84', reason: 'CloudWatch log group is always encrypted by default.' }]);

const cachePolicy = new CfnCachePolicy(this, 'CachePolicy', {
const cachePolicy = new CustomBackEndCachePolicy(this, 'CachePolicy', props);

const originRequestPolicy = new CustomBackEndOriginRequestPolicy(this, 'OriginRequestPolicy', props);

const apiGatewayRestApi = RestApi.fromRestApiId(this, 'ApiGatewayRestApi', Lazy.string({ produce: () => imageHandlerCloudFrontApiGatewayLambda.apiGateway.restApiId }));

const origin: IOrigin = new HttpOrigin(`${apiGatewayRestApi.restApiId}.execute-api.${Aws.REGION}.amazonaws.com`, {
originPath: '/image',
originSslProtocols: [OriginSslPolicy.TLS_V1_1, OriginSslPolicy.TLS_V1_2]
});

const cloudFrontDistributionProps: DistributionProps = {
comment: 'Image Handler Distribution for Serverless Image Handler',
defaultBehavior: {
origin: origin,
allowedMethods: AllowedMethods.ALLOW_GET_HEAD,
viewerProtocolPolicy: ViewerProtocolPolicy.HTTPS_ONLY,
originRequestPolicy: originRequestPolicy,
cachePolicy: cachePolicy
},
priceClass: props.cloudFrontPriceClass as PriceClass,
enableLogging: true,
logBucket: props.logsBucket,
logFilePrefix: 'api-cloudfront/',
errorResponses: [
{ httpStatus: 500, ttl: Duration.minutes(10) },
{ httpStatus: 501, ttl: Duration.minutes(10) },
{ httpStatus: 502, ttl: Duration.minutes(10) },
{ httpStatus: 503, ttl: Duration.minutes(10) },
{ httpStatus: 504, ttl: Duration.minutes(10) }
]
};

const logGroupProps = {
retention: props.logRetentionPeriod as RetentionDays
};

const apiGatewayProps: LambdaRestApiProps = {
handler: imageHandlerLambdaFunction,
deployOptions: {
stageName: 'image'
},
binaryMediaTypes: ['*/*']
};

const imageHandlerCloudFrontApiGatewayLambda = new CloudFrontToApiGatewayToLambda(this, 'ImageHandlerCloudFrontApiGatewayLambda', {
existingLambdaObj: imageHandlerLambdaFunction,
insertHttpSecurityHeaders: false,
logGroupProps: logGroupProps,
cloudFrontDistributionProps: cloudFrontDistributionProps,
apiGatewayProps: apiGatewayProps
});

imageHandlerCloudFrontApiGatewayLambda.apiGateway.node.tryRemoveChild('Endpoint'); // we don't need the RestApi endpoint in the outputs

this.domainName = imageHandlerCloudFrontApiGatewayLambda.cloudFrontWebDistribution.distributionDomainName;
}
}


class CustomBackEndCachePolicy extends Resource implements ICachePolicy {
public readonly cachePolicyId: string;

constructor(scope: Construct, id: string, props: BackEndProps) {
super(scope, id, {
physicalName: `ServerlessImageHandler-${props.uuid}`,
});

const cachePolicy = new CfnCachePolicy(this, 'Resource', {
cachePolicyConfig: {
name: `ServerlessImageHandler-${props.uuid}`,
defaultTtl: Duration.days(1).toSeconds(),
Expand All @@ -115,7 +183,7 @@ export class BackEnd extends Construct {
}
}
);

// https://github.com/aws/aws-cdk/issues/8396#issuecomment-857690411
cachePolicy.addOverride(
'Properties.CachePolicyConfig.ParametersInCacheKeyAndForwardedToOrigin.HeadersConfig.Headers',
Expand All @@ -128,11 +196,19 @@ export class BackEnd extends Construct {
}
);

const cachePolicyAdapter = new class implements ICachePolicy {
public readonly cachePolicyId = cachePolicy.ref;
}();
this.cachePolicyId = cachePolicy.ref;
}
}

class CustomBackEndOriginRequestPolicy extends Resource implements IOriginRequestPolicy {
public readonly originRequestPolicyId: string;

constructor(scope: Construct, id: string, props: BackEndProps) {
super(scope, id, {
physicalName: `ServerlessImageHandler-${props.uuid}`,
});

const originRequestPolicy = new CfnOriginRequestPolicy(this, 'OriginRequestPolicy', {
const originRequestPolicy = new CfnOriginRequestPolicy(this, 'Resource', {
originRequestPolicyConfig: {
name: `ServerlessImageHandler-${props.uuid}`,
headersConfig: {
Expand Down Expand Up @@ -160,61 +236,6 @@ export class BackEnd extends Construct {
}
);

const originRequestPolicyAdapter = new class implements IOriginRequestPolicy {
public readonly originRequestPolicyId = originRequestPolicy.ref;
}();

const apiGatewayRestApi = RestApi.fromRestApiId(this, 'ApiGatewayRestApi', Lazy.string({ produce: () => imageHandlerCloudFrontApiGatewayLambda.apiGateway.restApiId }));

const origin: IOrigin = new HttpOrigin(`${apiGatewayRestApi.restApiId}.execute-api.${Aws.REGION}.amazonaws.com`, {
originPath: '/image',
originSslProtocols: [OriginSslPolicy.TLS_V1_1, OriginSslPolicy.TLS_V1_2]
});

const cloudFrontDistributionProps: DistributionProps = {
comment: 'Image Handler Distribution for Serverless Image Handler',
defaultBehavior: {
origin: origin,
allowedMethods: AllowedMethods.ALLOW_GET_HEAD,
viewerProtocolPolicy: ViewerProtocolPolicy.HTTPS_ONLY,
originRequestPolicy: originRequestPolicyAdapter,
cachePolicy: cachePolicyAdapter
},
priceClass: props.cloudFrontPriceClass as PriceClass,
enableLogging: true,
logBucket: props.logsBucket,
logFilePrefix: 'api-cloudfront/',
errorResponses: [
{ httpStatus: 500, ttl: Duration.minutes(10) },
{ httpStatus: 501, ttl: Duration.minutes(10) },
{ httpStatus: 502, ttl: Duration.minutes(10) },
{ httpStatus: 503, ttl: Duration.minutes(10) },
{ httpStatus: 504, ttl: Duration.minutes(10) }
]
};

const logGroupProps = {
retention: props.logRetentionPeriod as RetentionDays
};

const apiGatewayProps: LambdaRestApiProps = {
handler: imageHandlerLambdaFunction,
deployOptions: {
stageName: 'image'
},
binaryMediaTypes: ['*/*']
};

const imageHandlerCloudFrontApiGatewayLambda = new CloudFrontToApiGatewayToLambda(this, 'ImageHandlerCloudFrontApiGatewayLambda', {
existingLambdaObj: imageHandlerLambdaFunction,
insertHttpSecurityHeaders: false,
logGroupProps: logGroupProps,
cloudFrontDistributionProps: cloudFrontDistributionProps,
apiGatewayProps: apiGatewayProps
});

imageHandlerCloudFrontApiGatewayLambda.apiGateway.node.tryRemoveChild('Endpoint'); // we don't need the RestApi endpoint in the outputs

this.domainName = imageHandlerCloudFrontApiGatewayLambda.cloudFrontWebDistribution.distributionDomainName;
this.originRequestPolicyId = originRequestPolicy.ref;
}
}
8 changes: 4 additions & 4 deletions source/constructs/test/__snapshots__/constructs.test.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -329,7 +329,7 @@ Object {
},
},
"Resources": Object {
"BackEndCachePolicy85AF2390": Object {
"BackEndCachePolicy1DCE9B1B": Object {
"Properties": Object {
"CachePolicyConfig": Object {
"DefaultTTL": 86400,
Expand Down Expand Up @@ -449,11 +449,11 @@ Object {
"HEAD",
],
"CachePolicyId": Object {
"Ref": "BackEndCachePolicy85AF2390",
"Ref": "BackEndCachePolicy1DCE9B1B",
},
"Compress": true,
"OriginRequestPolicyId": Object {
"Ref": "BackEndOriginRequestPolicyAF28A12A",
"Ref": "BackEndOriginRequestPolicy771345D7",
},
"TargetOriginId": "TestStackBackEndImageHandlerCloudFrontApiGatewayLambdaCloudFrontToApiGatewayCloudFrontDistributionOrigin1A053AEB7",
"ViewerProtocolPolicy": "https-only",
Expand Down Expand Up @@ -1220,7 +1220,7 @@ Object {
"Type": "AWS::Logs::LogGroup",
"UpdateReplacePolicy": "Retain",
},
"BackEndOriginRequestPolicyAF28A12A": Object {
"BackEndOriginRequestPolicy771345D7": Object {
"Properties": Object {
"OriginRequestPolicyConfig": Object {
"CookiesConfig": Object {
Expand Down

0 comments on commit 26d617e

Please sign in to comment.