From e835ac654b30429eae682a18833c0b522d6568b5 Mon Sep 17 00:00:00 2001 From: go-to-k <24818752+go-to-k@users.noreply.github.com> Date: Fri, 21 Feb 2025 16:44:48 +0900 Subject: [PATCH 1/4] fix(core): serviceTimeout for CustomResource does not work with token --- .../aws-cdk-lib/core/lib/custom-resource.ts | 3 +- .../core/test/custom-resource.test.ts | 40 ++++++++++++++++++- 2 files changed, 40 insertions(+), 3 deletions(-) diff --git a/packages/aws-cdk-lib/core/lib/custom-resource.ts b/packages/aws-cdk-lib/core/lib/custom-resource.ts index d5a8bb5d78d73..811a7996df590 100644 --- a/packages/aws-cdk-lib/core/lib/custom-resource.ts +++ b/packages/aws-cdk-lib/core/lib/custom-resource.ts @@ -154,8 +154,7 @@ export class CustomResource extends Resource { const pascalCaseProperties = props.pascalCaseProperties ?? false; const properties = pascalCaseProperties ? uppercaseProperties(props.properties || {}) : (props.properties || {}); - if (props.serviceTimeout !== undefined && !Token.isUnresolved(props.serviceTimeout) - ) { + if (props.serviceTimeout !== undefined && !props.serviceTimeout.isUnresolved()) { const serviceTimeoutSeconds = props.serviceTimeout.toSeconds(); if (serviceTimeoutSeconds < 1 || serviceTimeoutSeconds > 3600) { diff --git a/packages/aws-cdk-lib/core/test/custom-resource.test.ts b/packages/aws-cdk-lib/core/test/custom-resource.test.ts index 3334a0782c296..817d0b8867e7c 100644 --- a/packages/aws-cdk-lib/core/test/custom-resource.test.ts +++ b/packages/aws-cdk-lib/core/test/custom-resource.test.ts @@ -1,6 +1,6 @@ import { toCloudFormation } from './util'; import { Annotations } from '../../assertions'; -import { CustomResource, Duration, RemovalPolicy, Stack } from '../lib'; +import { CfnParameter, CustomResource, Duration, RemovalPolicy, Stack } from '../lib'; describe('custom resource', () => { test('simple case provider identified by service token', () => { @@ -201,6 +201,44 @@ describe('custom resource', () => { }); }); + test('set serviceTimeout with token', () => { + // GIVEN + const stack = new Stack(); + const durToken = new CfnParameter(stack, 'MyParameter', { + type: 'Number', + default: 60, + }); + + // WHEN + new CustomResource(stack, 'MyCustomResource', { + serviceToken: 'MyServiceToken', + serviceTimeout: Duration.seconds(durToken.valueAsNumber), + }); + + // THEN + expect(toCloudFormation(stack)).toEqual({ + Parameters: { + MyParameter: { + Default: 60, + Type: 'Number', + }, + }, + Resources: { + MyCustomResource: { + Type: 'AWS::CloudFormation::CustomResource', + Properties: { + ServiceToken: 'MyServiceToken', + ServiceTimeout: { + Ref: 'MyParameter', + }, + }, + UpdateReplacePolicy: 'Delete', + DeletionPolicy: 'Delete', + }, + }, + }); + }); + test.each([0, 4000])('throw an error when serviceTimeout is set to %d seconds.', (invalidSeconds: number) => { // GIVEN const stack = new Stack(); From 75e52619cd09f363882ff62561a53cd5cd79ab30 Mon Sep 17 00:00:00 2001 From: go-to-k <24818752+go-to-k@users.noreply.github.com> Date: Fri, 21 Feb 2025 17:06:08 +0900 Subject: [PATCH 2/4] add doc and tests for the type of duration --- .../aws-cdk-lib/core/lib/custom-resource.ts | 2 ++ .../core/test/custom-resource.test.ts | 19 ++++++++++++++++++- 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/packages/aws-cdk-lib/core/lib/custom-resource.ts b/packages/aws-cdk-lib/core/lib/custom-resource.ts index 811a7996df590..5274ebc2b60b0 100644 --- a/packages/aws-cdk-lib/core/lib/custom-resource.ts +++ b/packages/aws-cdk-lib/core/lib/custom-resource.ts @@ -65,6 +65,8 @@ export interface CustomResourceProps { * * The value must be between 1 second and 3600 seconds. * + * A token can be specified for this property, but it must be specified with `Duration.seconds()`. + * * Maps to [ServiceTimeout](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-cloudformation-customresource.html#cfn-cloudformation-customresource-servicetimeout) property for the `AWS::CloudFormation::CustomResource` resource * * @default Duration.seconds(3600) diff --git a/packages/aws-cdk-lib/core/test/custom-resource.test.ts b/packages/aws-cdk-lib/core/test/custom-resource.test.ts index 817d0b8867e7c..ac2df44be15b5 100644 --- a/packages/aws-cdk-lib/core/test/custom-resource.test.ts +++ b/packages/aws-cdk-lib/core/test/custom-resource.test.ts @@ -201,7 +201,7 @@ describe('custom resource', () => { }); }); - test('set serviceTimeout with token', () => { + test('set serviceTimeout with token as seconds', () => { // GIVEN const stack = new Stack(); const durToken = new CfnParameter(stack, 'MyParameter', { @@ -239,6 +239,23 @@ describe('custom resource', () => { }); }); + test('throws error when serviceTimeout is set with token as units other than seconds', () => { + // GIVEN + const stack = new Stack(); + const durToken = new CfnParameter(stack, 'MyParameter', { + type: 'Number', + default: 60, + }); + + // WHEN + expect(() => { + new CustomResource(stack, 'MyCustomResource', { + serviceToken: 'MyServiceToken', + serviceTimeout: Duration.minutes(durToken.valueAsNumber), + }); + }).toThrow('Duration must be specified as \'Duration.seconds()\' here since its value comes from a token and cannot be converted (got Duration.minutes)'); + }); + test.each([0, 4000])('throw an error when serviceTimeout is set to %d seconds.', (invalidSeconds: number) => { // GIVEN const stack = new Stack(); From 965f8af9928ab257ada2e9a464d8e6d484e61b5d Mon Sep 17 00:00:00 2001 From: go-to-k <24818752+go-to-k@users.noreply.github.com> Date: Fri, 21 Feb 2025 17:22:03 +0900 Subject: [PATCH 3/4] example --- packages/aws-cdk-lib/core/lib/custom-resource.ts | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/packages/aws-cdk-lib/core/lib/custom-resource.ts b/packages/aws-cdk-lib/core/lib/custom-resource.ts index 5274ebc2b60b0..091accaf56309 100644 --- a/packages/aws-cdk-lib/core/lib/custom-resource.ts +++ b/packages/aws-cdk-lib/core/lib/custom-resource.ts @@ -65,9 +65,19 @@ export interface CustomResourceProps { * * The value must be between 1 second and 3600 seconds. * + * Maps to [ServiceTimeout](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-cloudformation-customresource.html#cfn-cloudformation-customresource-servicetimeout) property for the `AWS::CloudFormation::CustomResource` resource + * * A token can be specified for this property, but it must be specified with `Duration.seconds()`. * - * Maps to [ServiceTimeout](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-cloudformation-customresource.html#cfn-cloudformation-customresource-servicetimeout) property for the `AWS::CloudFormation::CustomResource` resource + * @example + * const durToken = new CfnParameter(stack, 'MyParameter', { + * type: 'Number', + * default: 60, + * }); + * new CustomResource(stack, 'MyCustomResource', { + * serviceToken: 'MyServiceToken', + * serviceTimeout: Duration.seconds(durToken.valueAsNumber), + * }); * * @default Duration.seconds(3600) */ From 7fa7e16561ade3293221ce737ce1da61fdebf541 Mon Sep 17 00:00:00 2001 From: "Kenta Goto (k.goto)" <24818752+go-to-k@users.noreply.github.com> Date: Fri, 21 Feb 2025 17:54:46 +0900 Subject: [PATCH 4/4] Update custom-resource.ts --- packages/aws-cdk-lib/core/lib/custom-resource.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/aws-cdk-lib/core/lib/custom-resource.ts b/packages/aws-cdk-lib/core/lib/custom-resource.ts index 091accaf56309..25ba85793394c 100644 --- a/packages/aws-cdk-lib/core/lib/custom-resource.ts +++ b/packages/aws-cdk-lib/core/lib/custom-resource.ts @@ -70,6 +70,7 @@ export interface CustomResourceProps { * A token can be specified for this property, but it must be specified with `Duration.seconds()`. * * @example + * const stack = new Stack(); * const durToken = new CfnParameter(stack, 'MyParameter', { * type: 'Number', * default: 60,