diff --git a/packages/@aws-cdk/custom-resources/README.md b/packages/@aws-cdk/custom-resources/README.md index 13cd4a4002fe3..e75d619a7875e 100644 --- a/packages/@aws-cdk/custom-resources/README.md +++ b/packages/@aws-cdk/custom-resources/README.md @@ -380,6 +380,19 @@ Since a successful resource provisioning might or might not produce outputs, thi In both the cases, you will get a synth time error if you attempt to use it in conjunction with `ignoreErrorCodesMatching`. +### Customizing the Lambda function implementing the custom resource +Use the `role`, `timeout` and `logRetention` properties to customize the Lambda function implementing the custom +resource: + +```ts +new AwsCustomResource(this, 'Customized', { + // other props here + role: myRole, // must be assumable by the `lambda.amazonaws.com` service principal + timeout: cdk.Duration.minutes(10) // defaults to 2 minutes + logRetention: logs.RetentionDays.ONE_WEEK // defaults to never delete logs +}) +``` + ### Examples #### Verify a domain with SES diff --git a/packages/@aws-cdk/custom-resources/lib/aws-custom-resource/aws-custom-resource.ts b/packages/@aws-cdk/custom-resources/lib/aws-custom-resource/aws-custom-resource.ts index 881954c056e97..e0ea2b0d06199 100644 --- a/packages/@aws-cdk/custom-resources/lib/aws-custom-resource/aws-custom-resource.ts +++ b/packages/@aws-cdk/custom-resources/lib/aws-custom-resource/aws-custom-resource.ts @@ -1,6 +1,7 @@ import { CustomResource, CustomResourceProvider } from '@aws-cdk/aws-cloudformation'; import * as iam from '@aws-cdk/aws-iam'; import * as lambda from '@aws-cdk/aws-lambda'; +import * as logs from '@aws-cdk/aws-logs'; import * as cdk from '@aws-cdk/core'; import * as fs from 'fs'; import * as path from 'path'; @@ -235,6 +236,14 @@ export interface AwsCustomResourceProps { * @default Duration.minutes(2) */ readonly timeout?: cdk.Duration + + /** + * The number of days log events of the Lambda function implementing + * this custom resource are kept in CloudWatch Logs. + * + * @default logs.RetentionDays.INFINITE + */ + readonly logRetention?: logs.RetentionDays; } /** @@ -292,6 +301,7 @@ export class AwsCustomResource extends cdk.Construct implements iam.IGrantable { lambdaPurpose: 'AWS', timeout: props.timeout || cdk.Duration.minutes(2), role: props.role, + logRetention: props.logRetention, }); this.grantPrincipal = provider.grantPrincipal; diff --git a/packages/@aws-cdk/custom-resources/package.json b/packages/@aws-cdk/custom-resources/package.json index 38264cb2ad94a..b5c1ee73f71c9 100644 --- a/packages/@aws-cdk/custom-resources/package.json +++ b/packages/@aws-cdk/custom-resources/package.json @@ -87,6 +87,7 @@ "@aws-cdk/aws-cloudformation": "0.0.0", "@aws-cdk/aws-iam": "0.0.0", "@aws-cdk/aws-lambda": "0.0.0", + "@aws-cdk/aws-logs": "0.0.0", "@aws-cdk/aws-sns": "0.0.0", "@aws-cdk/aws-stepfunctions": "0.0.0", "@aws-cdk/aws-stepfunctions-tasks": "0.0.0", @@ -97,6 +98,7 @@ "@aws-cdk/aws-cloudformation": "0.0.0", "@aws-cdk/aws-iam": "0.0.0", "@aws-cdk/aws-lambda": "0.0.0", + "@aws-cdk/aws-logs": "0.0.0", "@aws-cdk/aws-sns": "0.0.0", "@aws-cdk/aws-stepfunctions": "0.0.0", "@aws-cdk/aws-stepfunctions-tasks": "0.0.0", diff --git a/packages/@aws-cdk/custom-resources/test/aws-custom-resource/aws-custom-resource.test.ts b/packages/@aws-cdk/custom-resources/test/aws-custom-resource/aws-custom-resource.test.ts index 27e3b89311703..4f5dcc5ec34d0 100644 --- a/packages/@aws-cdk/custom-resources/test/aws-custom-resource/aws-custom-resource.test.ts +++ b/packages/@aws-cdk/custom-resources/test/aws-custom-resource/aws-custom-resource.test.ts @@ -1,5 +1,6 @@ import '@aws-cdk/assert/jest'; import * as iam from '@aws-cdk/aws-iam'; +import * as logs from '@aws-cdk/aws-logs'; import * as cdk from '@aws-cdk/core'; import { AwsCustomResource, AwsCustomResourcePolicy, PhysicalResourceId } from '../../lib'; @@ -488,3 +489,35 @@ test('getDataString', () => { } }); }); + +test('can specify log retention', () => { + // GIVEN + const stack = new cdk.Stack(); + + // WHEN + new AwsCustomResource(stack, 'AwsSdk', { + onCreate: { + service: 'service', + action: 'action', + physicalResourceId: PhysicalResourceId.of('id') + }, + logRetention: logs.RetentionDays.ONE_WEEK, + policy: AwsCustomResourcePolicy.fromSdkCalls({ resources: AwsCustomResourcePolicy.ANY_RESOURCE }) + }); + + // THEN + expect(stack).toHaveResource('Custom::LogRetention', { + LogGroupName: { + 'Fn::Join': [ + '', + [ + '/aws/lambda/', + { + Ref: 'AWS679f53fac002430cb0da5b7982bd22872D164C4C' + } + ] + ] + }, + RetentionInDays: 7 + }); +});