Skip to content

Commit

Permalink
Switch to ci-scaler and instance-to-ami-cdk
Browse files Browse the repository at this point in the history
  • Loading branch information
dimikot committed Aug 26, 2024
1 parent 4046c27 commit 3cfccf0
Show file tree
Hide file tree
Showing 17 changed files with 5,958 additions and 1,658 deletions.
4 changes: 4 additions & 0 deletions .eslintrc.base.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ module.exports = (projectRoot, extraRules = {}) => ({
"typescript-enum",
"typescript-sort-keys",
"unused-imports",
"no-only-tests",
],
settings: {
react: {
Expand Down Expand Up @@ -434,6 +435,9 @@ module.exports = (projectRoot, extraRules = {}) => ({
],

quotes: ["error", "double", { avoidEscape: true }],

"no-only-tests/no-only-tests": "error",

...extraRules,
},
});
1 change: 0 additions & 1 deletion .npmrc

This file was deleted.

8 changes: 8 additions & 0 deletions .prettierrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"overrides": [
{
"files": ["*.ts", "*.tsx"],
"options": { "parser": "typescript" }
}
]
}
3 changes: 1 addition & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
# ci-storage-cdk: a CDK construct to deploy ci-storage infrastructure
# ci-storage-cdk: A CDK construct to deploy ci-storage infrastructure

![CI run](https://github.com/clickup/ci-storage-cdk/actions/workflows/ci.yml/badge.svg?branch=main)

See also:
- [full API documentation](https://github.com/clickup/ci-storage-cdk/blob/master/docs/modules.md)
- [ci-storage tool documentation](https://github.com/dimikot/ci-storage)

2 changes: 1 addition & 1 deletion docs/README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
@clickup/ci-storage-cdk / [Exports](modules.md)

# ci-storage-cdk: a CDK construct to deploy ci-storage infrastructure
# ci-storage-cdk: A CDK construct to deploy ci-storage infrastructure

![CI run](https://github.com/clickup/ci-storage-cdk/actions/workflows/ci.yml/badge.svg?branch=main)

Expand Down
81 changes: 50 additions & 31 deletions docs/classes/CiStorage.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,23 +5,25 @@
A reusable Construct to launch ci-storage infra in some other stack. This
class is meant to be put in a public domain and then used in any project.

- The construct launches a pool of self-hosted runners plus a number of
central "host" instances.
- The construct launches a pool of self-hosted runners plus a central "host"
instance.
- On each instance, a corresponding GitHub repo is pulled (possibly using a
sparse checkout), and then, `docker compose` is run. There is no need to
pre-build any images or publish them anywhere, it's all on the fly.
pre-build any images or publish them anywhere, it's all done on the fly.

Why vanilla EC2 instances + docker-compose and not ECS or Fargate?

1. Because for ECS and Fargate, in 2 minutes after the termination warning,
we only have more 2 minutes to shutdown the OS (it's documented, i.e. 4
minutes in total to cleanly shutdown). And for vanilla instances, people
claim that the second timeout is way higher (although undocumented). We
need more time to finish running CI jobs, and 4 minutes are not enough.
1. For ECS and Fargate, in 2 minutes after the termination warning, we only
have more 2 minutes to shutdown the OS (it's documented, i.e. 4 minutes in
total to cleanly shutdown). And for vanilla instances, people claim that
the second timeout is way higher (although undocumented). We need more
time to finish running CI jobs, and 4 minutes are not enough.
2. We anyways need to run tests locally on Mac, and to do this, we use
docker-compose. Which means that in the CI environment, we'd better use
exactly the same configuration (same docker-compose), otherwise the
environments diverge and are hard to debug/support.
3. Tests often times need to run "Docker in Docker", which is problematic in
ECS and Fargate environment.

## Hierarchy

Expand Down Expand Up @@ -53,7 +55,7 @@ Construct.constructor

#### Defined in

[src/CiStorage.ts:198](https://github.com/clickup/ci-storage-cdk/blob/master/src/CiStorage.ts#L198)
[src/CiStorage.ts:203](https://github.com/clickup/ci-storage-cdk/blob/master/src/CiStorage.ts#L203)

## Properties

Expand All @@ -63,17 +65,17 @@ Construct.constructor

#### Defined in

[src/CiStorage.ts:185](https://github.com/clickup/ci-storage-cdk/blob/master/src/CiStorage.ts#L185)
[src/CiStorage.ts:186](https://github.com/clickup/ci-storage-cdk/blob/master/src/CiStorage.ts#L186)

___

### securityGroup
### hostedZone

`Readonly` **securityGroup**: `SecurityGroup`
`Optional` `Readonly` **hostedZone**: `IHostedZone`

#### Defined in

[src/CiStorage.ts:186](https://github.com/clickup/ci-storage-cdk/blob/master/src/CiStorage.ts#L186)
[src/CiStorage.ts:187](https://github.com/clickup/ci-storage-cdk/blob/master/src/CiStorage.ts#L187)

___

Expand All @@ -83,7 +85,7 @@ ___

#### Defined in

[src/CiStorage.ts:187](https://github.com/clickup/ci-storage-cdk/blob/master/src/CiStorage.ts#L187)
[src/CiStorage.ts:188](https://github.com/clickup/ci-storage-cdk/blob/master/src/CiStorage.ts#L188)

___

Expand All @@ -93,7 +95,7 @@ ___

#### Defined in

[src/CiStorage.ts:188](https://github.com/clickup/ci-storage-cdk/blob/master/src/CiStorage.ts#L188)
[src/CiStorage.ts:189](https://github.com/clickup/ci-storage-cdk/blob/master/src/CiStorage.ts#L189)

___

Expand All @@ -110,47 +112,64 @@ ___

#### Defined in

[src/CiStorage.ts:189](https://github.com/clickup/ci-storage-cdk/blob/master/src/CiStorage.ts#L189)
[src/CiStorage.ts:190](https://github.com/clickup/ci-storage-cdk/blob/master/src/CiStorage.ts#L190)

___

### launchTemplate
### securityGroup

`Readonly` **launchTemplate**: `LaunchTemplate`
`Readonly` **securityGroup**: `SecurityGroup`

#### Defined in

[src/CiStorage.ts:190](https://github.com/clickup/ci-storage-cdk/blob/master/src/CiStorage.ts#L190)
[src/CiStorage.ts:191](https://github.com/clickup/ci-storage-cdk/blob/master/src/CiStorage.ts#L191)

___

### autoScalingGroup
### vpcLink

`Readonly` **autoScalingGroup**: `AutoScalingGroup`
`Readonly` **vpcLink**: `VpcLink`

#### Defined in

[src/CiStorage.ts:191](https://github.com/clickup/ci-storage-cdk/blob/master/src/CiStorage.ts#L191)
[src/CiStorage.ts:192](https://github.com/clickup/ci-storage-cdk/blob/master/src/CiStorage.ts#L192)

___

### hostedZone
### host

`Optional` `Readonly` **hostedZone**: `IHostedZone`
`Readonly` **host**: `Object`

#### Type declaration

| Name | Type |
| :------ | :------ |
| `fqdn` | `undefined` \| `string` |
| `instance` | `CfnInstance` |

#### Defined in

[src/CiStorage.ts:192](https://github.com/clickup/ci-storage-cdk/blob/master/src/CiStorage.ts#L192)
[src/CiStorage.ts:193](https://github.com/clickup/ci-storage-cdk/blob/master/src/CiStorage.ts#L193)

___

### hosts
### autoScalingGroups

`Readonly` **hosts**: \{ `fqdn`: `undefined` \| `string` ; `instance`: `Instance` }[] = `[]`
`Readonly` **autoScalingGroups**: \{ `autoScalingGroup`: `AutoScalingGroup` ; `launchTemplate`: `LaunchTemplate` }[] = `[]`

#### Defined in

[src/CiStorage.ts:193](https://github.com/clickup/ci-storage-cdk/blob/master/src/CiStorage.ts#L193)
[src/CiStorage.ts:197](https://github.com/clickup/ci-storage-cdk/blob/master/src/CiStorage.ts#L197)

___

### instanceToAmi

`Readonly` **instanceToAmi**: `InstanceToAmi`

#### Defined in

[src/CiStorage.ts:201](https://github.com/clickup/ci-storage-cdk/blob/master/src/CiStorage.ts#L201)

___

Expand All @@ -160,7 +179,7 @@ ___

#### Defined in

[src/CiStorage.ts:199](https://github.com/clickup/ci-storage-cdk/blob/master/src/CiStorage.ts#L199)
[src/CiStorage.ts:204](https://github.com/clickup/ci-storage-cdk/blob/master/src/CiStorage.ts#L204)

___

Expand All @@ -170,7 +189,7 @@ ___

#### Defined in

[src/CiStorage.ts:200](https://github.com/clickup/ci-storage-cdk/blob/master/src/CiStorage.ts#L200)
[src/CiStorage.ts:205](https://github.com/clickup/ci-storage-cdk/blob/master/src/CiStorage.ts#L205)

___

Expand All @@ -180,4 +199,4 @@ ___

#### Defined in

[src/CiStorage.ts:201](https://github.com/clickup/ci-storage-cdk/blob/master/src/CiStorage.ts#L201)
[src/CiStorage.ts:206](https://github.com/clickup/ci-storage-cdk/blob/master/src/CiStorage.ts#L206)
58 changes: 18 additions & 40 deletions docs/interfaces/CiStorageProps.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,20 +17,19 @@ VPC to use by this construct.

#### Defined in

[src/CiStorage.ts:57](https://github.com/clickup/ci-storage-cdk/blob/master/src/CiStorage.ts#L57)
[src/CiStorage.ts:62](https://github.com/clickup/ci-storage-cdk/blob/master/src/CiStorage.ts#L62)

___

### inlinePolicies

**inlinePolicies**: `undefined` \| \{ `[name: string]`: `PolicyDocument`; }

Instance Profile Role inline policies to be used for all created
instances.
Instance Profile Role inline policies for all created instances.

#### Defined in

[src/CiStorage.ts:60](https://github.com/clickup/ci-storage-cdk/blob/master/src/CiStorage.ts#L60)
[src/CiStorage.ts:64](https://github.com/clickup/ci-storage-cdk/blob/master/src/CiStorage.ts#L64)

___

Expand All @@ -43,7 +42,7 @@ with that value, separated by "-".

#### Defined in

[src/CiStorage.ts:63](https://github.com/clickup/ci-storage-cdk/blob/master/src/CiStorage.ts#L63)
[src/CiStorage.ts:67](https://github.com/clickup/ci-storage-cdk/blob/master/src/CiStorage.ts#L67)

___

Expand All @@ -62,7 +61,7 @@ A Hosted Zone to register the host instances in.

#### Defined in

[src/CiStorage.ts:65](https://github.com/clickup/ci-storage-cdk/blob/master/src/CiStorage.ts#L65)
[src/CiStorage.ts:69](https://github.com/clickup/ci-storage-cdk/blob/master/src/CiStorage.ts#L69)

___

Expand All @@ -75,7 +74,7 @@ must pre-exist.

#### Defined in

[src/CiStorage.ts:73](https://github.com/clickup/ci-storage-cdk/blob/master/src/CiStorage.ts#L73)
[src/CiStorage.ts:77](https://github.com/clickup/ci-storage-cdk/blob/master/src/CiStorage.ts#L77)

___

Expand All @@ -87,50 +86,30 @@ Time zone for instances, example: America/Los_Angeles.

#### Defined in

[src/CiStorage.ts:75](https://github.com/clickup/ci-storage-cdk/blob/master/src/CiStorage.ts#L75)
[src/CiStorage.ts:79](https://github.com/clickup/ci-storage-cdk/blob/master/src/CiStorage.ts#L79)

___

### runner
### runners

**runner**: `Object`
**runners**: \{ `label`: `string` ; `ghRepository`: `string` ; `ghDockerComposeDirectoryUrl`: `string` ; `imageSsmName`: `string` ; `volumeRootGb`: `number` ; `volumeRootIops?`: `number` ; `volumeRootThroughput?`: `number` ; `volumeLogsGb`: `number` ; `swapSizeGb?`: `number` ; `instanceRequirements`: [`InstanceRequirementsProperty`, ...InstanceRequirementsProperty[]] ; `onDemandPercentageAboveBaseCapacity`: `number` ; `minCapacity`: \{ `id`: `string` ; `value`: `number` ; `cron`: \{ `timeZone?`: `string` } & `CronOptions` }[] ; `maxCapacity`: `number` ; `maxInstanceLifetime`: `Duration` }[]

Configuration for self-hosted runner instances in the pool.

#### Type declaration

| Name | Type | Description |
| :------ | :------ | :------ |
| `ghRepository` | `string` | "{owner}/{repository}" which this self-hosted runners pool serves. |
| `ghDockerComposeDirectoryUrl` | `string` | URL of docker-compose.yml (or compose.yml) directory. The tool will sparse-checkout that directory. The format is Dockerfile-compatible: https://github.com/owner/repo[#[branch]:/directory/with/compose/] |
| `imageSsmName` | `string` | SSM parameter name which holds the reference to an instance image. |
| `volumeGb` | `number` | Size of the root volume. |
| `swapSizeGb?` | `number` | Size of swap file (if you need it). |
| `tmpfsMaxSizeGb?` | `number` | If set, mounts /var/lib/docker to tmpfs with the provided max size. |
| `instanceRequirements` | [`InstanceRequirementsProperty`, ...InstanceRequirementsProperty[]] | The list of requirements to choose Spot Instances. |
| `scale` | \{ `onDemandPercentageAboveBaseCapacity`: `number` ; `maxActiveRunnersPercent`: \{ `periodSec`: `number` ; `value`: `number` ; `scalingSteps?`: `number` } ; `minCapacity`: \{ `id`: `string` ; `value`: `number` ; `cron`: \{ `timeZone?`: `string` } & `CronOptions` }[] ; `maxCapacity`: `number` ; `maxInstanceLifetime`: `Duration` } | Scaling options. |
| `scale.onDemandPercentageAboveBaseCapacity` | `number` | The percentages of On-Demand Instances and Spot Instances for your additional capacity. |
| `scale.maxActiveRunnersPercent` | \{ `periodSec`: `number` ; `value`: `number` ; `scalingSteps?`: `number` } | Maximum percentage of active runners. If the MAX metric of number of active runners within the recent periodSec interval grows beyond this threshold, the autoscaling group will launch new instances until the percentage drops, or maxCapacity is reached. |
| `scale.maxActiveRunnersPercent.periodSec` | `number` | Calculate MAX metric within that period. The higher is the value, the slower will the capacity lower (but it doesn't affect how fast will it increase). |
| `scale.maxActiveRunnersPercent.value` | `number` | Value to use for the target percentage of active (busy) runners. |
| `scale.maxActiveRunnersPercent.scalingSteps?` | `number` | Desired number of ScalingInterval items in scalingSteps. |
| `scale.minCapacity` | \{ `id`: `string` ; `value`: `number` ; `cron`: \{ `timeZone?`: `string` } & `CronOptions` }[] | Minimal number of idle runners to keep, depending on the daytime. If the auto scaling group has less than this number of instances, the new instances will be created. |
| `scale.maxCapacity` | `number` | Maximum total number of instances. |
| `scale.maxInstanceLifetime` | `Duration` | Re-create instances time to time. |

#### Defined in

[src/CiStorage.ts:77](https://github.com/clickup/ci-storage-cdk/blob/master/src/CiStorage.ts#L77)
[src/CiStorage.ts:81](https://github.com/clickup/ci-storage-cdk/blob/master/src/CiStorage.ts#L81)

___

### host

**host**: `Object`

Configuration for ci-storage host instance in the pool. This instance also
runs common services reusable by self-hosted runners. Each self-hosted
runner has its localhost ports redirected to that instance.
Configuration for ci-storage host instance in the pool. This instance runs
ci-storage container, ci-scaler container and also common database services
reusable by self-hosted runners. Each self-hosted runner has its localhost
ports redirected to those instance's services.

#### Type declaration

Expand All @@ -139,12 +118,11 @@ runner has its localhost ports redirected to that instance.
| `ghDockerComposeDirectoryUrl` | `string` | URL of docker-compose.yml (or compose.yml) directory. The tool will sparse-checkout that directory. The format is Dockerfile-compatible: https://github.com/owner/repo[#[branch]:/directory/with/compose/] |
| `dockerComposeProfiles?` | `string`[] | List of profiles from docker-compose to additionally start. |
| `imageSsmName` | `string` | SSM parameter name which holds the reference to an instance image. |
| `swapSizeGb?` | `number` | Size of swap file (if you need it). |
| `tmpfsMaxSizeGb?` | `number` | If set, mounts /var/lib/docker to tmpfs with the provided max size and copies it from the old instance when the instance gets replaced. |
| `swapSizeGb?` | `number` | Size of swap file (if you need it). The swapfile will be placed to /var/swapfile on the root volume. |
| `varLibDockerOnTmpfsMaxSizeGb?` | `number` | If set, mounts the entire /var/lib/docker host instance directory to tmpfs with the provided max size, and also copies it from the old instance when the instance gets replaced. |
| `instanceType` | `string` | Full name of the Instance type. |
| `machines` | `number` | Number of instances to create. |
| `ports` | \{ `port`: `Port` ; `description`: `string` }[] | Ports to be open in the security group for connection from all runners to the host. |
| `ports` | \{ `port`: `Port` ; `description`: `string` ; `isWebhook?`: ``true`` }[] | Ports to be open in the security group for connection from any CI resources to the host (private IP addresses only). For a port marked as isWebhook=true, the following AWS resources will also be created: HttpApi->NLB->TargetGroup, where HttpApi will have an auto-generated AWS domain with SSL enabled, and the whole chain will proxy all POST requests (presumably, sent by GitHub webhooks) to the given host's port. |

#### Defined in

[src/CiStorage.ts:138](https://github.com/clickup/ci-storage-cdk/blob/master/src/CiStorage.ts#L138)
[src/CiStorage.ts:133](https://github.com/clickup/ci-storage-cdk/blob/master/src/CiStorage.ts#L133)
2 changes: 1 addition & 1 deletion jest.config.base.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ module.exports = {
restoreMocks: true,
...(process.env.IN_JEST_PROJECT
? {}
: { forceExit: true, testTimeout: 30000, forceExit: true }),
: { forceExit: true, testTimeout: 30000 }),
transform: {
"\\.ts$": "ts-jest",
},
Expand Down
Loading

0 comments on commit 3cfccf0

Please sign in to comment.