Skip to content

Commit bf165a1

Browse files
authored
feat(codebuild): interactive breakpoints using SSM (#22728)
Allowing breakpoints in CodeBuild builds using SSM session manager was already something users could do, but add a property to make the feature slightly more convenient to use, and advertise it better. ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
1 parent d1dddb4 commit bf165a1

21 files changed

+1558
-0
lines changed

packages/@aws-cdk/aws-codebuild/README.md

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -386,6 +386,50 @@ new codebuild.Project(this, 'Project', {
386386
})
387387
```
388388

389+
## Debugging builds interactively using SSM Session Manager
390+
391+
Integration with SSM Session Manager makes it possible to add breakpoints to your
392+
build commands, pause the build there and log into the container to interactively
393+
debug the environment.
394+
395+
To do so, you need to:
396+
397+
* Create the build with `ssmSessionPermissions: true`.
398+
* Use a build image with SSM agent installed and configured (default CodeBuild images come with the image preinstalled).
399+
* Start the build with [debugSessionEnabled](https://docs.aws.amazon.com/codebuild/latest/APIReference/API_StartBuild.html#CodeBuild-StartBuild-request-debugSessionEnabled) set to true.
400+
401+
If these conditions are met, execution of the command `codebuild-breakpoint`
402+
will suspend your build and allow you to attach a Session Manager session from
403+
the CodeBuild console.
404+
405+
For more information, see [View a running build in Session
406+
Manager](https://docs.aws.amazon.com/codebuild/latest/userguide/session-manager.html)
407+
in the CodeBuild documentation.
408+
409+
Example:
410+
411+
```ts
412+
new codebuild.Project(this, 'Project', {
413+
environment: {
414+
buildImage: codebuild.LinuxBuildImage.STANDARD_6_0,
415+
},
416+
ssmSessionPermissions: true,
417+
buildSpec: codebuild.BuildSpec.fromObject({
418+
version: '0.2',
419+
phases: {
420+
build: {
421+
commands: [
422+
// Pause the build container if possible
423+
'codebuild-breakpoint',
424+
// Regular build in a script in the repository
425+
'./my-build.sh',
426+
],
427+
},
428+
},
429+
}),
430+
})
431+
```
432+
389433
## Credentials
390434

391435
CodeBuild allows you to store credentials used when communicating with various sources,

packages/@aws-cdk/aws-codebuild/lib/project.ts

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -692,6 +692,26 @@ export interface CommonProjectProps {
692692
* @default - no explicit limit is set
693693
*/
694694
readonly concurrentBuildLimit?: number
695+
696+
/**
697+
* Add the permissions necessary for debugging builds with SSM Session Manager
698+
*
699+
* If the following prerequisites have been met:
700+
*
701+
* - The necessary permissions have been added by setting this flag to true.
702+
* - The build image has the SSM agent installed (true for default CodeBuild images).
703+
* - The build is started with [debugSessionEnabled](https://docs.aws.amazon.com/codebuild/latest/APIReference/API_StartBuild.html#CodeBuild-StartBuild-request-debugSessionEnabled) set to true.
704+
*
705+
* Then the build container can be paused and inspected using Session Manager
706+
* by invoking the `codebuild-breakpoint` command somewhere during the build.
707+
*
708+
* `codebuild-breakpoint` commands will be ignored if the build is not started
709+
* with `debugSessionEnabled=true`.
710+
*
711+
* @see https://docs.aws.amazon.com/codebuild/latest/userguide/session-manager.html
712+
* @default false
713+
*/
714+
readonly ssmSessionPermissions?: boolean;
695715
}
696716

697717
export interface ProjectProps extends CommonProjectProps {
@@ -1129,6 +1149,27 @@ export class Project extends ProjectBase {
11291149
}));
11301150
}
11311151

1152+
// https://docs.aws.amazon.com/codebuild/latest/userguide/session-manager.html
1153+
if (props.ssmSessionPermissions) {
1154+
this.addToRolePolicy(new iam.PolicyStatement({
1155+
actions: [
1156+
// For the SSM channel
1157+
'ssmmessages:CreateControlChannel',
1158+
'ssmmessages:CreateDataChannel',
1159+
'ssmmessages:OpenControlChannel',
1160+
'ssmmessages:OpenDataChannel',
1161+
// In case the SSM session is set up to log commands to CloudWatch
1162+
'logs:DescribeLogGroups',
1163+
'logs:CreateLogStream',
1164+
'logs:PutLogEvents',
1165+
// In case the SSM session is set up to log commands to S3.
1166+
's3:GetEncryptionConfiguration',
1167+
's3:PutObject',
1168+
],
1169+
resources: ['*'],
1170+
}));
1171+
}
1172+
11321173
if (props.encryptionKey) {
11331174
this.encryptionKey = props.encryptionKey;
11341175
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
{
2+
"version": "21.0.0",
3+
"files": {
4+
"21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22": {
5+
"source": {
6+
"path": "ReportGroupIntegTestDefaultTestDeployAssert57960C5A.template.json",
7+
"packaging": "file"
8+
},
9+
"destinations": {
10+
"current_account-current_region": {
11+
"bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}",
12+
"objectKey": "21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22.json",
13+
"assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}"
14+
}
15+
}
16+
}
17+
},
18+
"dockerImages": {}
19+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
{
2+
"Parameters": {
3+
"BootstrapVersion": {
4+
"Type": "AWS::SSM::Parameter::Value<String>",
5+
"Default": "/cdk-bootstrap/hnb659fds/version",
6+
"Description": "Version of the CDK Bootstrap resources in this environment, automatically retrieved from SSM Parameter Store. [cdk:skip]"
7+
}
8+
},
9+
"Rules": {
10+
"CheckBootstrapVersion": {
11+
"Assertions": [
12+
{
13+
"Assert": {
14+
"Fn::Not": [
15+
{
16+
"Fn::Contains": [
17+
[
18+
"1",
19+
"2",
20+
"3",
21+
"4",
22+
"5"
23+
],
24+
{
25+
"Ref": "BootstrapVersion"
26+
}
27+
]
28+
}
29+
]
30+
},
31+
"AssertDescription": "CDK bootstrap stack version 6 required. Please run 'cdk bootstrap' with a recent version of the CDK CLI."
32+
}
33+
]
34+
}
35+
}
36+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
{
2+
"version": "21.0.0",
3+
"files": {
4+
"38d79637293a2170812ef1108634858c002345d4d5803191fa1d821a30b29d37": {
5+
"source": {
6+
"path": "aws-cdk-codebuild-breakpoint.template.json",
7+
"packaging": "file"
8+
},
9+
"destinations": {
10+
"current_account-current_region": {
11+
"bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}",
12+
"objectKey": "38d79637293a2170812ef1108634858c002345d4d5803191fa1d821a30b29d37.json",
13+
"assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}"
14+
}
15+
}
16+
}
17+
},
18+
"dockerImages": {}
19+
}
Lines changed: 206 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,206 @@
1+
{
2+
"Resources": {
3+
"ProjectRole4CCB274E": {
4+
"Type": "AWS::IAM::Role",
5+
"Properties": {
6+
"AssumeRolePolicyDocument": {
7+
"Statement": [
8+
{
9+
"Action": "sts:AssumeRole",
10+
"Effect": "Allow",
11+
"Principal": {
12+
"Service": "codebuild.amazonaws.com"
13+
}
14+
}
15+
],
16+
"Version": "2012-10-17"
17+
}
18+
}
19+
},
20+
"ProjectRoleDefaultPolicy7F29461B": {
21+
"Type": "AWS::IAM::Policy",
22+
"Properties": {
23+
"PolicyDocument": {
24+
"Statement": [
25+
{
26+
"Action": [
27+
"logs:CreateLogGroup",
28+
"logs:CreateLogStream",
29+
"logs:PutLogEvents"
30+
],
31+
"Effect": "Allow",
32+
"Resource": [
33+
{
34+
"Fn::Join": [
35+
"",
36+
[
37+
"arn:",
38+
{
39+
"Ref": "AWS::Partition"
40+
},
41+
":logs:",
42+
{
43+
"Ref": "AWS::Region"
44+
},
45+
":",
46+
{
47+
"Ref": "AWS::AccountId"
48+
},
49+
":log-group:/aws/codebuild/",
50+
{
51+
"Ref": "ProjectC78D97AD"
52+
},
53+
":*"
54+
]
55+
]
56+
},
57+
{
58+
"Fn::Join": [
59+
"",
60+
[
61+
"arn:",
62+
{
63+
"Ref": "AWS::Partition"
64+
},
65+
":logs:",
66+
{
67+
"Ref": "AWS::Region"
68+
},
69+
":",
70+
{
71+
"Ref": "AWS::AccountId"
72+
},
73+
":log-group:/aws/codebuild/",
74+
{
75+
"Ref": "ProjectC78D97AD"
76+
}
77+
]
78+
]
79+
}
80+
]
81+
},
82+
{
83+
"Action": [
84+
"codebuild:BatchPutCodeCoverages",
85+
"codebuild:BatchPutTestCases",
86+
"codebuild:CreateReport",
87+
"codebuild:CreateReportGroup",
88+
"codebuild:UpdateReport"
89+
],
90+
"Effect": "Allow",
91+
"Resource": {
92+
"Fn::Join": [
93+
"",
94+
[
95+
"arn:",
96+
{
97+
"Ref": "AWS::Partition"
98+
},
99+
":codebuild:",
100+
{
101+
"Ref": "AWS::Region"
102+
},
103+
":",
104+
{
105+
"Ref": "AWS::AccountId"
106+
},
107+
":report-group/",
108+
{
109+
"Ref": "ProjectC78D97AD"
110+
},
111+
"-*"
112+
]
113+
]
114+
}
115+
},
116+
{
117+
"Action": [
118+
"logs:CreateLogStream",
119+
"logs:DescribeLogGroups",
120+
"logs:PutLogEvents",
121+
"s3:GetEncryptionConfiguration",
122+
"s3:PutObject",
123+
"ssmmessages:CreateControlChannel",
124+
"ssmmessages:CreateDataChannel",
125+
"ssmmessages:OpenControlChannel",
126+
"ssmmessages:OpenDataChannel"
127+
],
128+
"Effect": "Allow",
129+
"Resource": "*"
130+
}
131+
],
132+
"Version": "2012-10-17"
133+
},
134+
"PolicyName": "ProjectRoleDefaultPolicy7F29461B",
135+
"Roles": [
136+
{
137+
"Ref": "ProjectRole4CCB274E"
138+
}
139+
]
140+
}
141+
},
142+
"ProjectC78D97AD": {
143+
"Type": "AWS::CodeBuild::Project",
144+
"Properties": {
145+
"Artifacts": {
146+
"Type": "NO_ARTIFACTS"
147+
},
148+
"Environment": {
149+
"ComputeType": "BUILD_GENERAL1_SMALL",
150+
"Image": "aws/codebuild/standard:6.0",
151+
"ImagePullCredentialsType": "CODEBUILD",
152+
"PrivilegedMode": false,
153+
"Type": "LINUX_CONTAINER"
154+
},
155+
"ServiceRole": {
156+
"Fn::GetAtt": [
157+
"ProjectRole4CCB274E",
158+
"Arn"
159+
]
160+
},
161+
"Source": {
162+
"BuildSpec": "{\n \"version\": \"0.2\",\n \"phases\": {\n \"build\": {\n \"commands\": [\n \"codebuild-breakpoint\",\n \"echo \\\"regular build here\\\"\"\n ]\n }\n }\n}",
163+
"Type": "NO_SOURCE"
164+
},
165+
"Cache": {
166+
"Type": "NO_CACHE"
167+
},
168+
"EncryptionKey": "alias/aws/s3"
169+
}
170+
}
171+
},
172+
"Parameters": {
173+
"BootstrapVersion": {
174+
"Type": "AWS::SSM::Parameter::Value<String>",
175+
"Default": "/cdk-bootstrap/hnb659fds/version",
176+
"Description": "Version of the CDK Bootstrap resources in this environment, automatically retrieved from SSM Parameter Store. [cdk:skip]"
177+
}
178+
},
179+
"Rules": {
180+
"CheckBootstrapVersion": {
181+
"Assertions": [
182+
{
183+
"Assert": {
184+
"Fn::Not": [
185+
{
186+
"Fn::Contains": [
187+
[
188+
"1",
189+
"2",
190+
"3",
191+
"4",
192+
"5"
193+
],
194+
{
195+
"Ref": "BootstrapVersion"
196+
}
197+
]
198+
}
199+
]
200+
},
201+
"AssertDescription": "CDK bootstrap stack version 6 required. Please run 'cdk bootstrap' with a recent version of the CDK CLI."
202+
}
203+
]
204+
}
205+
}
206+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{"version":"21.0.0"}

0 commit comments

Comments
 (0)