Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

chore(integ-test-alpha): add log group retention days to integ test stack #29277

Merged
merged 7 commits into from
Mar 15, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions packages/@aws-cdk/integ-tests-alpha/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -439,6 +439,28 @@ invoke.expect(ExpectedResult.objectLike({
}));
```

The above example will by default create a CloudWatch log group that's never
expired. If you want to configure it with custom log retention days, you need
to specify the `logRenteion` property.
GavinZZ marked this conversation as resolved.
Show resolved Hide resolved

```ts
import * as logs from 'aws-cdk-lib/aws-logs';

declare const lambdaFunction: lambda.IFunction;
declare const app: App;

const stack = new Stack(app, 'cdk-integ-lambda-bundling');

const integ = new IntegTest(app, 'IntegTest', {
testCases: [stack],
});

const invoke = integ.assertions.invokeFunction({
functionName: lambdaFunction.functionName,
logRetention: logs.RetentionDays.ONE_WEEK,
});
```

#### Make an AWS API Call

In this example there is a StepFunctions state machine that is executed
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import * as path from 'path';
import { Duration, CfnResource, AssetStaging, Stack, FileAssetPackaging, Token, Lazy, Reference } from 'aws-cdk-lib/core';
import { Construct } from 'constructs';
import { awsSdkToIamAction } from 'aws-cdk-lib/custom-resources/lib/helpers-internal';
import { RetentionDays } from 'aws-cdk-lib/aws-logs';

/**
* Properties for a lambda function provider
Expand All @@ -13,6 +14,13 @@ export interface LambdaFunctionProviderProps {
* @default index.handler
*/
readonly handler?: string;

/**
* How long, in days, the log contents will be retained.
*
* @default - no retention days specified
GavinZZ marked this conversation as resolved.
Show resolved Hide resolved
*/
readonly logRetention?: RetentionDays;
}

/**
Expand Down Expand Up @@ -75,29 +83,34 @@ class LambdaFunctionProvider extends Construct {
},
});

const logGroup = new CfnResource(this, 'LogGroup', {
type: 'AWS::Logs::LogGroup',
properties: {
LogGroupName: `/aws/lambda/${id}`,
RetentionInDays: '14',
const functionProperties: any = {
Runtime: 'nodejs18.x',
Code: {
S3Bucket: asset.bucketName,
S3Key: asset.objectKey,
},
});
Timeout: Duration.minutes(2).toSeconds(),
Handler: props?.handler ?? 'index.handler',
Role: role.getAtt('Arn'),
};

if (props?.logRetention) {
const logGroup = new CfnResource(this, 'LogGroup', {
type: 'AWS::Logs::LogGroup',
properties: {
LogGroupName: `/aws/lambda/${id}`,
RetentionInDays: props.logRetention,
},
});

functionProperties.LoggingConfig = {
LogGroup: logGroup.ref,
};
}

const handler = new CfnResource(this, 'Handler', {
type: 'AWS::Lambda::Function',
properties: {
Runtime: 'nodejs18.x',
Code: {
S3Bucket: asset.bucketName,
S3Key: asset.objectKey,
},
Timeout: Duration.minutes(2).toSeconds(),
Handler: props?.handler ?? 'index.handler',
Role: role.getAtt('Arn'),
LoggingConfig: {
LogGroup: logGroup.ref,
},
},
properties: functionProperties,
});

this.serviceToken = Token.asString(handler.getAtt('Arn'));
Expand All @@ -118,6 +131,13 @@ interface SingletonFunctionProps extends LambdaFunctionProviderProps {
* We recommend generating a UUID per provider.
*/
readonly uuid: string;

/**
* How long, in days, the log contents will be retained.
*
* @default - no retention days specified
*/
readonly logRetention?: RetentionDays;
GavinZZ marked this conversation as resolved.
Show resolved Hide resolved
}

/**
Expand All @@ -142,6 +162,7 @@ class SingletonFunction extends Construct {

return new LambdaFunctionProvider(Stack.of(this), constructName, {
handler: props.handler,
logRetention: props.logRetention,
});
}

Expand Down Expand Up @@ -215,6 +236,7 @@ export class AssertionsProvider extends Construct {
this.handler = new SingletonFunction(this, 'AssertionsProvider', {
handler: props?.handler,
uuid: props?.uuid ?? '1488541a-7b23-4664-81b6-9b4408076b81',
logRetention: props?.logRetention,
});

this.handlerRoleArn = this.handler.lambdaFunction.roleArn;
Expand Down
13 changes: 12 additions & 1 deletion packages/@aws-cdk/integ-tests-alpha/lib/assertions/sdk.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { ApiCallBase, IApiCall } from './api-call-base';
import { ExpectedResult } from './common';
import { AssertionsProvider, SDK_RESOURCE_TYPE_PREFIX } from './providers';
import { WaiterStateMachine, WaiterStateMachineOptions } from './waiter-state-machine';
import { RetentionDays } from 'aws-cdk-lib/aws-logs';

/**
* Options to perform an AWS JavaScript V2 API call
Expand Down Expand Up @@ -75,7 +76,9 @@ export class AwsApiCall extends ApiCallBase {
constructor(scope: Construct, id: string, props: AwsApiCallProps) {
super(scope, id);

this.provider = new AssertionsProvider(this, 'SdkProvider');
this.provider = new AssertionsProvider(this, 'SdkProvider', {
logRetention: props.parameters?.RetentionDays,
});
this.provider.addPolicyStatementFromSdkCall(props.service, props.api);
this.name = `${props.service}${props.api}`;
this.api = props.api;
Expand Down Expand Up @@ -210,6 +213,13 @@ export interface LambdaInvokeFunctionProps {
*/
readonly logType?: LogType;

/**
* How long, in days, the log contents will be retained.
*
* @default - no retention days specified
*/
readonly logRetention?: RetentionDays;

/**
* Payload to send as part of the invoke
*
Expand All @@ -234,6 +244,7 @@ export class LambdaInvokeFunction extends AwsApiCall {
InvocationType: props.invocationType,
LogType: props.logType,
Payload: props.payload,
RetentionDays: props.logRetention,
},
});

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { Template } from 'aws-cdk-lib/assertions';
import { Stack } from 'aws-cdk-lib';
import { AssertionsProvider } from '../../../lib/assertions';
import { RetentionDays } from 'aws-cdk-lib/aws-logs';

let stack: Stack;
beforeEach(() => {
Expand All @@ -20,6 +21,25 @@ describe('AssertionProvider', () => {
});
});

test('default', () => {
// WHEN
const provider = new AssertionsProvider(stack, 'AssertionProvider', {
logRetention: RetentionDays.ONE_WEEK,
});

// THEN
const template = Template.fromStack(stack);
template.resourceCountIs('AWS::Logs::LogGroup', 1);
expect(stack.resolve(provider.serviceToken)).toEqual({ 'Fn::GetAtt': ['SingletonFunction1488541a7b23466481b69b4408076b81HandlerCD40AE9F', 'Arn'] });
Template.fromStack(stack).hasResourceProperties('AWS::Lambda::Function', {
Handler: 'index.handler',
Timeout: 120,
});
template.hasResourceProperties('AWS::Logs::LogGroup', {
RetentionInDays: 7,
});
});

describe('addPolicyStatementForSdkCall', () => {
test('default', () => {
// WHEN
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,11 @@ describe('AwsApiCall', () => {
// THEN
const template = Template.fromStack(deplossert.scope);
template.resourceCountIs('AWS::Lambda::Function', 1);
template.resourceCountIs('AWS::Logs::LogGroup', 1);
template.hasResourceProperties('Custom::DeployAssert@SdkCallMyServiceMyApi', {
service: 'MyService',
api: 'MyApi',
parameters: Match.absent(),
});
template.hasResourceProperties('AWS::Logs::LogGroup', {
RetentionInDays: '14',
});
});

test('parameters', () => {
Expand Down
Loading