diff --git a/images/windows-core-2022/bootstrap_win.ps1 b/images/windows-core-2022/bootstrap_win.ps1 new file mode 100644 index 0000000000..3cba59a089 --- /dev/null +++ b/images/windows-core-2022/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-2022/github_agent.windows.pkr.hcl b/images/windows-core-2022/github_agent.windows.pkr.hcl new file mode 100644 index 0000000000..47ca41b74d --- /dev/null +++ b/images/windows-core-2022/github_agent.windows.pkr.hcl @@ -0,0 +1,113 @@ +packer { + required_plugins { + amazon = { + version = ">= 0.0.2" + source = "github.com/hashicorp/amazon" + } + } +} + +variable "runner_version" { + description = "The version (no v prefix) of the runner software to install https://github.com/actions/runner/releases" + type = string + default = "2.286.1" +} + +variable "region" { + description = "The region to build the image in" + type = string + default = "eu-west-1" +} + +variable "security_group_id" { + description = "The ID of the security group Packer will associate with the builder to enable access" + type = string + default = null +} + +variable "subnet_id" { + description = "If using VPC, the ID of the subnet, such as subnet-12345def, where Packer will launch the EC2 instance. This field is required if you are using an non-default VPC" + type = string + default = null +} + +variable "root_volume_size_gb" { + type = number + default = 30 +} + +variable "ebs_delete_on_termination" { + description = "Indicates whether the EBS volume is deleted on instance termination." + type = bool + default = true +} + +variable "associate_public_ip_address" { + description = "If using a non-default VPC, there is no public IP address assigned to the EC2 instance. If you specified a public subnet, you probably want to set this to true. Otherwise the EC2 instance won't have access to the internet" + type = string + default = null +} + +variable "custom_shell_commands" { + description = "Additional commands to run on the EC2 instance, to customize the instance, like installing packages" + type = list(string) + default = [] +} + +source "amazon-ebs" "githubrunner" { + ami_name = "github-runner-windows-core-2022-${formatdate("YYYYMMDDhhmm", timestamp())}" + communicator = "winrm" + instance_type = "m4.xlarge" + region = var.region + security_group_id = var.security_group_id + subnet_id = var.subnet_id + associate_public_ip_address = var.associate_public_ip_address + + source_ami_filter { + filters = { + name = "Windows_Server-2022-English-Core-ContainersLatest-**" + root-device-type = "ebs" + virtualization-type = "hvm" + } + most_recent = true + owners = ["amazon"] + } + tags = { + OS_Version = "windows-core-2022" + 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" + + launch_block_device_mappings { + device_name = "/dev/sda1" + volume_size = "${var.root_volume_size_gb}" + delete_on_termination = "${var.ebs_delete_on_termination}" + } +} + +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 = concat([ + templatefile("./windows-provisioner.ps1", { + action_runner_url = "https://github.com/actions/runner/releases/download/v${var.runner_version}/actions-runner-win-x64-${var.runner_version}.zip" + }) + ], var.custom_shell_commands) + } +} diff --git a/images/windows-core-2022/windows-provisioner.ps1 b/images/windows-core-2022/windows-provisioner.ps1 new file mode 100644 index 0000000000..a192d7e983 --- /dev/null +++ b/images/windows-core-2022/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