diff --git a/.github/workflows/packer-build.yml b/.github/workflows/packer-build.yml
index 96f3de47a3..3ccac79f6a 100644
--- a/.github/workflows/packer-build.yml
+++ b/.github/workflows/packer-build.yml
@@ -18,9 +18,12 @@ jobs:
runs-on: ubuntu-latest
container:
image: hashicorp/packer:1.7.8
+ strategy:
+ matrix:
+ image: ["linux-amzn2", "windows-core-2019"]
defaults:
run:
- working-directory: images/linux-amzn2
+ working-directory: images/${{ matrix.image }}
steps:
- name: "Checkout"
uses: actions/checkout@v2
@@ -28,7 +31,7 @@ jobs:
- name: packer init
run: packer init .
- - name: check terraform formatting
+ - name: check packer formatting
run: packer fmt -recursive -check=true .
- name: packer validate
diff --git a/examples/prebuilt/README.md b/examples/prebuilt/README.md
index 3a560fb80d..5065965d85 100644
--- a/examples/prebuilt/README.md
+++ b/examples/prebuilt/README.md
@@ -4,7 +4,17 @@ This module shows how to create GitHub action runners using a prebuilt AMI for t
## Usages
-Steps for the full setup, such as creating a GitHub app can be found in the root module's [README](../../README.md).
+Steps for the full setup, such as creating a GitHub app can be found in the root module's [README](../../README.md).
+
+## Variables
+
+| Name | Description | Type | Default | Required |
+|------|-------------|------|---------|:--------:|
+| [ami\_filter](#input\_ami\_filter) | The amis to search. Use the default for the provided amazon linux image, `github-runner-windows-core-2019-*` for the provided widnows image | `string` | `github-runner-amzn2-x86_64-2021*` | no |
+| [github\_app\_key\_base64](#input\_github\_app\_key\_base64) | The base64 encoded private key you downloaded from GitHub when creating the app | `string` | | yes |
+| [github\_app\_id](#input\_github\_app\_id) | The id of the app you created on GitHub | `string` | | yes |
+| [region](#input\_region) | The target aws region | `string` | `eu-west-1` | no |
+| [runner\_os](#input\_runner\_os) | The os of the image, either `linux` or `windows` | `string` | `linux` | no |
### Lambdas
diff --git a/examples/prebuilt/main.tf b/examples/prebuilt/main.tf
index 7e417f460f..710f6c1f60 100644
--- a/examples/prebuilt/main.tf
+++ b/examples/prebuilt/main.tf
@@ -1,6 +1,5 @@
locals {
environment = "prebuilt"
- aws_region = "eu-west-1"
}
resource "random_id" "random" {
@@ -12,7 +11,7 @@ data "aws_caller_identity" "current" {}
module "runners" {
source = "../../"
create_service_linked_role_spot = true
- aws_region = local.aws_region
+ aws_region = var.aws_region
vpc_id = module.vpc.vpc_id
subnet_ids = module.vpc.private_subnets
@@ -24,15 +23,17 @@ module "runners" {
webhook_secret = random_id.random.hex
}
- 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"
+ webhook_lambda_zip = "lambdas-download/webhook.zip"
+ runner_binaries_syncer_lambda_zip = "lambdas-download/runner-binaries-syncer.zip"
+ runners_lambda_zip = "lambdas-download/runners.zip"
runner_extra_labels = "default,example"
+ runner_os = var.runner_os
+
# configure your pre-built AMI
enabled_userdata = false
- ami_filter = { name = ["github-runner-amzn2-x86_64-2021*"] }
+ ami_filter = { name = [var.ami_name_filter] }
ami_owners = [data.aws_caller_identity.current.account_id]
# enable access to the runners via SSM
diff --git a/examples/prebuilt/providers.tf b/examples/prebuilt/providers.tf
index b6c81d5415..c9d7ccbdea 100644
--- a/examples/prebuilt/providers.tf
+++ b/examples/prebuilt/providers.tf
@@ -1,3 +1,3 @@
provider "aws" {
- region = local.aws_region
+ region = var.aws_region
}
diff --git a/examples/prebuilt/variables.tf b/examples/prebuilt/variables.tf
index 69dcd0c61c..3e97a3144c 100644
--- a/examples/prebuilt/variables.tf
+++ b/examples/prebuilt/variables.tf
@@ -2,3 +2,18 @@
variable "github_app_key_base64" {}
variable "github_app_id" {}
+
+variable "runner_os" {
+ type = string
+ default = "linux"
+}
+
+variable "ami_name_filter" {
+ type = string
+ default = "github-runner-amzn2-x86_64-2021*"
+}
+
+variable "aws_region" {
+ type = string
+ default = "eu-west-1"
+}
\ No newline at end of file
diff --git a/examples/prebuilt/vpc.tf b/examples/prebuilt/vpc.tf
index a7d21422f1..1ac37cb4c8 100644
--- a/examples/prebuilt/vpc.tf
+++ b/examples/prebuilt/vpc.tf
@@ -2,6 +2,6 @@ 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
+ aws_region = var.aws_region
create_private_hosted_zone = false
}
diff --git a/images/README.md b/images/README.md
index 172f97d0a1..a3cbe7bec9 100644
--- a/images/README.md
+++ b/images/README.md
@@ -4,7 +4,7 @@ The images inside this folder are pre-built images designed to shorten the boot
These images share the same scripting as used in the user-data mechanism in `/modules/runners/templates/`. We use a `tempaltefile` mechanism to insert the relevant script fragments into the scripts used for provisioning the images.
-The example in `linux-amzn2` also uploads a `start-runner.sh` script that uses the exact same startup process as used in the user-data mechanism. This means that the image created here does not need any extra scripts injected or changes to boot up and connect to GH.
+The examples in `linux-amzn2` and `windows-core-2019` also upload a `start-runner` script that uses the exact same startup process as used in the user-data mechanism. This means that the image created here does not need any extra scripts injected or changes to boot up and connect to GH.
## Building your own
diff --git a/images/install-runner.ps1 b/images/install-runner.ps1
new file mode 100644
index 0000000000..e042333f00
--- /dev/null
+++ b/images/install-runner.ps1
@@ -0,0 +1,8 @@
+#!/bin/bash -e
+
+user_name=ec2-user
+
+## This wrapper file re-uses scripts in the /modules/runners/templates directory
+## of this repo. These are the same that are used by the user_data functionality
+## to bootstrap the instance if it is started from an existing AMI.
+${install_runner}
\ No newline at end of file
diff --git a/images/start-runner.ps1 b/images/start-runner.ps1
new file mode 100644
index 0000000000..e4b6b85e51
--- /dev/null
+++ b/images/start-runner.ps1
@@ -0,0 +1,3 @@
+Start-Transcript -Path "C:\runner-startup.log" -Append
+${start_runner}
+Stop-Transcript
diff --git a/images/windows-core-2019/bootstrap_win.ps1 b/images/windows-core-2019/bootstrap_win.ps1
new file mode 100644
index 0000000000..3cba59a089
--- /dev/null
+++ b/images/windows-core-2019/bootstrap_win.ps1
@@ -0,0 +1,38 @@
+
+
+Write-Output "Running User Data Script"
+Write-Host "(host) Running User Data Script"
+
+Set-ExecutionPolicy Unrestricted -Scope LocalMachine -Force -ErrorAction Ignore
+
+# Don't set this before Set-ExecutionPolicy as it throws an error
+$ErrorActionPreference = "stop"
+
+# Remove HTTP listener
+Remove-Item -Path WSMan:\Localhost\listener\listener* -Recurse
+
+# Create a self-signed certificate to let ssl work
+$Cert = New-SelfSignedCertificate -CertstoreLocation Cert:\LocalMachine\My -DnsName "packer"
+New-Item -Path WSMan:\LocalHost\Listener -Transport HTTPS -Address * -CertificateThumbPrint $Cert.Thumbprint -Force
+
+# WinRM
+Write-Output "Setting up WinRM"
+Write-Host "(host) setting up WinRM"
+
+# I'm not really sure why we need the cmd.exe wrapper, but it works with it and doesn't work without it
+cmd.exe /c winrm quickconfig -q
+cmd.exe /c winrm set "winrm/config" '@{MaxTimeoutms="1800000"}'
+cmd.exe /c winrm set "winrm/config/winrs" '@{MaxMemoryPerShellMB="1024"}'
+cmd.exe /c winrm set "winrm/config/service" '@{AllowUnencrypted="true"}'
+cmd.exe /c winrm set "winrm/config/client" '@{AllowUnencrypted="true"}'
+cmd.exe /c winrm set "winrm/config/service/auth" '@{Basic="true"}'
+cmd.exe /c winrm set "winrm/config/client/auth" '@{Basic="true"}'
+cmd.exe /c winrm set "winrm/config/service/auth" '@{CredSSP="true"}'
+cmd.exe /c winrm set "winrm/config/listener?Address=*+Transport=HTTPS" "@{Port=`"5986`";Hostname=`"packer`";CertificateThumbprint=`"$($Cert.Thumbprint)`"}"
+cmd.exe /c netsh advfirewall firewall set rule group="remote administration" new enable=yes
+cmd.exe /c netsh firewall add portopening TCP 5986 "Port 5986"
+cmd.exe /c net stop winrm
+cmd.exe /c sc config winrm start= auto
+cmd.exe /c net start winrm
+
+
\ No newline at end of file
diff --git a/images/windows-core-2019/github_agent.windows.pkr.hcl b/images/windows-core-2019/github_agent.windows.pkr.hcl
new file mode 100644
index 0000000000..d15d462476
--- /dev/null
+++ b/images/windows-core-2019/github_agent.windows.pkr.hcl
@@ -0,0 +1,66 @@
+packer {
+ required_plugins {
+ amazon = {
+ version = ">= 0.0.2"
+ source = "github.com/hashicorp/amazon"
+ }
+ }
+}
+
+variable "action_runner_url" {
+ description = "The URL to the tarball of the action runner"
+ type = string
+ default = "https://github.com/actions/runner/releases/download/v2.285.1/actions-runner-win-x64-2.285.1.zip"
+}
+
+variable "region" {
+ description = "The region to build the image in"
+ type = string
+ default = "eu-west-1"
+}
+
+source "amazon-ebs" "githubrunner" {
+ ami_name = "github-runner-windows-core-2019-${formatdate("YYYYMMDDhhmm", timestamp())}"
+ communicator = "winrm"
+ instance_type = "t3a.medium"
+ region = var.region
+ source_ami_filter {
+ filters = {
+ name = "Windows_Server-2019-English-Core-ContainersLatest-*"
+ root-device-type = "ebs"
+ virtualization-type = "hvm"
+ }
+ most_recent = true
+ owners = ["amazon"]
+ }
+ tags = {
+ OS_Version = "windows-core-2019"
+ Release = "Latest"
+ Base_AMI_Name = "{{ .SourceAMIName }}"
+ }
+ user_data_file = "./bootstrap_win.ps1"
+ winrm_insecure = true
+ winrm_port = 5986
+ winrm_use_ssl = true
+ winrm_username = "Administrator"
+}
+
+build {
+ name = "githubactions-runner"
+ sources = [
+ "source.amazon-ebs.githubrunner"
+ ]
+
+ provisioner "file" {
+ content = templatefile("../start-runner.ps1", {
+ start_runner = templatefile("../../modules/runners/templates/start-runner.ps1", {})
+ })
+ destination = "C:\\start-runner.ps1"
+ }
+
+ provisioner "powershell" {
+ inline = [templatefile("./windows-provisioner.ps1", {
+ action_runner_url = var.action_runner_url
+ })]
+ }
+}
\ No newline at end of file
diff --git a/images/windows-core-2019/windows-provisioner.ps1 b/images/windows-core-2019/windows-provisioner.ps1
new file mode 100644
index 0000000000..a192d7e983
--- /dev/null
+++ b/images/windows-core-2019/windows-provisioner.ps1
@@ -0,0 +1,52 @@
+$ErrorActionPreference = "Continue"
+$VerbosePreference = "Continue"
+
+# Install Chocolatey
+[System.Net.ServicePointManager]::SecurityProtocol = [System.Net.SecurityProtocolType]::Tls12
+$env:chocolateyUseWindowsCompression = 'true'
+Invoke-WebRequest https://chocolatey.org/install.ps1 -UseBasicParsing | Invoke-Expression
+
+# Add Chocolatey to powershell profile
+$ChocoProfileValue = @'
+$ChocolateyProfile = "$env:ChocolateyInstall\helpers\chocolateyProfile.psm1"
+if (Test-Path($ChocolateyProfile)) {
+ Import-Module "$ChocolateyProfile"
+}
+
+refreshenv
+'@
+# Write it to the $profile location
+Set-Content -Path "$PsHome\Microsoft.PowerShell_profile.ps1" -Value $ChocoProfileValue -Force
+# Source it
+. "$PsHome\Microsoft.PowerShell_profile.ps1"
+
+refreshenv
+
+Write-Host "Installing cloudwatch agent..."
+Invoke-WebRequest -Uri https://s3.amazonaws.com/amazoncloudwatch-agent/windows/amd64/latest/amazon-cloudwatch-agent.msi -OutFile C:\amazon-cloudwatch-agent.msi
+$cloudwatchParams = '/i', 'C:\amazon-cloudwatch-agent.msi', '/qn', '/L*v', 'C:\CloudwatchInstall.log'
+Start-Process "msiexec.exe" $cloudwatchParams -Wait -NoNewWindow
+Remove-Item C:\amazon-cloudwatch-agent.msi
+
+# Install dependent tools
+Write-Host "Installing additional development tools"
+choco install git awscli -y
+refreshenv
+
+Write-Host "Creating actions-runner directory for the GH Action installtion"
+New-Item -ItemType Directory -Path C:\actions-runner ; Set-Location C:\actions-runner
+
+Write-Host "Downloading the GH Action runner from ${action_runner_url}"
+Invoke-WebRequest -Uri ${action_runner_url} -OutFile actions-runner.zip
+
+Write-Host "Un-zip action runner"
+Expand-Archive -Path actions-runner.zip -DestinationPath .
+
+Write-Host "Delete zip file"
+Remove-Item actions-runner.zip
+
+$action = New-ScheduledTaskAction -WorkingDirectory "C:\actions-runner" -Execute "PowerShell.exe" -Argument "-File C:\start-runner.ps1"
+$trigger = New-ScheduledTaskTrigger -AtStartup
+Register-ScheduledTask -TaskName "runnerinit" -Action $action -Trigger $trigger -User System -RunLevel Highest -Force
+
+C:\ProgramData\Amazon\EC2-Windows\Launch\Scripts\InitializeInstance.ps1 -Schedule
\ No newline at end of file