diff --git a/packages/@aws-cdk/aws-apigateway/lib/restapi.ts b/packages/@aws-cdk/aws-apigateway/lib/restapi.ts index 32812cd838d65..abfa8b50626f9 100644 --- a/packages/@aws-cdk/aws-apigateway/lib/restapi.ts +++ b/packages/@aws-cdk/aws-apigateway/lib/restapi.ts @@ -301,7 +301,7 @@ export class RestApi extends Resource implements IRestApi { /** * Adds a usage plan. */ - public addUsagePlan(id: string, props: UsagePlanProps): UsagePlan { + public addUsagePlan(id: string, props: UsagePlanProps = {}): UsagePlan { return new UsagePlan(this, id, props); } diff --git a/packages/@aws-cdk/aws-apigateway/lib/usage-plan.ts b/packages/@aws-cdk/aws-apigateway/lib/usage-plan.ts index 51b44840f5daa..c0d9d9d18be65 100644 --- a/packages/@aws-cdk/aws-apigateway/lib/usage-plan.ts +++ b/packages/@aws-cdk/aws-apigateway/lib/usage-plan.ts @@ -178,7 +178,12 @@ export class UsagePlan extends Resource { * @param apiKey */ public addApiKey(apiKey: IApiKey): void { - new CfnUsagePlanKey(this, 'UsagePlanKeyResource', { + const prefix = 'UsagePlanKeyResource'; + + // Postfixing apikey id only from the 2nd child, to keep physicalIds of UsagePlanKey for existing CDK apps unmodifed. + const id = this.node.tryFindChild(prefix) ? `${prefix}:${apiKey.node.uniqueId}` : prefix; + + new CfnUsagePlanKey(this, id, { keyId: apiKey.keyId, keyType: UsagePlanKeyType.API_KEY, usagePlanId: this.usagePlanId diff --git a/packages/@aws-cdk/aws-apigateway/test/integ.usage-plan.multikey.expected.json b/packages/@aws-cdk/aws-apigateway/test/integ.usage-plan.multikey.expected.json new file mode 100644 index 0000000000000..669c3c14f0c20 --- /dev/null +++ b/packages/@aws-cdk/aws-apigateway/test/integ.usage-plan.multikey.expected.json @@ -0,0 +1,44 @@ +{ + "Resources": { + "myusageplan4B391740": { + "Type": "AWS::ApiGateway::UsagePlan", + "Properties": {} + }, + "myusageplanUsagePlanKeyResource095B4EA9": { + "Type": "AWS::ApiGateway::UsagePlanKey", + "Properties": { + "KeyId": { + "Ref": "myapikey18B056ACE" + }, + "KeyType": "API_KEY", + "UsagePlanId": { + "Ref": "myusageplan4B391740" + } + } + }, + "myusageplanUsagePlanKeyResourcetestapigatewayusageplanmultikeymyapikey29D6460C6AE8DE59D": { + "Type": "AWS::ApiGateway::UsagePlanKey", + "Properties": { + "KeyId": { + "Ref": "myapikey250C8F11B" + }, + "KeyType": "API_KEY", + "UsagePlanId": { + "Ref": "myusageplan4B391740" + } + } + }, + "myapikey18B056ACE": { + "Type": "AWS::ApiGateway::ApiKey", + "Properties": { + "Enabled": true + } + }, + "myapikey250C8F11B": { + "Type": "AWS::ApiGateway::ApiKey", + "Properties": { + "Enabled": true + } + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-apigateway/test/integ.usage-plan.multikey.ts b/packages/@aws-cdk/aws-apigateway/test/integ.usage-plan.multikey.ts new file mode 100644 index 0000000000000..da83c33a8e224 --- /dev/null +++ b/packages/@aws-cdk/aws-apigateway/test/integ.usage-plan.multikey.ts @@ -0,0 +1,20 @@ +import cdk = require('@aws-cdk/core'); +import apigateway = require('../lib'); + +class Test extends cdk.Stack { + constructor(scope: cdk.App, id: string) { + super(scope, id); + + const usageplan = new apigateway.UsagePlan(this, 'myusageplan'); + const apikey1 = new apigateway.ApiKey(this, 'myapikey1'); + const apikey2 = new apigateway.ApiKey(this, 'myapikey2'); + usageplan.addApiKey(apikey1); + usageplan.addApiKey(apikey2); + } +} + +const app = new cdk.App(); + +new Test(app, 'test-apigateway-usageplan-multikey'); + +app.synth(); diff --git a/packages/@aws-cdk/aws-apigateway/test/test.usage-plan.ts b/packages/@aws-cdk/aws-apigateway/test/test.usage-plan.ts index 7ece505a1bb11..1a8b7112a2d0a 100644 --- a/packages/@aws-cdk/aws-apigateway/test/test.usage-plan.ts +++ b/packages/@aws-cdk/aws-apigateway/test/test.usage-plan.ts @@ -129,5 +129,41 @@ export = { }, ResourcePart.Properties)); test.done(); - } + }, + + 'UsagePlan can have multiple keys'(test: Test) { + // GIVEN + const stack = new cdk.Stack(); + const usagePlan = new apigateway.UsagePlan(stack, 'my-usage-plan'); + const apiKey1 = new apigateway.ApiKey(stack, 'my-api-key-1', { + apiKeyName: 'my-api-key-1' + }); + const apiKey2 = new apigateway.ApiKey(stack, 'my-api-key-2', { + apiKeyName: 'my-api-key-2' + }); + + // WHEN + usagePlan.addApiKey(apiKey1); + usagePlan.addApiKey(apiKey2); + + // THEN + expect(stack).to(haveResource('AWS::ApiGateway::ApiKey', { + Name: 'my-api-key-1' + }, ResourcePart.Properties)); + expect(stack).to(haveResource('AWS::ApiGateway::ApiKey', { + Name: 'my-api-key-2' + }, ResourcePart.Properties)); + expect(stack).to(haveResource('AWS::ApiGateway::UsagePlanKey', { + KeyId: { + Ref: 'myapikey11F723FC7' + } + }, ResourcePart.Properties)); + expect(stack).to(haveResource('AWS::ApiGateway::UsagePlanKey', { + KeyId: { + Ref: 'myapikey2ABDEF012' + } + }, ResourcePart.Properties)); + + test.done(); + }, };