diff --git a/API.md b/API.md index 3619c724..3e164e69 100644 --- a/API.md +++ b/API.md @@ -418,8 +418,6 @@ Any object. | image | RunnerImage | Docker image loaded with GitHub Actions Runner and its prerequisites. | | labels | string[] | Labels associated with this provider. | | project | aws-cdk-lib.aws_codebuild.Project | CodeBuild project hosting the runner. | -| securityGroup | aws-cdk-lib.aws_ec2.ISecurityGroup | Security group attached to the task. | -| vpc | aws-cdk-lib.aws_ec2.IVpc | VPC used for hosting the project. | --- @@ -497,30 +495,6 @@ CodeBuild project hosting the runner. --- -##### `securityGroup`Optional - -```typescript -public readonly securityGroup: ISecurityGroup; -``` - -- *Type:* aws-cdk-lib.aws_ec2.ISecurityGroup - -Security group attached to the task. - ---- - -##### `vpc`Optional - -```typescript -public readonly vpc: IVpc; -``` - -- *Type:* aws-cdk-lib.aws_ec2.IVpc - -VPC used for hosting the project. - ---- - #### Constants | **Name** | **Type** | **Description** | @@ -576,7 +550,7 @@ Available build arguments that can be set in the image builder: ### ContainerImageBuilder -- *Implements:* IImageBuilder +- *Implements:* IImageBuilder, aws-cdk-lib.aws_ec2.IConnectable An image builder that uses AWS Image Builder to build Docker images pre-baked with all the GitHub Actions runner requirements. @@ -742,6 +716,7 @@ Any object. | **Name** | **Type** | **Description** | | --- | --- | --- | | node | constructs.Node | The tree node. | +| connections | aws-cdk-lib.aws_ec2.Connections | The network connections associated with this resource. | | repository | aws-cdk-lib.aws_ecr.IRepository | *No description.* | --- @@ -758,6 +733,18 @@ The tree node. --- +##### `connections`Required + +```typescript +public readonly connections: Connections; +``` + +- *Type:* aws-cdk-lib.aws_ec2.Connections + +The network connections associated with this resource. + +--- + ##### `repository`Required ```typescript @@ -915,7 +902,6 @@ Any object. | connections | aws-cdk-lib.aws_ec2.Connections | The network connections associated with this resource. | | grantPrincipal | aws-cdk-lib.aws_iam.IPrincipal | Grant principal used to add permissions to the runner role. | | labels | string[] | Labels associated with this provider. | -| securityGroup | aws-cdk-lib.aws_ec2.ISecurityGroup | Security group attached to launched instances. | --- @@ -967,18 +953,6 @@ Labels associated with this provider. --- -##### `securityGroup`Optional - -```typescript -public readonly securityGroup: ISecurityGroup; -``` - -- *Type:* aws-cdk-lib.aws_ec2.ISecurityGroup - -Security group attached to launched instances. - ---- - ### FargateRunner @@ -1134,7 +1108,6 @@ Any object. | labels | string[] | Labels associated with this provider. | | spot | boolean | Use spot pricing for Fargate tasks. | | task | aws-cdk-lib.aws_ecs.FargateTaskDefinition | Fargate task hosting the runner. | -| securityGroup | aws-cdk-lib.aws_ec2.ISecurityGroup | Security group attached to the task. | | subnetSelection | aws-cdk-lib.aws_ec2.SubnetSelection | Subnets used for hosting the runner task. | | vpc | aws-cdk-lib.aws_ec2.IVpc | VPC used for hosting the runner task. | @@ -1262,18 +1235,6 @@ Fargate task hosting the runner. --- -##### `securityGroup`Optional - -```typescript -public readonly securityGroup: ISecurityGroup; -``` - -- *Type:* aws-cdk-lib.aws_ec2.ISecurityGroup - -Security group attached to the task. - ---- - ##### `subnetSelection`Optional ```typescript @@ -1907,8 +1868,6 @@ Any object. | grantPrincipal | aws-cdk-lib.aws_iam.IPrincipal | Grant principal used to add permissions to the runner role. | | image | RunnerImage | Docker image loaded with GitHub Actions Runner and its prerequisites. | | labels | string[] | Labels associated with this provider. | -| securityGroup | aws-cdk-lib.aws_ec2.ISecurityGroup | Security group attached to the function. | -| vpc | aws-cdk-lib.aws_ec2.IVpc | VPC used for hosting the function. | --- @@ -1986,30 +1945,6 @@ Labels associated with this provider. --- -##### `securityGroup`Optional - -```typescript -public readonly securityGroup: ISecurityGroup; -``` - -- *Type:* aws-cdk-lib.aws_ec2.ISecurityGroup - -Security group attached to the function. - ---- - -##### `vpc`Optional - -```typescript -public readonly vpc: IVpc; -``` - -- *Type:* aws-cdk-lib.aws_ec2.IVpc - -VPC used for hosting the function. - ---- - #### Constants | **Name** | **Type** | **Description** | @@ -2436,7 +2371,8 @@ const codeBuildRunnerProps: CodeBuildRunnerProps = { ... } | imageBuilder | IImageBuilder | Image builder for CodeBuild image with GitHub runner pre-configured. | | label | string | GitHub Actions label used for this provider. | | labels | string[] | GitHub Actions labels used for this provider. | -| securityGroup | aws-cdk-lib.aws_ec2.ISecurityGroup | Security Group to assign to this instance. | +| securityGroup | aws-cdk-lib.aws_ec2.ISecurityGroup | Security group to assign to this instance. | +| securityGroups | aws-cdk-lib.aws_ec2.ISecurityGroup[] | Security groups to assign to this instance. | | subnetSelection | aws-cdk-lib.aws_ec2.SubnetSelection | Where to place the network interfaces within the VPC. | | timeout | aws-cdk-lib.Duration | The number of minutes after which AWS CodeBuild stops the build if it's not complete. | | vpc | aws-cdk-lib.aws_ec2.IVpc | VPC to launch the runners in. | @@ -2522,7 +2458,9 @@ job's labels, this provider will be chosen and spawn a new runner. --- -##### `securityGroup`Optional +##### ~~`securityGroup`~~Optional + +- *Deprecated:* use {@link securityGroups} ```typescript public readonly securityGroup: ISecurityGroup; @@ -2531,7 +2469,20 @@ public readonly securityGroup: ISecurityGroup; - *Type:* aws-cdk-lib.aws_ec2.ISecurityGroup - *Default:* public project with no security group -Security Group to assign to this instance. +Security group to assign to this instance. + +--- + +##### `securityGroups`Optional + +```typescript +public readonly securityGroups: ISecurityGroup[]; +``` + +- *Type:* aws-cdk-lib.aws_ec2.ISecurityGroup[] +- *Default:* a new security group, if {@link vpc} is used + +Security groups to assign to this instance. --- @@ -2601,7 +2552,8 @@ const containerImageBuilderProps: ContainerImageBuilderProps = { ... } | parentImage | string | Parent image for the new Docker Image. | | rebuildInterval | aws-cdk-lib.Duration | Schedule the image to be rebuilt every given interval. | | runnerVersion | RunnerVersion | Version of GitHub Runners to install. | -| securityGroup | aws-cdk-lib.aws_ec2.ISecurityGroup | Security Group to assign to this instance. | +| securityGroup | aws-cdk-lib.aws_ec2.ISecurityGroup | Security group to assign to launched builder instances. | +| securityGroups | aws-cdk-lib.aws_ec2.ISecurityGroup[] | Security groups to assign to launched builder instances. | | subnetSelection | aws-cdk-lib.aws_ec2.SubnetSelection | Where to place the network interfaces within the VPC. | | vpc | aws-cdk-lib.aws_ec2.IVpc | VPC to launch the runners in. | @@ -2725,16 +2677,31 @@ Version of GitHub Runners to install. --- -##### `securityGroup`Optional +##### ~~`securityGroup`~~Optional + +- *Deprecated:* use {@link securityGroups} ```typescript public readonly securityGroup: ISecurityGroup; ``` - *Type:* aws-cdk-lib.aws_ec2.ISecurityGroup -- *Default:* default account security group +- *Default:* new security group -Security Group to assign to this instance. +Security group to assign to launched builder instances. + +--- + +##### `securityGroups`Optional + +```typescript +public readonly securityGroups: ISecurityGroup[]; +``` + +- *Type:* aws-cdk-lib.aws_ec2.ISecurityGroup[] +- *Default:* new security group + +Security groups to assign to launched builder instances. --- @@ -2785,6 +2752,7 @@ const ec2RunnerProps: Ec2RunnerProps = { ... } | instanceType | aws-cdk-lib.aws_ec2.InstanceType | Instance type for launched runner instances. | | labels | string[] | GitHub Actions labels used for this provider. | | securityGroup | aws-cdk-lib.aws_ec2.ISecurityGroup | Security Group to assign to launched runner instances. | +| securityGroups | aws-cdk-lib.aws_ec2.ISecurityGroup[] | Security groups to assign to launched runner instances. | | spot | boolean | Use spot instances to save money. | | spotMaxPrice | string | Set a maximum price for spot instances. | | storageSize | aws-cdk-lib.Size | Size of volume available for launched runner instances. | @@ -2856,19 +2824,34 @@ job's labels, this provider will be chosen and spawn a new runner. --- -##### `securityGroup`Optional +##### ~~`securityGroup`~~Optional + +- *Deprecated:* use {@link securityGroups} ```typescript public readonly securityGroup: ISecurityGroup; ``` - *Type:* aws-cdk-lib.aws_ec2.ISecurityGroup -- *Default:* account's default security group +- *Default:* a new security group Security Group to assign to launched runner instances. --- +##### `securityGroups`Optional + +```typescript +public readonly securityGroups: ISecurityGroup[]; +``` + +- *Type:* aws-cdk-lib.aws_ec2.ISecurityGroup[] +- *Default:* a new security group + +Security groups to assign to launched runner instances. + +--- + ##### `spot`Optional ```typescript @@ -2980,7 +2963,8 @@ const fargateRunnerProps: FargateRunnerProps = { ... } | label | string | GitHub Actions label used for this provider. | | labels | string[] | GitHub Actions labels used for this provider. | | memoryLimitMiB | number | The amount (in MiB) of memory used by the task. | -| securityGroup | aws-cdk-lib.aws_ec2.ISecurityGroup | Security Group to assign to the task. | +| securityGroup | aws-cdk-lib.aws_ec2.ISecurityGroup | Security group to assign to the task. | +| securityGroups | aws-cdk-lib.aws_ec2.ISecurityGroup[] | Security groups to assign to the task. | | spot | boolean | Use Fargate spot capacity provider to save money. | | subnetSelection | aws-cdk-lib.aws_ec2.SubnetSelection | Subnets to run the runners in. | | vpc | aws-cdk-lib.aws_ec2.IVpc | VPC to launch the runners in. | @@ -3149,7 +3133,9 @@ Between 8192 (8 GB) and 30720 (30 GB) in increments of 1024 (1 GB) - Available c --- -##### `securityGroup`Optional +##### ~~`securityGroup`~~Optional + +- *Deprecated:* use {@link securityGroupss} ```typescript public readonly securityGroup: ISecurityGroup; @@ -3158,7 +3144,20 @@ public readonly securityGroup: ISecurityGroup; - *Type:* aws-cdk-lib.aws_ec2.ISecurityGroup - *Default:* a new security group -Security Group to assign to the task. +Security group to assign to the task. + +--- + +##### `securityGroups`Optional + +```typescript +public readonly securityGroups: ISecurityGroup[]; +``` + +- *Type:* aws-cdk-lib.aws_ec2.ISecurityGroup[] +- *Default:* a new security group + +Security groups to assign to the task. --- @@ -3504,7 +3503,8 @@ const lambdaRunnerProps: LambdaRunnerProps = { ... } | label | string | GitHub Actions label used for this provider. | | labels | string[] | GitHub Actions labels used for this provider. | | memorySize | number | The amount of memory, in MB, that is allocated to your Lambda function. | -| securityGroup | aws-cdk-lib.aws_ec2.ISecurityGroup | Security Group to assign to this instance. | +| securityGroup | aws-cdk-lib.aws_ec2.ISecurityGroup | Security group to assign to this instance. | +| securityGroups | aws-cdk-lib.aws_ec2.ISecurityGroup[] | Security groups to assign to this instance. | | subnetSelection | aws-cdk-lib.aws_ec2.SubnetSelection | Where to place the network interfaces within the VPC. | | timeout | aws-cdk-lib.Duration | The function execution time (in seconds) after which Lambda terminates the function. | | vpc | aws-cdk-lib.aws_ec2.IVpc | VPC to launch the runners in. | @@ -3607,7 +3607,9 @@ Developer Guide. --- -##### `securityGroup`Optional +##### ~~`securityGroup`~~Optional + +- *Deprecated:* use {@link securityGroups} ```typescript public readonly securityGroup: ISecurityGroup; @@ -3616,7 +3618,20 @@ public readonly securityGroup: ISecurityGroup; - *Type:* aws-cdk-lib.aws_ec2.ISecurityGroup - *Default:* public lambda with no security group -Security Group to assign to this instance. +Security group to assign to this instance. + +--- + +##### `securityGroups`Optional + +```typescript +public readonly securityGroups: ISecurityGroup[]; +``` + +- *Type:* aws-cdk-lib.aws_ec2.ISecurityGroup[] +- *Default:* public lambda with no security group + +Security groups to assign to this instance. --- @@ -5038,8 +5053,6 @@ grantable for the status function. | connections | aws-cdk-lib.aws_ec2.Connections | The network connections associated with this resource. | | grantPrincipal | aws-cdk-lib.aws_iam.IPrincipal | The principal to grant permissions to. | | labels | string[] | GitHub Actions labels used for this provider. | -| securityGroup | aws-cdk-lib.aws_ec2.ISecurityGroup | Security group associated with runners. | -| vpc | aws-cdk-lib.aws_ec2.IVpc | VPC network in which runners will be placed. | --- @@ -5083,30 +5096,6 @@ job's labels, this provider will be chosen and spawn a new runner. --- -##### `securityGroup`Optional - -```typescript -public readonly securityGroup: ISecurityGroup; -``` - -- *Type:* aws-cdk-lib.aws_ec2.ISecurityGroup - -Security group associated with runners. - ---- - -##### `vpc`Optional - -```typescript -public readonly vpc: IVpc; -``` - -- *Type:* aws-cdk-lib.aws_ec2.IVpc - -VPC network in which runners will be placed. - ---- - ### IRunnerProviderStatus - *Implemented By:* IRunnerProviderStatus @@ -5123,7 +5112,7 @@ Interface for runner image status used by status.json. | ami | IRunnerAmiStatus | Details about AMI used by this runner provider. | | image | IRunnerImageStatus | Details about Docker image used by this runner provider. | | roleArn | string | Role attached to runners. | -| securityGroup | string | Security group attached to runners. | +| securityGroups | string[] | Security groups attached to runners. | | vpcArn | string | VPC where runners will be launched. | --- @@ -5188,15 +5177,15 @@ Role attached to runners. --- -##### `securityGroup`Optional +##### `securityGroups`Optional ```typescript -public readonly securityGroup: string; +public readonly securityGroups: string[]; ``` -- *Type:* string +- *Type:* string[] -Security group attached to runners. +Security groups attached to runners. --- diff --git a/src/providers/codebuild.ts b/src/providers/codebuild.ts index 134a7d9d..842520c9 100644 --- a/src/providers/codebuild.ts +++ b/src/providers/codebuild.ts @@ -62,12 +62,21 @@ export interface CodeBuildRunnerProps extends RunnerProviderProps { readonly vpc?: ec2.IVpc; /** - * Security Group to assign to this instance. + * Security group to assign to this instance. * * @default public project with no security group + * + * @deprecated use {@link securityGroups} */ readonly securityGroup?: ec2.ISecurityGroup; + /** + * Security groups to assign to this instance. + * + * @default a new security group, if {@link vpc} is used + */ + readonly securityGroups?: ec2.ISecurityGroup[]; + /** * Where to place the network interfaces within the VPC. * @@ -137,16 +146,6 @@ export class CodeBuildRunner extends BaseProvider implements IRunnerProvider { */ readonly labels: string[]; - /** - * VPC used for hosting the project. - */ - readonly vpc?: ec2.IVpc; - - /** - * Security group attached to the task. - */ - readonly securityGroup?: ec2.ISecurityGroup; - /** * Grant principal used to add permissions to the runner role. */ @@ -157,12 +156,25 @@ export class CodeBuildRunner extends BaseProvider implements IRunnerProvider { */ readonly image: RunnerImage; + private readonly vpc?: ec2.IVpc; + private readonly securityGroups?: ec2.ISecurityGroup[]; + constructor(scope: Construct, id: string, props: CodeBuildRunnerProps) { super(scope, id); this.labels = this.labelsFromProperties('codebuild', props.label, props.labels); this.vpc = props.vpc; - this.securityGroup = props.securityGroup; + if (props.securityGroup) { + this.securityGroups = [props.securityGroup]; + } else { + if (props.securityGroups) { + this.securityGroups = props.securityGroups; + } else { + if (this.vpc) { + this.securityGroups = [new ec2.SecurityGroup(this, 'SG', { vpc: this.vpc })]; + } + } + } let buildSpec = { version: '0.2', @@ -237,7 +249,7 @@ export class CodeBuildRunner extends BaseProvider implements IRunnerProvider { description: `GitHub Actions self-hosted runner for labels ${this.labels}`, buildSpec: codebuild.BuildSpec.fromObject(buildSpec), vpc: this.vpc, - securityGroups: this.securityGroup ? [this.securityGroup] : undefined, + securityGroups: this.securityGroups, subnetSelection: props.subnetSelection, timeout: props.timeout ?? Duration.hours(1), environment: { @@ -317,7 +329,7 @@ export class CodeBuildRunner extends BaseProvider implements IRunnerProvider { type: this.constructor.name, labels: this.labels, vpcArn: this.vpc?.vpcArn, - securityGroup: this.securityGroup?.securityGroupId, + securityGroups: this.securityGroups?.map(sg => sg.securityGroupId), roleArn: this.project.role?.roleArn, image: { imageRepository: this.image.imageRepository.repositoryUri, diff --git a/src/providers/common.ts b/src/providers/common.ts index 13ab3cd7..57aefc2f 100644 --- a/src/providers/common.ts +++ b/src/providers/common.ts @@ -349,9 +349,9 @@ export interface IRunnerProviderStatus { readonly vpcArn?: string; /** - * Security group attached to runners. + * Security groups attached to runners. */ - readonly securityGroup?: string; + readonly securityGroups?: string[]; /** * Role attached to runners. @@ -382,16 +382,6 @@ export interface IRunnerProvider extends ec2.IConnectable, iam.IGrantable { */ readonly labels: string[]; - /** - * VPC network in which runners will be placed. - */ - readonly vpc?: ec2.IVpc; - - /** - * Security group associated with runners. - */ - readonly securityGroup?: ec2.ISecurityGroup; - /** * Generate step function tasks that execute the runner. * diff --git a/src/providers/ec2.ts b/src/providers/ec2.ts index 095cb9eb..7e91c2dc 100644 --- a/src/providers/ec2.ts +++ b/src/providers/ec2.ts @@ -159,10 +159,19 @@ export interface Ec2RunnerProps extends RunnerProviderProps { /** * Security Group to assign to launched runner instances. * - * @default account's default security group + * @default a new security group + * + * @deprecated use {@link securityGroups} */ readonly securityGroup?: ec2.ISecurityGroup; + /** + * Security groups to assign to launched runner instances. + * + * @default a new security group + */ + readonly securityGroups?: ec2.ISecurityGroup[]; + /** * Subnet where the runner instances will be launched. * @@ -212,11 +221,6 @@ export class Ec2Runner extends BaseProvider implements IRunnerProvider { */ readonly labels: string[]; - /** - * Security group attached to launched instances. - */ - readonly securityGroup?: ec2.ISecurityGroup; - /** * Grant principal used to add permissions to the runner role. */ @@ -229,13 +233,16 @@ export class Ec2Runner extends BaseProvider implements IRunnerProvider { private readonly storageSize: cdk.Size; private readonly spot: boolean; private readonly spotMaxPrice: string | undefined; + private readonly vpc: ec2.IVpc; private readonly subnet?: ec2.ISubnet; + private readonly securityGroups: ec2.ISecurityGroup[]; constructor(scope: Construct, id: string, props: Ec2RunnerProps) { super(scope, id); this.labels = props.labels ?? ['ec2']; - this.securityGroup = props.securityGroup; + this.vpc = props.vpc ?? ec2.Vpc.fromLookup(this, 'Default VPC', { isDefault: true }); + this.securityGroups = props.securityGroup ? [props.securityGroup] : (props.securityGroups ?? [new ec2.SecurityGroup(this, 'SG', { vpc: this.vpc })]); this.subnet = props.subnet ?? props.vpc?.selectSubnets(props.subnetSelection).subnets[0]; this.instanceType = props.instanceType ?? ec2.InstanceType.of(ec2.InstanceClass.M5, ec2.InstanceSize.LARGE); this.storageSize = props.storageSize ?? cdk.Size.gibibytes(30); // 30 is the minimum for Windows @@ -245,6 +252,7 @@ export class Ec2Runner extends BaseProvider implements IRunnerProvider { const amiBuilder = props.amiBuilder ?? new AmiBuilder(this, 'Image Builder', { vpc: props.vpc, subnetSelection: props.subnetSelection, + securityGroups: this.securityGroups, }); this.ami = amiBuilder.bind(); @@ -334,7 +342,7 @@ export class Ec2Runner extends BaseProvider implements IRunnerProvider { MetadataOptions: { HttpTokens: 'required', }, - SecurityGroupIds: this.securityGroup ? [this.securityGroup.securityGroupId] : undefined, + SecurityGroupIds: this.securityGroups.map(sg => sg.securityGroupId), SubnetId: this.subnet?.subnetId, BlockDeviceMappings: [{ DeviceName: '/dev/sda1', @@ -386,7 +394,7 @@ export class Ec2Runner extends BaseProvider implements IRunnerProvider { return { type: this.constructor.name, labels: this.labels, - securityGroup: this.securityGroup?.securityGroupId, + securityGroups: this.securityGroups.map(sg => sg.securityGroupId), roleArn: this.role.roleArn, ami: { launchTemplate: this.ami.launchTemplate.launchTemplateId || 'unknown', @@ -399,6 +407,6 @@ export class Ec2Runner extends BaseProvider implements IRunnerProvider { * The network connections associated with this resource. */ public get connections(): ec2.Connections { - return this.securityGroup?.connections ?? new ec2.Connections(); + return new ec2.Connections({ securityGroups: this.securityGroups }); } } diff --git a/src/providers/fargate.ts b/src/providers/fargate.ts index 636f4435..a4b1e6b8 100644 --- a/src/providers/fargate.ts +++ b/src/providers/fargate.ts @@ -20,7 +20,8 @@ import { Os, RunnerImage, RunnerProviderProps, - RunnerRuntimeParameters, RunnerVersion, + RunnerRuntimeParameters, + RunnerVersion, } from './common'; import { CodeBuildImageBuilder } from './image-builders/codebuild'; @@ -69,12 +70,21 @@ export interface FargateRunnerProps extends RunnerProviderProps { readonly subnetSelection?: ec2.SubnetSelection; /** - * Security Group to assign to the task. + * Security group to assign to the task. * * @default a new security group + * + * @deprecated use {@link securityGroupss} */ readonly securityGroup?: ec2.ISecurityGroup; + /** + * Security groups to assign to the task. + * + * @default a new security group + */ + readonly securityGroups?: ec2.ISecurityGroup[]; + /** * Existing Fargate cluster to use. * @@ -160,7 +170,8 @@ interface EcsFargateLaunchTargetProps { * Our special launch target that can use spot instances and set EnableExecuteCommand. */ class EcsFargateLaunchTarget implements stepfunctions_tasks.IEcsLaunchTarget { - constructor(readonly props: EcsFargateLaunchTargetProps) {} + constructor(readonly props: EcsFargateLaunchTargetProps) { + } /** * Called when the Fargate launch type configured on RunTask @@ -240,11 +251,6 @@ export class FargateRunner extends BaseProvider implements IRunnerProvider { */ readonly subnetSelection?: ec2.SubnetSelection; - /** - * Security group attached to the task. - */ - readonly securityGroup?: ec2.ISecurityGroup; - /** * Whether runner task will have a public IP. */ @@ -270,14 +276,16 @@ export class FargateRunner extends BaseProvider implements IRunnerProvider { */ readonly image: RunnerImage; + private readonly securityGroups: ec2.ISecurityGroup[]; + constructor(scope: Construct, id: string, props: FargateRunnerProps) { super(scope, id); this.labels = this.labelsFromProperties('fargate', props.label, props.labels); this.vpc = props.vpc ?? ec2.Vpc.fromLookup(this, 'default vpc', { isDefault: true }); this.subnetSelection = props.subnetSelection; - this.securityGroup = props.securityGroup ?? new ec2.SecurityGroup(this, 'security group', { vpc: this.vpc }); - this.connections = this.securityGroup.connections; + this.securityGroups = props.securityGroup ? [props.securityGroup] : (props.securityGroups ?? [new ec2.SecurityGroup(this, 'security group', { vpc: this.vpc })]); + this.connections = new ec2.Connections({ securityGroups: this.securityGroups }); this.assignPublicIp = props.assignPublicIp ?? true; this.cluster = props.cluster ? props.cluster : new ecs.Cluster( this, @@ -367,7 +375,7 @@ export class FargateRunner extends BaseProvider implements IRunnerProvider { }), subnets: this.subnetSelection, assignPublicIp: this.assignPublicIp, - securityGroups: this.securityGroup ? [this.securityGroup] : undefined, + securityGroups: this.securityGroups, containerOverrides: [ { containerDefinition: this.container, @@ -413,7 +421,7 @@ export class FargateRunner extends BaseProvider implements IRunnerProvider { type: this.constructor.name, labels: this.labels, vpcArn: this.vpc?.vpcArn, - securityGroup: this.securityGroup?.securityGroupId, + securityGroups: this.securityGroups.map(sg => sg.securityGroupId), roleArn: this.task.taskRole.roleArn, image: { imageRepository: this.image.imageRepository.repositoryUri, diff --git a/src/providers/image-builders/ami.ts b/src/providers/image-builders/ami.ts index cd44e169..55dc732f 100644 --- a/src/providers/image-builders/ami.ts +++ b/src/providers/image-builders/ami.ts @@ -60,12 +60,21 @@ export interface AmiBuilderProps { readonly vpc?: ec2.IVpc; /** - * Security Group to assign to launched builder instances. + * Security group to assign to launched builder instances. * - * @default default account security group + * @default new security group + * + * @deprecated use {@link securityGroups} */ readonly securityGroup?: ec2.ISecurityGroup; + /** + * Security groups to assign to launched builder instances. + * + * @default new security group + */ + readonly securityGroups?: ec2.ISecurityGroup[]; + /** * Where to place the network interfaces within the VPC. Only the first matched subnet will be used. * @@ -219,7 +228,7 @@ export class AmiBuilder extends ImageBuilderBase implements IAmiBuilder { supportedArchitectures: [Architecture.X86_64, Architecture.ARM64], instanceType: props?.instanceType, vpc: props?.vpc, - securityGroup: props?.securityGroup, + securityGroups: props?.securityGroup ? [props.securityGroup] : props?.securityGroups, subnetSelection: props?.subnetSelection, logRemovalPolicy: props?.logRemovalPolicy, logRetention: props?.logRetention, diff --git a/src/providers/image-builders/common.ts b/src/providers/image-builders/common.ts index ed8f620d..98b81393 100644 --- a/src/providers/image-builders/common.ts +++ b/src/providers/image-builders/common.ts @@ -292,11 +292,11 @@ export interface ImageBuilderBaseProps { readonly vpc?: ec2.IVpc; /** - * Security Group to assign to launched builder instances. + * Security groups to assign to launched builder instances. * - * @default default account security group + * @default new security group */ - readonly securityGroup?: ec2.ISecurityGroup; + readonly securityGroups?: ec2.ISecurityGroup[]; /** * Where to place the network interfaces within the VPC. @@ -339,7 +339,7 @@ export interface ImageBuilderBaseProps { /** * @internal */ -export abstract class ImageBuilderBase extends Construct { +export abstract class ImageBuilderBase extends Construct implements ec2.IConnectable { protected readonly architecture: Architecture; protected readonly os: Os; protected readonly platform: 'Windows' | 'Linux'; @@ -350,8 +350,9 @@ export abstract class ImageBuilderBase extends Construct { protected components: ImageBuilderComponent[] = []; + private readonly vpc: ec2.IVpc; private readonly subnetId: string | undefined; - private readonly securityGroupIds: string[] | undefined; + private readonly securityGroups: ec2.ISecurityGroup[]; private readonly instanceType: ec2.InstanceType; private readonly rebuildInterval: Duration; @@ -387,11 +388,16 @@ export abstract class ImageBuilderBase extends Construct { // vpc settings if (props?.vpc) { + this.vpc = props.vpc; this.subnetId = props.vpc.selectSubnets(props.subnetSelection).subnetIds[0]; + } else { + this.vpc = ec2.Vpc.fromLookup(this, 'Default VPC', { isDefault: true }); } - if (props?.securityGroup) { - this.securityGroupIds = [props.securityGroup.securityGroupId]; + if (props?.securityGroups) { + this.securityGroups = props.securityGroups; + } else { + this.securityGroups = [new ec2.SecurityGroup(this, 'SG', { vpc: this.vpc })]; } // instance type @@ -433,7 +439,7 @@ export abstract class ImageBuilderBase extends Construct { name: uniqueImageBuilderName(this), description: this.description, subnetId: this.subnetId, - securityGroupIds: this.securityGroupIds, + securityGroupIds: this.securityGroups.map(sg => sg.securityGroupId), instanceTypes: [this.instanceType.toString()], instanceProfileName: new iam.CfnInstanceProfile(this, 'Instance Profile', { roles: [ @@ -486,4 +492,11 @@ export abstract class ImageBuilderBase extends Construct { return pipeline; } + + /** + * The network connections associated with this resource. + */ + public get connections(): ec2.Connections { + return new ec2.Connections({ securityGroups: this.securityGroups }); + } } diff --git a/src/providers/image-builders/container.ts b/src/providers/image-builders/container.ts index 9fa9bfe8..09e40875 100644 --- a/src/providers/image-builders/container.ts +++ b/src/providers/image-builders/container.ts @@ -72,12 +72,21 @@ export interface ContainerImageBuilderProps { readonly vpc?: ec2.IVpc; /** - * Security Group to assign to this instance. + * Security group to assign to launched builder instances. * - * @default default account security group + * @default new security group + * + * @deprecated use {@link securityGroups} */ readonly securityGroup?: ec2.ISecurityGroup; + /** + * Security groups to assign to launched builder instances. + * + * @default new security group + */ + readonly securityGroups?: ec2.ISecurityGroup[]; + /** * Where to place the network interfaces within the VPC. * @@ -226,7 +235,7 @@ export class ContainerImageBuilder extends ImageBuilderBase implements IImageBui supportedArchitectures: [Architecture.X86_64], instanceType: props?.instanceType, vpc: props?.vpc, - securityGroup: props?.securityGroup, + securityGroups: props?.securityGroup ? [props.securityGroup] : props?.securityGroups, subnetSelection: props?.subnetSelection, logRemovalPolicy: props?.logRemovalPolicy, logRetention: props?.logRetention, diff --git a/src/providers/lambda.ts b/src/providers/lambda.ts index d0f36586..b630d319 100644 --- a/src/providers/lambda.ts +++ b/src/providers/lambda.ts @@ -67,10 +67,10 @@ export interface LambdaRunnerProps extends RunnerProviderProps { readonly memorySize?: number; /** - * The size of the function’s /tmp directory in MiB. - * - * @default 10 GiB - */ + * The size of the function’s /tmp directory in MiB. + * + * @default 10 GiB + */ readonly ephemeralStorageSize?: cdk.Size; /** @@ -83,24 +83,33 @@ export interface LambdaRunnerProps extends RunnerProviderProps { readonly timeout?: cdk.Duration; /** - * VPC to launch the runners in. - * - * @default no VPC - */ + * VPC to launch the runners in. + * + * @default no VPC + */ readonly vpc?: ec2.IVpc; /** - * Security Group to assign to this instance. - * - * @default public lambda with no security group - */ + * Security group to assign to this instance. + * + * @default public lambda with no security group + * + * @deprecated use {@link securityGroups} + */ readonly securityGroup?: ec2.ISecurityGroup; /** - * Where to place the network interfaces within the VPC. - * - * @default no subnet - */ + * Security groups to assign to this instance. + * + * @default public lambda with no security group + */ + readonly securityGroups?: ec2.ISecurityGroup[]; + + /** + * Where to place the network interfaces within the VPC. + * + * @default no subnet + */ readonly subnetSelection?: ec2.SubnetSelection; } @@ -140,16 +149,6 @@ export class LambdaRunner extends BaseProvider implements IRunnerProvider { */ readonly labels: string[]; - /** - * VPC used for hosting the function. - */ - readonly vpc?: ec2.IVpc; - - /** - * Security group attached to the function. - */ - readonly securityGroup?: ec2.ISecurityGroup; - /** * Grant principal used to add permissions to the runner role. */ @@ -160,12 +159,15 @@ export class LambdaRunner extends BaseProvider implements IRunnerProvider { */ readonly image: RunnerImage; + private readonly vpc?: ec2.IVpc; + private readonly securityGroups?: ec2.ISecurityGroup[]; + constructor(scope: Construct, id: string, props: LambdaRunnerProps) { super(scope, id); this.labels = this.labelsFromProperties('lambda', props.label, props.labels); this.vpc = props.vpc; - this.securityGroup = props.securityGroup; + this.securityGroups = props.securityGroup ? [props.securityGroup] : props.securityGroups; const imageBuilder = props.imageBuilder ?? new CodeBuildImageBuilder(this, 'Image Builder', { dockerfilePath: LambdaRunner.LINUX_X64_DOCKERFILE_PATH, @@ -195,7 +197,7 @@ export class LambdaRunner extends BaseProvider implements IRunnerProvider { labels: this.labels, architecture: architecture.name, vpc: this.vpc?.vpcId, - securityGroups: this.securityGroup?.securityGroupId, + securityGroups: this.securityGroups?.map(sg => sg.securityGroupId), vpcSubnets: props.subnetSelection?.subnets?.map(s => s.subnetId), timeout: props.timeout?.toSeconds(), memorySize: props.memorySize, @@ -212,7 +214,7 @@ export class LambdaRunner extends BaseProvider implements IRunnerProvider { code: lambda.DockerImageCode.fromEcr(image.imageRepository, { tagOrDigest: `sha256:${imageDigest}` }), architecture, vpc: this.vpc, - securityGroups: this.securityGroup && [this.securityGroup], + securityGroups: this.securityGroups, vpcSubnets: props.subnetSelection, timeout: props.timeout || cdk.Duration.minutes(15), memorySize: props.memorySize || 2048, @@ -308,7 +310,7 @@ export class LambdaRunner extends BaseProvider implements IRunnerProvider { type: this.constructor.name, labels: this.labels, vpcArn: this.vpc?.vpcArn, - securityGroup: this.securityGroup?.securityGroupId, + securityGroups: this.securityGroups?.map(sg => sg.securityGroupId), roleArn: this.function.role?.roleArn, image: { imageRepository: this.image.imageRepository.repositoryUri, diff --git a/test/default.integ.snapshot/github-runners-test.assets.json b/test/default.integ.snapshot/github-runners-test.assets.json index 23355f1b..e5f0182f 100644 --- a/test/default.integ.snapshot/github-runners-test.assets.json +++ b/test/default.integ.snapshot/github-runners-test.assets.json @@ -222,7 +222,7 @@ } } }, - "ef38c3bac82a92a68774e24daab1bd0301a575c0a16dc214d62775adc01976e5": { + "cb8b028063cbb5d802bc47dc5ba6314eaf9e718d1c9f0f62decd46320644f7a3": { "source": { "path": "github-runners-test.template.json", "packaging": "file" @@ -230,7 +230,7 @@ "destinations": { "current_account-current_region": { "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", - "objectKey": "ef38c3bac82a92a68774e24daab1bd0301a575c0a16dc214d62775adc01976e5.json", + "objectKey": "cb8b028063cbb5d802bc47dc5ba6314eaf9e718d1c9f0f62decd46320644f7a3.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 1cccd137..dd1df42c 100644 --- a/test/default.integ.snapshot/github-runners-test.template.json +++ b/test/default.integ.snapshot/github-runners-test.template.json @@ -1800,6 +1800,22 @@ } } }, + "WindowsImageBuilderSG5ACD1618": { + "Type": "AWS::EC2::SecurityGroup", + "Properties": { + "GroupDescription": "github-runners-test/Windows Image Builder/SG", + "SecurityGroupEgress": [ + { + "CidrIp": "0.0.0.0/0", + "Description": "Allow all outbound traffic by default", + "IpProtocol": "-1" + } + ], + "VpcId": { + "Ref": "Vpc8378EB38" + } + } + }, "WindowsImageBuilderRepositoryA4CBB6D8": { "Type": "AWS::ECR::Repository", "Properties": { @@ -2254,7 +2270,18 @@ "Description": "Build image for GitHub Actions runner github-runners-test/Windows Image Builder (Windows/X86_64)", "InstanceTypes": [ "m5.large" - ] + ], + "SecurityGroupIds": [ + { + "Fn::GetAtt": [ + "WindowsImageBuilderSG5ACD1618", + "GroupId" + ] + } + ], + "SubnetId": { + "Ref": "VpcPublicSubnet1Subnet5C2D37C4" + } } }, "WindowsImageBuilderImage7065BB07": { @@ -2572,6 +2599,22 @@ "LogRetentionaae0aa3c5b4d4f87b02d85b201efdd8aServiceRole9741ECFB" ] }, + "AMILinuxBuilderSGEDC86329": { + "Type": "AWS::EC2::SecurityGroup", + "Properties": { + "GroupDescription": "github-runners-test/AMI Linux Builder/SG", + "SecurityGroupEgress": [ + { + "CidrIp": "0.0.0.0/0", + "Description": "Allow all outbound traffic by default", + "IpProtocol": "-1" + } + ], + "VpcId": { + "Ref": "Vpc8378EB38" + } + } + }, "AMILinuxBuilderUpgradepackagesandinstallbasicsVersionA685EC4B": { "Type": "Custom::ImageBuilder-Component-Version", "Properties": { @@ -3258,7 +3301,18 @@ "Description": "Build AMI for GitHub Actions runner github-runners-test/AMI Linux Builder (Linux/X86_64)", "InstanceTypes": [ "m5.large" - ] + ], + "SecurityGroupIds": [ + { + "Fn::GetAtt": [ + "AMILinuxBuilderSGEDC86329", + "GroupId" + ] + } + ], + "SubnetId": { + "Ref": "VpcPublicSubnet1Subnet5C2D37C4" + } } }, "AMILinuxBuilderImage1049E111": { @@ -7548,6 +7602,22 @@ "UpdateReplacePolicy": "Delete", "DeletionPolicy": "Delete" }, + "EC2LinuxSGF5B89300": { + "Type": "AWS::EC2::SecurityGroup", + "Properties": { + "GroupDescription": "github-runners-test/EC2 Linux/SG", + "SecurityGroupEgress": [ + { + "CidrIp": "0.0.0.0/0", + "Description": "Allow all outbound traffic by default", + "IpProtocol": "-1" + } + ], + "VpcId": { + "Ref": "Vpc8378EB38" + } + } + }, "EC2LinuxRole8B6519A2": { "Type": "AWS::IAM::Role", "Properties": { @@ -7753,6 +7823,22 @@ "RetentionInDays": 30 } }, + "EC2SpotLinuxSG8D846B64": { + "Type": "AWS::EC2::SecurityGroup", + "Properties": { + "GroupDescription": "github-runners-test/EC2 Spot Linux/SG", + "SecurityGroupEgress": [ + { + "CidrIp": "0.0.0.0/0", + "Description": "Allow all outbound traffic by default", + "IpProtocol": "-1" + } + ], + "VpcId": { + "Ref": "Vpc8378EB38" + } + } + }, "EC2SpotLinuxRole86333E5D": { "Type": "AWS::IAM::Role", "Properties": { @@ -7850,6 +7936,22 @@ ] } }, + "AMILinuxarm64BuilderSG94315968": { + "Type": "AWS::EC2::SecurityGroup", + "Properties": { + "GroupDescription": "github-runners-test/AMI Linux arm64 Builder/SG", + "SecurityGroupEgress": [ + { + "CidrIp": "0.0.0.0/0", + "Description": "Allow all outbound traffic by default", + "IpProtocol": "-1" + } + ], + "VpcId": { + "Ref": "Vpc8378EB38" + } + } + }, "AMILinuxarm64BuilderUpgradepackagesandinstallbasicsVersionCD58A101": { "Type": "Custom::ImageBuilder-Component-Version", "Properties": { @@ -8536,7 +8638,18 @@ "Description": "Build AMI for GitHub Actions runner github-runners-test/AMI Linux arm64 Builder (Linux/ARM64)", "InstanceTypes": [ "m6g.large" - ] + ], + "SecurityGroupIds": [ + { + "Fn::GetAtt": [ + "AMILinuxarm64BuilderSG94315968", + "GroupId" + ] + } + ], + "SubnetId": { + "Ref": "VpcPublicSubnet1Subnet5C2D37C4" + } } }, "AMILinuxarm64BuilderImageA637431C": { @@ -8670,6 +8783,22 @@ "UpdateReplacePolicy": "Delete", "DeletionPolicy": "Delete" }, + "EC2Linuxarm64SG550ECD6C": { + "Type": "AWS::EC2::SecurityGroup", + "Properties": { + "GroupDescription": "github-runners-test/EC2 Linux arm64/SG", + "SecurityGroupEgress": [ + { + "CidrIp": "0.0.0.0/0", + "Description": "Allow all outbound traffic by default", + "IpProtocol": "-1" + } + ], + "VpcId": { + "Ref": "Vpc8378EB38" + } + } + }, "EC2Linuxarm64Role242F68FF": { "Type": "AWS::IAM::Role", "Properties": { @@ -8767,6 +8896,22 @@ ] } }, + "WindowsEC2BuilderSGE3F67842": { + "Type": "AWS::EC2::SecurityGroup", + "Properties": { + "GroupDescription": "github-runners-test/Windows EC2 Builder/SG", + "SecurityGroupEgress": [ + { + "CidrIp": "0.0.0.0/0", + "Description": "Allow all outbound traffic by default", + "IpProtocol": "-1" + } + ], + "VpcId": { + "Ref": "Vpc8378EB38" + } + } + }, "WindowsEC2BuilderCloudWatchagentVersion05F51F3E": { "Type": "Custom::ImageBuilder-Component-Version", "Properties": { @@ -9390,7 +9535,18 @@ "Description": "Build AMI for GitHub Actions runner github-runners-test/Windows EC2 Builder (Windows/X86_64)", "InstanceTypes": [ "m5.large" - ] + ], + "SecurityGroupIds": [ + { + "Fn::GetAtt": [ + "WindowsEC2BuilderSGE3F67842", + "GroupId" + ] + } + ], + "SubnetId": { + "Ref": "VpcPublicSubnet1Subnet5C2D37C4" + } } }, "WindowsEC2BuilderImage6E6F4F1F": { @@ -9524,6 +9680,22 @@ "UpdateReplacePolicy": "Delete", "DeletionPolicy": "Delete" }, + "EC2WindowsSG13E24976": { + "Type": "AWS::EC2::SecurityGroup", + "Properties": { + "GroupDescription": "github-runners-test/EC2 Windows/SG", + "SecurityGroupEgress": [ + { + "CidrIp": "0.0.0.0/0", + "Description": "Allow all outbound traffic by default", + "IpProtocol": "-1" + } + ], + "VpcId": { + "Ref": "Vpc8378EB38" + } + } + }, "EC2WindowsRoleC0D850D2": { "Type": "AWS::IAM::Role", "Properties": { @@ -11143,7 +11315,18 @@ "Arn" ] }, - "\"},\"MetadataOptions\":{\"HttpTokens\":\"required\"},\"BlockDeviceMappings\":[{\"DeviceName\":\"/dev/sda1\",\"Ebs\":{\"DeleteOnTermination\":true,\"VolumeSize\":30}}]}},\"ec2-spot, linux, x64 data\":{\"Type\":\"Pass\",\"ResultPath\":\"$.ec2\",\"Parameters\":{\"userdataTemplate\":\"#!/bin/bash -x\\nTASK_TOKEN=\\\"{}\\\"\\nheartbeat () \\\\{\\n while true; do\\n aws stepfunctions send-task-heartbeat --task-token \\\"$TASK_TOKEN\\\"\\n sleep 60\\n done\\n\\\\}\\nsetup_logs () \\\\{\\n cat < /tmp/log.conf || exit 1\\n \\\\{\\n \\\"logs\\\": \\\\{\\n \\\"log_stream_name\\\": \\\"unknown\\\",\\n \\\"logs_collected\\\": \\\\{\\n \\\"files\\\": \\\\{\\n \\\"collect_list\\\": [\\n \\\\{\\n \\\"file_path\\\": \\\"/var/log/runner.log\\\",\\n \\\"log_group_name\\\": \\\"{}\\\",\\n \\\"log_stream_name\\\": \\\"{}\\\",\\n \\\"timezone\\\": \\\"UTC\\\"\\n \\\\}\\n ]\\n \\\\}\\n \\\\}\\n \\\\}\\n \\\\}\\nEOF\\n /opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-ctl -a fetch-config -m ec2 -s -c file:/tmp/log.conf || exit 2\\n\\\\}\\naction () \\\\{\\n sudo -Hu runner /home/runner/config.sh --unattended --url \\\"https://{}/{}/{}\\\" --token \\\"{}\\\" --ephemeral --work _work --labels \\\"{}\\\" {} --name \\\"{}\\\" || exit 1\\n sudo --preserve-env=AWS_REGION -Hu runner /home/runner/run.sh || exit 2\\n\\\\}\\nheartbeat &\\nif setup_logs && action | tee /var/log/runner.log 2>&1; then\\n aws stepfunctions send-task-success --task-token \\\"$TASK_TOKEN\\\" --task-output '\\\\{\\\"ok\\\": true\\\\}'\\nelse\\n aws stepfunctions send-task-failure --task-token \\\"$TASK_TOKEN\\\"\\nfi\\npoweroff\\n\"},\"Next\":\"ec2-spot, linux, x64\"},\"ec2-spot, linux, x64\":{\"End\":true,\"Type\":\"Task\",\"HeartbeatSeconds\":300,\"Resource\":\"arn:", + "\"},\"MetadataOptions\":{\"HttpTokens\":\"required\"},\"SecurityGroupIds\":[\"", + { + "Fn::GetAtt": [ + "EC2LinuxSGF5B89300", + "GroupId" + ] + }, + "\"],\"SubnetId\":\"", + { + "Ref": "VpcPublicSubnet1Subnet5C2D37C4" + }, + "\",\"BlockDeviceMappings\":[{\"DeviceName\":\"/dev/sda1\",\"Ebs\":{\"DeleteOnTermination\":true,\"VolumeSize\":30}}]}},\"ec2-spot, linux, x64 data\":{\"Type\":\"Pass\",\"ResultPath\":\"$.ec2\",\"Parameters\":{\"userdataTemplate\":\"#!/bin/bash -x\\nTASK_TOKEN=\\\"{}\\\"\\nheartbeat () \\\\{\\n while true; do\\n aws stepfunctions send-task-heartbeat --task-token \\\"$TASK_TOKEN\\\"\\n sleep 60\\n done\\n\\\\}\\nsetup_logs () \\\\{\\n cat < /tmp/log.conf || exit 1\\n \\\\{\\n \\\"logs\\\": \\\\{\\n \\\"log_stream_name\\\": \\\"unknown\\\",\\n \\\"logs_collected\\\": \\\\{\\n \\\"files\\\": \\\\{\\n \\\"collect_list\\\": [\\n \\\\{\\n \\\"file_path\\\": \\\"/var/log/runner.log\\\",\\n \\\"log_group_name\\\": \\\"{}\\\",\\n \\\"log_stream_name\\\": \\\"{}\\\",\\n \\\"timezone\\\": \\\"UTC\\\"\\n \\\\}\\n ]\\n \\\\}\\n \\\\}\\n \\\\}\\n \\\\}\\nEOF\\n /opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-ctl -a fetch-config -m ec2 -s -c file:/tmp/log.conf || exit 2\\n\\\\}\\naction () \\\\{\\n sudo -Hu runner /home/runner/config.sh --unattended --url \\\"https://{}/{}/{}\\\" --token \\\"{}\\\" --ephemeral --work _work --labels \\\"{}\\\" {} --name \\\"{}\\\" || exit 1\\n sudo --preserve-env=AWS_REGION -Hu runner /home/runner/run.sh || exit 2\\n\\\\}\\nheartbeat &\\nif setup_logs && action | tee /var/log/runner.log 2>&1; then\\n aws stepfunctions send-task-success --task-token \\\"$TASK_TOKEN\\\" --task-output '\\\\{\\\"ok\\\": true\\\\}'\\nelse\\n aws stepfunctions send-task-failure --task-token \\\"$TASK_TOKEN\\\"\\nfi\\npoweroff\\n\"},\"Next\":\"ec2-spot, linux, x64\"},\"ec2-spot, linux, x64\":{\"End\":true,\"Type\":\"Task\",\"HeartbeatSeconds\":300,\"Resource\":\"arn:", { "Ref": "AWS::Partition" }, @@ -11162,7 +11345,18 @@ "Arn" ] }, - "\"},\"MetadataOptions\":{\"HttpTokens\":\"required\"},\"BlockDeviceMappings\":[{\"DeviceName\":\"/dev/sda1\",\"Ebs\":{\"DeleteOnTermination\":true,\"VolumeSize\":30}}],\"InstanceMarketOptions\":{\"MarketType\":\"spot\",\"SpotOptions\":{\"SpotInstanceType\":\"one-time\"}}}},\"ec2, linux, arm64 data\":{\"Type\":\"Pass\",\"ResultPath\":\"$.ec2\",\"Parameters\":{\"userdataTemplate\":\"#!/bin/bash -x\\nTASK_TOKEN=\\\"{}\\\"\\nheartbeat () \\\\{\\n while true; do\\n aws stepfunctions send-task-heartbeat --task-token \\\"$TASK_TOKEN\\\"\\n sleep 60\\n done\\n\\\\}\\nsetup_logs () \\\\{\\n cat < /tmp/log.conf || exit 1\\n \\\\{\\n \\\"logs\\\": \\\\{\\n \\\"log_stream_name\\\": \\\"unknown\\\",\\n \\\"logs_collected\\\": \\\\{\\n \\\"files\\\": \\\\{\\n \\\"collect_list\\\": [\\n \\\\{\\n \\\"file_path\\\": \\\"/var/log/runner.log\\\",\\n \\\"log_group_name\\\": \\\"{}\\\",\\n \\\"log_stream_name\\\": \\\"{}\\\",\\n \\\"timezone\\\": \\\"UTC\\\"\\n \\\\}\\n ]\\n \\\\}\\n \\\\}\\n \\\\}\\n \\\\}\\nEOF\\n /opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-ctl -a fetch-config -m ec2 -s -c file:/tmp/log.conf || exit 2\\n\\\\}\\naction () \\\\{\\n sudo -Hu runner /home/runner/config.sh --unattended --url \\\"https://{}/{}/{}\\\" --token \\\"{}\\\" --ephemeral --work _work --labels \\\"{}\\\" {} --name \\\"{}\\\" || exit 1\\n sudo --preserve-env=AWS_REGION -Hu runner /home/runner/run.sh || exit 2\\n\\\\}\\nheartbeat &\\nif setup_logs && action | tee /var/log/runner.log 2>&1; then\\n aws stepfunctions send-task-success --task-token \\\"$TASK_TOKEN\\\" --task-output '\\\\{\\\"ok\\\": true\\\\}'\\nelse\\n aws stepfunctions send-task-failure --task-token \\\"$TASK_TOKEN\\\"\\nfi\\npoweroff\\n\"},\"Next\":\"ec2, linux, arm64\"},\"ec2, linux, arm64\":{\"End\":true,\"Type\":\"Task\",\"HeartbeatSeconds\":300,\"Resource\":\"arn:", + "\"},\"MetadataOptions\":{\"HttpTokens\":\"required\"},\"SecurityGroupIds\":[\"", + { + "Fn::GetAtt": [ + "EC2SpotLinuxSG8D846B64", + "GroupId" + ] + }, + "\"],\"SubnetId\":\"", + { + "Ref": "VpcPublicSubnet1Subnet5C2D37C4" + }, + "\",\"BlockDeviceMappings\":[{\"DeviceName\":\"/dev/sda1\",\"Ebs\":{\"DeleteOnTermination\":true,\"VolumeSize\":30}}],\"InstanceMarketOptions\":{\"MarketType\":\"spot\",\"SpotOptions\":{\"SpotInstanceType\":\"one-time\"}}}},\"ec2, linux, arm64 data\":{\"Type\":\"Pass\",\"ResultPath\":\"$.ec2\",\"Parameters\":{\"userdataTemplate\":\"#!/bin/bash -x\\nTASK_TOKEN=\\\"{}\\\"\\nheartbeat () \\\\{\\n while true; do\\n aws stepfunctions send-task-heartbeat --task-token \\\"$TASK_TOKEN\\\"\\n sleep 60\\n done\\n\\\\}\\nsetup_logs () \\\\{\\n cat < /tmp/log.conf || exit 1\\n \\\\{\\n \\\"logs\\\": \\\\{\\n \\\"log_stream_name\\\": \\\"unknown\\\",\\n \\\"logs_collected\\\": \\\\{\\n \\\"files\\\": \\\\{\\n \\\"collect_list\\\": [\\n \\\\{\\n \\\"file_path\\\": \\\"/var/log/runner.log\\\",\\n \\\"log_group_name\\\": \\\"{}\\\",\\n \\\"log_stream_name\\\": \\\"{}\\\",\\n \\\"timezone\\\": \\\"UTC\\\"\\n \\\\}\\n ]\\n \\\\}\\n \\\\}\\n \\\\}\\n \\\\}\\nEOF\\n /opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-ctl -a fetch-config -m ec2 -s -c file:/tmp/log.conf || exit 2\\n\\\\}\\naction () \\\\{\\n sudo -Hu runner /home/runner/config.sh --unattended --url \\\"https://{}/{}/{}\\\" --token \\\"{}\\\" --ephemeral --work _work --labels \\\"{}\\\" {} --name \\\"{}\\\" || exit 1\\n sudo --preserve-env=AWS_REGION -Hu runner /home/runner/run.sh || exit 2\\n\\\\}\\nheartbeat &\\nif setup_logs && action | tee /var/log/runner.log 2>&1; then\\n aws stepfunctions send-task-success --task-token \\\"$TASK_TOKEN\\\" --task-output '\\\\{\\\"ok\\\": true\\\\}'\\nelse\\n aws stepfunctions send-task-failure --task-token \\\"$TASK_TOKEN\\\"\\nfi\\npoweroff\\n\"},\"Next\":\"ec2, linux, arm64\"},\"ec2, linux, arm64\":{\"End\":true,\"Type\":\"Task\",\"HeartbeatSeconds\":300,\"Resource\":\"arn:", { "Ref": "AWS::Partition" }, @@ -11181,7 +11375,18 @@ "Arn" ] }, - "\"},\"MetadataOptions\":{\"HttpTokens\":\"required\"},\"BlockDeviceMappings\":[{\"DeviceName\":\"/dev/sda1\",\"Ebs\":{\"DeleteOnTermination\":true,\"VolumeSize\":30}}]}},\"ec2, windows, x64 data\":{\"Type\":\"Pass\",\"ResultPath\":\"$.ec2\",\"Parameters\":{\"userdataTemplate\":\"\\n$TASK_TOKEN = \\\"{}\\\"\\nStart-Job -ScriptBlock \\\\{\\n while (1) \\\\{\\n aws stepfunctions send-task-heartbeat --task-token \\\"$using:TASK_TOKEN\\\"\\n sleep 60\\n \\\\}\\n\\\\}\\nfunction setup_logs () \\\\{\\n echo '\\\\{\\n \\\"logs\\\": \\\\{\\n \\\"log_stream_name\\\": \\\"unknown\\\",\\n \\\"logs_collected\\\": \\\\{\\n \\\"files\\\": \\\\{\\n \\\"collect_list\\\": [\\n \\\\{\\n \\\"file_path\\\": \\\"/actions/runner.log\\\",\\n \\\"log_group_name\\\": \\\"{}\\\",\\n \\\"log_stream_name\\\": \\\"{}\\\",\\n \\\"timezone\\\": \\\"UTC\\\"\\n \\\\}\\n ]\\n \\\\}\\n \\\\}\\n \\\\}\\n \\\\}' | Out-File -Encoding ASCII $Env:TEMP/log.conf\\n & \\\"C:/Program Files/Amazon/AmazonCloudWatchAgent/amazon-cloudwatch-agent-ctl.ps1\\\" -a fetch-config -m ec2 -s -c file:$Env:TEMP/log.conf\\n\\\\}\\nfunction action () \\\\{\\n cd /actions\\n ./config.cmd --unattended --url \\\"https://{}/{}/{}\\\" --token \\\"{}\\\" --ephemeral --work _work --labels \\\"{}\\\" {} --name \\\"{}\\\" 2>&1 | Out-File -Encoding ASCII -Append /actions/runner.log\\n if ($LASTEXITCODE -ne 0) \\\\{ return 1 \\\\}\\n ./run.cmd 2>&1 | Out-File -Encoding ASCII -Append /actions/runner.log\\n if ($LASTEXITCODE -ne 0) \\\\{ return 2 \\\\}\\n return 0\\n\\\\}\\nsetup_logs\\n$r = action\\nif ($r -eq 0) \\\\{\\n aws stepfunctions send-task-success --task-token \\\"$TASK_TOKEN\\\" --task-output '\\\\{ \\\\}'\\n\\\\} else \\\\{\\n aws stepfunctions send-task-failure --task-token \\\"$TASK_TOKEN\\\"\\n\\\\}\\nStop-Computer -ComputerName localhost -Force\\n\\n\"},\"Next\":\"ec2, windows, x64\"},\"ec2, windows, x64\":{\"End\":true,\"Type\":\"Task\",\"HeartbeatSeconds\":300,\"Resource\":\"arn:", + "\"},\"MetadataOptions\":{\"HttpTokens\":\"required\"},\"SecurityGroupIds\":[\"", + { + "Fn::GetAtt": [ + "EC2Linuxarm64SG550ECD6C", + "GroupId" + ] + }, + "\"],\"SubnetId\":\"", + { + "Ref": "VpcPublicSubnet1Subnet5C2D37C4" + }, + "\",\"BlockDeviceMappings\":[{\"DeviceName\":\"/dev/sda1\",\"Ebs\":{\"DeleteOnTermination\":true,\"VolumeSize\":30}}]}},\"ec2, windows, x64 data\":{\"Type\":\"Pass\",\"ResultPath\":\"$.ec2\",\"Parameters\":{\"userdataTemplate\":\"\\n$TASK_TOKEN = \\\"{}\\\"\\nStart-Job -ScriptBlock \\\\{\\n while (1) \\\\{\\n aws stepfunctions send-task-heartbeat --task-token \\\"$using:TASK_TOKEN\\\"\\n sleep 60\\n \\\\}\\n\\\\}\\nfunction setup_logs () \\\\{\\n echo '\\\\{\\n \\\"logs\\\": \\\\{\\n \\\"log_stream_name\\\": \\\"unknown\\\",\\n \\\"logs_collected\\\": \\\\{\\n \\\"files\\\": \\\\{\\n \\\"collect_list\\\": [\\n \\\\{\\n \\\"file_path\\\": \\\"/actions/runner.log\\\",\\n \\\"log_group_name\\\": \\\"{}\\\",\\n \\\"log_stream_name\\\": \\\"{}\\\",\\n \\\"timezone\\\": \\\"UTC\\\"\\n \\\\}\\n ]\\n \\\\}\\n \\\\}\\n \\\\}\\n \\\\}' | Out-File -Encoding ASCII $Env:TEMP/log.conf\\n & \\\"C:/Program Files/Amazon/AmazonCloudWatchAgent/amazon-cloudwatch-agent-ctl.ps1\\\" -a fetch-config -m ec2 -s -c file:$Env:TEMP/log.conf\\n\\\\}\\nfunction action () \\\\{\\n cd /actions\\n ./config.cmd --unattended --url \\\"https://{}/{}/{}\\\" --token \\\"{}\\\" --ephemeral --work _work --labels \\\"{}\\\" {} --name \\\"{}\\\" 2>&1 | Out-File -Encoding ASCII -Append /actions/runner.log\\n if ($LASTEXITCODE -ne 0) \\\\{ return 1 \\\\}\\n ./run.cmd 2>&1 | Out-File -Encoding ASCII -Append /actions/runner.log\\n if ($LASTEXITCODE -ne 0) \\\\{ return 2 \\\\}\\n return 0\\n\\\\}\\nsetup_logs\\n$r = action\\nif ($r -eq 0) \\\\{\\n aws stepfunctions send-task-success --task-token \\\"$TASK_TOKEN\\\" --task-output '\\\\{ \\\\}'\\n\\\\} else \\\\{\\n aws stepfunctions send-task-failure --task-token \\\"$TASK_TOKEN\\\"\\n\\\\}\\nStop-Computer -ComputerName localhost -Force\\n\\n\"},\"Next\":\"ec2, windows, x64\"},\"ec2, windows, x64\":{\"End\":true,\"Type\":\"Task\",\"HeartbeatSeconds\":300,\"Resource\":\"arn:", { "Ref": "AWS::Partition" }, @@ -11200,7 +11405,18 @@ "Arn" ] }, - "\"},\"MetadataOptions\":{\"HttpTokens\":\"required\"},\"BlockDeviceMappings\":[{\"DeviceName\":\"/dev/sda1\",\"Ebs\":{\"DeleteOnTermination\":true,\"VolumeSize\":30}}]}}}},{\"StartAt\":\"Wait\",\"States\":{\"Wait\":{\"Type\":\"Wait\",\"Seconds\":600,\"Next\":\"Delete Idle Runner\"},\"Delete Idle Runner\":{\"End\":true,\"Retry\":[{\"ErrorEquals\":[\"Lambda.ServiceException\",\"Lambda.AWSLambdaException\",\"Lambda.SdkClientException\"],\"IntervalSeconds\":2,\"MaxAttempts\":6,\"BackoffRate\":2}],\"Type\":\"Task\",\"ResultPath\":\"$.delete\",\"Resource\":\"", + "\"},\"MetadataOptions\":{\"HttpTokens\":\"required\"},\"SecurityGroupIds\":[\"", + { + "Fn::GetAtt": [ + "EC2WindowsSG13E24976", + "GroupId" + ] + }, + "\"],\"SubnetId\":\"", + { + "Ref": "VpcPublicSubnet1Subnet5C2D37C4" + }, + "\",\"BlockDeviceMappings\":[{\"DeviceName\":\"/dev/sda1\",\"Ebs\":{\"DeleteOnTermination\":true,\"VolumeSize\":30}}]}}}},{\"StartAt\":\"Wait\",\"States\":{\"Wait\":{\"Type\":\"Wait\",\"Seconds\":600,\"Next\":\"Delete Idle Runner\"},\"Delete Idle Runner\":{\"End\":true,\"Retry\":[{\"ErrorEquals\":[\"Lambda.ServiceException\",\"Lambda.AWSLambdaException\",\"Lambda.SdkClientException\"],\"IntervalSeconds\":2,\"MaxAttempts\":6,\"BackoffRate\":2}],\"Type\":\"Task\",\"ResultPath\":\"$.delete\",\"Resource\":\"", { "Fn::GetAtt": [ "runnersdeleterunner7F8D5293", @@ -12254,12 +12470,14 @@ ] ] }, - "securityGroup": { - "Fn::GetAtt": [ - "FargatesecuritygroupAFCAFD34", - "GroupId" - ] - }, + "securityGroups": [ + { + "Fn::GetAtt": [ + "FargatesecuritygroupAFCAFD34", + "GroupId" + ] + } + ], "roleArn": { "Fn::GetAtt": [ "FargatetaskTaskRoleEFFCDAF8", @@ -12348,12 +12566,14 @@ ] ] }, - "securityGroup": { - "Fn::GetAtt": [ - "Fargatex64spotsecuritygroup2A9F4299", - "GroupId" - ] - }, + "securityGroups": [ + { + "Fn::GetAtt": [ + "Fargatex64spotsecuritygroup2A9F4299", + "GroupId" + ] + } + ], "roleArn": { "Fn::GetAtt": [ "Fargatex64spottaskTaskRole02893C25", @@ -12442,12 +12662,14 @@ ] ] }, - "securityGroup": { - "Fn::GetAtt": [ - "Fargatearm64securitygroup08ABAD9E", - "GroupId" - ] - }, + "securityGroups": [ + { + "Fn::GetAtt": [ + "Fargatearm64securitygroup08ABAD9E", + "GroupId" + ] + } + ], "roleArn": { "Fn::GetAtt": [ "Fargatearm64taskTaskRoleD3C2CD58", @@ -12536,12 +12758,14 @@ ] ] }, - "securityGroup": { - "Fn::GetAtt": [ - "Fargatearm64spotsecuritygroup20C885E4", - "GroupId" - ] - }, + "securityGroups": [ + { + "Fn::GetAtt": [ + "Fargatearm64spotsecuritygroup20C885E4", + "GroupId" + ] + } + ], "roleArn": { "Fn::GetAtt": [ "Fargatearm64spottaskTaskRole0F078C81", @@ -12630,12 +12854,14 @@ ] ] }, - "securityGroup": { - "Fn::GetAtt": [ - "FargateWindowssecuritygroupE684A7B0", - "GroupId" - ] - }, + "securityGroups": [ + { + "Fn::GetAtt": [ + "FargateWindowssecuritygroupE684A7B0", + "GroupId" + ] + } + ], "roleArn": { "Fn::GetAtt": [ "FargateWindowstaskTaskRole364508C8", @@ -12701,6 +12927,14 @@ "linux", "x64" ], + "securityGroups": [ + { + "Fn::GetAtt": [ + "EC2LinuxSGF5B89300", + "GroupId" + ] + } + ], "roleArn": { "Fn::GetAtt": [ "EC2LinuxRole8B6519A2", @@ -12723,6 +12957,14 @@ "linux", "x64" ], + "securityGroups": [ + { + "Fn::GetAtt": [ + "EC2SpotLinuxSG8D846B64", + "GroupId" + ] + } + ], "roleArn": { "Fn::GetAtt": [ "EC2SpotLinuxRole86333E5D", @@ -12745,6 +12987,14 @@ "linux", "arm64" ], + "securityGroups": [ + { + "Fn::GetAtt": [ + "EC2Linuxarm64SG550ECD6C", + "GroupId" + ] + } + ], "roleArn": { "Fn::GetAtt": [ "EC2Linuxarm64Role242F68FF", @@ -12767,6 +13017,14 @@ "windows", "x64" ], + "securityGroups": [ + { + "Fn::GetAtt": [ + "EC2WindowsSG13E24976", + "GroupId" + ] + } + ], "roleArn": { "Fn::GetAtt": [ "EC2WindowsRoleC0D850D2", diff --git a/test/default.integ.snapshot/manifest.json b/test/default.integ.snapshot/manifest.json index d842ce84..6131004b 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}/ef38c3bac82a92a68774e24daab1bd0301a575c0a16dc214d62775adc01976e5.json", + "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/cb8b028063cbb5d802bc47dc5ba6314eaf9e718d1c9f0f62decd46320644f7a3.json", "requiresBootstrapStackVersion": 6, "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", "additionalDependencies": [ @@ -309,6 +309,12 @@ "data": "LambdaImageBuilderx64DependableImagePushruleAllowEventRulegithubrunnerstestupdatelambdadcc036c8876b451ea2c1552f9e06e9e17433A98E7BC3031D" } ], + "/github-runners-test/Windows Image Builder/SG/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "WindowsImageBuilderSG5ACD1618" + } + ], "/github-runners-test/Windows Image Builder/Repository/Resource": [ { "type": "aws:cdk:logicalId", @@ -471,6 +477,12 @@ "data": "LogRetentionaae0aa3c5b4d4f87b02d85b201efdd8aFD4BFC8A" } ], + "/github-runners-test/AMI Linux Builder/SG/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "AMILinuxBuilderSGEDC86329" + } + ], "/github-runners-test/AMI Linux Builder/Upgrade packages and install basics/Version/Default": [ { "type": "aws:cdk:logicalId", @@ -1197,6 +1209,12 @@ "data": "FargateWindowslogs52881DBF" } ], + "/github-runners-test/EC2 Linux/SG/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "EC2LinuxSGF5B89300" + } + ], "/github-runners-test/EC2 Linux/Role/Resource": [ { "type": "aws:cdk:logicalId", @@ -1251,6 +1269,12 @@ "data": "deleteamidcc036c8876b451ea2c1552f9e06e9e1LogRetention85F808EB" } ], + "/github-runners-test/EC2 Spot Linux/SG/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "EC2SpotLinuxSG8D846B64" + } + ], "/github-runners-test/EC2 Spot Linux/Role/Resource": [ { "type": "aws:cdk:logicalId", @@ -1275,6 +1299,12 @@ "data": "EC2SpotLinuxInstanceProfileB12320D4" } ], + "/github-runners-test/AMI Linux arm64 Builder/SG/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "AMILinuxarm64BuilderSG94315968" + } + ], "/github-runners-test/AMI Linux arm64 Builder/Upgrade packages and install basics/Version/Default": [ { "type": "aws:cdk:logicalId", @@ -1437,6 +1467,12 @@ "data": "AMILinuxarm64BuilderAMIDeleter27E72E27" } ], + "/github-runners-test/EC2 Linux arm64/SG/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "EC2Linuxarm64SG550ECD6C" + } + ], "/github-runners-test/EC2 Linux arm64/Role/Resource": [ { "type": "aws:cdk:logicalId", @@ -1467,6 +1503,12 @@ "data": "SsmParameterValueawsservicecanonicalubuntuserverfocalstablecurrentarm64hvmebsgp2amiidC96584B6F00A464EAD1953AFF4B05118Parameter" } ], + "/github-runners-test/Windows EC2 Builder/SG/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "WindowsEC2BuilderSGE3F67842" + } + ], "/github-runners-test/Windows EC2 Builder/CloudWatch agent/Version/Default": [ { "type": "aws:cdk:logicalId", @@ -1617,6 +1659,12 @@ "data": "WindowsEC2BuilderAMIDeleterF9643905" } ], + "/github-runners-test/EC2 Windows/SG/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "EC2WindowsSG13E24976" + } + ], "/github-runners-test/EC2 Windows/Role/Resource": [ { "type": "aws:cdk:logicalId", diff --git a/test/default.integ.snapshot/tree.json b/test/default.integ.snapshot/tree.json index ebb895d5..6c6a1208 100644 --- a/test/default.integ.snapshot/tree.json +++ b/test/default.integ.snapshot/tree.json @@ -2575,6 +2575,40 @@ "id": "Windows Image Builder", "path": "github-runners-test/Windows Image Builder", "children": { + "SG": { + "id": "SG", + "path": "github-runners-test/Windows Image Builder/SG", + "children": { + "Resource": { + "id": "Resource", + "path": "github-runners-test/Windows Image Builder/SG/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::SecurityGroup", + "aws:cdk:cloudformation:props": { + "groupDescription": "github-runners-test/Windows Image Builder/SG", + "securityGroupEgress": [ + { + "cidrIp": "0.0.0.0/0", + "description": "Allow all outbound traffic by default", + "ipProtocol": "-1" + } + ], + "vpcId": { + "Ref": "Vpc8378EB38" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_ec2.CfnSecurityGroup", + "version": "2.50.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_ec2.SecurityGroup", + "version": "2.50.0" + } + }, "Repository": { "id": "Repository", "path": "github-runners-test/Windows Image Builder/Repository", @@ -3045,7 +3079,18 @@ "description": "Build image for GitHub Actions runner github-runners-test/Windows Image Builder (Windows/X86_64)", "instanceTypes": [ "m5.large" - ] + ], + "securityGroupIds": [ + { + "Fn::GetAtt": [ + "WindowsImageBuilderSG5ACD1618", + "GroupId" + ] + } + ], + "subnetId": { + "Ref": "VpcPublicSubnet1Subnet5C2D37C4" + } } }, "constructInfo": { @@ -3541,6 +3586,40 @@ "id": "AMI Linux Builder", "path": "github-runners-test/AMI Linux Builder", "children": { + "SG": { + "id": "SG", + "path": "github-runners-test/AMI Linux Builder/SG", + "children": { + "Resource": { + "id": "Resource", + "path": "github-runners-test/AMI Linux Builder/SG/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::SecurityGroup", + "aws:cdk:cloudformation:props": { + "groupDescription": "github-runners-test/AMI Linux Builder/SG", + "securityGroupEgress": [ + { + "cidrIp": "0.0.0.0/0", + "description": "Allow all outbound traffic by default", + "ipProtocol": "-1" + } + ], + "vpcId": { + "Ref": "Vpc8378EB38" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_ec2.CfnSecurityGroup", + "version": "2.50.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_ec2.SecurityGroup", + "version": "2.50.0" + } + }, "Upgrade packages and install basics": { "id": "Upgrade packages and install basics", "path": "github-runners-test/AMI Linux Builder/Upgrade packages and install basics", @@ -4204,7 +4283,18 @@ "description": "Build AMI for GitHub Actions runner github-runners-test/AMI Linux Builder (Linux/X86_64)", "instanceTypes": [ "m5.large" - ] + ], + "securityGroupIds": [ + { + "Fn::GetAtt": [ + "AMILinuxBuilderSGEDC86329", + "GroupId" + ] + } + ], + "subnetId": { + "Ref": "VpcPublicSubnet1Subnet5C2D37C4" + } } }, "constructInfo": { @@ -10393,6 +10483,40 @@ "id": "EC2 Linux", "path": "github-runners-test/EC2 Linux", "children": { + "SG": { + "id": "SG", + "path": "github-runners-test/EC2 Linux/SG", + "children": { + "Resource": { + "id": "Resource", + "path": "github-runners-test/EC2 Linux/SG/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::SecurityGroup", + "aws:cdk:cloudformation:props": { + "groupDescription": "github-runners-test/EC2 Linux/SG", + "securityGroupEgress": [ + { + "cidrIp": "0.0.0.0/0", + "description": "Allow all outbound traffic by default", + "ipProtocol": "-1" + } + ], + "vpcId": { + "Ref": "Vpc8378EB38" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_ec2.CfnSecurityGroup", + "version": "2.50.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_ec2.SecurityGroup", + "version": "2.50.0" + } + }, "Role": { "id": "Role", "path": "github-runners-test/EC2 Linux/Role", @@ -10779,6 +10903,40 @@ "id": "EC2 Spot Linux", "path": "github-runners-test/EC2 Spot Linux", "children": { + "SG": { + "id": "SG", + "path": "github-runners-test/EC2 Spot Linux/SG", + "children": { + "Resource": { + "id": "Resource", + "path": "github-runners-test/EC2 Spot Linux/SG/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::SecurityGroup", + "aws:cdk:cloudformation:props": { + "groupDescription": "github-runners-test/EC2 Spot Linux/SG", + "securityGroupEgress": [ + { + "cidrIp": "0.0.0.0/0", + "description": "Allow all outbound traffic by default", + "ipProtocol": "-1" + } + ], + "vpcId": { + "Ref": "Vpc8378EB38" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_ec2.CfnSecurityGroup", + "version": "2.50.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_ec2.SecurityGroup", + "version": "2.50.0" + } + }, "Role": { "id": "Role", "path": "github-runners-test/EC2 Spot Linux/Role", @@ -10962,6 +11120,40 @@ "id": "AMI Linux arm64 Builder", "path": "github-runners-test/AMI Linux arm64 Builder", "children": { + "SG": { + "id": "SG", + "path": "github-runners-test/AMI Linux arm64 Builder/SG", + "children": { + "Resource": { + "id": "Resource", + "path": "github-runners-test/AMI Linux arm64 Builder/SG/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::SecurityGroup", + "aws:cdk:cloudformation:props": { + "groupDescription": "github-runners-test/AMI Linux arm64 Builder/SG", + "securityGroupEgress": [ + { + "cidrIp": "0.0.0.0/0", + "description": "Allow all outbound traffic by default", + "ipProtocol": "-1" + } + ], + "vpcId": { + "Ref": "Vpc8378EB38" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_ec2.CfnSecurityGroup", + "version": "2.50.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_ec2.SecurityGroup", + "version": "2.50.0" + } + }, "Upgrade packages and install basics": { "id": "Upgrade packages and install basics", "path": "github-runners-test/AMI Linux arm64 Builder/Upgrade packages and install basics", @@ -11625,7 +11817,18 @@ "description": "Build AMI for GitHub Actions runner github-runners-test/AMI Linux arm64 Builder (Linux/ARM64)", "instanceTypes": [ "m6g.large" - ] + ], + "securityGroupIds": [ + { + "Fn::GetAtt": [ + "AMILinuxarm64BuilderSG94315968", + "GroupId" + ] + } + ], + "subnetId": { + "Ref": "VpcPublicSubnet1Subnet5C2D37C4" + } } }, "constructInfo": { @@ -11811,6 +12014,40 @@ "id": "EC2 Linux arm64", "path": "github-runners-test/EC2 Linux arm64", "children": { + "SG": { + "id": "SG", + "path": "github-runners-test/EC2 Linux arm64/SG", + "children": { + "Resource": { + "id": "Resource", + "path": "github-runners-test/EC2 Linux arm64/SG/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::SecurityGroup", + "aws:cdk:cloudformation:props": { + "groupDescription": "github-runners-test/EC2 Linux arm64/SG", + "securityGroupEgress": [ + { + "cidrIp": "0.0.0.0/0", + "description": "Allow all outbound traffic by default", + "ipProtocol": "-1" + } + ], + "vpcId": { + "Ref": "Vpc8378EB38" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_ec2.CfnSecurityGroup", + "version": "2.50.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_ec2.SecurityGroup", + "version": "2.50.0" + } + }, "Role": { "id": "Role", "path": "github-runners-test/EC2 Linux arm64/Role", @@ -12010,6 +12247,40 @@ "id": "Windows EC2 Builder", "path": "github-runners-test/Windows EC2 Builder", "children": { + "SG": { + "id": "SG", + "path": "github-runners-test/Windows EC2 Builder/SG", + "children": { + "Resource": { + "id": "Resource", + "path": "github-runners-test/Windows EC2 Builder/SG/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::SecurityGroup", + "aws:cdk:cloudformation:props": { + "groupDescription": "github-runners-test/Windows EC2 Builder/SG", + "securityGroupEgress": [ + { + "cidrIp": "0.0.0.0/0", + "description": "Allow all outbound traffic by default", + "ipProtocol": "-1" + } + ], + "vpcId": { + "Ref": "Vpc8378EB38" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_ec2.CfnSecurityGroup", + "version": "2.50.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_ec2.SecurityGroup", + "version": "2.50.0" + } + }, "CloudWatch agent": { "id": "CloudWatch agent", "path": "github-runners-test/Windows EC2 Builder/CloudWatch agent", @@ -12617,7 +12888,18 @@ "description": "Build AMI for GitHub Actions runner github-runners-test/Windows EC2 Builder (Windows/X86_64)", "instanceTypes": [ "m5.large" - ] + ], + "securityGroupIds": [ + { + "Fn::GetAtt": [ + "WindowsEC2BuilderSGE3F67842", + "GroupId" + ] + } + ], + "subnetId": { + "Ref": "VpcPublicSubnet1Subnet5C2D37C4" + } } }, "constructInfo": { @@ -12803,6 +13085,40 @@ "id": "EC2 Windows", "path": "github-runners-test/EC2 Windows", "children": { + "SG": { + "id": "SG", + "path": "github-runners-test/EC2 Windows/SG", + "children": { + "Resource": { + "id": "Resource", + "path": "github-runners-test/EC2 Windows/SG/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::SecurityGroup", + "aws:cdk:cloudformation:props": { + "groupDescription": "github-runners-test/EC2 Windows/SG", + "securityGroupEgress": [ + { + "cidrIp": "0.0.0.0/0", + "description": "Allow all outbound traffic by default", + "ipProtocol": "-1" + } + ], + "vpcId": { + "Ref": "Vpc8378EB38" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_ec2.CfnSecurityGroup", + "version": "2.50.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_ec2.SecurityGroup", + "version": "2.50.0" + } + }, "Role": { "id": "Role", "path": "github-runners-test/EC2 Windows/Role", @@ -14879,7 +15195,18 @@ "Arn" ] }, - "\"},\"MetadataOptions\":{\"HttpTokens\":\"required\"},\"BlockDeviceMappings\":[{\"DeviceName\":\"/dev/sda1\",\"Ebs\":{\"DeleteOnTermination\":true,\"VolumeSize\":30}}]}},\"ec2-spot, linux, x64 data\":{\"Type\":\"Pass\",\"ResultPath\":\"$.ec2\",\"Parameters\":{\"userdataTemplate\":\"#!/bin/bash -x\\nTASK_TOKEN=\\\"{}\\\"\\nheartbeat () \\\\{\\n while true; do\\n aws stepfunctions send-task-heartbeat --task-token \\\"$TASK_TOKEN\\\"\\n sleep 60\\n done\\n\\\\}\\nsetup_logs () \\\\{\\n cat < /tmp/log.conf || exit 1\\n \\\\{\\n \\\"logs\\\": \\\\{\\n \\\"log_stream_name\\\": \\\"unknown\\\",\\n \\\"logs_collected\\\": \\\\{\\n \\\"files\\\": \\\\{\\n \\\"collect_list\\\": [\\n \\\\{\\n \\\"file_path\\\": \\\"/var/log/runner.log\\\",\\n \\\"log_group_name\\\": \\\"{}\\\",\\n \\\"log_stream_name\\\": \\\"{}\\\",\\n \\\"timezone\\\": \\\"UTC\\\"\\n \\\\}\\n ]\\n \\\\}\\n \\\\}\\n \\\\}\\n \\\\}\\nEOF\\n /opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-ctl -a fetch-config -m ec2 -s -c file:/tmp/log.conf || exit 2\\n\\\\}\\naction () \\\\{\\n sudo -Hu runner /home/runner/config.sh --unattended --url \\\"https://{}/{}/{}\\\" --token \\\"{}\\\" --ephemeral --work _work --labels \\\"{}\\\" {} --name \\\"{}\\\" || exit 1\\n sudo --preserve-env=AWS_REGION -Hu runner /home/runner/run.sh || exit 2\\n\\\\}\\nheartbeat &\\nif setup_logs && action | tee /var/log/runner.log 2>&1; then\\n aws stepfunctions send-task-success --task-token \\\"$TASK_TOKEN\\\" --task-output '\\\\{\\\"ok\\\": true\\\\}'\\nelse\\n aws stepfunctions send-task-failure --task-token \\\"$TASK_TOKEN\\\"\\nfi\\npoweroff\\n\"},\"Next\":\"ec2-spot, linux, x64\"},\"ec2-spot, linux, x64\":{\"End\":true,\"Type\":\"Task\",\"HeartbeatSeconds\":300,\"Resource\":\"arn:", + "\"},\"MetadataOptions\":{\"HttpTokens\":\"required\"},\"SecurityGroupIds\":[\"", + { + "Fn::GetAtt": [ + "EC2LinuxSGF5B89300", + "GroupId" + ] + }, + "\"],\"SubnetId\":\"", + { + "Ref": "VpcPublicSubnet1Subnet5C2D37C4" + }, + "\",\"BlockDeviceMappings\":[{\"DeviceName\":\"/dev/sda1\",\"Ebs\":{\"DeleteOnTermination\":true,\"VolumeSize\":30}}]}},\"ec2-spot, linux, x64 data\":{\"Type\":\"Pass\",\"ResultPath\":\"$.ec2\",\"Parameters\":{\"userdataTemplate\":\"#!/bin/bash -x\\nTASK_TOKEN=\\\"{}\\\"\\nheartbeat () \\\\{\\n while true; do\\n aws stepfunctions send-task-heartbeat --task-token \\\"$TASK_TOKEN\\\"\\n sleep 60\\n done\\n\\\\}\\nsetup_logs () \\\\{\\n cat < /tmp/log.conf || exit 1\\n \\\\{\\n \\\"logs\\\": \\\\{\\n \\\"log_stream_name\\\": \\\"unknown\\\",\\n \\\"logs_collected\\\": \\\\{\\n \\\"files\\\": \\\\{\\n \\\"collect_list\\\": [\\n \\\\{\\n \\\"file_path\\\": \\\"/var/log/runner.log\\\",\\n \\\"log_group_name\\\": \\\"{}\\\",\\n \\\"log_stream_name\\\": \\\"{}\\\",\\n \\\"timezone\\\": \\\"UTC\\\"\\n \\\\}\\n ]\\n \\\\}\\n \\\\}\\n \\\\}\\n \\\\}\\nEOF\\n /opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-ctl -a fetch-config -m ec2 -s -c file:/tmp/log.conf || exit 2\\n\\\\}\\naction () \\\\{\\n sudo -Hu runner /home/runner/config.sh --unattended --url \\\"https://{}/{}/{}\\\" --token \\\"{}\\\" --ephemeral --work _work --labels \\\"{}\\\" {} --name \\\"{}\\\" || exit 1\\n sudo --preserve-env=AWS_REGION -Hu runner /home/runner/run.sh || exit 2\\n\\\\}\\nheartbeat &\\nif setup_logs && action | tee /var/log/runner.log 2>&1; then\\n aws stepfunctions send-task-success --task-token \\\"$TASK_TOKEN\\\" --task-output '\\\\{\\\"ok\\\": true\\\\}'\\nelse\\n aws stepfunctions send-task-failure --task-token \\\"$TASK_TOKEN\\\"\\nfi\\npoweroff\\n\"},\"Next\":\"ec2-spot, linux, x64\"},\"ec2-spot, linux, x64\":{\"End\":true,\"Type\":\"Task\",\"HeartbeatSeconds\":300,\"Resource\":\"arn:", { "Ref": "AWS::Partition" }, @@ -14898,7 +15225,18 @@ "Arn" ] }, - "\"},\"MetadataOptions\":{\"HttpTokens\":\"required\"},\"BlockDeviceMappings\":[{\"DeviceName\":\"/dev/sda1\",\"Ebs\":{\"DeleteOnTermination\":true,\"VolumeSize\":30}}],\"InstanceMarketOptions\":{\"MarketType\":\"spot\",\"SpotOptions\":{\"SpotInstanceType\":\"one-time\"}}}},\"ec2, linux, arm64 data\":{\"Type\":\"Pass\",\"ResultPath\":\"$.ec2\",\"Parameters\":{\"userdataTemplate\":\"#!/bin/bash -x\\nTASK_TOKEN=\\\"{}\\\"\\nheartbeat () \\\\{\\n while true; do\\n aws stepfunctions send-task-heartbeat --task-token \\\"$TASK_TOKEN\\\"\\n sleep 60\\n done\\n\\\\}\\nsetup_logs () \\\\{\\n cat < /tmp/log.conf || exit 1\\n \\\\{\\n \\\"logs\\\": \\\\{\\n \\\"log_stream_name\\\": \\\"unknown\\\",\\n \\\"logs_collected\\\": \\\\{\\n \\\"files\\\": \\\\{\\n \\\"collect_list\\\": [\\n \\\\{\\n \\\"file_path\\\": \\\"/var/log/runner.log\\\",\\n \\\"log_group_name\\\": \\\"{}\\\",\\n \\\"log_stream_name\\\": \\\"{}\\\",\\n \\\"timezone\\\": \\\"UTC\\\"\\n \\\\}\\n ]\\n \\\\}\\n \\\\}\\n \\\\}\\n \\\\}\\nEOF\\n /opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-ctl -a fetch-config -m ec2 -s -c file:/tmp/log.conf || exit 2\\n\\\\}\\naction () \\\\{\\n sudo -Hu runner /home/runner/config.sh --unattended --url \\\"https://{}/{}/{}\\\" --token \\\"{}\\\" --ephemeral --work _work --labels \\\"{}\\\" {} --name \\\"{}\\\" || exit 1\\n sudo --preserve-env=AWS_REGION -Hu runner /home/runner/run.sh || exit 2\\n\\\\}\\nheartbeat &\\nif setup_logs && action | tee /var/log/runner.log 2>&1; then\\n aws stepfunctions send-task-success --task-token \\\"$TASK_TOKEN\\\" --task-output '\\\\{\\\"ok\\\": true\\\\}'\\nelse\\n aws stepfunctions send-task-failure --task-token \\\"$TASK_TOKEN\\\"\\nfi\\npoweroff\\n\"},\"Next\":\"ec2, linux, arm64\"},\"ec2, linux, arm64\":{\"End\":true,\"Type\":\"Task\",\"HeartbeatSeconds\":300,\"Resource\":\"arn:", + "\"},\"MetadataOptions\":{\"HttpTokens\":\"required\"},\"SecurityGroupIds\":[\"", + { + "Fn::GetAtt": [ + "EC2SpotLinuxSG8D846B64", + "GroupId" + ] + }, + "\"],\"SubnetId\":\"", + { + "Ref": "VpcPublicSubnet1Subnet5C2D37C4" + }, + "\",\"BlockDeviceMappings\":[{\"DeviceName\":\"/dev/sda1\",\"Ebs\":{\"DeleteOnTermination\":true,\"VolumeSize\":30}}],\"InstanceMarketOptions\":{\"MarketType\":\"spot\",\"SpotOptions\":{\"SpotInstanceType\":\"one-time\"}}}},\"ec2, linux, arm64 data\":{\"Type\":\"Pass\",\"ResultPath\":\"$.ec2\",\"Parameters\":{\"userdataTemplate\":\"#!/bin/bash -x\\nTASK_TOKEN=\\\"{}\\\"\\nheartbeat () \\\\{\\n while true; do\\n aws stepfunctions send-task-heartbeat --task-token \\\"$TASK_TOKEN\\\"\\n sleep 60\\n done\\n\\\\}\\nsetup_logs () \\\\{\\n cat < /tmp/log.conf || exit 1\\n \\\\{\\n \\\"logs\\\": \\\\{\\n \\\"log_stream_name\\\": \\\"unknown\\\",\\n \\\"logs_collected\\\": \\\\{\\n \\\"files\\\": \\\\{\\n \\\"collect_list\\\": [\\n \\\\{\\n \\\"file_path\\\": \\\"/var/log/runner.log\\\",\\n \\\"log_group_name\\\": \\\"{}\\\",\\n \\\"log_stream_name\\\": \\\"{}\\\",\\n \\\"timezone\\\": \\\"UTC\\\"\\n \\\\}\\n ]\\n \\\\}\\n \\\\}\\n \\\\}\\n \\\\}\\nEOF\\n /opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-ctl -a fetch-config -m ec2 -s -c file:/tmp/log.conf || exit 2\\n\\\\}\\naction () \\\\{\\n sudo -Hu runner /home/runner/config.sh --unattended --url \\\"https://{}/{}/{}\\\" --token \\\"{}\\\" --ephemeral --work _work --labels \\\"{}\\\" {} --name \\\"{}\\\" || exit 1\\n sudo --preserve-env=AWS_REGION -Hu runner /home/runner/run.sh || exit 2\\n\\\\}\\nheartbeat &\\nif setup_logs && action | tee /var/log/runner.log 2>&1; then\\n aws stepfunctions send-task-success --task-token \\\"$TASK_TOKEN\\\" --task-output '\\\\{\\\"ok\\\": true\\\\}'\\nelse\\n aws stepfunctions send-task-failure --task-token \\\"$TASK_TOKEN\\\"\\nfi\\npoweroff\\n\"},\"Next\":\"ec2, linux, arm64\"},\"ec2, linux, arm64\":{\"End\":true,\"Type\":\"Task\",\"HeartbeatSeconds\":300,\"Resource\":\"arn:", { "Ref": "AWS::Partition" }, @@ -14917,7 +15255,18 @@ "Arn" ] }, - "\"},\"MetadataOptions\":{\"HttpTokens\":\"required\"},\"BlockDeviceMappings\":[{\"DeviceName\":\"/dev/sda1\",\"Ebs\":{\"DeleteOnTermination\":true,\"VolumeSize\":30}}]}},\"ec2, windows, x64 data\":{\"Type\":\"Pass\",\"ResultPath\":\"$.ec2\",\"Parameters\":{\"userdataTemplate\":\"\\n$TASK_TOKEN = \\\"{}\\\"\\nStart-Job -ScriptBlock \\\\{\\n while (1) \\\\{\\n aws stepfunctions send-task-heartbeat --task-token \\\"$using:TASK_TOKEN\\\"\\n sleep 60\\n \\\\}\\n\\\\}\\nfunction setup_logs () \\\\{\\n echo '\\\\{\\n \\\"logs\\\": \\\\{\\n \\\"log_stream_name\\\": \\\"unknown\\\",\\n \\\"logs_collected\\\": \\\\{\\n \\\"files\\\": \\\\{\\n \\\"collect_list\\\": [\\n \\\\{\\n \\\"file_path\\\": \\\"/actions/runner.log\\\",\\n \\\"log_group_name\\\": \\\"{}\\\",\\n \\\"log_stream_name\\\": \\\"{}\\\",\\n \\\"timezone\\\": \\\"UTC\\\"\\n \\\\}\\n ]\\n \\\\}\\n \\\\}\\n \\\\}\\n \\\\}' | Out-File -Encoding ASCII $Env:TEMP/log.conf\\n & \\\"C:/Program Files/Amazon/AmazonCloudWatchAgent/amazon-cloudwatch-agent-ctl.ps1\\\" -a fetch-config -m ec2 -s -c file:$Env:TEMP/log.conf\\n\\\\}\\nfunction action () \\\\{\\n cd /actions\\n ./config.cmd --unattended --url \\\"https://{}/{}/{}\\\" --token \\\"{}\\\" --ephemeral --work _work --labels \\\"{}\\\" {} --name \\\"{}\\\" 2>&1 | Out-File -Encoding ASCII -Append /actions/runner.log\\n if ($LASTEXITCODE -ne 0) \\\\{ return 1 \\\\}\\n ./run.cmd 2>&1 | Out-File -Encoding ASCII -Append /actions/runner.log\\n if ($LASTEXITCODE -ne 0) \\\\{ return 2 \\\\}\\n return 0\\n\\\\}\\nsetup_logs\\n$r = action\\nif ($r -eq 0) \\\\{\\n aws stepfunctions send-task-success --task-token \\\"$TASK_TOKEN\\\" --task-output '\\\\{ \\\\}'\\n\\\\} else \\\\{\\n aws stepfunctions send-task-failure --task-token \\\"$TASK_TOKEN\\\"\\n\\\\}\\nStop-Computer -ComputerName localhost -Force\\n\\n\"},\"Next\":\"ec2, windows, x64\"},\"ec2, windows, x64\":{\"End\":true,\"Type\":\"Task\",\"HeartbeatSeconds\":300,\"Resource\":\"arn:", + "\"},\"MetadataOptions\":{\"HttpTokens\":\"required\"},\"SecurityGroupIds\":[\"", + { + "Fn::GetAtt": [ + "EC2Linuxarm64SG550ECD6C", + "GroupId" + ] + }, + "\"],\"SubnetId\":\"", + { + "Ref": "VpcPublicSubnet1Subnet5C2D37C4" + }, + "\",\"BlockDeviceMappings\":[{\"DeviceName\":\"/dev/sda1\",\"Ebs\":{\"DeleteOnTermination\":true,\"VolumeSize\":30}}]}},\"ec2, windows, x64 data\":{\"Type\":\"Pass\",\"ResultPath\":\"$.ec2\",\"Parameters\":{\"userdataTemplate\":\"\\n$TASK_TOKEN = \\\"{}\\\"\\nStart-Job -ScriptBlock \\\\{\\n while (1) \\\\{\\n aws stepfunctions send-task-heartbeat --task-token \\\"$using:TASK_TOKEN\\\"\\n sleep 60\\n \\\\}\\n\\\\}\\nfunction setup_logs () \\\\{\\n echo '\\\\{\\n \\\"logs\\\": \\\\{\\n \\\"log_stream_name\\\": \\\"unknown\\\",\\n \\\"logs_collected\\\": \\\\{\\n \\\"files\\\": \\\\{\\n \\\"collect_list\\\": [\\n \\\\{\\n \\\"file_path\\\": \\\"/actions/runner.log\\\",\\n \\\"log_group_name\\\": \\\"{}\\\",\\n \\\"log_stream_name\\\": \\\"{}\\\",\\n \\\"timezone\\\": \\\"UTC\\\"\\n \\\\}\\n ]\\n \\\\}\\n \\\\}\\n \\\\}\\n \\\\}' | Out-File -Encoding ASCII $Env:TEMP/log.conf\\n & \\\"C:/Program Files/Amazon/AmazonCloudWatchAgent/amazon-cloudwatch-agent-ctl.ps1\\\" -a fetch-config -m ec2 -s -c file:$Env:TEMP/log.conf\\n\\\\}\\nfunction action () \\\\{\\n cd /actions\\n ./config.cmd --unattended --url \\\"https://{}/{}/{}\\\" --token \\\"{}\\\" --ephemeral --work _work --labels \\\"{}\\\" {} --name \\\"{}\\\" 2>&1 | Out-File -Encoding ASCII -Append /actions/runner.log\\n if ($LASTEXITCODE -ne 0) \\\\{ return 1 \\\\}\\n ./run.cmd 2>&1 | Out-File -Encoding ASCII -Append /actions/runner.log\\n if ($LASTEXITCODE -ne 0) \\\\{ return 2 \\\\}\\n return 0\\n\\\\}\\nsetup_logs\\n$r = action\\nif ($r -eq 0) \\\\{\\n aws stepfunctions send-task-success --task-token \\\"$TASK_TOKEN\\\" --task-output '\\\\{ \\\\}'\\n\\\\} else \\\\{\\n aws stepfunctions send-task-failure --task-token \\\"$TASK_TOKEN\\\"\\n\\\\}\\nStop-Computer -ComputerName localhost -Force\\n\\n\"},\"Next\":\"ec2, windows, x64\"},\"ec2, windows, x64\":{\"End\":true,\"Type\":\"Task\",\"HeartbeatSeconds\":300,\"Resource\":\"arn:", { "Ref": "AWS::Partition" }, @@ -14936,7 +15285,18 @@ "Arn" ] }, - "\"},\"MetadataOptions\":{\"HttpTokens\":\"required\"},\"BlockDeviceMappings\":[{\"DeviceName\":\"/dev/sda1\",\"Ebs\":{\"DeleteOnTermination\":true,\"VolumeSize\":30}}]}}}},{\"StartAt\":\"Wait\",\"States\":{\"Wait\":{\"Type\":\"Wait\",\"Seconds\":600,\"Next\":\"Delete Idle Runner\"},\"Delete Idle Runner\":{\"End\":true,\"Retry\":[{\"ErrorEquals\":[\"Lambda.ServiceException\",\"Lambda.AWSLambdaException\",\"Lambda.SdkClientException\"],\"IntervalSeconds\":2,\"MaxAttempts\":6,\"BackoffRate\":2}],\"Type\":\"Task\",\"ResultPath\":\"$.delete\",\"Resource\":\"", + "\"},\"MetadataOptions\":{\"HttpTokens\":\"required\"},\"SecurityGroupIds\":[\"", + { + "Fn::GetAtt": [ + "EC2WindowsSG13E24976", + "GroupId" + ] + }, + "\"],\"SubnetId\":\"", + { + "Ref": "VpcPublicSubnet1Subnet5C2D37C4" + }, + "\",\"BlockDeviceMappings\":[{\"DeviceName\":\"/dev/sda1\",\"Ebs\":{\"DeleteOnTermination\":true,\"VolumeSize\":30}}]}}}},{\"StartAt\":\"Wait\",\"States\":{\"Wait\":{\"Type\":\"Wait\",\"Seconds\":600,\"Next\":\"Delete Idle Runner\"},\"Delete Idle Runner\":{\"End\":true,\"Retry\":[{\"ErrorEquals\":[\"Lambda.ServiceException\",\"Lambda.AWSLambdaException\",\"Lambda.SdkClientException\"],\"IntervalSeconds\":2,\"MaxAttempts\":6,\"BackoffRate\":2}],\"Type\":\"Task\",\"ResultPath\":\"$.delete\",\"Resource\":\"", { "Fn::GetAtt": [ "runnersdeleterunner7F8D5293", diff --git a/test/default.integ.ts b/test/default.integ.ts index fcc1e69d..4f103a43 100644 --- a/test/default.integ.ts +++ b/test/default.integ.ts @@ -13,20 +13,21 @@ import { AmiBuilder } from '../src/providers/image-builders/ami'; const app = new cdk.App(); const stack = new cdk.Stack(app, 'github-runners-test'); +const vpc = new ec2.Vpc(stack, 'Vpc', { + subnetConfiguration: [ + // just public so we don't need to waste money on VPC endpoints or NAT gateway + { + name: 'Public', + subnetType: ec2.SubnetType.PUBLIC, + }, + ], +}); const cluster = new ecs.Cluster( stack, 'cluster', { enableFargateCapacityProviders: true, - vpc: new ec2.Vpc(stack, 'Vpc', { - subnetConfiguration: [ - // just public so we don't need to waste money on VPC endpoints or NAT gateway - { - name: 'Public', - subnetType: ec2.SubnetType.PUBLIC, - }, - ], - }), + vpc: vpc, }, ); const fargateX64Builder = new CodeBuildImageBuilder(stack, 'Fargate builder', { @@ -44,8 +45,11 @@ const lambdaImageBuilder = new CodeBuildImageBuilder(stack, 'Lambda Image Builde const windowsImageBuilder = new ContainerImageBuilder(stack, 'Windows Image Builder', { architecture: Architecture.X86_64, os: Os.WINDOWS, + vpc, +}); +const amiX64Builder = new AmiBuilder(stack, 'AMI Linux Builder', { + vpc, }); -const amiX64Builder = new AmiBuilder(stack, 'AMI Linux Builder'); new GitHubRunners(stack, 'runners', { providers: [ new CodeBuildRunner(stack, 'CodeBuildx64', { @@ -129,25 +133,31 @@ new GitHubRunners(stack, 'runners', { new Ec2Runner(stack, 'EC2 Linux', { labels: ['ec2', 'linux', 'x64'], amiBuilder: amiX64Builder, + vpc, }), new Ec2Runner(stack, 'EC2 Spot Linux', { labels: ['ec2-spot', 'linux', 'x64'], amiBuilder: amiX64Builder, spot: true, + vpc, }), new Ec2Runner(stack, 'EC2 Linux arm64', { labels: ['ec2', 'linux', 'arm64'], amiBuilder: new AmiBuilder(stack, 'AMI Linux arm64 Builder', { architecture: Architecture.ARM64, instanceType: ec2.InstanceType.of(ec2.InstanceClass.M6G, ec2.InstanceSize.LARGE), + vpc, }), instanceType: ec2.InstanceType.of(ec2.InstanceClass.M6G, ec2.InstanceSize.LARGE), + vpc, }), new Ec2Runner(stack, 'EC2 Windows', { labels: ['ec2', 'windows', 'x64'], amiBuilder: new AmiBuilder(stack, 'Windows EC2 Builder', { os: Os.WINDOWS, + vpc, }), + vpc, }), ], }); diff --git a/test/imagebuilder.test.ts b/test/imagebuilder.test.ts index d731525b..3c5285b7 100644 --- a/test/imagebuilder.test.ts +++ b/test/imagebuilder.test.ts @@ -7,10 +7,13 @@ test('AMI builder matching instance type', () => { const app = new cdk.App(); const stack = new cdk.Stack(app, 'test'); + const vpc = new ec2.Vpc(stack, 'vpc'); + expect(() => { new AmiBuilder(stack, 'linux arm64', { os: Os.LINUX, architecture: Architecture.ARM64, + vpc, }); }).toThrowError('Builder architecture (ARM64) doesn\'t match selected instance type (m5.large / x86_64)'); }); @@ -19,23 +22,29 @@ test('AMI builder supported OS', () => { const app = new cdk.App(); const stack = new cdk.Stack(app, 'test'); + const vpc = new ec2.Vpc(stack, 'vpc'); + new AmiBuilder(stack, 'linux x64', { os: Os.LINUX, architecture: Architecture.X86_64, + vpc, }); new AmiBuilder(stack, 'linux arm64', { os: Os.LINUX, architecture: Architecture.ARM64, instanceType: ec2.InstanceType.of(ec2.InstanceClass.M6G, ec2.InstanceSize.LARGE), + vpc, }); new AmiBuilder(stack, 'win x64', { os: Os.WINDOWS, architecture: Architecture.X86_64, + vpc, }); new AmiBuilder(stack, 'win arm64', { os: Os.WINDOWS, architecture: Architecture.ARM64, instanceType: ec2.InstanceType.of(ec2.InstanceClass.M6G, ec2.InstanceSize.LARGE), + vpc, }); }); @@ -43,10 +52,13 @@ test('Container image builder supported OS', () => { const app = new cdk.App(); const stack = new cdk.Stack(app, 'test'); + const vpc = new ec2.Vpc(stack, 'vpc'); + expect(() => { new ContainerImageBuilder(stack, 'linux x64', { os: Os.LINUX, architecture: Architecture.X86_64, + vpc, }); }).toThrowError('Unsupported OS: Linux.'); expect(() => { @@ -54,17 +66,20 @@ test('Container image builder supported OS', () => { os: Os.LINUX, architecture: Architecture.ARM64, instanceType: ec2.InstanceType.of(ec2.InstanceClass.M6G, ec2.InstanceSize.LARGE), + vpc, }); }).toThrowError('Unsupported architecture: ARM64. Consider CodeBuild for faster image builds.'); new ContainerImageBuilder(stack, 'win x64', { os: Os.WINDOWS, architecture: Architecture.X86_64, + vpc, }); expect(() => { new ContainerImageBuilder(stack, 'win arm64', { os: Os.WINDOWS, architecture: Architecture.ARM64, instanceType: ec2.InstanceType.of(ec2.InstanceClass.M6G, ec2.InstanceSize.LARGE), + vpc, }); }).toThrowError('Unsupported architecture: ARM64. Consider CodeBuild for faster image builds.'); });