From e7cd4619ea3ffaa00c5e08eaa7e3bce849711946 Mon Sep 17 00:00:00 2001 From: Amir Szekely Date: Sun, 9 Apr 2023 14:58:17 -0700 Subject: [PATCH] feat: Notification on runner image build failures (#278) ``` const runners = new GitHubRunners(this, 'runners'); const topic = runners.failedImageBuildsTopic(); topic.addSubscription(new subs.EmailSubscription('me@example.com')) ``` Fix #277 --- .eslintrc.json | 3 +- .gitattributes | 1 + .gitignore | 1 + .projen/files.json | 1 + .projen/tasks.json | 21 + API.md | 13 + package.json | 2 + .../aws-image-builder/builder.ts | 36 +- .../filter-failed-builds-function.ts | 26 + .../filter-failed-builds.lambda.ts | 19 + src/providers/image-builders/codebuild.ts | 19 +- src/runner.ts | 21 + .../github-runners-test.assets.json | 17 +- .../github-runners-test.template.json | 334 ++++++++++ test/default.integ.snapshot/manifest.json | 129 +++- test/default.integ.snapshot/tree.json | 597 ++++++++++++++++++ test/default.integ.ts | 9 +- 17 files changed, 1240 insertions(+), 9 deletions(-) create mode 100644 src/providers/image-builders/aws-image-builder/filter-failed-builds-function.ts create mode 100644 src/providers/image-builders/aws-image-builder/filter-failed-builds.lambda.ts diff --git a/.eslintrc.json b/.eslintrc.json index 9041f73b..f6df56e7 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -155,7 +155,8 @@ "src/lambdas/status.lambda.ts", "src/lambdas/token-retriever.lambda.ts", "src/lambdas/update-lambda.lambda.ts", - "src/lambdas/webhook-handler.lambda.ts" + "src/lambdas/webhook-handler.lambda.ts", + "src/providers/image-builders/aws-image-builder/filter-failed-builds.lambda.ts" ], "optionalDependencies": false, "peerDependencies": true diff --git a/.gitattributes b/.gitattributes index 198cebd4..bf040b33 100644 --- a/.gitattributes +++ b/.gitattributes @@ -33,6 +33,7 @@ /src/lambdas/token-retriever-function.ts linguist-generated /src/lambdas/update-lambda-function.ts linguist-generated /src/lambdas/webhook-handler-function.ts linguist-generated +/src/providers/image-builders/aws-image-builder/filter-failed-builds-function.ts linguist-generated /tsconfig.dev.json linguist-generated /yarn.lock linguist-generated Dockerfile eol=lf \ No newline at end of file diff --git a/.gitignore b/.gitignore index 329bd793..140400c9 100644 --- a/.gitignore +++ b/.gitignore @@ -64,6 +64,7 @@ tsconfig.json !/src/lambdas/token-retriever-function.ts !/src/lambdas/update-lambda-function.ts !/src/lambdas/webhook-handler-function.ts +!/src/providers/image-builders/aws-image-builder/filter-failed-builds-function.ts test/.tmp test/default.integ.snapshot/asset.* test/default.integ.snapshot/**/asset.* diff --git a/.projen/files.json b/.projen/files.json index e7d8c86f..30ad6529 100644 --- a/.projen/files.json +++ b/.projen/files.json @@ -22,6 +22,7 @@ "src/lambdas/token-retriever-function.ts", "src/lambdas/update-lambda-function.ts", "src/lambdas/webhook-handler-function.ts", + "src/providers/image-builders/aws-image-builder/filter-failed-builds-function.ts", "tsconfig.dev.json" ], "//": "~~ Generated by projen. To modify, edit .projenrc.js and run \"npx projen\"." diff --git a/.projen/tasks.json b/.projen/tasks.json index 5088ec7a..069f6906 100644 --- a/.projen/tasks.json +++ b/.projen/tasks.json @@ -72,6 +72,9 @@ { "spawn": "bundle:lambdas/webhook-handler.lambda" }, + { + "spawn": "bundle:providers/image-builders/aws-image-builder/filter-failed-builds.lambda" + }, { "exec": "cp -r src/providers/docker-images assets" }, @@ -245,6 +248,24 @@ } ] }, + "bundle:providers/image-builders/aws-image-builder/filter-failed-builds.lambda": { + "name": "bundle:providers/image-builders/aws-image-builder/filter-failed-builds.lambda", + "description": "Create a JavaScript bundle from src/providers/image-builders/aws-image-builder/filter-failed-builds.lambda.ts", + "steps": [ + { + "exec": "esbuild --bundle src/providers/image-builders/aws-image-builder/filter-failed-builds.lambda.ts --target=\"node16\" --platform=\"node\" --outfile=\"assets/providers/image-builders/aws-image-builder/filter-failed-builds.lambda/index.js\" --tsconfig=\"tsconfig.dev.json\" --external:aws-sdk" + } + ] + }, + "bundle:providers/image-builders/aws-image-builder/filter-failed-builds.lambda:watch": { + "name": "bundle:providers/image-builders/aws-image-builder/filter-failed-builds.lambda:watch", + "description": "Continuously update the JavaScript bundle from src/providers/image-builders/aws-image-builder/filter-failed-builds.lambda.ts", + "steps": [ + { + "exec": "esbuild --bundle src/providers/image-builders/aws-image-builder/filter-failed-builds.lambda.ts --target=\"node16\" --platform=\"node\" --outfile=\"assets/providers/image-builders/aws-image-builder/filter-failed-builds.lambda/index.js\" --tsconfig=\"tsconfig.dev.json\" --external:aws-sdk --watch" + } + ] + }, "clobber": { "name": "clobber", "description": "hard resets to HEAD of origin and cleans the local repo", diff --git a/API.md b/API.md index 85cf5077..04eeceb1 100644 --- a/API.md +++ b/API.md @@ -3101,6 +3101,7 @@ new GitHubRunners(scope: Construct, id: string, props?: GitHubRunnersProps) | **Name** | **Description** | | --- | --- | | toString | Returns a string representation of this construct. | +| failedImageBuildsTopic | Creates a topic for notifications when a runner image build fails. | | metricFailed | Metric for failed runner executions. | | metricJobCompleted | Metric for the number of GitHub Actions jobs completed. | | metricSucceeded | Metric for successful executions. | @@ -3116,6 +3117,18 @@ public toString(): string Returns a string representation of this construct. +##### `failedImageBuildsTopic` + +```typescript +public failedImageBuildsTopic(): Topic +``` + +Creates a topic for notifications when a runner image build fails. + +Runner images are rebuilt every week by default. This provides the latest GitHub Runner version and software updates. + +If you want to be sure you are using the latest runner version, you can use this topic to be notified when a build fails. + ##### `metricFailed` ```typescript diff --git a/package.json b/package.json index 2eb2fd51..899b3d0e 100644 --- a/package.json +++ b/package.json @@ -27,6 +27,8 @@ "bundle:lambdas/update-lambda.lambda:watch": "npx projen bundle:lambdas/update-lambda.lambda:watch", "bundle:lambdas/webhook-handler.lambda": "npx projen bundle:lambdas/webhook-handler.lambda", "bundle:lambdas/webhook-handler.lambda:watch": "npx projen bundle:lambdas/webhook-handler.lambda:watch", + "bundle:providers/image-builders/aws-image-builder/filter-failed-builds.lambda": "npx projen bundle:providers/image-builders/aws-image-builder/filter-failed-builds.lambda", + "bundle:providers/image-builders/aws-image-builder/filter-failed-builds.lambda:watch": "npx projen bundle:providers/image-builders/aws-image-builder/filter-failed-builds.lambda:watch", "clobber": "npx projen clobber", "compat": "npx projen compat", "compile": "npx projen compile", diff --git a/src/providers/image-builders/aws-image-builder/builder.ts b/src/providers/image-builders/aws-image-builder/builder.ts index e21530e2..3452069c 100644 --- a/src/providers/image-builders/aws-image-builder/builder.ts +++ b/src/providers/image-builders/aws-image-builder/builder.ts @@ -9,6 +9,8 @@ import { aws_imagebuilder as imagebuilder, aws_logs as logs, aws_s3_assets as s3_assets, + aws_sns as sns, + aws_sns_subscriptions as subs, CustomResource, Duration, RemovalPolicy, @@ -16,10 +18,11 @@ import { } from 'aws-cdk-lib'; import { TagMutability, TagStatus } from 'aws-cdk-lib/aws-ecr'; import { RetentionDays } from 'aws-cdk-lib/aws-logs'; -import { Construct } from 'constructs'; +import { Construct, IConstruct } from 'constructs'; import { AmiRecipe, defaultBaseAmi } from './ami'; import { ImageBuilderObjectBase } from './common'; import { ContainerRecipe, defaultBaseDockerImage } from './container'; +import { FilterFailedBuildsFunction } from './filter-failed-builds-function'; import { BuildImageFunction } from '../../../lambdas/build-image-function'; import { DeleteAmiFunction } from '../../../lambdas/delete-ami-function'; import { singletonLambda } from '../../../utils'; @@ -643,3 +646,34 @@ export class AwsImageBuilderRunnerImageBuilder extends RunnerImageBuilderBase { return this.boundComponents; } } + +/** + * @internal + */ +export class AwsImageBuilderFailedBuildNotifier implements cdk.IAspect { + public static createFilteringTopic(scope: Construct, targetTopic: sns.Topic) { + const topic = new sns.Topic(scope, 'Image Builder Builds'); + const filter = new FilterFailedBuildsFunction(scope, 'Image Builder Builds Filter', { + logRetention: logs.RetentionDays.ONE_MONTH, + environment: { + TARGET_TOPIC_ARN: targetTopic.topicArn, + }, + }); + + topic.addSubscription(new subs.LambdaSubscription(filter)); + targetTopic.grantPublish(filter); + + return topic; + } + + constructor(private topic: sns.ITopic) { + } + + public visit(node: IConstruct): void { + if (node instanceof AwsImageBuilderRunnerImageBuilder) { + const builder = node as AwsImageBuilderRunnerImageBuilder; + const infra = builder.node.findChild('Infrastructure') as imagebuilder.CfnInfrastructureConfiguration; + infra.snsTopicArn = this.topic.topicArn; + } + } +} diff --git a/src/providers/image-builders/aws-image-builder/filter-failed-builds-function.ts b/src/providers/image-builders/aws-image-builder/filter-failed-builds-function.ts new file mode 100644 index 00000000..3ab3add4 --- /dev/null +++ b/src/providers/image-builders/aws-image-builder/filter-failed-builds-function.ts @@ -0,0 +1,26 @@ +// ~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen". +import * as path from 'path'; +import * as lambda from 'aws-cdk-lib/aws-lambda'; +import { Construct } from 'constructs'; + +/** + * Props for FilterFailedBuildsFunction + */ +export interface FilterFailedBuildsFunctionProps extends lambda.FunctionOptions { +} + +/** + * An AWS Lambda function which executes src/providers/image-builders/aws-image-builder/filter-failed-builds. + */ +export class FilterFailedBuildsFunction extends lambda.Function { + constructor(scope: Construct, id: string, props?: FilterFailedBuildsFunctionProps) { + super(scope, id, { + description: 'src/providers/image-builders/aws-image-builder/filter-failed-builds.lambda.ts', + ...props, + runtime: new lambda.Runtime('nodejs16.x', lambda.RuntimeFamily.NODEJS), + handler: 'index.handler', + code: lambda.Code.fromAsset(path.join(__dirname, '../../../../assets/providers/image-builders/aws-image-builder/filter-failed-builds.lambda')), + }); + this.addEnvironment('AWS_NODEJS_CONNECTION_REUSE_ENABLED', '1', { removeInEdge: true }); + } +} \ No newline at end of file diff --git a/src/providers/image-builders/aws-image-builder/filter-failed-builds.lambda.ts b/src/providers/image-builders/aws-image-builder/filter-failed-builds.lambda.ts new file mode 100644 index 00000000..798a8a79 --- /dev/null +++ b/src/providers/image-builders/aws-image-builder/filter-failed-builds.lambda.ts @@ -0,0 +1,19 @@ +/* eslint-disable-next-line import/no-extraneous-dependencies,import/no-unresolved */ +import * as AWSLambda from 'aws-lambda'; +/* eslint-disable-next-line import/no-extraneous-dependencies */ +import * as AWS from 'aws-sdk'; + +const sns = new AWS.SNS(); + +exports.handler = async function(event: AWSLambda.SNSEvent) { + console.log(JSON.stringify(event)); + for (const record of event.Records) { + let message = JSON.parse(record.Sns.Message); + if (message.state.status === 'FAILED') { + await sns.publish({ + TopicArn: process.env.TARGET_TOPIC_ARN, + Message: record.Sns.Message, + }).promise(); + } + } +}; diff --git a/src/providers/image-builders/codebuild.ts b/src/providers/image-builders/codebuild.ts index 651e20c5..54d850c2 100644 --- a/src/providers/image-builders/codebuild.ts +++ b/src/providers/image-builders/codebuild.ts @@ -9,6 +9,7 @@ import { aws_iam as iam, aws_logs as logs, aws_s3_assets as s3_assets, + aws_sns as sns, CustomResource, Duration, RemovalPolicy, @@ -16,7 +17,7 @@ import { import { ComputeType } from 'aws-cdk-lib/aws-codebuild'; import { TagMutability, TagStatus } from 'aws-cdk-lib/aws-ecr'; import { RetentionDays } from 'aws-cdk-lib/aws-logs'; -import { Construct } from 'constructs'; +import { Construct, IConstruct } from 'constructs'; import { defaultBaseDockerImage } from './aws-image-builder'; import { RunnerImageBuilderBase, RunnerImageBuilderProps } from './common'; import { BuildImageFunction } from '../../lambdas/build-image-function'; @@ -362,3 +363,19 @@ export class CodeBuildRunnerImageBuilder extends RunnerImageBuilderBase { return this.role; } } + +/** + * @internal + */ +export class CodeBuildImageBuilderFailedBuildNotifier implements cdk.IAspect { + constructor(private topic: sns.ITopic) { + } + + public visit(node: IConstruct): void { + if (node instanceof CodeBuildRunnerImageBuilder) { + const builder = node as CodeBuildRunnerImageBuilder; + const project = builder.node.findChild('CodeBuild') as codebuild.Project; + project.notifyOnBuildFailed('BuildFailed', this.topic); + } + } +} diff --git a/src/runner.ts b/src/runner.ts index 8d2ae2bd..af59576c 100644 --- a/src/runner.ts +++ b/src/runner.ts @@ -6,6 +6,7 @@ import { aws_iam as iam, aws_lambda as lambda, aws_logs as logs, + aws_sns as sns, aws_stepfunctions as stepfunctions, aws_stepfunctions_tasks as stepfunctions_tasks, RemovalPolicy, @@ -16,6 +17,7 @@ import { DeleteRunnerFunction } from './lambdas/delete-runner-function'; import { SetupFunction } from './lambdas/setup-function'; import { StatusFunction } from './lambdas/status-function'; import { TokenRetrieverFunction } from './lambdas/token-retriever-function'; +import { AwsImageBuilderFailedBuildNotifier, CodeBuildImageBuilderFailedBuildNotifier } from './providers'; import { CodeBuildRunnerProvider } from './providers/codebuild'; import { IRunnerProvider } from './providers/common'; import { FargateRunnerProvider } from './providers/fargate'; @@ -614,4 +616,23 @@ export class GitHubRunners extends Construct { public metricTime(props?: cloudwatch.MetricProps): cloudwatch.Metric { return this.orchestrator.metricTime(props); } + + /** + * Creates a topic for notifications when a runner image build fails. + * + * Runner images are rebuilt every week by default. This provides the latest GitHub Runner version and software updates. + * + * If you want to be sure you are using the latest runner version, you can use this topic to be notified when a build fails. + */ + public failedImageBuildsTopic() { + const topic = new sns.Topic(this, 'Failed Runner Image Builds'); + const stack = cdk.Stack.of(this); + cdk.Aspects.of(stack).add(new CodeBuildImageBuilderFailedBuildNotifier(topic)); + cdk.Aspects.of(stack).add( + new AwsImageBuilderFailedBuildNotifier( + AwsImageBuilderFailedBuildNotifier.createFilteringTopic(this, topic), + ), + ); + return topic; + } } diff --git a/test/default.integ.snapshot/github-runners-test.assets.json b/test/default.integ.snapshot/github-runners-test.assets.json index eaa5c5d2..e457e0a2 100644 --- a/test/default.integ.snapshot/github-runners-test.assets.json +++ b/test/default.integ.snapshot/github-runners-test.assets.json @@ -183,7 +183,20 @@ } } }, - "d683e78c33c4de0163529ce1ae47b62cbdea581ddc99af53dff5e914efc37944": { + "a03b764f5d4bc761c5335ccb74f4496f0ac4044feac5c489f1b70e2f082f25f8": { + "source": { + "path": "asset.a03b764f5d4bc761c5335ccb74f4496f0ac4044feac5c489f1b70e2f082f25f8.lambda", + "packaging": "zip" + }, + "destinations": { + "current_account-current_region": { + "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", + "objectKey": "a03b764f5d4bc761c5335ccb74f4496f0ac4044feac5c489f1b70e2f082f25f8.zip", + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" + } + } + }, + "3eae1c989c4929e82fc388bb698cb8ef1310f800f06fee5e92b0ed0824cc1245": { "source": { "path": "github-runners-test.template.json", "packaging": "file" @@ -191,7 +204,7 @@ "destinations": { "current_account-current_region": { "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", - "objectKey": "d683e78c33c4de0163529ce1ae47b62cbdea581ddc99af53dff5e914efc37944.json", + "objectKey": "3eae1c989c4929e82fc388bb698cb8ef1310f800f06fee5e92b0ed0824cc1245.json", "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" } } diff --git a/test/default.integ.snapshot/github-runners-test.template.json b/test/default.integ.snapshot/github-runners-test.template.json index efcc0055..9a25d3ba 100644 --- a/test/default.integ.snapshot/github-runners-test.template.json +++ b/test/default.integ.snapshot/github-runners-test.template.json @@ -589,6 +589,30 @@ ] } }, + "FargatebuilderCodeBuildBuildFailed1D2D3785": { + "Type": "AWS::CodeStarNotifications::NotificationRule", + "Properties": { + "DetailType": "FULL", + "EventTypeIds": [ + "codebuild-project-build-state-failed" + ], + "Name": "githubrunnerstestFargatebuilderCodeBuildBuildFailed8BDBCD42", + "Resource": { + "Fn::GetAtt": [ + "FargatebuilderCodeBuild4F182743", + "Arn" + ] + }, + "Targets": [ + { + "TargetAddress": { + "Ref": "runnersFailedRunnerImageBuilds233D2237" + }, + "TargetType": "SNS" + } + ] + } + }, "FargatebuilderCRPolicy22FB4B05": { "Type": "AWS::IAM::Policy", "Properties": { @@ -725,6 +749,7 @@ "buildimagedcc036c8876b451ea2c1552f9e06e9e1LogRetention13129CEB", "buildimagedcc036c8876b451ea2c1552f9e06e9e173B4162A", "buildimagedcc036c8876b451ea2c1552f9e06e9e1ServiceRoleC3DE4837", + "FargatebuilderCodeBuildBuildFailed1D2D3785", "FargatebuilderCodeBuildEventsRoleDefaultPolicyD2B048CD", "FargatebuilderCodeBuildEventsRole92F2259E", "FargatebuilderCodeBuild4F182743", @@ -1162,6 +1187,30 @@ ] } }, + "FargatebuilderarmCodeBuildBuildFailed264992E6": { + "Type": "AWS::CodeStarNotifications::NotificationRule", + "Properties": { + "DetailType": "FULL", + "EventTypeIds": [ + "codebuild-project-build-state-failed" + ], + "Name": "githubrunnerstestFargatebuilderarmCodeBuildBuildFailed60EDAF2B", + "Resource": { + "Fn::GetAtt": [ + "FargatebuilderarmCodeBuild0D30679A", + "Arn" + ] + }, + "Targets": [ + { + "TargetAddress": { + "Ref": "runnersFailedRunnerImageBuilds233D2237" + }, + "TargetType": "SNS" + } + ] + } + }, "FargatebuilderarmCRPolicyD241BB66": { "Type": "AWS::IAM::Policy", "Properties": { @@ -1298,6 +1347,7 @@ "buildimagedcc036c8876b451ea2c1552f9e06e9e1LogRetention13129CEB", "buildimagedcc036c8876b451ea2c1552f9e06e9e173B4162A", "buildimagedcc036c8876b451ea2c1552f9e06e9e1ServiceRoleC3DE4837", + "FargatebuilderarmCodeBuildBuildFailed264992E6", "FargatebuilderarmCodeBuildEventsRoleDefaultPolicy39CAA8CB", "FargatebuilderarmCodeBuildEventsRole20E8CE66", "FargatebuilderarmCodeBuild0D30679A", @@ -1743,6 +1793,30 @@ ] } }, + "LambdaImageBuilderx64CodeBuildBuildFailed7E839416": { + "Type": "AWS::CodeStarNotifications::NotificationRule", + "Properties": { + "DetailType": "FULL", + "EventTypeIds": [ + "codebuild-project-build-state-failed" + ], + "Name": "thubrunnerstestLambdaImageBuilderx64CodeBuildBuildFailedE326D971", + "Resource": { + "Fn::GetAtt": [ + "LambdaImageBuilderx64CodeBuild67DE14C8", + "Arn" + ] + }, + "Targets": [ + { + "TargetAddress": { + "Ref": "runnersFailedRunnerImageBuilds233D2237" + }, + "TargetType": "SNS" + } + ] + } + }, "LambdaImageBuilderx64CRPolicy6DBE0D1F": { "Type": "AWS::IAM::Policy", "Properties": { @@ -1887,6 +1961,7 @@ "buildimagedcc036c8876b451ea2c1552f9e06e9e1LogRetention13129CEB", "buildimagedcc036c8876b451ea2c1552f9e06e9e173B4162A", "buildimagedcc036c8876b451ea2c1552f9e06e9e1ServiceRoleC3DE4837", + "LambdaImageBuilderx64CodeBuildBuildFailed7E839416", "LambdaImageBuilderx64CodeBuildEventsRoleDefaultPolicy2B894997", "LambdaImageBuilderx64CodeBuildEventsRoleF8B03C21", "LambdaImageBuilderx64CodeBuild67DE14C8", @@ -2838,6 +2913,9 @@ ] } ], + "SnsTopicArn": { + "Ref": "runnersImageBuilderBuildsDF5A50E4" + }, "SubnetId": { "Ref": "VpcPublicSubnet1Subnet5C2D37C4" } @@ -3888,6 +3966,9 @@ ] } ], + "SnsTopicArn": { + "Ref": "runnersImageBuilderBuildsDF5A50E4" + }, "SubnetId": { "Ref": "VpcPublicSubnet1Subnet5C2D37C4" } @@ -4415,6 +4496,30 @@ ] } }, + "CodeBuildImageBuilderCodeBuildBuildFailed9B205D70": { + "Type": "AWS::CodeStarNotifications::NotificationRule", + "Properties": { + "DetailType": "FULL", + "EventTypeIds": [ + "codebuild-project-build-state-failed" + ], + "Name": "thubrunnerstestCodeBuildImageBuilderCodeBuildBuildFailed73942339", + "Resource": { + "Fn::GetAtt": [ + "CodeBuildImageBuilderCodeBuild38ECAA44", + "Arn" + ] + }, + "Targets": [ + { + "TargetAddress": { + "Ref": "runnersFailedRunnerImageBuilds233D2237" + }, + "TargetType": "SNS" + } + ] + } + }, "CodeBuildImageBuilderCRPolicyAFC63F28": { "Type": "AWS::IAM::Policy", "Properties": { @@ -4551,6 +4656,7 @@ "buildimagedcc036c8876b451ea2c1552f9e06e9e1LogRetention13129CEB", "buildimagedcc036c8876b451ea2c1552f9e06e9e173B4162A", "buildimagedcc036c8876b451ea2c1552f9e06e9e1ServiceRoleC3DE4837", + "CodeBuildImageBuilderCodeBuildBuildFailed9B205D70", "CodeBuildImageBuilderCodeBuildEventsRoleDefaultPolicyF7AE539D", "CodeBuildImageBuilderCodeBuildEventsRole4277A55E", "CodeBuildImageBuilderCodeBuild38ECAA44", @@ -4988,6 +5094,30 @@ ] } }, + "CodeBuildImageBuilderarmCodeBuildBuildFailed7605ECB2": { + "Type": "AWS::CodeStarNotifications::NotificationRule", + "Properties": { + "DetailType": "FULL", + "EventTypeIds": [ + "codebuild-project-build-state-failed" + ], + "Name": "brunnerstestCodeBuildImageBuilderarmCodeBuildBuildFailedF9370687", + "Resource": { + "Fn::GetAtt": [ + "CodeBuildImageBuilderarmCodeBuildBFF1CF57", + "Arn" + ] + }, + "Targets": [ + { + "TargetAddress": { + "Ref": "runnersFailedRunnerImageBuilds233D2237" + }, + "TargetType": "SNS" + } + ] + } + }, "CodeBuildImageBuilderarmCRPolicy75CB8D91": { "Type": "AWS::IAM::Policy", "Properties": { @@ -5124,6 +5254,7 @@ "buildimagedcc036c8876b451ea2c1552f9e06e9e1LogRetention13129CEB", "buildimagedcc036c8876b451ea2c1552f9e06e9e173B4162A", "buildimagedcc036c8876b451ea2c1552f9e06e9e1ServiceRoleC3DE4837", + "CodeBuildImageBuilderarmCodeBuildBuildFailed7605ECB2", "CodeBuildImageBuilderarmCodeBuildEventsRoleDefaultPolicyEA24770D", "CodeBuildImageBuilderarmCodeBuildEventsRole5ADCAD89", "CodeBuildImageBuilderarmCodeBuildBFF1CF57", @@ -5569,6 +5700,30 @@ ] } }, + "LambdaImageBuilderzCodeBuildBuildFailedFBCC1CE8": { + "Type": "AWS::CodeStarNotifications::NotificationRule", + "Properties": { + "DetailType": "FULL", + "EventTypeIds": [ + "codebuild-project-build-state-failed" + ], + "Name": "githubrunnerstestLambdaImageBuilderzCodeBuildBuildFailedD221038C", + "Resource": { + "Fn::GetAtt": [ + "LambdaImageBuilderzCodeBuild73AB6718", + "Arn" + ] + }, + "Targets": [ + { + "TargetAddress": { + "Ref": "runnersFailedRunnerImageBuilds233D2237" + }, + "TargetType": "SNS" + } + ] + } + }, "LambdaImageBuilderzCRPolicyC9B09855": { "Type": "AWS::IAM::Policy", "Properties": { @@ -5713,6 +5868,7 @@ "buildimagedcc036c8876b451ea2c1552f9e06e9e1LogRetention13129CEB", "buildimagedcc036c8876b451ea2c1552f9e06e9e173B4162A", "buildimagedcc036c8876b451ea2c1552f9e06e9e1ServiceRoleC3DE4837", + "LambdaImageBuilderzCodeBuildBuildFailedFBCC1CE8", "LambdaImageBuilderzCodeBuildEventsRoleDefaultPolicyE0DB8E23", "LambdaImageBuilderzCodeBuildEventsRoleE9E50664", "LambdaImageBuilderzCodeBuild73AB6718", @@ -6790,6 +6946,9 @@ ] } ], + "SnsTopicArn": { + "Ref": "runnersImageBuilderBuildsDF5A50E4" + }, "SubnetId": { "Ref": "VpcPublicSubnet1Subnet5C2D37C4" } @@ -7839,6 +7998,9 @@ ] } ], + "SnsTopicArn": { + "Ref": "runnersImageBuilderBuildsDF5A50E4" + }, "SubnetId": { "Ref": "VpcPublicSubnet1Subnet5C2D37C4" } @@ -17620,6 +17782,178 @@ }, "RetentionInDays": 30 } + }, + "runnersFailedRunnerImageBuilds233D2237": { + "Type": "AWS::SNS::Topic" + }, + "runnersFailedRunnerImageBuildsPolicyC1C99AF8": { + "Type": "AWS::SNS::TopicPolicy", + "Properties": { + "PolicyDocument": { + "Statement": [ + { + "Action": "sns:Publish", + "Effect": "Allow", + "Principal": { + "Service": "codestar-notifications.amazonaws.com" + }, + "Resource": { + "Ref": "runnersFailedRunnerImageBuilds233D2237" + }, + "Sid": "0" + } + ], + "Version": "2012-10-17" + }, + "Topics": [ + { + "Ref": "runnersFailedRunnerImageBuilds233D2237" + } + ] + } + }, + "runnersImageBuilderBuildsDF5A50E4": { + "Type": "AWS::SNS::Topic" + }, + "runnersImageBuilderBuildsFilterServiceRoleED82BC5F": { + "Type": "AWS::IAM::Role", + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "lambda.amazonaws.com" + } + } + ], + "Version": "2012-10-17" + }, + "ManagedPolicyArns": [ + { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" + ] + ] + } + ] + } + }, + "runnersImageBuilderBuildsFilterServiceRoleDefaultPolicy4525F6C1": { + "Type": "AWS::IAM::Policy", + "Properties": { + "PolicyDocument": { + "Statement": [ + { + "Action": "sns:Publish", + "Effect": "Allow", + "Resource": { + "Ref": "runnersFailedRunnerImageBuilds233D2237" + } + } + ], + "Version": "2012-10-17" + }, + "PolicyName": "runnersImageBuilderBuildsFilterServiceRoleDefaultPolicy4525F6C1", + "Roles": [ + { + "Ref": "runnersImageBuilderBuildsFilterServiceRoleED82BC5F" + } + ] + } + }, + "runnersImageBuilderBuildsFilterD708AA06": { + "Type": "AWS::Lambda::Function", + "Properties": { + "Code": { + "S3Bucket": { + "Fn::Sub": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}" + }, + "S3Key": "a03b764f5d4bc761c5335ccb74f4496f0ac4044feac5c489f1b70e2f082f25f8.zip" + }, + "Role": { + "Fn::GetAtt": [ + "runnersImageBuilderBuildsFilterServiceRoleED82BC5F", + "Arn" + ] + }, + "Description": "src/providers/image-builders/aws-image-builder/filter-failed-builds.lambda.ts", + "Environment": { + "Variables": { + "TARGET_TOPIC_ARN": { + "Ref": "runnersFailedRunnerImageBuilds233D2237" + }, + "AWS_NODEJS_CONNECTION_REUSE_ENABLED": "1" + } + }, + "Handler": "index.handler", + "Runtime": "nodejs16.x" + }, + "DependsOn": [ + "runnersImageBuilderBuildsFilterServiceRoleDefaultPolicy4525F6C1", + "runnersImageBuilderBuildsFilterServiceRoleED82BC5F" + ] + }, + "runnersImageBuilderBuildsFilterLogRetentionD5005098": { + "Type": "Custom::LogRetention", + "Properties": { + "ServiceToken": { + "Fn::GetAtt": [ + "LogRetentionaae0aa3c5b4d4f87b02d85b201efdd8aFD4BFC8A", + "Arn" + ] + }, + "LogGroupName": { + "Fn::Join": [ + "", + [ + "/aws/lambda/", + { + "Ref": "runnersImageBuilderBuildsFilterD708AA06" + } + ] + ] + }, + "RetentionInDays": 30 + } + }, + "runnersImageBuilderBuildsFilterAllowInvokegithubrunnerstestrunnersImageBuilderBuilds109FC9E855AB30DD": { + "Type": "AWS::Lambda::Permission", + "Properties": { + "Action": "lambda:InvokeFunction", + "FunctionName": { + "Fn::GetAtt": [ + "runnersImageBuilderBuildsFilterD708AA06", + "Arn" + ] + }, + "Principal": "sns.amazonaws.com", + "SourceArn": { + "Ref": "runnersImageBuilderBuildsDF5A50E4" + } + } + }, + "runnersImageBuilderBuildsFilterImageBuilderBuilds7F42F563": { + "Type": "AWS::SNS::Subscription", + "Properties": { + "Protocol": "lambda", + "TopicArn": { + "Ref": "runnersImageBuilderBuildsDF5A50E4" + }, + "Endpoint": { + "Fn::GetAtt": [ + "runnersImageBuilderBuildsFilterD708AA06", + "Arn" + ] + } + } } }, "Parameters": { diff --git a/test/default.integ.snapshot/manifest.json b/test/default.integ.snapshot/manifest.json index deab3782..b6279f8d 100644 --- a/test/default.integ.snapshot/manifest.json +++ b/test/default.integ.snapshot/manifest.json @@ -23,7 +23,7 @@ "validateOnSynth": false, "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-deploy-role-${AWS::AccountId}-${AWS::Region}", "cloudFormationExecutionRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-cfn-exec-role-${AWS::AccountId}-${AWS::Region}", - "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/d683e78c33c4de0163529ce1ae47b62cbdea581ddc99af53dff5e914efc37944.json", + "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/3eae1c989c4929e82fc388bb698cb8ef1310f800f06fee5e92b0ed0824cc1245.json", "requiresBootstrapStackVersion": 6, "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", "additionalDependencies": [ @@ -39,6 +39,43 @@ "github-runners-test.assets" ], "metadata": { + "/github-runners-test": [ + { + "type": "aws:cdk:info", + "data": "Number of resources: 402 is approaching allowed maximum of 500", + "trace": [ + "Annotations.addMessage (C:\\Users\\kichi\\Dropbox\\Dev\\cdk-github-runners\\node_modules\\aws-cdk-lib\\core\\lib\\annotations.js:1:1213)", + "Annotations.addInfo (C:\\Users\\kichi\\Dropbox\\Dev\\cdk-github-runners\\node_modules\\aws-cdk-lib\\core\\lib\\annotations.js:1:682)", + "Stack._synthesizeTemplate (C:\\Users\\kichi\\Dropbox\\Dev\\cdk-github-runners\\node_modules\\aws-cdk-lib\\core\\lib\\stack.js:1:9240)", + "DefaultStackSynthesizer.synthesizeTemplate (C:\\Users\\kichi\\Dropbox\\Dev\\cdk-github-runners\\node_modules\\aws-cdk-lib\\core\\lib\\stack-synthesizers\\stack-synthesizer.js:1:1584)", + "DefaultStackSynthesizer.synthesize (C:\\Users\\kichi\\Dropbox\\Dev\\cdk-github-runners\\node_modules\\aws-cdk-lib\\core\\lib\\stack-synthesizers\\default-synthesizer.js:1:5757)", + "C:\\Users\\kichi\\Dropbox\\Dev\\cdk-github-runners\\node_modules\\aws-cdk-lib\\core\\lib\\private\\synthesis.js:1:2661", + "visit (C:\\Users\\kichi\\Dropbox\\Dev\\cdk-github-runners\\node_modules\\aws-cdk-lib\\core\\lib\\private\\synthesis.js:3:179)", + "visit (C:\\Users\\kichi\\Dropbox\\Dev\\cdk-github-runners\\node_modules\\aws-cdk-lib\\core\\lib\\private\\synthesis.js:3:141)", + "synthesizeTree (C:\\Users\\kichi\\Dropbox\\Dev\\cdk-github-runners\\node_modules\\aws-cdk-lib\\core\\lib\\private\\synthesis.js:1:2505)", + "Object.synthesize (C:\\Users\\kichi\\Dropbox\\Dev\\cdk-github-runners\\node_modules\\aws-cdk-lib\\core\\lib\\private\\synthesis.js:1:735)", + "App.synth (C:\\Users\\kichi\\Dropbox\\Dev\\cdk-github-runners\\node_modules\\aws-cdk-lib\\core\\lib\\stage.js:1:1883)", + "Object. (C:\\Users\\kichi\\Dropbox\\Dev\\cdk-github-runners\\test\\default.integ.ts:241:5)", + "Module._compile (node:internal/modules/cjs/loader:1254:14)", + "Module.m._compile (C:\\Users\\kichi\\Dropbox\\Dev\\cdk-github-runners\\node_modules\\ts-node\\src\\index.ts:1618:23)", + "Module._extensions..js (node:internal/modules/cjs/loader:1308:10)", + "Object.require.extensions. [as .ts] (C:\\Users\\kichi\\Dropbox\\Dev\\cdk-github-runners\\node_modules\\ts-node\\src\\index.ts:1621:12)", + "Module.load (node:internal/modules/cjs/loader:1117:32)", + "Function.Module._load (node:internal/modules/cjs/loader:958:12)", + "Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:81:12)", + "phase4 (C:\\Users\\kichi\\Dropbox\\Dev\\cdk-github-runners\\node_modules\\ts-node\\src\\bin.ts:649:14)", + "bootstrap (C:\\Users\\kichi\\Dropbox\\Dev\\cdk-github-runners\\node_modules\\ts-node\\src\\bin.ts:95:10)", + "main (C:\\Users\\kichi\\Dropbox\\Dev\\cdk-github-runners\\node_modules\\ts-node\\src\\bin.ts:55:10)", + "Object. (C:\\Users\\kichi\\Dropbox\\Dev\\cdk-github-runners\\node_modules\\ts-node\\src\\bin.ts:800:3)", + "Module._compile (node:internal/modules/cjs/loader:1254:14)", + "Object.Module._extensions..js (node:internal/modules/cjs/loader:1308:10)", + "Module.load (node:internal/modules/cjs/loader:1117:32)", + "Function.Module._load (node:internal/modules/cjs/loader:958:12)", + "Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:81:12)", + "node:internal/main/run_main_module:23:47" + ] + } + ], "/github-runners-test/Vpc/Resource": [ { "type": "aws:cdk:logicalId", @@ -159,6 +196,12 @@ "data": "FargatebuilderCodeBuildEventsRoleDefaultPolicyD2B048CD" } ], + "/github-runners-test/Fargate builder/CodeBuild/BuildFailed/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "FargatebuilderCodeBuildBuildFailed1D2D3785" + } + ], "/github-runners-test/Fargate builder/CR Policy/Resource": [ { "type": "aws:cdk:logicalId", @@ -219,6 +262,12 @@ "data": "FargatebuilderarmCodeBuildEventsRoleDefaultPolicy39CAA8CB" } ], + "/github-runners-test/Fargate builder arm/CodeBuild/BuildFailed/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "FargatebuilderarmCodeBuildBuildFailed264992E6" + } + ], "/github-runners-test/Fargate builder arm/CR Policy/Resource": [ { "type": "aws:cdk:logicalId", @@ -279,6 +328,12 @@ "data": "LambdaImageBuilderx64CodeBuildEventsRoleDefaultPolicy2B894997" } ], + "/github-runners-test/Lambda Image Builder x64/CodeBuild/BuildFailed/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "LambdaImageBuilderx64CodeBuildBuildFailed7E839416" + } + ], "/github-runners-test/Lambda Image Builder x64/CR Policy/Resource": [ { "type": "aws:cdk:logicalId", @@ -723,6 +778,12 @@ "data": "CodeBuildImageBuilderCodeBuildEventsRoleDefaultPolicyF7AE539D" } ], + "/github-runners-test/CodeBuild Image Builder/CodeBuild/BuildFailed/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "CodeBuildImageBuilderCodeBuildBuildFailed9B205D70" + } + ], "/github-runners-test/CodeBuild Image Builder/CR Policy/Resource": [ { "type": "aws:cdk:logicalId", @@ -783,6 +844,12 @@ "data": "CodeBuildImageBuilderarmCodeBuildEventsRoleDefaultPolicyEA24770D" } ], + "/github-runners-test/CodeBuild Image Builder arm/CodeBuild/BuildFailed/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "CodeBuildImageBuilderarmCodeBuildBuildFailed7605ECB2" + } + ], "/github-runners-test/CodeBuild Image Builder arm/CR Policy/Resource": [ { "type": "aws:cdk:logicalId", @@ -843,6 +910,12 @@ "data": "LambdaImageBuilderzCodeBuildEventsRoleDefaultPolicyE0DB8E23" } ], + "/github-runners-test/Lambda Image Builderz/CodeBuild/BuildFailed/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "LambdaImageBuilderzCodeBuildBuildFailedFBCC1CE8" + } + ], "/github-runners-test/Lambda Image Builderz/CR Policy/Resource": [ { "type": "aws:cdk:logicalId", @@ -2403,6 +2476,60 @@ "data": "runnersstatuscommand4A30F0F5" } ], + "/github-runners-test/runners/Failed Runner Image Builds/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "runnersFailedRunnerImageBuilds233D2237" + } + ], + "/github-runners-test/runners/Failed Runner Image Builds/Policy/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "runnersFailedRunnerImageBuildsPolicyC1C99AF8" + } + ], + "/github-runners-test/runners/Image Builder Builds/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "runnersImageBuilderBuildsDF5A50E4" + } + ], + "/github-runners-test/runners/Image Builder Builds Filter/ServiceRole/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "runnersImageBuilderBuildsFilterServiceRoleED82BC5F" + } + ], + "/github-runners-test/runners/Image Builder Builds Filter/ServiceRole/DefaultPolicy/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "runnersImageBuilderBuildsFilterServiceRoleDefaultPolicy4525F6C1" + } + ], + "/github-runners-test/runners/Image Builder Builds Filter/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "runnersImageBuilderBuildsFilterD708AA06" + } + ], + "/github-runners-test/runners/Image Builder Builds Filter/LogRetention/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "runnersImageBuilderBuildsFilterLogRetentionD5005098" + } + ], + "/github-runners-test/runners/Image Builder Builds Filter/AllowInvoke:githubrunnerstestrunnersImageBuilderBuilds109FC9E8": [ + { + "type": "aws:cdk:logicalId", + "data": "runnersImageBuilderBuildsFilterAllowInvokegithubrunnerstestrunnersImageBuilderBuilds109FC9E855AB30DD" + } + ], + "/github-runners-test/runners/Image Builder Builds Filter/Image Builder Builds/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "runnersImageBuilderBuildsFilterImageBuilderBuilds7F42F563" + } + ], "/github-runners-test/Service-principalMap": [ { "type": "aws:cdk:logicalId", diff --git a/test/default.integ.snapshot/tree.json b/test/default.integ.snapshot/tree.json index 87d8c01e..880d3e72 100644 --- a/test/default.integ.snapshot/tree.json +++ b/test/default.integ.snapshot/tree.json @@ -905,6 +905,48 @@ "fqn": "aws-cdk-lib.aws_iam.Role", "version": "2.50.0" } + }, + "BuildFailed": { + "id": "BuildFailed", + "path": "github-runners-test/Fargate builder/CodeBuild/BuildFailed", + "children": { + "Resource": { + "id": "Resource", + "path": "github-runners-test/Fargate builder/CodeBuild/BuildFailed/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::CodeStarNotifications::NotificationRule", + "aws:cdk:cloudformation:props": { + "detailType": "FULL", + "eventTypeIds": [ + "codebuild-project-build-state-failed" + ], + "name": "githubrunnerstestFargatebuilderCodeBuildBuildFailed8BDBCD42", + "resource": { + "Fn::GetAtt": [ + "FargatebuilderCodeBuild4F182743", + "Arn" + ] + }, + "targets": [ + { + "targetType": "SNS", + "targetAddress": { + "Ref": "runnersFailedRunnerImageBuilds233D2237" + } + } + ] + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_codestarnotifications.CfnNotificationRule", + "version": "2.50.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_codestarnotifications.NotificationRule", + "version": "2.50.0" + } } }, "constructInfo": { @@ -1591,6 +1633,48 @@ "fqn": "aws-cdk-lib.aws_iam.Role", "version": "2.50.0" } + }, + "BuildFailed": { + "id": "BuildFailed", + "path": "github-runners-test/Fargate builder arm/CodeBuild/BuildFailed", + "children": { + "Resource": { + "id": "Resource", + "path": "github-runners-test/Fargate builder arm/CodeBuild/BuildFailed/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::CodeStarNotifications::NotificationRule", + "aws:cdk:cloudformation:props": { + "detailType": "FULL", + "eventTypeIds": [ + "codebuild-project-build-state-failed" + ], + "name": "githubrunnerstestFargatebuilderarmCodeBuildBuildFailed60EDAF2B", + "resource": { + "Fn::GetAtt": [ + "FargatebuilderarmCodeBuild0D30679A", + "Arn" + ] + }, + "targets": [ + { + "targetType": "SNS", + "targetAddress": { + "Ref": "runnersFailedRunnerImageBuilds233D2237" + } + } + ] + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_codestarnotifications.CfnNotificationRule", + "version": "2.50.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_codestarnotifications.NotificationRule", + "version": "2.50.0" + } } }, "constructInfo": { @@ -2337,6 +2421,48 @@ "fqn": "aws-cdk-lib.aws_iam.Role", "version": "2.50.0" } + }, + "BuildFailed": { + "id": "BuildFailed", + "path": "github-runners-test/Lambda Image Builder x64/CodeBuild/BuildFailed", + "children": { + "Resource": { + "id": "Resource", + "path": "github-runners-test/Lambda Image Builder x64/CodeBuild/BuildFailed/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::CodeStarNotifications::NotificationRule", + "aws:cdk:cloudformation:props": { + "detailType": "FULL", + "eventTypeIds": [ + "codebuild-project-build-state-failed" + ], + "name": "thubrunnerstestLambdaImageBuilderx64CodeBuildBuildFailedE326D971", + "resource": { + "Fn::GetAtt": [ + "LambdaImageBuilderx64CodeBuild67DE14C8", + "Arn" + ] + }, + "targets": [ + { + "targetType": "SNS", + "targetAddress": { + "Ref": "runnersFailedRunnerImageBuilds233D2237" + } + } + ] + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_codestarnotifications.CfnNotificationRule", + "version": "2.50.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_codestarnotifications.NotificationRule", + "version": "2.50.0" + } } }, "constructInfo": { @@ -3432,6 +3558,9 @@ ] } ], + "snsTopicArn": { + "Ref": "runnersImageBuilderBuildsDF5A50E4" + }, "subnetId": { "Ref": "VpcPublicSubnet1Subnet5C2D37C4" } @@ -4531,6 +4660,9 @@ ] } ], + "snsTopicArn": { + "Ref": "runnersImageBuilderBuildsDF5A50E4" + }, "subnetId": { "Ref": "VpcPublicSubnet1Subnet5C2D37C4" } @@ -5267,6 +5399,48 @@ "fqn": "aws-cdk-lib.aws_iam.Role", "version": "2.50.0" } + }, + "BuildFailed": { + "id": "BuildFailed", + "path": "github-runners-test/CodeBuild Image Builder/CodeBuild/BuildFailed", + "children": { + "Resource": { + "id": "Resource", + "path": "github-runners-test/CodeBuild Image Builder/CodeBuild/BuildFailed/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::CodeStarNotifications::NotificationRule", + "aws:cdk:cloudformation:props": { + "detailType": "FULL", + "eventTypeIds": [ + "codebuild-project-build-state-failed" + ], + "name": "thubrunnerstestCodeBuildImageBuilderCodeBuildBuildFailed73942339", + "resource": { + "Fn::GetAtt": [ + "CodeBuildImageBuilderCodeBuild38ECAA44", + "Arn" + ] + }, + "targets": [ + { + "targetType": "SNS", + "targetAddress": { + "Ref": "runnersFailedRunnerImageBuilds233D2237" + } + } + ] + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_codestarnotifications.CfnNotificationRule", + "version": "2.50.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_codestarnotifications.NotificationRule", + "version": "2.50.0" + } } }, "constructInfo": { @@ -5953,6 +6127,48 @@ "fqn": "aws-cdk-lib.aws_iam.Role", "version": "2.50.0" } + }, + "BuildFailed": { + "id": "BuildFailed", + "path": "github-runners-test/CodeBuild Image Builder arm/CodeBuild/BuildFailed", + "children": { + "Resource": { + "id": "Resource", + "path": "github-runners-test/CodeBuild Image Builder arm/CodeBuild/BuildFailed/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::CodeStarNotifications::NotificationRule", + "aws:cdk:cloudformation:props": { + "detailType": "FULL", + "eventTypeIds": [ + "codebuild-project-build-state-failed" + ], + "name": "brunnerstestCodeBuildImageBuilderarmCodeBuildBuildFailedF9370687", + "resource": { + "Fn::GetAtt": [ + "CodeBuildImageBuilderarmCodeBuildBFF1CF57", + "Arn" + ] + }, + "targets": [ + { + "targetType": "SNS", + "targetAddress": { + "Ref": "runnersFailedRunnerImageBuilds233D2237" + } + } + ] + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_codestarnotifications.CfnNotificationRule", + "version": "2.50.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_codestarnotifications.NotificationRule", + "version": "2.50.0" + } } }, "constructInfo": { @@ -6699,6 +6915,48 @@ "fqn": "aws-cdk-lib.aws_iam.Role", "version": "2.50.0" } + }, + "BuildFailed": { + "id": "BuildFailed", + "path": "github-runners-test/Lambda Image Builderz/CodeBuild/BuildFailed", + "children": { + "Resource": { + "id": "Resource", + "path": "github-runners-test/Lambda Image Builderz/CodeBuild/BuildFailed/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::CodeStarNotifications::NotificationRule", + "aws:cdk:cloudformation:props": { + "detailType": "FULL", + "eventTypeIds": [ + "codebuild-project-build-state-failed" + ], + "name": "githubrunnerstestLambdaImageBuilderzCodeBuildBuildFailedD221038C", + "resource": { + "Fn::GetAtt": [ + "LambdaImageBuilderzCodeBuild73AB6718", + "Arn" + ] + }, + "targets": [ + { + "targetType": "SNS", + "targetAddress": { + "Ref": "runnersFailedRunnerImageBuilds233D2237" + } + } + ] + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_codestarnotifications.CfnNotificationRule", + "version": "2.50.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_codestarnotifications.NotificationRule", + "version": "2.50.0" + } } }, "constructInfo": { @@ -7908,6 +8166,9 @@ ] } ], + "snsTopicArn": { + "Ref": "runnersImageBuilderBuildsDF5A50E4" + }, "subnetId": { "Ref": "VpcPublicSubnet1Subnet5C2D37C4" } @@ -9019,6 +9280,9 @@ ] } ], + "snsTopicArn": { + "Ref": "runnersImageBuilderBuildsDF5A50E4" + }, "subnetId": { "Ref": "VpcPublicSubnet1Subnet5C2D37C4" } @@ -21292,6 +21556,339 @@ "fqn": "aws-cdk-lib.CfnOutput", "version": "2.50.0" } + }, + "Failed Runner Image Builds": { + "id": "Failed Runner Image Builds", + "path": "github-runners-test/runners/Failed Runner Image Builds", + "children": { + "Resource": { + "id": "Resource", + "path": "github-runners-test/runners/Failed Runner Image Builds/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::SNS::Topic", + "aws:cdk:cloudformation:props": {} + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_sns.CfnTopic", + "version": "2.50.0" + } + }, + "Policy": { + "id": "Policy", + "path": "github-runners-test/runners/Failed Runner Image Builds/Policy", + "children": { + "Resource": { + "id": "Resource", + "path": "github-runners-test/runners/Failed Runner Image Builds/Policy/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::SNS::TopicPolicy", + "aws:cdk:cloudformation:props": { + "policyDocument": { + "Statement": [ + { + "Action": "sns:Publish", + "Effect": "Allow", + "Principal": { + "Service": "codestar-notifications.amazonaws.com" + }, + "Resource": { + "Ref": "runnersFailedRunnerImageBuilds233D2237" + }, + "Sid": "0" + } + ], + "Version": "2012-10-17" + }, + "topics": [ + { + "Ref": "runnersFailedRunnerImageBuilds233D2237" + } + ] + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_sns.CfnTopicPolicy", + "version": "2.50.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_sns.TopicPolicy", + "version": "2.50.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_sns.Topic", + "version": "2.50.0" + } + }, + "Image Builder Builds": { + "id": "Image Builder Builds", + "path": "github-runners-test/runners/Image Builder Builds", + "children": { + "Resource": { + "id": "Resource", + "path": "github-runners-test/runners/Image Builder Builds/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::SNS::Topic", + "aws:cdk:cloudformation:props": {} + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_sns.CfnTopic", + "version": "2.50.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_sns.Topic", + "version": "2.50.0" + } + }, + "Image Builder Builds Filter": { + "id": "Image Builder Builds Filter", + "path": "github-runners-test/runners/Image Builder Builds Filter", + "children": { + "ServiceRole": { + "id": "ServiceRole", + "path": "github-runners-test/runners/Image Builder Builds Filter/ServiceRole", + "children": { + "Resource": { + "id": "Resource", + "path": "github-runners-test/runners/Image Builder Builds Filter/ServiceRole/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::IAM::Role", + "aws:cdk:cloudformation:props": { + "assumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "lambda.amazonaws.com" + } + } + ], + "Version": "2012-10-17" + }, + "managedPolicyArns": [ + { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" + ] + ] + } + ] + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_iam.CfnRole", + "version": "2.50.0" + } + }, + "DefaultPolicy": { + "id": "DefaultPolicy", + "path": "github-runners-test/runners/Image Builder Builds Filter/ServiceRole/DefaultPolicy", + "children": { + "Resource": { + "id": "Resource", + "path": "github-runners-test/runners/Image Builder Builds Filter/ServiceRole/DefaultPolicy/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::IAM::Policy", + "aws:cdk:cloudformation:props": { + "policyDocument": { + "Statement": [ + { + "Action": "sns:Publish", + "Effect": "Allow", + "Resource": { + "Ref": "runnersFailedRunnerImageBuilds233D2237" + } + } + ], + "Version": "2012-10-17" + }, + "policyName": "runnersImageBuilderBuildsFilterServiceRoleDefaultPolicy4525F6C1", + "roles": [ + { + "Ref": "runnersImageBuilderBuildsFilterServiceRoleED82BC5F" + } + ] + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_iam.CfnPolicy", + "version": "2.50.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_iam.Policy", + "version": "2.50.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_iam.Role", + "version": "2.50.0" + } + }, + "Code": { + "id": "Code", + "path": "github-runners-test/runners/Image Builder Builds Filter/Code", + "children": { + "Stage": { + "id": "Stage", + "path": "github-runners-test/runners/Image Builder Builds Filter/Code/Stage", + "constructInfo": { + "fqn": "aws-cdk-lib.AssetStaging", + "version": "2.50.0" + } + }, + "AssetBucket": { + "id": "AssetBucket", + "path": "github-runners-test/runners/Image Builder Builds Filter/Code/AssetBucket", + "constructInfo": { + "fqn": "aws-cdk-lib.aws_s3.BucketBase", + "version": "2.50.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_s3_assets.Asset", + "version": "2.50.0" + } + }, + "Resource": { + "id": "Resource", + "path": "github-runners-test/runners/Image Builder Builds Filter/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::Lambda::Function", + "aws:cdk:cloudformation:props": { + "code": { + "s3Bucket": { + "Fn::Sub": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}" + }, + "s3Key": "a03b764f5d4bc761c5335ccb74f4496f0ac4044feac5c489f1b70e2f082f25f8.zip" + }, + "role": { + "Fn::GetAtt": [ + "runnersImageBuilderBuildsFilterServiceRoleED82BC5F", + "Arn" + ] + }, + "description": "src/providers/image-builders/aws-image-builder/filter-failed-builds.lambda.ts", + "environment": { + "variables": { + "TARGET_TOPIC_ARN": { + "Ref": "runnersFailedRunnerImageBuilds233D2237" + }, + "AWS_NODEJS_CONNECTION_REUSE_ENABLED": "1" + } + }, + "handler": "index.handler", + "runtime": "nodejs16.x" + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_lambda.CfnFunction", + "version": "2.50.0" + } + }, + "LogRetention": { + "id": "LogRetention", + "path": "github-runners-test/runners/Image Builder Builds Filter/LogRetention", + "children": { + "Resource": { + "id": "Resource", + "path": "github-runners-test/runners/Image Builder Builds Filter/LogRetention/Resource", + "constructInfo": { + "fqn": "aws-cdk-lib.CfnResource", + "version": "2.50.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_logs.LogRetention", + "version": "2.50.0" + } + }, + "LogGroup": { + "id": "LogGroup", + "path": "github-runners-test/runners/Image Builder Builds Filter/LogGroup", + "constructInfo": { + "fqn": "aws-cdk-lib.Resource", + "version": "2.50.0" + } + }, + "AllowInvoke:githubrunnerstestrunnersImageBuilderBuilds109FC9E8": { + "id": "AllowInvoke:githubrunnerstestrunnersImageBuilderBuilds109FC9E8", + "path": "github-runners-test/runners/Image Builder Builds Filter/AllowInvoke:githubrunnerstestrunnersImageBuilderBuilds109FC9E8", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::Lambda::Permission", + "aws:cdk:cloudformation:props": { + "action": "lambda:InvokeFunction", + "functionName": { + "Fn::GetAtt": [ + "runnersImageBuilderBuildsFilterD708AA06", + "Arn" + ] + }, + "principal": "sns.amazonaws.com", + "sourceArn": { + "Ref": "runnersImageBuilderBuildsDF5A50E4" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_lambda.CfnPermission", + "version": "2.50.0" + } + }, + "Image Builder Builds": { + "id": "Image Builder Builds", + "path": "github-runners-test/runners/Image Builder Builds Filter/Image Builder Builds", + "children": { + "Resource": { + "id": "Resource", + "path": "github-runners-test/runners/Image Builder Builds Filter/Image Builder Builds/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::SNS::Subscription", + "aws:cdk:cloudformation:props": { + "protocol": "lambda", + "topicArn": { + "Ref": "runnersImageBuilderBuildsDF5A50E4" + }, + "endpoint": { + "Fn::GetAtt": [ + "runnersImageBuilderBuildsFilterD708AA06", + "Arn" + ] + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_sns.CfnSubscription", + "version": "2.50.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_sns.Subscription", + "version": "2.50.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_lambda.Function", + "version": "2.50.0" + } } }, "constructInfo": { diff --git a/test/default.integ.ts b/test/default.integ.ts index 5d1b6abc..2df09ecc 100644 --- a/test/default.integ.ts +++ b/test/default.integ.ts @@ -10,13 +10,13 @@ import { Architecture, CodeBuildRunnerProvider, Ec2RunnerProvider, + EcsRunnerProvider, FargateRunnerProvider, GitHubRunners, LambdaRunnerProvider, Os, RunnerImageComponent, } from '../src'; -import { EcsRunnerProvider } from '../src/providers/ecs'; const app = new cdk.App(); const stack = new cdk.Stack(app, 'github-runners-test'); @@ -121,7 +121,7 @@ const ec2WindowsImageBuilder = Ec2RunnerProvider.imageBuilder(stack, 'Windows EC }); ec2WindowsImageBuilder.addComponent(extraFilesComponentWindows); -new GitHubRunners(stack, 'runners', { +const runners = new GitHubRunners(stack, 'runners', { providers: [ new CodeBuildRunnerProvider(stack, 'CodeBuildx64', { label: 'codebuild-x64', @@ -233,6 +233,9 @@ new GitHubRunners(stack, 'runners', { vpc, }), ], -}).metricJobCompleted(); +}); + +runners.metricJobCompleted(); +runners.failedImageBuildsTopic(); app.synth();