From c94a999ec4567eec4404d2ac1b6b595748677ddd Mon Sep 17 00:00:00 2001 From: Calvin Combs <66279577+comcalvi@users.noreply.github.com> Date: Tue, 17 Jan 2023 18:54:48 -0800 Subject: [PATCH] Revert "feat(trigger): Allow trigger to work with Lambda functions with long timeouts (#23062)" This reverts commit 9fd3811b3213a227b84d79348e635a520fc537c7. --- packages/@aws-cdk/triggers/README.md | 27 ---- .../@aws-cdk/triggers/lib/lambda/index.ts | 22 +-- packages/@aws-cdk/triggers/lib/trigger.ts | 39 ----- .../MyStack.template.json | 133 ++---------------- .../@aws-cdk/triggers/test/integ.triggers.ts | 22 +-- .../triggers/test/trigger-handler.test.ts | 14 +- .../@aws-cdk/triggers/test/triggers.test.ts | 53 +------ 7 files changed, 30 insertions(+), 280 deletions(-) diff --git a/packages/@aws-cdk/triggers/README.md b/packages/@aws-cdk/triggers/README.md index d859fe1430f34..2c86e946c1941 100644 --- a/packages/@aws-cdk/triggers/README.md +++ b/packages/@aws-cdk/triggers/README.md @@ -39,33 +39,6 @@ new triggers.TriggerFunction(stack, 'MyTrigger', { In the above example, the AWS Lambda function defined in `myLambdaFunction` will be invoked when the stack is deployed. -It is also possible to trigger a predefined Lambda function by using the `Trigger` construct: - -```ts -import * as lambda from '@aws-cdk/aws-lambda'; -import * as triggers from '@aws-cdk/triggers'; -import { Stack } from '@aws-cdk/core'; - -declare const stack: Stack; - -const func = new lambda.Function(stack, 'MyFunction', { - handler: 'index.handler', - runtime: lambda.Runtime.NODEJS_14_X, - code: lambda.Code.fromInline('foo'), -}); - -new triggers.Trigger(stack, 'MyTrigger', { - handler: func, - timeout: Duration.minutes(10), - invocationType: triggers.InvocationType.EVENT, -}); -``` - -Addition properties can be used to fine-tune the behaviour of the trigger. -The `timeout` property can be used to determine how long the invocation of the function should take. -The `invocationType` property can be used to change the invocation type of the function. -This might be useful in scenarios where a fire-and-forget strategy for invoking the function is sufficient. - ## Trigger Failures If the trigger handler fails (e.g. an exception is raised), the CloudFormation diff --git a/packages/@aws-cdk/triggers/lib/lambda/index.ts b/packages/@aws-cdk/triggers/lib/lambda/index.ts index 6f3bd38bcc42e..8fb4db66a3cc3 100644 --- a/packages/@aws-cdk/triggers/lib/lambda/index.ts +++ b/packages/@aws-cdk/triggers/lib/lambda/index.ts @@ -3,16 +3,11 @@ // eslint-disable-next-line import/no-extraneous-dependencies import * as AWS from 'aws-sdk'; -export type InvokeFunction = (functionName: string, invocationType: string, timeout: number) => Promise; +export type InvokeFunction = (functionName: string) => Promise; -export const invoke: InvokeFunction = async (functionName, invocationType, timeout) => { - const lambda = new AWS.Lambda({ - httpOptions: { - timeout, - }, - }); - - const invokeRequest = { FunctionName: functionName, InvocationType: invocationType }; +export const invoke: InvokeFunction = async (functionName) => { + const lambda = new AWS.Lambda(); + const invokeRequest = { FunctionName: functionName }; console.log({ invokeRequest }); // IAM policy changes can take some time to fully propagate @@ -56,10 +51,7 @@ export async function handler(event: AWSLambda.CloudFormationCustomResourceEvent throw new Error('The "HandlerArn" property is required'); } - const invocationType = event.ResourceProperties.InvocationType; - const timeout = event.ResourceProperties.Timeout; - - const invokeResponse = await invoke(handlerArn, invocationType, timeout); + const invokeResponse = await invoke(handlerArn); if (invokeResponse.StatusCode !== 200) { throw new Error(`Trigger handler failed with status code ${invokeResponse.StatusCode}`); @@ -76,9 +68,7 @@ export async function handler(event: AWSLambda.CloudFormationCustomResourceEvent */ function parseError(payload: string | undefined): string { console.log(`Error payload: ${payload}`); - if (!payload) { - return 'unknown handler error'; - } + if (!payload) { return 'unknown handler error'; } try { const error = JSON.parse(payload); const concat = [error.errorMessage, error.trace].filter(x => x).join('\n'); diff --git a/packages/@aws-cdk/triggers/lib/trigger.ts b/packages/@aws-cdk/triggers/lib/trigger.ts index 2a74a0a6fd874..6febb482966cf 100644 --- a/packages/@aws-cdk/triggers/lib/trigger.ts +++ b/packages/@aws-cdk/triggers/lib/trigger.ts @@ -2,7 +2,6 @@ import { join } from 'path'; import * as lambda from '@aws-cdk/aws-lambda'; import { CustomResource, CustomResourceProvider, CustomResourceProviderRuntime } from '@aws-cdk/core'; import { Construct, IConstruct, Node } from 'constructs'; -import { Duration } from '../../core'; /** * Interface for triggers. @@ -62,28 +61,6 @@ export interface TriggerOptions { readonly executeOnHandlerChange?: boolean; } -/** - * The invocation type to apply to a trigger. This determines whether the trigger function should await the result of the to be triggered function or not. - */ -export enum InvocationType { - /** - * Invoke the function synchronously. Keep the connection open until the function returns a response or times out. - * The API response includes the function response and additional data. - */ - EVENT = 'Event', - - /** - * Invoke the function asynchronously. Send events that fail multiple times to the function's dead-letter queue (if one is configured). - * The API response only includes a status code. - */ - REQUEST_RESPONSE = 'RequestResponse', - - /** - * Validate parameter values and verify that the user or role has permission to invoke the function. - */ - DRY_RUN = 'DryRun' -} - /** * Props for `Trigger`. */ @@ -92,20 +69,6 @@ export interface TriggerProps extends TriggerOptions { * The AWS Lambda function of the handler to execute. */ readonly handler: lambda.Function; - - /** - * The invocation type to invoke the Lambda function with. - * - * @default RequestResponse - */ - readonly invocationType?: InvocationType; - - /** - * The timeout of the invocation call of the Lambda function to be triggered. - * - * @default Duration.minutes(2) - */ - readonly timeout?: Duration; } /** @@ -132,8 +95,6 @@ export class Trigger extends Construct implements ITrigger { serviceToken: provider.serviceToken, properties: { HandlerArn: handlerArn, - InvocationType: props.invocationType ?? 'RequestResponse', - Timeout: props.timeout?.toMilliseconds() ?? Duration.minutes(2).toMilliseconds(), }, }); diff --git a/packages/@aws-cdk/triggers/test/integ.triggers.js.snapshot/MyStack.template.json b/packages/@aws-cdk/triggers/test/integ.triggers.js.snapshot/MyStack.template.json index 31625a36f0bee..fde860ed9ad4b 100644 --- a/packages/@aws-cdk/triggers/test/integ.triggers.js.snapshot/MyStack.template.json +++ b/packages/@aws-cdk/triggers/test/integ.triggers.js.snapshot/MyStack.template.json @@ -3,13 +3,13 @@ "Topic198E71B3E": { "Type": "AWS::SNS::Topic", "DependsOn": [ - "MyTriggerFunctionTrigger5424E7A7" + "MyFunctionTriggerDB129D7B" ] }, "Topic269377B75": { "Type": "AWS::SNS::Topic" }, - "MyTriggerFunctionServiceRole1BB78C29": { + "MyFunctionServiceRole3C357FF2": { "Type": "AWS::IAM::Role", "Properties": { "AssumeRolePolicyDocument": { @@ -40,7 +40,7 @@ ] } }, - "MyTriggerFunction056842F6": { + "MyFunction3BAA72D1": { "Type": "AWS::Lambda::Function", "Properties": { "Code": { @@ -48,18 +48,18 @@ }, "Role": { "Fn::GetAtt": [ - "MyTriggerFunctionServiceRole1BB78C29", + "MyFunctionServiceRole3C357FF2", "Arn" ] }, "Handler": "index.handler", - "Runtime": "nodejs16.x" + "Runtime": "nodejs14.x" }, "DependsOn": [ - "MyTriggerFunctionServiceRole1BB78C29" + "MyFunctionServiceRole3C357FF2" ] }, - "MyTriggerFunctionTrigger5424E7A7": { + "MyFunctionTriggerDB129D7B": { "Type": "Custom::Trigger", "Properties": { "ServiceToken": { @@ -69,10 +69,8 @@ ] }, "HandlerArn": { - "Ref": "MyTriggerFunctionCurrentVersion61957CE160cd5b4c06c4d00191dc10a647ea0777" - }, - "InvocationType": "RequestResponse", - "Timeout": 120000 + "Ref": "MyFunctionCurrentVersion197490AF2cb2bc11080c1ef11d3b49c1f1603957" + } }, "DependsOn": [ "Topic269377B75" @@ -80,11 +78,11 @@ "UpdateReplacePolicy": "Delete", "DeletionPolicy": "Delete" }, - "MyTriggerFunctionCurrentVersion61957CE160cd5b4c06c4d00191dc10a647ea0777": { + "MyFunctionCurrentVersion197490AF2cb2bc11080c1ef11d3b49c1f1603957": { "Type": "AWS::Lambda::Version", "Properties": { "FunctionName": { - "Ref": "MyTriggerFunction056842F6" + "Ref": "MyFunction3BAA72D1" } } }, @@ -126,29 +124,7 @@ [ { "Fn::GetAtt": [ - "MyTriggerFunction056842F6", - "Arn" - ] - }, - ":*" - ] - ] - } - ] - }, - { - "Effect": "Allow", - "Action": [ - "lambda:InvokeFunction" - ], - "Resource": [ - { - "Fn::Join": [ - "", - [ - { - "Fn::GetAtt": [ - "MyLambdaFunction67CCA873", + "MyFunction3BAA72D1", "Arn" ] }, @@ -210,87 +186,6 @@ "AWSCDKTriggerCustomResourceProviderCustomResourceProviderRoleE18FAF0A" ] }, - "MyLambdaFunctionServiceRole313A4D46": { - "Type": "AWS::IAM::Role", - "Properties": { - "AssumeRolePolicyDocument": { - "Statement": [ - { - "Action": "sts:AssumeRole", - "Effect": "Allow", - "Principal": { - "Service": "lambda.amazonaws.com" - } - } - ], - "Version": "2012-10-17" - }, - "ManagedPolicyArns": [ - { - "Fn::Join": [ - "", - [ - "arn:", - { - "Ref": "AWS::Partition" - }, - ":iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" - ] - ] - } - ] - } - }, - "MyLambdaFunction67CCA873": { - "Type": "AWS::Lambda::Function", - "Properties": { - "Code": { - "ZipFile": "exports.handler = function() { await setTimeout(3*60*1000, \"hi\"); };" - }, - "Role": { - "Fn::GetAtt": [ - "MyLambdaFunctionServiceRole313A4D46", - "Arn" - ] - }, - "Handler": "index.handler", - "Runtime": "nodejs16.x", - "Timeout": 900 - }, - "DependsOn": [ - "MyLambdaFunctionServiceRole313A4D46" - ] - }, - "MyLambdaFunctionCurrentVersion4FAB80ECdc4d4e257bb2b44c9c4b9231f0d16f4c": { - "Type": "AWS::Lambda::Version", - "Properties": { - "FunctionName": { - "Ref": "MyLambdaFunction67CCA873" - } - } - }, - "MyTrigger": { - "Type": "Custom::Trigger", - "Properties": { - "ServiceToken": { - "Fn::GetAtt": [ - "AWSCDKTriggerCustomResourceProviderCustomResourceProviderHandler97BECD91", - "Arn" - ] - }, - "HandlerArn": { - "Ref": "MyLambdaFunctionCurrentVersion4FAB80ECdc4d4e257bb2b44c9c4b9231f0d16f4c" - }, - "InvocationType": "Event", - "Timeout": 60000 - }, - "DependsOn": [ - "Topic198E71B3E", - "Topic269377B75" - ], - "UpdateReplacePolicy": "Delete", - "DeletionPolicy": "Delete" - }, "MySecondFunctionServiceRole5B930841": { "Type": "AWS::IAM::Role", "Properties": { @@ -352,9 +247,7 @@ }, "HandlerArn": { "Ref": "MySecondFunctionCurrentVersion7D497B5D173a4bb1f758991022ea97d651403362" - }, - "InvocationType": "RequestResponse", - "Timeout": 120000 + } }, "UpdateReplacePolicy": "Delete", "DeletionPolicy": "Delete" diff --git a/packages/@aws-cdk/triggers/test/integ.triggers.ts b/packages/@aws-cdk/triggers/test/integ.triggers.ts index de5023461ed2e..9e24277509c58 100644 --- a/packages/@aws-cdk/triggers/test/integ.triggers.ts +++ b/packages/@aws-cdk/triggers/test/integ.triggers.ts @@ -1,8 +1,7 @@ import * as lambda from '@aws-cdk/aws-lambda'; import * as sns from '@aws-cdk/aws-sns'; -import { App, Duration, Stack } from '@aws-cdk/core'; +import { App, Stack } from '@aws-cdk/core'; import * as triggers from '../lib'; -import { InvocationType } from '../lib'; const app = new App(); const stack = new Stack(app, 'MyStack'); @@ -10,28 +9,13 @@ const stack = new Stack(app, 'MyStack'); const topic1 = new sns.Topic(stack, 'Topic1'); const topic2 = new sns.Topic(stack, 'Topic2'); -const triggerFunction = new triggers.TriggerFunction(stack, 'MyTriggerFunction', { - runtime: lambda.Runtime.NODEJS_16_X, +const trigger = new triggers.TriggerFunction(stack, 'MyFunction', { + runtime: lambda.Runtime.NODEJS_14_X, handler: 'index.handler', code: lambda.Code.fromInline('exports.handler = function() { console.log("hi"); };'), executeBefore: [topic1], }); -const func = new lambda.Function(stack, 'MyLambdaFunction', { - runtime: lambda.Runtime.NODEJS_16_X, - handler: 'index.handler', - timeout: Duration.minutes(15), - code: lambda.Code.fromInline('exports.handler = function() { await setTimeout(3*60*1000, "hi"); };'), -}); - -const trigger = new triggers.Trigger(stack, 'MyTrigger', { - handler: func, - invocationType: InvocationType.EVENT, - timeout: Duration.minutes(1), - executeAfter: [topic1], -}); - -triggerFunction.executeAfter(topic2); trigger.executeAfter(topic2); new triggers.TriggerFunction(stack, 'MySecondFunction', { diff --git a/packages/@aws-cdk/triggers/test/trigger-handler.test.ts b/packages/@aws-cdk/triggers/test/trigger-handler.test.ts index 09a4d77a657b5..18eea6a881ceb 100644 --- a/packages/@aws-cdk/triggers/test/trigger-handler.test.ts +++ b/packages/@aws-cdk/triggers/test/trigger-handler.test.ts @@ -29,8 +29,6 @@ const mockRequest = { ResourceProperties: { ServiceToken: 'arn:aws:lambda:us-east-1:123456789012:function:MyFunction', HandlerArn: handlerArn, - Timeout: 600, - InvocationType: 'Event', }, RequestId: 'MyRequestId', ResourceType: 'Custom::Trigger', @@ -41,14 +39,14 @@ test('Create', async () => { await lambda.handler({ RequestType: 'Create', ...mockRequest }); expect(invokeMock).toBeCalledTimes(1); - expect(invokeMock).toBeCalledWith({ FunctionName: handlerArn, InvocationType: 'Event' }); + expect(invokeMock).toBeCalledWith({ FunctionName: handlerArn }); }); test('Update', async () => { await lambda.handler({ RequestType: 'Update', PhysicalResourceId: 'PRID', OldResourceProperties: {}, ...mockRequest }); expect(invokeMock).toBeCalledTimes(1); - expect(invokeMock).toBeCalledWith({ FunctionName: handlerArn, InvocationType: 'Event' }); + expect(invokeMock).toBeCalledWith({ FunctionName: handlerArn }); }); test('Delete - handler not called', async () => { @@ -66,7 +64,7 @@ test('non-200 status code throws an error', async () => { .toMatchObject({ message: 'Trigger handler failed with status code 500' }); expect(invokeMock).toBeCalledTimes(1); - expect(invokeMock).toBeCalledWith({ FunctionName: handlerArn, InvocationType: 'Event' }); + expect(invokeMock).toBeCalledWith({ FunctionName: handlerArn }); }); test('retry with access denied exception', async () => { @@ -83,7 +81,7 @@ test('retry with access denied exception', async () => { await response; expect(invokeMock).toBeCalledTimes(2); - expect(invokeMock).toBeCalledWith({ FunctionName: handlerArn, InvocationType: 'Event' }); + expect(invokeMock).toBeCalledWith({ FunctionName: handlerArn }); }); test('throws an error for other exceptions', async () => { @@ -96,7 +94,7 @@ test('throws an error for other exceptions', async () => { .toThrow(); expect(invokeMock).toBeCalledTimes(1); - expect(invokeMock).toBeCalledWith({ FunctionName: handlerArn, InvocationType: 'Event' }); + expect(invokeMock).toBeCalledWith({ FunctionName: handlerArn }); }); describe('function error', () => { @@ -113,7 +111,7 @@ describe('function error', () => { .toMatchObject({ message: expectedError }); expect(invokeMock).toBeCalledTimes(1); - expect(invokeMock).toBeCalledWith({ FunctionName: handlerArn, InvocationType: 'Event' }); + expect(invokeMock).toBeCalledWith({ FunctionName: handlerArn }); }; }; diff --git a/packages/@aws-cdk/triggers/test/triggers.test.ts b/packages/@aws-cdk/triggers/test/triggers.test.ts index 8c3b4d05a29e9..cc4edb610bade 100644 --- a/packages/@aws-cdk/triggers/test/triggers.test.ts +++ b/packages/@aws-cdk/triggers/test/triggers.test.ts @@ -1,11 +1,10 @@ import { Template } from '@aws-cdk/assertions'; import * as lambda from '@aws-cdk/aws-lambda'; import * as sns from '@aws-cdk/aws-sns'; -import { Duration, Stack } from '@aws-cdk/core'; +import { Stack } from '@aws-cdk/core'; import * as triggers from '../lib'; -import { InvocationType } from '../lib'; -test('minimal trigger function', () => { +test('minimal', () => { // GIVEN const stack = new Stack(); @@ -90,51 +89,3 @@ test('multiple functions', () => { const triggerIamRole = roles.AWSCDKTriggerCustomResourceProviderCustomResourceProviderRoleE18FAF0A; expect(triggerIamRole.Properties.Policies[0].PolicyDocument.Statement.length).toBe(2); }); - -test('minimal trigger', () => { - // GIVEN - const stack = new Stack(); - const func = new lambda.Function(stack, 'MyFunction', { - handler: 'index.handler', - runtime: lambda.Runtime.NODEJS_14_X, - code: lambda.Code.fromInline('foo'), - }); - - // WHEN - new triggers.Trigger(stack, 'MyTrigger', { - handler: func, - }); - - // THEN - const template = Template.fromStack(stack); - template.hasResourceProperties('AWS::Lambda::Function', {}); - template.hasResourceProperties('Custom::Trigger', { - HandlerArn: { Ref: 'MyFunctionCurrentVersion197490AF2e4e06d52af2bb609d8c23243d665966' }, - }); -}); - -test('trigger with optional properties', () => { - // GIVEN - const stack = new Stack(); - const func = new lambda.Function(stack, 'MyFunction', { - handler: 'index.handler', - runtime: lambda.Runtime.NODEJS_14_X, - code: lambda.Code.fromInline('foo'), - }); - - // WHEN - new triggers.Trigger(stack, 'MyTrigger', { - handler: func, - timeout: Duration.minutes(10), - invocationType: InvocationType.EVENT, - }); - - // THEN - const template = Template.fromStack(stack); - template.hasResourceProperties('AWS::Lambda::Function', {}); - template.hasResourceProperties('Custom::Trigger', { - HandlerArn: { Ref: 'MyFunctionCurrentVersion197490AF2e4e06d52af2bb609d8c23243d665966' }, - Timeout: 600000, - InvocationType: 'Event', - }); -});