I have an AWS VDK v2 based application stack that sets up a CodePipeline with different stages, application and all that, that works alright. But this setup creates quite some log-groups where the retention time is not set. As the log groups are not created by my cdk code, but under the hood by cdk itself, I cannot explicitly set the retention time.
So I tried to use Aspects
to achieve that. I created the following:
export class LogGroupRetentionChecker implements IAspect {
prefix: String
constructor(prefix: String) {
this.prefix = prefix;
}
visit(node: IConstruct): void {
console.log(`${(this.prefix)}: checking node ${node.constructor.name}`)
if (node instanceof CfnResource) {
console.log(`${this.prefix}: resource type ${node.cfnResourceType}`)
}
if (node instanceof CfnLogGroup) {
console.log(`aspect found log-group ${node.logGroupName}, retention: ${node.retentionInDays}`);
if (node.retentionInDays === undefined) {
node.retentionInDays = 60
}
}
}
}
At the place where the pipeline is created, I then do this:
Aspects.of(this.pipeline).add(new LogGroupRetentionChecker("pipeline"));
And If have one more call where I create a stage. For the aspect on the pipleine this shows for example
pipeline: checking node CodePipeline
pipeline: checking node Pipeline
pipeline: checking node Key
pipeline: checking node CfnKey
pipeline: resource type AWS::KMS::Key
pipeline: checking node Alias
pipeline: checking node CfnAlias
pipeline: resource type AWS::KMS::Alias
pipeline: checking node Bucket
pipeline: checking node CfnBucket
pipeline: resource type AWS::S3::Bucket
pipeline: checking node BucketPolicy
pipeline: checking node CfnBucketPolicy
pipeline: resource type AWS::S3::BucketPolicy
pipeline: checking node Role
pipeline: checking node CfnRole
pipeline: resource type AWS::IAM::Role
pipeline: checking node Policy
pipeline: checking node CfnPolicyConditional
pipeline: resource type AWS::IAM::Policy
pipeline: checking node CfnPipeline
pipeline: resource type AWS::CodePipeline::Pipeline
pipeline: checking node Construct
pipeline: checking node Construct
pipeline: checking node Role
pipeline: checking node CfnRole
pipeline: resource type AWS::IAM::Role
pipeline: checking node Policy
pipeline: checking node CfnPolicyConditional
pipeline: resource type AWS::IAM::Policy
pipeline: checking node Construct
...
So the aspect is called, but none of the IConstruct
s that are visited is a CfnLogGroup
.
My question now: How can I get these log-groups configured? If not by aspect, is there another way to do that?
CodePudding user response:
For log groups you can't access directly in CDK/Cfn, use a Lambda-backed Trigger or CustomResource to put a retention policy using SDK calls. CloudFormation will invoke your Lambda as part of the pipeline stack's deploy lifecycle. Configure the Trigger/CR to run the Lambda only on stack create.
The Lambda's job is to:
- Look up the log groups with DescribeLogGroups. Filter by setting
logGroupNamePrefix: "/aws/codebuild/MyPipeline"
. - Invoke PutRetentionPolicy for each log group name.
Edit: Another Option
Another option is to create explicit log groups for each CodeBuild project in the pipeline.
Many pipeline constructs, including ShellStep
, deploy a AWS::CodeBuild::Project
resource under the hood. If we create a LogGroup with the desired retention days set, we can pass it to a project.
For indirectly created projects (like that underlying ShellStep
) we must first use escape hatch syntax to reference the underlying CfnProject constructs. Then we pass our configured LogGroup name to the its logsConfig property.
It's easier for an explicitly constructed codebuild.Project
. It accepts a LogGroup
directly in the logging:LoggingOptions prop.