Skip to content

Commit

Permalink
feat: add windows support (philips-labs#1476)
Browse files Browse the repository at this point in the history
Integrate the windows support to the module.

Co-authored-by: Niek Palm <npalm@users.noreply.github.com>
Co-authored-by: Richard Simpson <rsimpson@uship.com>
Co-authored-by: Eli Uriegas <1700823+seemethere@users.noreply.github.com>
  • Loading branch information
4 people authored Dec 9, 2021
1 parent 83bb07b commit dbba705
Show file tree
Hide file tree
Showing 34 changed files with 496 additions and 114 deletions.
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -266,6 +266,8 @@ idle_config = [{
}]
```

_**Note**_: When using Windows runners it's recommended to keep a few runners warmed up due to the minutes-long cold start time.

### Prebuilt Images

This module also allows you to run agents from a prebuilt AMI to gain faster startup times. You can find more information in [the image README.md](/images/README.md)
Expand Down Expand Up @@ -294,7 +296,9 @@ Examples are located in the [examples](./examples) directory. The following exam

- _[Default](examples/default/README.md)_: The default example of the module
- _[Permissions boundary](examples/permissions-boundary/README.md)_: Example usages of permissions boundaries.
- _[Ubuntu](examples/ubuntu/README.md)_: Example usage of creating a runner using Ubuntu AMIs.
- _[Prebuilt Images](examples/prebuilt/README.md)_: Example usages of deploying runners with a custom prebuilt image.
- _[Windows](examples/windows/README.md)_: Example usage of creating a runner using Windows as the OS.

## Sub modules

Expand Down
6 changes: 3 additions & 3 deletions examples/default/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ locals {
aws_region = "eu-west-1"
}

resource "random_password" "random" {
length = 28
resource "random_id" "random" {
byte_length = 20
}


Expand All @@ -27,7 +27,7 @@ module "runners" {
github_app = {
key_base64 = var.github_app_key_base64
id = var.github_app_id
webhook_secret = random_password.random.result
webhook_secret = random_id.random.hex
}

webhook_lambda_zip = "lambdas-download/webhook.zip"
Expand Down
2 changes: 1 addition & 1 deletion examples/default/outputs.tf
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,6 @@ output "webhook_endpoint" {

output "webhook_secret" {
sensitive = true
value = random_password.random.result
value = random_id.random.hex
}

6 changes: 3 additions & 3 deletions examples/permissions-boundary/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ locals {
aws_region = "eu-west-1"
}

resource "random_password" "random" {
length = 32
resource "random_id" "random" {
byte_length = 20
}

data "terraform_remote_state" "iam" {
Expand Down Expand Up @@ -46,7 +46,7 @@ module "runners" {
id = var.github_app_id
client_id = var.github_app_client_id
client_secret = var.github_app_client_secret
webhook_secret = random_password.random.result
webhook_secret = random_id.random.hex
}

webhook_lambda_zip = "lambdas-download/webhook.zip"
Expand Down
2 changes: 1 addition & 1 deletion examples/permissions-boundary/outputs.tf
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ output "runners" {

output "webhook" {
value = {
secret = random_password.random.result
secret = random_id.random.hex
endpoint = module.runners.webhook.endpoint
}
}
6 changes: 3 additions & 3 deletions examples/prebuilt/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ locals {
aws_region = "eu-west-1"
}

resource "random_password" "random" {
length = 28
resource "random_id" "random" {
byte_length = 20
}

data "aws_caller_identity" "current" {}
Expand All @@ -21,7 +21,7 @@ module "runners" {
github_app = {
key_base64 = var.github_app_key_base64
id = var.github_app_id
webhook_secret = random_password.random.result
webhook_secret = random_id.random.hex
}

webhook_lambda_zip = "../../lambda_output/webhook.zip"
Expand Down
2 changes: 1 addition & 1 deletion examples/prebuilt/outputs.tf
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,6 @@ output "webhook_endpoint" {

output "webhook_secret" {
sensitive = true
value = random_password.random.result
value = random_id.random.hex
}

6 changes: 3 additions & 3 deletions examples/ubuntu/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ locals {
aws_region = "eu-west-1"
}

resource "random_password" "random" {
length = 28
resource "random_id" "random" {
byte_length = 20
}

module "runners" {
Expand All @@ -22,7 +22,7 @@ module "runners" {
github_app = {
key_base64 = var.github_app_key_base64
id = var.github_app_id
webhook_secret = random_password.random.result
webhook_secret = random_id.random.hex
}

# webhook_lambda_zip = "lambdas-download/webhook.zip"
Expand Down
2 changes: 1 addition & 1 deletion examples/ubuntu/outputs.tf
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ output "runners" {

output "webhook" {
value = {
secret = random_password.random.result
secret = random_id.random.hex
endpoint = module.runners.webhook.endpoint
}
}
39 changes: 39 additions & 0 deletions examples/windows/.terraform.lock.hcl

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

26 changes: 26 additions & 0 deletions examples/windows/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# Action runners deployment windows example

This module shows how to create GitHub action runners using an Windows Runners. Lambda release will be downloaded from GitHub.

## Usages

Steps for the full setup, such as creating a GitHub app can be found in the root module's [README](../../README.md). First, download the Lambda releases from GitHub. Alternatively you can build the lambdas locally with Node or Docker, for which there is a build script available at `<root>/.ci/build.sh`. In the `main.tf` you can remove the location of the lambda zip files, the default location will work in this case.

> Ensure you have set the version in `lambdas-download/main.tf` for running the example. The version needs to be set to a GitHub release version, see <https://github.com/philips-labs/terraform-aws-github-runner/releases>

```pwsh
cd lambdas-download
terraform init
terraform apply
cd ..
```

Before running Terraform, ensure the GitHub app is configured.

```bash
terraform init
terraform apply
```

_**Note**_: It can take upwards of ten minutes for a runner to start processing jobs, and about as long for logs to start showing up. It's recommend that scale the runners via a warm-up job and then keep them idled.
25 changes: 25 additions & 0 deletions examples/windows/lambdas-download/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
locals {
version = "<REPLACE_BY_GITHUB_RELEASE_VERSION>"
}

module "lambdas" {
source = "../../../modules/download-lambda"
lambdas = [
{
name = "webhook"
tag = local.version
},
{
name = "runners"
tag = local.version
},
{
name = "runner-binaries-syncer"
tag = local.version
}
]
}

output "files" {
value = module.lambdas.files
}
48 changes: 48 additions & 0 deletions examples/windows/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
locals {
environment = "windows"
aws_region = "eu-west-1"
}

resource "random_id" "random" {
byte_length = 20
}

module "runners" {
source = "../../"

aws_region = local.aws_region
vpc_id = module.vpc.vpc_id
subnet_ids = module.vpc.private_subnets
environment = local.environment

github_app = {
key_base64 = var.github_app_key_base64
id = var.github_app_id
webhook_secret = random_id.random.hex
}

# Grab the lambda packages from local directory. Must run /.ci/build.sh first
webhook_lambda_zip = "../../lambda_output/webhook.zip"
runner_binaries_syncer_lambda_zip = "../../lambda_output/runner-binaries-syncer.zip"
runners_lambda_zip = "../../lambda_output/runners.zip"

enable_organization_runners = false
# no need to add extra windows tag here as it is automatically added by GitHub
runner_extra_labels = "default,example"

# Set the OS to Windows
runner_os = "win"
# we need to give the runner time to start because this is windows.
runner_boot_time_in_minutes = 20

# enable access to the runners via SSM
enable_ssm_on_runners = true

instance_types = ["m5.large", "c5.large"]

# override delay of events in seconds for testing
delay_webhook_event = 5

# override scaling down for testing
scale_down_schedule_expression = "cron(* * * * ? *)"
}
15 changes: 15 additions & 0 deletions examples/windows/outputs.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
output "runners" {
value = {
lambda_syncer_name = module.runners.binaries_syncer.lambda.function_name
}
}

output "webhook_endpoint" {
value = module.runners.webhook.endpoint
}

output "webhook_secret" {
sensitive = true
value = random_id.random.hex
}

3 changes: 3 additions & 0 deletions examples/windows/providers.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
provider "aws" {
region = local.aws_region
}
4 changes: 4 additions & 0 deletions examples/windows/variables.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@

variable "github_app_key_base64" {}

variable "github_app_id" {}
7 changes: 7 additions & 0 deletions examples/windows/vpc.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
module "vpc" {
source = "git::https://github.com/philips-software/terraform-aws-vpc.git?ref=2.2.0"

environment = local.environment
aws_region = local.aws_region
create_private_hosted_zone = false
}
8 changes: 4 additions & 4 deletions main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,6 @@ locals {

s3_action_runner_url = "s3://${module.runner_binaries.bucket.id}/${module.runner_binaries.runner_distribution_object_key}"
runner_architecture = substr(var.instance_type, 0, 2) == "a1" || substr(var.instance_type, 1, 2) == "6g" ? "arm64" : "x64"

ami_filter = length(var.ami_filter) > 0 ? var.ami_filter : local.runner_architecture == "arm64" ? { name = ["amzn2-ami-hvm-2*-arm64-gp2"] } : { name = ["amzn2-ami-hvm-2.*-x86_64-ebs"] }

github_app_parameters = {
id = module.ssm.parameters.github_app_id
key_base64 = module.ssm.parameters.github_app_key_base64
Expand Down Expand Up @@ -82,20 +79,22 @@ module "runners" {
s3_bucket_runner_binaries = module.runner_binaries.bucket
s3_location_runner_binaries = local.s3_action_runner_url

runner_os = var.runner_os
instance_type = var.instance_type
instance_types = var.instance_types
market_options = var.market_options
block_device_mappings = var.block_device_mappings

runner_architecture = local.runner_architecture
ami_filter = local.ami_filter
ami_filter = var.ami_filter
ami_owners = var.ami_owners

sqs_build_queue = aws_sqs_queue.queued_builds
github_app_parameters = local.github_app_parameters
enable_organization_runners = var.enable_organization_runners
scale_down_schedule_expression = var.scale_down_schedule_expression
minimum_running_time_in_minutes = var.minimum_running_time_in_minutes
runner_boot_time_in_minutes = var.runner_boot_time_in_minutes
runner_extra_labels = var.runner_extra_labels
runner_as_root = var.runner_as_root
runners_maximum_count = var.runners_maximum_count
Expand Down Expand Up @@ -155,6 +154,7 @@ module "runner_binaries" {

distribution_bucket_name = "${var.environment}-dist-${random_string.random.result}"

runner_os = var.runner_os
runner_architecture = local.runner_architecture
runner_allow_prerelease_binaries = var.runner_allow_prerelease_binaries

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -310,3 +310,23 @@ describe('Synchronize action distribution for arm64.', () => {
await expect(sync()).rejects.toThrow(errorMessage);
});
});

describe('Synchronize action distribution for windows.', () => {
const errorMessage = 'Cannot find GitHub release asset.';
beforeEach(() => {
process.env.S3_BUCKET_NAME = bucketName;
process.env.S3_OBJECT_KEY = bucketObjectKey;
process.env.GITHUB_RUNNER_OS = 'win';
});

it('No win asset.', async () => {
mockOctokit.repos.listReleases.mockImplementation(() => ({
data: listReleases.map((release) => ({
...release,
assets: release.assets.filter((asset) => !asset.name.includes('win')),
})),
}));

await expect(sync()).rejects.toThrow(errorMessage);
});
});
Loading

0 comments on commit dbba705

Please sign in to comment.