-
Notifications
You must be signed in to change notification settings - Fork 4k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(cloudfront-origins): allow custom originPath for apigateway.Rest…
…Api constructs (#24023) ### Current behavior - the `apigateway.RestApi` splits the `restApi.url` and uses the stage name as `originPath` / "Origin path - optional" option in the CloudFront Origin by default ### Issue / Limitation - when using multiple Behaviors in my CloudFront Distribution: - S3 as the default behavior - Regional API Gateway as additional behavior and CloudFront Origin My API Gateway receives an extra `/<api-gateway-stage>/` in its event path and doesn't trigger the correct lambda integration. The below CDK example reproduces the behavior mentioned above: ```typescript import * as cdk from "aws-cdk-lib"; const meLambda = new cdk.aws_lambda_nodejs.NodejsFunction( this, "meLambda", { entry: "handlers/me.ts", } ); const s3_bucket = new cdk.aws_s3.Bucket(this, "somebucket"); const api = new cdk.aws_apigateway.RestApi(this, "somerestapi", { endpointConfiguration: { types: [apigw.EndpointType.REGIONAL], }, defaultCorsPreflightOptions: { allowOrigins: ["*"], }, }); api.root .addResource("me") .addMethod("GET", new apigw.LambdaIntegration(meLambda)); const apiOrigin = new cdk.aws_cloudfront_origins.RestApiOrigin(api); const cdn = new cdk.aws_cloudfront.Distribution(this, "websitecdn", { defaultBehavior: { origin: new cdk.aws_cloudfront_origins.S3Origin(s3_bucket), allowedMethods: cdk.aws_cloudfront.AllowedMethods.ALLOW_GET_HEAD_OPTIONS, viewerProtocolPolicy: cdk.aws_cloudfront.ViewerProtocolPolicy.REDIRECT_TO_HTTPS, }, additionalBehaviors: { "prod/*": { // <<<---- The "prod/" is added in the CloudFront Origin Path, NOT DESIRED IS THIS CASE origin: apiOrigin, allowedMethods: cdk.aws_cloudfront.AllowedMethods.ALLOW_ALL, cachePolicy: cdk.aws_cloudfront.CachePolicy.CACHING_DISABLED, viewerProtocolPolicy: cdk.aws_cloudfront.ViewerProtocolPolicy.HTTPS_ONLY, }, }, }); ``` The above will have the following URLs: - `https://<api-gateway-url>/<api-gateway-stage>` - `https://<cloudfront-distribution-url>/some-image.png` => Default Behavior, S3 Bucket - `https://<cloudfront-distribution-url>/<api-gateway-stage>` => API Gateway forward request Because the CloudFront Origin created by `RestApiOrigin` appends the `<api-gateway-stage>` in its CloudFront Origin "Origin Path - optional" option, when using `https://<cloudfront-distribution-url>/<api-gateway-stage>/me` the API Gateway receives `/<api-gateway-stage>/<api-gateway-stage>/me` instead of `/<api-gateway-stage>/me` Removing the "Origin Path - optional" value, fixes the problem. ![00](https://user-images.githubusercontent.com/829902/216874002-06338400-9d88-4c98-b393-da56cc63be02.png) ![01](https://user-images.githubusercontent.com/829902/216874042-643ef152-b2ad-465e-bdda-8a98c68c6dcd.png) ### Workaround - To fix the problem described above, I need to use a custom `cdk.aws_cloudfront_origins.HttpOrigin` construct Replace the `apiOrigin` construct in the example above by: ```typescript const apiOrigin = new origins.HttpOrigin( `${api.restApiId}.execute-api.${cdk.Aws.REGION}.${cdk.Aws.URL_SUFFIX}`, { originSslProtocols: [cloudfront.OriginSslPolicy.TLS_V1_2], protocolPolicy: cloudfront.OriginProtocolPolicy.HTTPS_ONLY, } ); ``` ### Solution - This PR allows the customization of `apigateway.RestApi` by extending its props from `cloudfront.OriginProps` - Allowing the consumer to pass a `props.originPath` to the `RestApiOrigin` class
- Loading branch information
1 parent
f1fa09c
commit bc3db02
Showing
20 changed files
with
1,828 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
1 change: 1 addition & 0 deletions
1
.../aws-cloudfront-origins/test/integ.rest-api-origin-custom-origin-path.js.snapshot/cdk.out
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
{"version":"30.1.0"} |
19 changes: 19 additions & 0 deletions
19
...m-origin-path.js.snapshot/integ-cloudfront-rest-api-origin-custom-origin-path.assets.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
{ | ||
"version": "30.1.0", | ||
"files": { | ||
"caae80484d7f18b3e0e3e74d50e278f1f6a6f6ad5d264fa03a7fe46851fc2d8c": { | ||
"source": { | ||
"path": "integ-cloudfront-rest-api-origin-custom-origin-path.template.json", | ||
"packaging": "file" | ||
}, | ||
"destinations": { | ||
"current_account-current_region": { | ||
"bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", | ||
"objectKey": "caae80484d7f18b3e0e3e74d50e278f1f6a6f6ad5d264fa03a7fe46851fc2d8c.json", | ||
"assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" | ||
} | ||
} | ||
} | ||
}, | ||
"dockerImages": {} | ||
} |
234 changes: 234 additions & 0 deletions
234
...origin-path.js.snapshot/integ-cloudfront-rest-api-origin-custom-origin-path.template.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,234 @@ | ||
{ | ||
"Resources": { | ||
"RestApi0C43BF4B": { | ||
"Type": "AWS::ApiGateway::RestApi", | ||
"Properties": { | ||
"EndpointConfiguration": { | ||
"Types": [ | ||
"REGIONAL" | ||
] | ||
}, | ||
"Name": "RestApi" | ||
} | ||
}, | ||
"RestApiCloudWatchRoleE3ED6605": { | ||
"Type": "AWS::IAM::Role", | ||
"Properties": { | ||
"AssumeRolePolicyDocument": { | ||
"Statement": [ | ||
{ | ||
"Action": "sts:AssumeRole", | ||
"Effect": "Allow", | ||
"Principal": { | ||
"Service": "apigateway.amazonaws.com" | ||
} | ||
} | ||
], | ||
"Version": "2012-10-17" | ||
}, | ||
"ManagedPolicyArns": [ | ||
{ | ||
"Fn::Join": [ | ||
"", | ||
[ | ||
"arn:", | ||
{ | ||
"Ref": "AWS::Partition" | ||
}, | ||
":iam::aws:policy/service-role/AmazonAPIGatewayPushToCloudWatchLogs" | ||
] | ||
] | ||
} | ||
] | ||
}, | ||
"UpdateReplacePolicy": "Retain", | ||
"DeletionPolicy": "Retain" | ||
}, | ||
"RestApiAccount7C83CF5A": { | ||
"Type": "AWS::ApiGateway::Account", | ||
"Properties": { | ||
"CloudWatchRoleArn": { | ||
"Fn::GetAtt": [ | ||
"RestApiCloudWatchRoleE3ED6605", | ||
"Arn" | ||
] | ||
} | ||
}, | ||
"DependsOn": [ | ||
"RestApi0C43BF4B" | ||
], | ||
"UpdateReplacePolicy": "Retain", | ||
"DeletionPolicy": "Retain" | ||
}, | ||
"RestApiDeployment180EC50368af6d4b358eff290c08cb2de07c4042": { | ||
"Type": "AWS::ApiGateway::Deployment", | ||
"Properties": { | ||
"RestApiId": { | ||
"Ref": "RestApi0C43BF4B" | ||
}, | ||
"Description": "Automatically created by the RestApi construct" | ||
}, | ||
"DependsOn": [ | ||
"RestApiGET0F59260B" | ||
] | ||
}, | ||
"RestApiDeploymentStageprod3855DE66": { | ||
"Type": "AWS::ApiGateway::Stage", | ||
"Properties": { | ||
"RestApiId": { | ||
"Ref": "RestApi0C43BF4B" | ||
}, | ||
"DeploymentId": { | ||
"Ref": "RestApiDeployment180EC50368af6d4b358eff290c08cb2de07c4042" | ||
}, | ||
"StageName": "prod" | ||
}, | ||
"DependsOn": [ | ||
"RestApiAccount7C83CF5A" | ||
] | ||
}, | ||
"RestApiGET0F59260B": { | ||
"Type": "AWS::ApiGateway::Method", | ||
"Properties": { | ||
"HttpMethod": "GET", | ||
"ResourceId": { | ||
"Fn::GetAtt": [ | ||
"RestApi0C43BF4B", | ||
"RootResourceId" | ||
] | ||
}, | ||
"RestApiId": { | ||
"Ref": "RestApi0C43BF4B" | ||
}, | ||
"AuthorizationType": "NONE", | ||
"Integration": { | ||
"Type": "MOCK" | ||
} | ||
} | ||
}, | ||
"Distribution830FAC52": { | ||
"Type": "AWS::CloudFront::Distribution", | ||
"Properties": { | ||
"DistributionConfig": { | ||
"DefaultCacheBehavior": { | ||
"CachePolicyId": "658327ea-f89d-4fab-a63d-7e88639e58f6", | ||
"Compress": true, | ||
"TargetOriginId": "integcloudfrontrestapiorigincustomoriginpathDistributionOrigin1635825EA", | ||
"ViewerProtocolPolicy": "allow-all" | ||
}, | ||
"Enabled": true, | ||
"HttpVersion": "http2", | ||
"IPV6Enabled": true, | ||
"Origins": [ | ||
{ | ||
"CustomOriginConfig": { | ||
"OriginProtocolPolicy": "https-only", | ||
"OriginSSLProtocols": [ | ||
"TLSv1.2" | ||
] | ||
}, | ||
"DomainName": { | ||
"Fn::Select": [ | ||
2, | ||
{ | ||
"Fn::Split": [ | ||
"/", | ||
{ | ||
"Fn::Join": [ | ||
"", | ||
[ | ||
"https://", | ||
{ | ||
"Ref": "RestApi0C43BF4B" | ||
}, | ||
".execute-api.", | ||
{ | ||
"Ref": "AWS::Region" | ||
}, | ||
".", | ||
{ | ||
"Ref": "AWS::URLSuffix" | ||
}, | ||
"/", | ||
{ | ||
"Ref": "RestApiDeploymentStageprod3855DE66" | ||
}, | ||
"/" | ||
] | ||
] | ||
} | ||
] | ||
} | ||
] | ||
}, | ||
"Id": "integcloudfrontrestapiorigincustomoriginpathDistributionOrigin1635825EA", | ||
"OriginPath": "" | ||
} | ||
] | ||
} | ||
} | ||
} | ||
}, | ||
"Outputs": { | ||
"RestApiEndpoint0551178A": { | ||
"Value": { | ||
"Fn::Join": [ | ||
"", | ||
[ | ||
"https://", | ||
{ | ||
"Ref": "RestApi0C43BF4B" | ||
}, | ||
".execute-api.", | ||
{ | ||
"Ref": "AWS::Region" | ||
}, | ||
".", | ||
{ | ||
"Ref": "AWS::URLSuffix" | ||
}, | ||
"/", | ||
{ | ||
"Ref": "RestApiDeploymentStageprod3855DE66" | ||
}, | ||
"/" | ||
] | ||
] | ||
} | ||
} | ||
}, | ||
"Parameters": { | ||
"BootstrapVersion": { | ||
"Type": "AWS::SSM::Parameter::Value<String>", | ||
"Default": "/cdk-bootstrap/hnb659fds/version", | ||
"Description": "Version of the CDK Bootstrap resources in this environment, automatically retrieved from SSM Parameter Store. [cdk:skip]" | ||
} | ||
}, | ||
"Rules": { | ||
"CheckBootstrapVersion": { | ||
"Assertions": [ | ||
{ | ||
"Assert": { | ||
"Fn::Not": [ | ||
{ | ||
"Fn::Contains": [ | ||
[ | ||
"1", | ||
"2", | ||
"3", | ||
"4", | ||
"5" | ||
], | ||
{ | ||
"Ref": "BootstrapVersion" | ||
} | ||
] | ||
} | ||
] | ||
}, | ||
"AssertDescription": "CDK bootstrap stack version 6 required. Please run 'cdk bootstrap' with a recent version of the CDK CLI." | ||
} | ||
] | ||
} | ||
} | ||
} |
12 changes: 12 additions & 0 deletions
12
...s-cloudfront-origins/test/integ.rest-api-origin-custom-origin-path.js.snapshot/integ.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
{ | ||
"version": "30.1.0", | ||
"testCases": { | ||
"rest-api-origin-custom-origin-path/DefaultTest": { | ||
"stacks": [ | ||
"integ-cloudfront-rest-api-origin-custom-origin-path" | ||
], | ||
"assertionStack": "rest-api-origin-custom-origin-path/DefaultTest/DeployAssert", | ||
"assertionStackName": "restapiorigincustomoriginpathDefaultTestDeployAssertCD227A2A" | ||
} | ||
} | ||
} |
Oops, something went wrong.