Skip to content

Commit

Permalink
feat(apigateway): create BasePathMapping without stage (aws#21488)
Browse files Browse the repository at this point in the history
Closes aws#15806

Creates a new prop `attachToStage` to `BasePathMappingOptions` to allow a base path mapping to be created without a stage. Setting `stage` to `undefined` does not work, as in this case the default stage will be used.

----

### All Submissions:

* [X] Have you followed the guidelines in our [Contributing guide?](https://github.com/aws/aws-cdk/blob/main/CONTRIBUTING.md)

### Adding new Unconventional Dependencies:

* [ ] This PR adds new unconventional dependencies following the process described [here](https://github.com/aws/aws-cdk/blob/main/CONTRIBUTING.md/#adding-new-unconventional-dependencies)

### New Features

* [x] Have you added the new feature to an [integration test](https://github.com/aws/aws-cdk/blob/main/INTEGRATION_TESTS.md)?
	* [ ] Did you use `yarn integ` to deploy the infrastructure and generate the snapshot (i.e. `yarn integ` without `--dry-run`)?

*By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
  • Loading branch information
cecheta authored and arewa committed Oct 8, 2022
1 parent 8916a65 commit 308780d
Show file tree
Hide file tree
Showing 12 changed files with 751 additions and 5 deletions.
34 changes: 32 additions & 2 deletions packages/@aws-cdk/aws-apigateway/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -950,8 +950,8 @@ domain.addBasePathMapping(api1, { basePath: 'go-to-api1' });
domain.addBasePathMapping(api2, { basePath: 'boom' });
```

You can specify the API `Stage` to which this base path URL will map to. By default, this will be the
`deploymentStage` of the `RestApi`.
By default, the base path URL will map to the `deploymentStage` of the `RestApi`.
You can specify a different API `Stage` to which the base path URL will map to.

```ts
declare const domain: apigateway.DomainName;
Expand All @@ -966,6 +966,19 @@ const betaStage = new apigateway.Stage(this, 'beta-stage', {
domain.addBasePathMapping(restapi, { basePath: 'api/beta', stage: betaStage });
```

It is possible to create a base path mapping without associating it with a
stage by using the `attachToStage` property. When set to `false`, the stage must be
included in the URL when invoking the API. For example,
<https://example.com/myapi/prod> will invoke the stage named `prod` from the
`myapi` base path mapping.

```ts
declare const domain: apigateway.DomainName;
declare const api: apigateway.RestApi;

domain.addBasePathMapping(api, { basePath: 'myapi', attachToStage: false });
```

If you don't specify `basePath`, all URLs under this domain will be mapped
to the API, and you won't be able to map another API to the same domain:

Expand All @@ -978,6 +991,23 @@ domain.addBasePathMapping(api);
This can also be achieved through the `mapping` configuration when defining the
domain as demonstrated above.

Base path mappings can also be created with the `BasePathMapping` resource.

```ts
declare const api: apigateway.RestApi;

const domainName = apigateway.DomainName.fromDomainNameAttributes(this, 'DomainName', {
domainName: 'domainName',
domainNameAliasHostedZoneId: 'domainNameAliasHostedZoneId',
domainNameAliasTarget: 'domainNameAliasTarget',
});

new apigateway.BasePathMapping(this, 'BasePathMapping', {
domainName: domainName,
restApi: api,
});
```

If you wish to setup this domain with an Amazon Route53 alias, use the `targets.ApiGatewayDomain`:

```ts
Expand Down
15 changes: 13 additions & 2 deletions packages/@aws-cdk/aws-apigateway/lib/base-path-mapping.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,14 @@ export interface BasePathMappingOptions {
* @default - map to deploymentStage of restApi otherwise stage needs to pass in URL
*/
readonly stage?: Stage;

/**
* Whether to attach the base path mapping to a stage.
* Use this property to create a base path mapping without attaching it to the Rest API default stage.
* This property is ignored if `stage` is provided.
* @default - true
*/
readonly attachToStage?: boolean;
}

export interface BasePathMappingProps extends BasePathMappingOptions {
Expand Down Expand Up @@ -53,17 +61,20 @@ export class BasePathMapping extends Resource {
}
}

const attachToStage = props.attachToStage ?? true;

// if restApi is an owned API and it has a deployment stage, map all requests
// to that stage. otherwise, the stage will have to be specified in the URL.
const stage = props.stage ?? (props.restApi instanceof RestApiBase
// if props.attachToStage is false, then do not attach to the stage.
const stage = props.stage ?? (props.restApi instanceof RestApiBase && attachToStage
? props.restApi.deploymentStage
: undefined);

new CfnBasePathMapping(this, 'Resource', {
basePath: props.basePath,
domainName: props.domainName.domainName,
restApiId: props.restApi.restApiId,
stage: stage && stage.stageName,
stage: stage?.stageName,
});
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"version": "21.0.0",
"files": {
"21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22": {
"source": {
"path": "basepathmappingDefaultTestDeployAssertDA82B6F0.template.json",
"packaging": "file"
},
"destinations": {
"current_account-current_region": {
"bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}",
"objectKey": "21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22.json",
"assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}"
}
}
}
},
"dockerImages": {}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
{
"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."
}
]
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"version":"21.0.0"}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"version": "21.0.0",
"testCases": {
"base-path-mapping/DefaultTest": {
"stacks": [
"test-stack"
],
"assertionStack": "base-path-mapping/DefaultTest/DeployAssert",
"assertionStackName": "basepathmappingDefaultTestDeployAssertDA82B6F0"
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
{
"version": "21.0.0",
"artifacts": {
"Tree": {
"type": "cdk:tree",
"properties": {
"file": "tree.json"
}
},
"test-stack.assets": {
"type": "cdk:asset-manifest",
"properties": {
"file": "test-stack.assets.json",
"requiresBootstrapStackVersion": 6,
"bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version"
}
},
"test-stack": {
"type": "aws:cloudformation:stack",
"environment": "aws://unknown-account/unknown-region",
"properties": {
"templateFile": "test-stack.template.json",
"validateOnSynth": false,
"assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-deploy-role-${AWS::AccountId}-${AWS::Region}",
"cloudFormationExecutionRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-cfn-exec-role-${AWS::AccountId}-${AWS::Region}",
"stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/4328166cfc76604ab46a2a088da69e6631472872129e804d27c8b5336c842774.json",
"requiresBootstrapStackVersion": 6,
"bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version",
"additionalDependencies": [
"test-stack.assets"
],
"lookupRole": {
"arn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-lookup-role-${AWS::AccountId}-${AWS::Region}",
"requiresBootstrapStackVersion": 8,
"bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version"
}
},
"dependencies": [
"test-stack.assets"
],
"metadata": {
"/test-stack/Api/Resource": [
{
"type": "aws:cdk:logicalId",
"data": "ApiF70053CD"
}
],
"/test-stack/Api/Deployment/Resource": [
{
"type": "aws:cdk:logicalId",
"data": "ApiDeploymentB17BE62Df672ad8455f9678e4a3db5854bdb8d73"
}
],
"/test-stack/Api/DeploymentStage.prod/Resource": [
{
"type": "aws:cdk:logicalId",
"data": "ApiDeploymentStageprod3EB9684E"
}
],
"/test-stack/Api/Endpoint": [
{
"type": "aws:cdk:logicalId",
"data": "ApiEndpoint4F160690"
}
],
"/test-stack/Api/Default/GET/Resource": [
{
"type": "aws:cdk:logicalId",
"data": "ApiGET9257B917"
}
],
"/test-stack/MappingOne/Resource": [
{
"type": "aws:cdk:logicalId",
"data": "MappingOneAB5D4FD4"
}
],
"/test-stack/MappingTwo/Resource": [
{
"type": "aws:cdk:logicalId",
"data": "MappingTwo551C79ED"
}
],
"/test-stack/BootstrapVersion": [
{
"type": "aws:cdk:logicalId",
"data": "BootstrapVersion"
}
],
"/test-stack/CheckBootstrapVersion": [
{
"type": "aws:cdk:logicalId",
"data": "CheckBootstrapVersion"
}
]
},
"displayName": "test-stack"
},
"basepathmappingDefaultTestDeployAssertDA82B6F0.assets": {
"type": "cdk:asset-manifest",
"properties": {
"file": "basepathmappingDefaultTestDeployAssertDA82B6F0.assets.json",
"requiresBootstrapStackVersion": 6,
"bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version"
}
},
"basepathmappingDefaultTestDeployAssertDA82B6F0": {
"type": "aws:cloudformation:stack",
"environment": "aws://unknown-account/unknown-region",
"properties": {
"templateFile": "basepathmappingDefaultTestDeployAssertDA82B6F0.template.json",
"validateOnSynth": false,
"assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-deploy-role-${AWS::AccountId}-${AWS::Region}",
"cloudFormationExecutionRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-cfn-exec-role-${AWS::AccountId}-${AWS::Region}",
"stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22.json",
"requiresBootstrapStackVersion": 6,
"bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version",
"additionalDependencies": [
"basepathmappingDefaultTestDeployAssertDA82B6F0.assets"
],
"lookupRole": {
"arn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-lookup-role-${AWS::AccountId}-${AWS::Region}",
"requiresBootstrapStackVersion": 8,
"bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version"
}
},
"dependencies": [
"basepathmappingDefaultTestDeployAssertDA82B6F0.assets"
],
"metadata": {
"/base-path-mapping/DefaultTest/DeployAssert/BootstrapVersion": [
{
"type": "aws:cdk:logicalId",
"data": "BootstrapVersion"
}
],
"/base-path-mapping/DefaultTest/DeployAssert/CheckBootstrapVersion": [
{
"type": "aws:cdk:logicalId",
"data": "CheckBootstrapVersion"
}
]
},
"displayName": "base-path-mapping/DefaultTest/DeployAssert"
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"version": "21.0.0",
"files": {
"4328166cfc76604ab46a2a088da69e6631472872129e804d27c8b5336c842774": {
"source": {
"path": "test-stack.template.json",
"packaging": "file"
},
"destinations": {
"current_account-current_region": {
"bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}",
"objectKey": "4328166cfc76604ab46a2a088da69e6631472872129e804d27c8b5336c842774.json",
"assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}"
}
}
}
},
"dockerImages": {}
}
Loading

0 comments on commit 308780d

Please sign in to comment.