Last active
July 6, 2022 00:25
-
-
Save SydneyUni-Jim/7a427203b64e013af331883f7bb59bb0 to your computer and use it in GitHub Desktop.
Custom logical ids for CodeBuild projects
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import * as cdk from 'aws-cdk-lib' | |
import * as codebuild from 'aws-cdk-lib/aws-codebuild' | |
import * as pipelines from 'aws-cdk-lib/pipelines' | |
import { Construct } from 'constructs' | |
export class PipelineStack extends cdk.Stack { | |
public readonly pipeline: pipelines.CodePipeline | |
constructor(scope: Construct, id: string, props: cdk.StackProps) { | |
super(scope, id, props) | |
this.pipeline = new pipelines.CodePipeline(this, 'CdkPipeline', { | |
synth: new pipelines.ShellStep('CdkSynth', { | |
// ……… | |
}), | |
}) | |
} | |
protected allocateLogicalId(cfnElement: cdk.CfnElement): string { | |
const logicalId = super.allocateLogicalId(cfnElement) | |
if (cfnElement instanceof codebuild.CfnProject) { | |
const hash = logicalId.slice(-8) | |
const idStack = ( | |
cfnElement.node.scopes | |
.slice(cfnElement.node.scopes.indexOf(cfnElement.stack) + 1) | |
.map(x => x.node.id) | |
) | |
let id = idStack.pop() | |
while (id && (id === 'Resource' || id === 'CdkBuildProject')) { | |
id = idStack.pop() | |
} | |
id ??= cfnElement.node.id | |
id = id.replace(/[^A-Za-z0-9]/g, '') | |
return `${this.stackName}${id}${hash}` | |
} else { | |
return logicalId | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
What does this do?
It customises how CDK allocates logical IDs for CodeBuild projects.
Normally the CDK allocates logical IDs by concatenating all the Construct / CfnElement ids from one past the stack down to the particular node.
In this example, the ShellStep id is CdkSynth. Normally the CDK would allocate an ID like
CdkPipelineBuildCdkSynthCdkBuildProjectA713CFA7
. This is because the hierarchy of ids would have been CdkPipeline, Build, CdkSynth, CdkBuildProject, Resource. The physical ID ends up being something likeCdkPipelineBuildCdkSynthCdk-x7qn180HcLtp
.With this, for CodeBuild projects only, it finds the deepest id that is not Resource or CdkBuildProject and assigns that as the logical ID, prefixing it with the name of the stack. It also suffixes it with the hash as normal to ensure the logical IDs are unique in the stack.
Instead of
CdkPipelineBuildCdkSynthCdkBuildProjectA713CFA7
, the CDK allocates an ID likedemoSynthCdkA713CFA7
, assuming the stack's name is demo. This ends up being a physical ID likedemoCdkSynthA713CFA7-X3vCwqQ9mxIZ
.Why do I want to do this?
By default, CloudFormation does not prefix the physical ID of CodeBuild projects with the name of the stack they came from. Also the physical IDs of CodeBuild projects are relatively short. On top of the, the CDK creates long logical IDs were the useful part towards the end is truncated to form the physical ID. This means you end up with a bunch of CodeBuild projects with unhelpful physical IDs.
In this example — if the CDK app builds two Docker images — without this you would end up with these CodeBuild projects.
You can see the problem particularly with the two CodeBuild projects for the Docker images.
With this, you instead end up with these CodeBuild projects, assuming the stack is called demo.
Much more helpful.