Skip to content

Commit

Permalink
feat(codebuild): interactive breakpoints using SSM (#22728)
Browse files Browse the repository at this point in the history
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*
  • Loading branch information
rix0rrr committed Nov 4, 2022
1 parent d1dddb4 commit bf165a1
Show file tree
Hide file tree
Showing 21 changed files with 1,558 additions and 0 deletions.
44 changes: 44 additions & 0 deletions packages/@aws-cdk/aws-codebuild/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -386,6 +386,50 @@ new codebuild.Project(this, 'Project', {
})
```

## Debugging builds interactively using SSM Session Manager

Integration with SSM Session Manager makes it possible to add breakpoints to your
build commands, pause the build there and log into the container to interactively
debug the environment.

To do so, you need to:

* Create the build with `ssmSessionPermissions: true`.
* Use a build image with SSM agent installed and configured (default CodeBuild images come with the image preinstalled).
* Start the build with [debugSessionEnabled](https://docs.aws.amazon.com/codebuild/latest/APIReference/API_StartBuild.html#CodeBuild-StartBuild-request-debugSessionEnabled) set to true.

If these conditions are met, execution of the command `codebuild-breakpoint`
will suspend your build and allow you to attach a Session Manager session from
the CodeBuild console.

For more information, see [View a running build in Session
Manager](https://docs.aws.amazon.com/codebuild/latest/userguide/session-manager.html)
in the CodeBuild documentation.

Example:

```ts
new codebuild.Project(this, 'Project', {
environment: {
buildImage: codebuild.LinuxBuildImage.STANDARD_6_0,
},
ssmSessionPermissions: true,
buildSpec: codebuild.BuildSpec.fromObject({
version: '0.2',
phases: {
build: {
commands: [
// Pause the build container if possible
'codebuild-breakpoint',
// Regular build in a script in the repository
'./my-build.sh',
],
},
},
}),
})
```

## Credentials

CodeBuild allows you to store credentials used when communicating with various sources,
Expand Down
41 changes: 41 additions & 0 deletions packages/@aws-cdk/aws-codebuild/lib/project.ts
Original file line number Diff line number Diff line change
Expand Up @@ -692,6 +692,26 @@ export interface CommonProjectProps {
* @default - no explicit limit is set
*/
readonly concurrentBuildLimit?: number

/**
* Add the permissions necessary for debugging builds with SSM Session Manager
*
* If the following prerequisites have been met:
*
* - The necessary permissions have been added by setting this flag to true.
* - The build image has the SSM agent installed (true for default CodeBuild images).
* - The build is started with [debugSessionEnabled](https://docs.aws.amazon.com/codebuild/latest/APIReference/API_StartBuild.html#CodeBuild-StartBuild-request-debugSessionEnabled) set to true.
*
* Then the build container can be paused and inspected using Session Manager
* by invoking the `codebuild-breakpoint` command somewhere during the build.
*
* `codebuild-breakpoint` commands will be ignored if the build is not started
* with `debugSessionEnabled=true`.
*
* @see https://docs.aws.amazon.com/codebuild/latest/userguide/session-manager.html
* @default false
*/
readonly ssmSessionPermissions?: boolean;
}

export interface ProjectProps extends CommonProjectProps {
Expand Down Expand Up @@ -1129,6 +1149,27 @@ export class Project extends ProjectBase {
}));
}

// https://docs.aws.amazon.com/codebuild/latest/userguide/session-manager.html
if (props.ssmSessionPermissions) {
this.addToRolePolicy(new iam.PolicyStatement({
actions: [
// For the SSM channel
'ssmmessages:CreateControlChannel',
'ssmmessages:CreateDataChannel',
'ssmmessages:OpenControlChannel',
'ssmmessages:OpenDataChannel',
// In case the SSM session is set up to log commands to CloudWatch
'logs:DescribeLogGroups',
'logs:CreateLogStream',
'logs:PutLogEvents',
// In case the SSM session is set up to log commands to S3.
's3:GetEncryptionConfiguration',
's3:PutObject',
],
resources: ['*'],
}));
}

if (props.encryptionKey) {
this.encryptionKey = props.encryptionKey;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"version": "21.0.0",
"files": {
"21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22": {
"source": {
"path": "ReportGroupIntegTestDefaultTestDeployAssert57960C5A.template.json",
"packaging": "file"
},
"destinations": {
"current_account-current_region": {
"bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}",
"objectKey": "21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22.json",
"assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}"
}
}
}
},
"dockerImages": {}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
{
"Parameters": {
"BootstrapVersion": {
"Type": "AWS::SSM::Parameter::Value<String>",
"Default": "/cdk-bootstrap/hnb659fds/version",
"Description": "Version of the CDK Bootstrap resources in this environment, automatically retrieved from SSM Parameter Store. [cdk:skip]"
}
},
"Rules": {
"CheckBootstrapVersion": {
"Assertions": [
{
"Assert": {
"Fn::Not": [
{
"Fn::Contains": [
[
"1",
"2",
"3",
"4",
"5"
],
{
"Ref": "BootstrapVersion"
}
]
}
]
},
"AssertDescription": "CDK bootstrap stack version 6 required. Please run 'cdk bootstrap' with a recent version of the CDK CLI."
}
]
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"version": "21.0.0",
"files": {
"38d79637293a2170812ef1108634858c002345d4d5803191fa1d821a30b29d37": {
"source": {
"path": "aws-cdk-codebuild-breakpoint.template.json",
"packaging": "file"
},
"destinations": {
"current_account-current_region": {
"bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}",
"objectKey": "38d79637293a2170812ef1108634858c002345d4d5803191fa1d821a30b29d37.json",
"assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}"
}
}
}
},
"dockerImages": {}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,206 @@
{
"Resources": {
"ProjectRole4CCB274E": {
"Type": "AWS::IAM::Role",
"Properties": {
"AssumeRolePolicyDocument": {
"Statement": [
{
"Action": "sts:AssumeRole",
"Effect": "Allow",
"Principal": {
"Service": "codebuild.amazonaws.com"
}
}
],
"Version": "2012-10-17"
}
}
},
"ProjectRoleDefaultPolicy7F29461B": {
"Type": "AWS::IAM::Policy",
"Properties": {
"PolicyDocument": {
"Statement": [
{
"Action": [
"logs:CreateLogGroup",
"logs:CreateLogStream",
"logs:PutLogEvents"
],
"Effect": "Allow",
"Resource": [
{
"Fn::Join": [
"",
[
"arn:",
{
"Ref": "AWS::Partition"
},
":logs:",
{
"Ref": "AWS::Region"
},
":",
{
"Ref": "AWS::AccountId"
},
":log-group:/aws/codebuild/",
{
"Ref": "ProjectC78D97AD"
},
":*"
]
]
},
{
"Fn::Join": [
"",
[
"arn:",
{
"Ref": "AWS::Partition"
},
":logs:",
{
"Ref": "AWS::Region"
},
":",
{
"Ref": "AWS::AccountId"
},
":log-group:/aws/codebuild/",
{
"Ref": "ProjectC78D97AD"
}
]
]
}
]
},
{
"Action": [
"codebuild:BatchPutCodeCoverages",
"codebuild:BatchPutTestCases",
"codebuild:CreateReport",
"codebuild:CreateReportGroup",
"codebuild:UpdateReport"
],
"Effect": "Allow",
"Resource": {
"Fn::Join": [
"",
[
"arn:",
{
"Ref": "AWS::Partition"
},
":codebuild:",
{
"Ref": "AWS::Region"
},
":",
{
"Ref": "AWS::AccountId"
},
":report-group/",
{
"Ref": "ProjectC78D97AD"
},
"-*"
]
]
}
},
{
"Action": [
"logs:CreateLogStream",
"logs:DescribeLogGroups",
"logs:PutLogEvents",
"s3:GetEncryptionConfiguration",
"s3:PutObject",
"ssmmessages:CreateControlChannel",
"ssmmessages:CreateDataChannel",
"ssmmessages:OpenControlChannel",
"ssmmessages:OpenDataChannel"
],
"Effect": "Allow",
"Resource": "*"
}
],
"Version": "2012-10-17"
},
"PolicyName": "ProjectRoleDefaultPolicy7F29461B",
"Roles": [
{
"Ref": "ProjectRole4CCB274E"
}
]
}
},
"ProjectC78D97AD": {
"Type": "AWS::CodeBuild::Project",
"Properties": {
"Artifacts": {
"Type": "NO_ARTIFACTS"
},
"Environment": {
"ComputeType": "BUILD_GENERAL1_SMALL",
"Image": "aws/codebuild/standard:6.0",
"ImagePullCredentialsType": "CODEBUILD",
"PrivilegedMode": false,
"Type": "LINUX_CONTAINER"
},
"ServiceRole": {
"Fn::GetAtt": [
"ProjectRole4CCB274E",
"Arn"
]
},
"Source": {
"BuildSpec": "{\n \"version\": \"0.2\",\n \"phases\": {\n \"build\": {\n \"commands\": [\n \"codebuild-breakpoint\",\n \"echo \\\"regular build here\\\"\"\n ]\n }\n }\n}",
"Type": "NO_SOURCE"
},
"Cache": {
"Type": "NO_CACHE"
},
"EncryptionKey": "alias/aws/s3"
}
}
},
"Parameters": {
"BootstrapVersion": {
"Type": "AWS::SSM::Parameter::Value<String>",
"Default": "/cdk-bootstrap/hnb659fds/version",
"Description": "Version of the CDK Bootstrap resources in this environment, automatically retrieved from SSM Parameter Store. [cdk:skip]"
}
},
"Rules": {
"CheckBootstrapVersion": {
"Assertions": [
{
"Assert": {
"Fn::Not": [
{
"Fn::Contains": [
[
"1",
"2",
"3",
"4",
"5"
],
{
"Ref": "BootstrapVersion"
}
]
}
]
},
"AssertDescription": "CDK bootstrap stack version 6 required. Please run 'cdk bootstrap' with a recent version of the CDK CLI."
}
]
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"version":"21.0.0"}
Loading

0 comments on commit bf165a1

Please sign in to comment.