Skip to content

Commit 53877bb

Browse files
authored
feat: add CloudWatch LogGroup with retention policy to Lambda functions (#117)
## Summary Add explicit CDK-managed CloudWatch LogGroups with 1-week retention to all Lambda functions to prevent unbounded log storage costs. ## Problem Without explicit LogGroup configuration, Lambda auto-creates LogGroups with infinite retention. As logs accumulate, storage costs grow without bound. ## Changes Added `LogGroup` with `RetentionDays.ONE_WEEK` and `RemovalPolicy.DESTROY` to: | Construct | Lambda | File | |-----------|--------|------| | Webapp | Handler | `cdk/lib/constructs/webapp.ts` | | Webapp | MigrationRunner | `cdk/lib/constructs/webapp.ts` | | AsyncJob | Handler | `cdk/lib/constructs/async-job.ts` | CDK test snapshots updated accordingly. ## Out of scope Lambda@Edge (SignPayload) is excluded — edge-region LogGroups cannot be managed by CDK and will become unnecessary after #66. Closes #103
1 parent 03c5a00 commit 53877bb

File tree

4 files changed

+94
-2
lines changed

4 files changed

+94
-2
lines changed

cdk/lib/constructs/async-job.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { Construct } from 'constructs';
2-
import { CfnOutput, Duration, TimeZone } from 'aws-cdk-lib';
2+
import { CfnOutput, Duration, RemovalPolicy, TimeZone } from 'aws-cdk-lib';
3+
import { LogGroup, RetentionDays } from 'aws-cdk-lib/aws-logs';
34
import { Architecture, DockerImageCode, DockerImageFunction, IFunction } from 'aws-cdk-lib/aws-lambda';
45
import { Platform } from 'aws-cdk-lib/aws-ecr-assets';
56
import { Database } from './database';
@@ -37,6 +38,10 @@ export class AsyncJob extends Construct {
3738
vpc: database.cluster.vpc,
3839
// limit concurrency to mitigate any possible EDoS attacks
3940
reservedConcurrentExecutions: 1,
41+
logGroup: new LogGroup(this, 'HandlerLogs', {
42+
retention: RetentionDays.ONE_WEEK,
43+
removalPolicy: RemovalPolicy.DESTROY,
44+
}),
4045
});
4146

4247
handler.connections.allowToDefaultPort(database);

cdk/lib/constructs/webapp.ts

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
import { IgnoreMode, Duration, CfnOutput, Stack } from 'aws-cdk-lib';
1+
import { IgnoreMode, Duration, CfnOutput, Stack, RemovalPolicy } from 'aws-cdk-lib';
2+
import { LogGroup, RetentionDays } from 'aws-cdk-lib/aws-logs';
23
import { Platform } from 'aws-cdk-lib/aws-ecr-assets';
34
import { DockerImageFunction, DockerImageCode, Architecture } from 'aws-cdk-lib/aws-lambda';
45
import { Construct } from 'constructs';
@@ -84,6 +85,10 @@ export class Webapp extends Construct {
8485
vpc: database.cluster.vpc,
8586
memorySize: 1024,
8687
architecture: Architecture.ARM_64,
88+
logGroup: new LogGroup(this, 'HandlerLogs', {
89+
retention: RetentionDays.ONE_WEEK,
90+
removalPolicy: RemovalPolicy.DESTROY,
91+
}),
8792
});
8893
handler.connections.allowToDefaultPort(database);
8994
asyncJob.handler.grantInvoke(handler);
@@ -154,6 +159,10 @@ export class Webapp extends Construct {
154159
},
155160
vpc: database.cluster.vpc,
156161
memorySize: 256,
162+
logGroup: new LogGroup(this, 'MigrationRunnerLogs', {
163+
retention: RetentionDays.ONE_WEEK,
164+
removalPolicy: RemovalPolicy.DESTROY,
165+
}),
157166
});
158167
migrationRunner.connections.allowToDefaultPort(database);
159168

cdk/test/__snapshots__/serverless-fullstack-webapp-starter-kit-without-domain.test.ts.snap

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -809,6 +809,11 @@ exports[`Snapshot test 2`] = `
809809
"async-job-runner.handler",
810810
],
811811
},
812+
"LoggingConfig": {
813+
"LogGroup": {
814+
"Ref": "AsyncJobHandlerLogs20DFEE3E",
815+
},
816+
},
812817
"MemorySize": 256,
813818
"PackageType": "Image",
814819
"ReservedConcurrentExecutions": 1,
@@ -843,6 +848,14 @@ exports[`Snapshot test 2`] = `
843848
},
844849
"Type": "AWS::Lambda::Function",
845850
},
851+
"AsyncJobHandlerLogs20DFEE3E": {
852+
"DeletionPolicy": "Delete",
853+
"Properties": {
854+
"RetentionInDays": 7,
855+
},
856+
"Type": "AWS::Logs::LogGroup",
857+
"UpdateReplacePolicy": "Delete",
858+
},
846859
"AsyncJobHandlerSecurityGroupF59812E6": {
847860
"DependsOn": [
848861
"VpcPrivateSubnet1DefaultRouteBE02A9ED",
@@ -3466,6 +3479,11 @@ service iptables save",
34663479
},
34673480
},
34683481
},
3482+
"LoggingConfig": {
3483+
"LogGroup": {
3484+
"Ref": "WebappHandlerLogs87A6D2D7",
3485+
},
3486+
},
34693487
"MemorySize": 1024,
34703488
"PackageType": "Image",
34713489
"Role": {
@@ -3536,6 +3554,14 @@ service iptables save",
35363554
},
35373555
"Type": "AWS::Lambda::Url",
35383556
},
3557+
"WebappHandlerLogs87A6D2D7": {
3558+
"DeletionPolicy": "Delete",
3559+
"Properties": {
3560+
"RetentionInDays": 7,
3561+
},
3562+
"Type": "AWS::Logs::LogGroup",
3563+
"UpdateReplacePolicy": "Delete",
3564+
},
35393565
"WebappHandlerSecurityGroup5451B519": {
35403566
"DependsOn": [
35413567
"VpcPrivateSubnet1DefaultRouteBE02A9ED",
@@ -3829,6 +3855,11 @@ service iptables save",
38293855
"migration-runner.handler",
38303856
],
38313857
},
3858+
"LoggingConfig": {
3859+
"LogGroup": {
3860+
"Ref": "WebappMigrationRunnerLogsD9A84B90",
3861+
},
3862+
},
38323863
"MemorySize": 256,
38333864
"PackageType": "Image",
38343865
"Role": {
@@ -3878,6 +3909,14 @@ service iptables save",
38783909
},
38793910
"Type": "AWS::Lambda::Version",
38803911
},
3912+
"WebappMigrationRunnerLogsD9A84B90": {
3913+
"DeletionPolicy": "Delete",
3914+
"Properties": {
3915+
"RetentionInDays": 7,
3916+
},
3917+
"Type": "AWS::Logs::LogGroup",
3918+
"UpdateReplacePolicy": "Delete",
3919+
},
38813920
"WebappMigrationRunnerSecurityGroup7F0DF264": {
38823921
"DependsOn": [
38833922
"VpcPrivateSubnet1DefaultRouteBE02A9ED",

cdk/test/__snapshots__/serverless-fullstack-webapp-starter-kit.test.ts.snap

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -830,6 +830,11 @@ exports[`Snapshot test 2`] = `
830830
"async-job-runner.handler",
831831
],
832832
},
833+
"LoggingConfig": {
834+
"LogGroup": {
835+
"Ref": "AsyncJobHandlerLogs20DFEE3E",
836+
},
837+
},
833838
"MemorySize": 256,
834839
"PackageType": "Image",
835840
"ReservedConcurrentExecutions": 1,
@@ -864,6 +869,14 @@ exports[`Snapshot test 2`] = `
864869
},
865870
"Type": "AWS::Lambda::Function",
866871
},
872+
"AsyncJobHandlerLogs20DFEE3E": {
873+
"DeletionPolicy": "Delete",
874+
"Properties": {
875+
"RetentionInDays": 7,
876+
},
877+
"Type": "AWS::Logs::LogGroup",
878+
"UpdateReplacePolicy": "Delete",
879+
},
867880
"AsyncJobHandlerSecurityGroupF59812E6": {
868881
"DependsOn": [
869882
"VpcPrivateSubnet1DefaultRouteBE02A9ED",
@@ -3296,6 +3309,11 @@ service iptables save",
32963309
},
32973310
},
32983311
},
3312+
"LoggingConfig": {
3313+
"LogGroup": {
3314+
"Ref": "WebappHandlerLogs87A6D2D7",
3315+
},
3316+
},
32993317
"MemorySize": 1024,
33003318
"PackageType": "Image",
33013319
"Role": {
@@ -3366,6 +3384,14 @@ service iptables save",
33663384
},
33673385
"Type": "AWS::Lambda::Url",
33683386
},
3387+
"WebappHandlerLogs87A6D2D7": {
3388+
"DeletionPolicy": "Delete",
3389+
"Properties": {
3390+
"RetentionInDays": 7,
3391+
},
3392+
"Type": "AWS::Logs::LogGroup",
3393+
"UpdateReplacePolicy": "Delete",
3394+
},
33693395
"WebappHandlerSecurityGroup5451B519": {
33703396
"DependsOn": [
33713397
"VpcPrivateSubnet1DefaultRouteBE02A9ED",
@@ -3635,6 +3661,11 @@ service iptables save",
36353661
"migration-runner.handler",
36363662
],
36373663
},
3664+
"LoggingConfig": {
3665+
"LogGroup": {
3666+
"Ref": "WebappMigrationRunnerLogsD9A84B90",
3667+
},
3668+
},
36383669
"MemorySize": 256,
36393670
"PackageType": "Image",
36403671
"Role": {
@@ -3684,6 +3715,14 @@ service iptables save",
36843715
},
36853716
"Type": "AWS::Lambda::Version",
36863717
},
3718+
"WebappMigrationRunnerLogsD9A84B90": {
3719+
"DeletionPolicy": "Delete",
3720+
"Properties": {
3721+
"RetentionInDays": 7,
3722+
},
3723+
"Type": "AWS::Logs::LogGroup",
3724+
"UpdateReplacePolicy": "Delete",
3725+
},
36873726
"WebappMigrationRunnerSecurityGroup7F0DF264": {
36883727
"DependsOn": [
36893728
"VpcPrivateSubnet1DefaultRouteBE02A9ED",

0 commit comments

Comments
 (0)