-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
add ubuntu and windows packer images for AWS (#300)
* add ubuntu and windows packer images for AWS * fixes to windows provisioner scripts * increase EBS volume size for snapshot
- Loading branch information
1 parent
74a6e00
commit c922a6e
Showing
5 changed files
with
374 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,169 @@ | ||
packer { | ||
required_plugins { | ||
amazon = { | ||
version = ">= 0.0.2" | ||
source = "github.com/hashicorp/amazon" | ||
} | ||
} | ||
} | ||
|
||
variable "region" { | ||
description = "The region to build the image in" | ||
type = string | ||
default = "us-west-2" | ||
} | ||
|
||
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 "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 "instance_type" { | ||
description = "The instance type Packer will use for the builder" | ||
type = string | ||
default = "t3.medium" | ||
} | ||
|
||
variable "root_volume_size_gb" { | ||
type = number | ||
default = 50 | ||
} | ||
|
||
variable "ebs_delete_on_termination" { | ||
description = "Indicates whether the EBS volume is deleted on instance termination." | ||
type = bool | ||
default = true | ||
} | ||
|
||
variable "global_tags" { | ||
description = "Tags to apply to everything" | ||
type = map(string) | ||
default = {} | ||
} | ||
|
||
variable "ami_tags" { | ||
description = "Tags to apply to the AMI" | ||
type = map(string) | ||
default = {} | ||
} | ||
|
||
variable "snapshot_tags" { | ||
description = "Tags to apply to the snapshot" | ||
type = map(string) | ||
default = {} | ||
} | ||
|
||
variable "custom_shell_commands" { | ||
description = "Additional commands to run on the EC2 instance, to customize the instance, like installing packages" | ||
type = list(string) | ||
default = [] | ||
} | ||
|
||
variable "temporary_security_group_source_public_ip" { | ||
description = "When enabled, use public IP of the host (obtained from https://checkip.amazonaws.com) as CIDR block to be authorized access to the instance, when packer is creating a temporary security group. Note: If you specify `security_group_id` then this input is ignored." | ||
type = bool | ||
default = false | ||
} | ||
|
||
source "amazon-ebs" "ubuntu-jammy-amd64" { | ||
ami_name = "ubuntu-jammy-amd64-${formatdate("YYYYMMDDhhmm", timestamp())}" | ||
instance_type = var.instance_type | ||
region = var.region | ||
security_group_id = var.security_group_id | ||
subnet_id = var.subnet_id | ||
associate_public_ip_address = var.associate_public_ip_address | ||
temporary_security_group_source_public_ip = var.temporary_security_group_source_public_ip | ||
|
||
source_ami_filter { | ||
filters = { | ||
name = "*ubuntu/images/hvm-ssd/ubuntu-jammy-22.04-amd64-server-*" | ||
root-device-type = "ebs" | ||
virtualization-type = "hvm" | ||
} | ||
most_recent = true | ||
owners = ["099720109477"] | ||
} | ||
ssh_username = "ubuntu" | ||
tags = merge( | ||
var.global_tags, | ||
var.ami_tags, | ||
{ | ||
OS_Version = "ubuntu-jammy" | ||
Release = "Latest" | ||
Base_AMI_Name = "{{ .SourceAMIName }}" | ||
}) | ||
snapshot_tags = merge( | ||
var.global_tags, | ||
var.snapshot_tags, | ||
) | ||
|
||
launch_block_device_mappings { | ||
device_name = "/dev/sda1" | ||
volume_size = "${var.root_volume_size_gb}" | ||
volume_type = "gp3" | ||
delete_on_termination = "${var.ebs_delete_on_termination}" | ||
} | ||
} | ||
|
||
build { | ||
name = "githubactions-runner" | ||
sources = [ | ||
"source.amazon-ebs.githubrunner" | ||
] | ||
provisioner "shell" { | ||
environment_vars = [ | ||
"DEBIAN_FRONTEND=noninteractive" | ||
] | ||
inline = concat([ | ||
"sudo cloud-init status --wait", | ||
"sudo apt-get -y update", | ||
"sudo apt-get -y install ca-certificates curl gnupg lsb-release", | ||
"sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg", | ||
"echo deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null", | ||
"sudo apt-get -y update", | ||
"sudo apt-get -y install docker-ce docker-ce-cli containerd.io jq git unzip pkg-config openssl libssl3 libtool cmake build-essential acl aria2 autoconf automake binutils brotli bzip2 coreutils dbus curl dnsutils fakeroot file findutils g++ gcc gnupg2 iproute2 iputils-ping jq atop nload locales lz4 make net-tools netcat openssh-client rsync shellcheck sqlite3 ssh sshpass sudo tar tzdata unzip wget zip zsync --no-install-recommends", | ||
"sudo systemctl enable containerd.service", | ||
"sudo service docker start", | ||
"sudo usermod -a -G docker ubuntu", | ||
"sudo curl -f https://s3.amazonaws.com/amazoncloudwatch-agent/ubuntu/amd64/latest/amazon-cloudwatch-agent.deb -o amazon-cloudwatch-agent.deb", | ||
"sudo dpkg -i amazon-cloudwatch-agent.deb", | ||
"sudo systemctl restart amazon-cloudwatch-agent", | ||
"sudo curl -f https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip -o awscliv2.zip", | ||
"unzip awscliv2.zip", | ||
"sudo ./aws/install", | ||
], var.custom_shell_commands) | ||
} | ||
|
||
provisioner "file" { | ||
source = "./post_installer.sh" | ||
destination = "/tmp/post_installer.sh" | ||
} | ||
|
||
provisioner "shell" { | ||
environment_vars = [ | ||
"FOO=bar" | ||
] | ||
inline = [ | ||
"sudo chmod +x /tmp/post_installer.sh", | ||
"sudo /tmp/post_installer.sh", | ||
] | ||
} | ||
|
||
post-processor "manifest" { | ||
output = "manifest.json" | ||
strip_path = true | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
#!/bin/sh | ||
|
||
set -e | ||
|
||
exec > >(tee /var/log/user-data.log | logger -t user-data -s 2>/dev/console) 2>&1 | ||
echo "hello world" | ||
echo "this is a post-install script" | ||
|
||
exit 0 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,109 @@ | ||
packer { | ||
required_plugins { | ||
amazon = { | ||
version = ">= 0.0.2" | ||
source = "github.com/hashicorp/amazon" | ||
} | ||
} | ||
} | ||
|
||
variable "region" { | ||
description = "The region to build the image in" | ||
type = string | ||
default = "us-west-2" | ||
} | ||
|
||
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 = [] | ||
} | ||
|
||
variable "temporary_security_group_source_public_ip" { | ||
description = "When enabled, use public IP of the host (obtained from https://checkip.amazonaws.com) as CIDR block to be authorized access to the instance, when packer is creating a temporary security group. Note: If you specify `security_group_id` then this input is ignored." | ||
type = bool | ||
default = false | ||
} | ||
|
||
source "amazon-ebs" "windows-core-2022" { | ||
ami_name = "windows-core-2022-${formatdate("YYYYMMDDhhmm", timestamp())}" | ||
communicator = "winrm" | ||
instance_type = "m7.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 | ||
temporary_security_group_source_public_ip = var.temporary_security_group_source_public_ip | ||
|
||
source_ami_filter { | ||
filters = { | ||
name = "Windows_Server-2022-English-Full-ECS_Optimized-*" | ||
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 = "windows-core-2022" | ||
sources = [ | ||
"source.amazon-ebs.windows-core-2022" | ||
] | ||
|
||
provisioner "powershell" { | ||
inline = concat([ | ||
templatefile("./windows-provisioner.ps1") | ||
], var.custom_shell_commands) | ||
} | ||
post-processor "manifest" { | ||
output = "manifest.json" | ||
strip_path = true | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
<powershell> | ||
|
||
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 | ||
|
||
</powershell> |
49 changes: 49 additions & 0 deletions
49
resources/packer/windows-core-2022/windows-provisioner.ps1
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
$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 7zip-zstd curl wget jq mingw cmake openssl -y | ||
refreshenv | ||
|
||
$EC2LaunchFolder = "C:\EC2Launch" | ||
New-Item -ItemType Directory -Force -Path $EC2LaunchFolder | ||
|
||
$Url = "https://s3.amazonaws.com/ec2-downloads-windows/EC2Launch/latest/EC2-Windows-Launch.zip" | ||
$DownloadZipFile = Join-Path -Path $EC2LaunchFolder -ChildPath $(Split-Path -Path $Url -Leaf) | ||
Invoke-WebRequest -Uri $Url -OutFile $DownloadZipFile | ||
|
||
$Url = "https://s3.amazonaws.com/ec2-downloads-windows/EC2Launch/latest/install.ps1" | ||
$DownloadInstallFile = Join-Path -Path $EC2LaunchFolder -ChildPath $(Split-Path -Path $Url -Leaf) | ||
Invoke-WebRequest -Uri $Url -OutFile $DownloadInstallFile | ||
|
||
& $DownloadInstallFile | ||
|
||
& "C:\ProgramData\Amazon\EC2-Windows\Launch\Scripts\InitializeInstance.ps1" -Schedule |