Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

triggers: Trigger and TriggerFunction resource fail on subsequent deployments. maybe incorrect serialization of timeout? #30861

Closed
sebastianplesciuc opened this issue Jul 15, 2024 · 6 comments
Labels
@aws-cdk/triggers Related to the triggers package bug This issue is a bug. needs-triage This issue or PR still needs to be triaged.

Comments

@sebastianplesciuc
Copy link

sebastianplesciuc commented Jul 15, 2024

Describe the bug

The Trigger custom resource in CDK causes a CloudFormation error when trying to deploy. This seems to be because we're using a String value for a Number field but the error is not clear on which fields.

CloudFormation error on the PostDeploymentHandlerTrigger7245B54D Trigger resource with CREATE_FAILED:

Received response status [FAILED] from custom resource. Message returned: Error: NUMBER_VALUE can not be converted to a String SerializationException: NUMBER_VALUE can not be converted to a String, at throwDefaultError (/var/task/index.js:42:5084), at /var/task/index.js:42:5251, at de_CommandError (/var/task/index.js:73:155469), at process.processTicksAndRejections (node:internal/process/task_queues:95:5), at async /var/task/index.js:31:11378, at async /var/task/index.js:32:9394, at async /var/task/index.js:42:15907, at async /var/task/index.js:30:508546, at async bb.execute (/var/task/index.js:74:18032), at async Runtime.XUt [as handler] (/var/task/index.js:74:18374) at P (/var/task/index.js:1:1756) at process.processTicksAndRejections (node:internal/process/task_queues:95:5) at async Runtime.handler (/var/task/__entrypoint__.js:1:932) (RequestId: f5c1b14b-eea4-4862-8fda-9568d5cce4df)

Looking at the template JSON file:

  "PostDeploymentHandlerTrigger7245B54D": {
   "Type": "Custom::Trigger",
   "Properties": {
    "ServiceToken": {
     "Fn::GetAtt": [
      "AWSCDKTriggerCustomResourceProviderCustomResourceProviderHandler97BECD91",
      "Arn"
     ]
    },
    "HandlerArn": {
     "Ref": "PostDeploymentHandlerCurrentVersion0ABAF863ee3b74d8952aafc71fa7460e67144692"
    },
    "InvocationType": "RequestResponse",
    "Timeout": "900000", 
    "ExecuteOnHandlerChange": true
   },
   "UpdateReplacePolicy": "Delete",
   "DeletionPolicy": "Delete",
   "Metadata": {
    "aws:cdk:path": "REDACTED"
   }
  },

When compared to other resources like:

"AWSCDKTriggerCustomResourceProviderCustomResourceProviderHandler97BECD91": {
   "Type": "AWS::Lambda::Function",
   "Properties": {
    "Code": {
     "S3Bucket": {
      "Fn::Sub": "cdk-ff31197769-assets-${AWS::AccountId}-eu-west-2"
     },
     "S3Key": "redacted.zip"
    },
    "Timeout": 900, 
    "MemorySize": 128,
    "Handler": "__entrypoint__.handler",
    "Role": {
     "Fn::GetAtt": [
      "AWSCDKTriggerCustomResourceProviderCustomResourceProviderRoleE18FAF0A",
      "Arn"
     ]
    },
    "Runtime": "nodejs20.x"
   },
   "DependsOn": [
    "AWSCDKTriggerCustomResourceProviderCustomResourceProviderRoleE18FAF0A"
   ],
   "Metadata": {
    "aws:cdk:path": "REDACTED",
    "aws:asset:path": "../REDACTED",
    "aws:asset:property": "Code"
   }
  },

Seems to be because of toString usage here:

Timeout: props.timeout?.toMilliseconds().toString() ?? Duration.minutes(2).toMilliseconds().toString(),

It's also strange because the first time the deployment ran successfully.

Expected Behavior

Template file contains number for timeout instead of string. Deployment succeeds. Function is triggered.

Current Behavior

Deployment failed with CloudFormation Error:

Received response status [FAILED] from custom resource. Message returned: Error: NUMBER_VALUE can not be converted to a String SerializationException: NUMBER_VALUE can not be converted to a String, at throwDefaultError (/var/task/index.js:42:5084), at /var/task/index.js:42:5251, at de_CommandError (/var/task/index.js:73:155469), at process.processTicksAndRejections (node:internal/process/task_queues:95:5), at async /var/task/index.js:31:11378, at async /var/task/index.js:32:9394, at async /var/task/index.js:42:15907, at async /var/task/index.js:30:508546, at async bb.execute (/var/task/index.js:74:18032), at async Runtime.XUt [as handler] (/var/task/index.js:74:18374) at P (/var/task/index.js:1:1756) at process.processTicksAndRejections (node:internal/process/task_queues:95:5) at async Runtime.handler (/var/task/__entrypoint__.js:1:932) (RequestId: f5c1b14b-eea4-4862-8fda-9568d5cce4df)

Reproduction Steps

import { TriggerFunction } from 'aws-cdk-lib/triggers';
import { Duration } from 'aws-cdk-lib';
import { Code, Runtime } from 'aws-cdk-lib/aws-lambda';

new TriggerFunction(this, 'testHandler', {
      functionName: 'test',
      code: Code.fromInline('console.log("here")'),
      timeout: Duration.minutes(15),
      runtime: Runtime.NODEJS_20_X,
      environment: {
        // The timestamp causes a configuration change such that the function is executed every time the stack is updated.
        APP_DEPLOYMENT_TIMESTAMP: new Date().toISOString(),
      },
      executeOnHandlerChange: true, // Explicitly execute when code or config changes for the handler
    });

Possible Solution

Potentially, if the timeout field is the issue, fix it such that it's synthesized with a number instead of a string for the timeout field.

Additional Information/Context

No response

CDK CLI Version

2.149.0 (build c8e5924)

Framework Version

2.149.0

Node.js Version

20

OS

MacOS Sonoma 14.5 (23F79)

Language

TypeScript

Language Version

5.0.4

Other information

No response

@sebastianplesciuc sebastianplesciuc added bug This issue is a bug. needs-triage This issue or PR still needs to be triaged. labels Jul 15, 2024
@github-actions github-actions bot added the @aws-cdk/triggers Related to the triggers package label Jul 15, 2024
@sebastianplesciuc
Copy link
Author

sebastianplesciuc commented Jul 15, 2024

Now looking at it, the timeout thing seems to be a red herring.

It is a parameter to the Trigger Custom Resource handler and looking at the mangled code for it (because i can't find it elsewhere) parses it to an integer: n=parseInt(t); if(isNaN(n))throw new Error(The "Timeout" property with value ${t} is not parsable to a number);.

I really can't tell what's causing CloudFormation to output that error.

@sebastianplesciuc
Copy link
Author

Founds the logs:

{
  invokeRequest: {
    FunctionName: 'arn:aws:lambda:eu-west-2:<REDACTED>:function:<REDACTED>-PostDeployment:12',
    InvocationType: 'RequestResponse'
  }
}
{
  invokeResponse: {
    '$metadata': {
      httpStatusCode: 200,
      requestId: '4cbc5040-d804-425c-bb1c-d6b950ec7b8b',
      extendedRequestId: undefined,
      cfId: undefined,
      attempts: 2,
      totalRetryDelay: 24
    },
    FunctionError: 'Unhandled',
    ExecutedVersion: '12',
    Payload: '{"errorType":"SerializationException","errorMessage":"NUMBER_VALUE can not be converted to a String","trace":["SerializationException: NUMBER_VALUE can not be converted to a String","    at throwDefaultError (/var/task/index.js:42:5084)","    at /var/task/index.js:42:5251","    at de_CommandError (/var/task/index.js:73:155469)","    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)","    at async /var/task/index.js:31:11378","    at async /var/task/index.js:32:9394","    at async /var/task/index.js:42:15907","    at async /var/task/index.js:30:508546","    at async bb.execute (/var/task/index.js:74:18032)","    at async Runtime.XUt [as handler] (/var/task/index.js:74:18374)"]}',
    StatusCode: 200
  }
{
    "errorType": "SerializationException",
    "errorMessage": "NUMBER_VALUE can not be converted to a String",
    "trace": [
        "SerializationException: NUMBER_VALUE can not be converted to a String",
        "    at throwDefaultError (/var/task/index.js:42:5084)",
        "    at /var/task/index.js:42:5251",
        "    at de_CommandError (/var/task/index.js:73:155469)",
        "    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)",
        "    at async /var/task/index.js:31:11378",
        "    at async /var/task/index.js:32:9394",
        "    at async /var/task/index.js:42:15907",
        "    at async /var/task/index.js:30:508546",
        "    at async bb.execute (/var/task/index.js:74:18032)",
        "    at async Runtime.XUt [as handler] (/var/task/index.js:74:18374)"
    ]
}

@sebastianplesciuc
Copy link
Author

sebastianplesciuc commented Jul 15, 2024

Resource re-creation also does not seem to work. But roll-back seems to work fine. Also, deletion worked.

@sebastianplesciuc
Copy link
Author

sebastianplesciuc commented Jul 16, 2024

Well, this was completely my fault. An API Call to UpdateFunctionConfigurationCommand was sent from within the handler that was failing because an Env var was number, not string.

Copy link

⚠️COMMENT VISIBILITY WARNING⚠️

Comments on closed issues are hard for our team to see.
If you need more assistance, please either tag a team member or open a new issue that references this one.
If you wish to keep having a conversation with other community members under this issue feel free to do so.

@aws-cdk-automation
Copy link
Collaborator

Comments on closed issues and PRs are hard for our team to see. If you need help, please open a new issue that references this one.

@aws aws locked as resolved and limited conversation to collaborators Jul 25, 2024
# for free to subscribe to this conversation on GitHub. Already have an account? #.
Labels
@aws-cdk/triggers Related to the triggers package bug This issue is a bug. needs-triage This issue or PR still needs to be triaged.
Projects
None yet
Development

No branches or pull requests

2 participants