From a65545b2b26c76f4cc2e940f274e53e2e309acc3 Mon Sep 17 00:00:00 2001 From: Chengjun Li Date: Wed, 23 Sep 2026 15:53:18 -0700 Subject: [PATCH] fix(integration-tests): make MyFirstApiKey value stack-scoped The api_with_authorizer_apikey template hardcodes both the API Key's Value and the Lambda authorizer's usageIdentifierKey to the literal "needatleast20characters". AWS API Gateway enforces an undocumented uniqueness constraint on the API Key value across account+region (returns 409 ConflictException with HandlerErrorCode: AlreadyExists on collision). Any orphaned resource from a previous run - for example, a test runner that timed out before its cleanup could complete - will hold the value and block every subsequent run of this test until the orphan is deleted externally. Scope the API Key value to ${AWS::StackName} so it is unique per CFN stack, while still matching the authorizer's usageIdentifierKey. Substituted length stays within API Gateway's [20, 128]-character bounds (empirically verified: min=20 with "API Key value should be at least 20 characters", max=128 with "API Key value exceeds maximum size of 128 characters"). Verified end-to-end by deploying the fixed template as two concurrent stacks in a dev account - both created cleanly with distinct stack-scoped values, and the runtime authorizer flow returned 200 for allow / 403 for deny. --- .../templates/combination/api_with_authorizer_apikey.yaml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/integration/resources/templates/combination/api_with_authorizer_apikey.yaml b/integration/resources/templates/combination/api_with_authorizer_apikey.yaml index 862c4adec..06abbe8de 100644 --- a/integration/resources/templates/combination/api_with_authorizer_apikey.yaml +++ b/integration/resources/templates/combination/api_with_authorizer_apikey.yaml @@ -50,7 +50,7 @@ Resources: Properties: Handler: index.handler Runtime: nodejs18.x - InlineCode: | + InlineCode: !Sub | exports.handler = async (event, context, callback) => { console.log(event); const token = event.type === 'TOKEN' ? event.authorizationToken : event.queryStringParameters.authorization @@ -65,7 +65,7 @@ Resources: return { principalId: 'user', - usageIdentifierKey: 'needatleast20characters', + usageIdentifierKey: 'needatleast20chars-${AWS::StackName}', context: { }, policyDocument } @@ -77,7 +77,7 @@ Resources: - MyUsagePlan Properties: Enabled: true - Value: needatleast20characters + Value: !Sub "needatleast20chars-${AWS::StackName}" StageKeys: - RestApiId: Ref: MyApi