Skip to content

Commit 24a2987

Browse files
committed
feat: add ubuntu 24.04 (noble) image examples
1 parent 6e88223 commit 24a2987

File tree

2 files changed

+430
-0
lines changed

2 files changed

+430
-0
lines changed
Lines changed: 215 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,215 @@
1+
packer {
2+
required_plugins {
3+
amazon = {
4+
version = ">= 0.0.2"
5+
source = "github.com/hashicorp/amazon"
6+
}
7+
}
8+
}
9+
10+
variable "runner_version" {
11+
description = "The version (no v prefix) of the runner software to install https://github.com/actions/runner/releases. The latest release will be fetched from GitHub if not provided."
12+
default = null
13+
}
14+
15+
variable "region" {
16+
description = "The region to build the image in"
17+
type = string
18+
default = "eu-west-1"
19+
}
20+
21+
variable "security_group_id" {
22+
description = "The ID of the security group Packer will associate with the builder to enable access"
23+
type = string
24+
default = null
25+
}
26+
27+
variable "subnet_id" {
28+
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"
29+
type = string
30+
default = null
31+
}
32+
33+
variable "associate_public_ip_address" {
34+
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"
35+
type = string
36+
default = null
37+
}
38+
39+
variable "instance_type" {
40+
description = "The instance type Packer will use for the builder"
41+
type = string
42+
default = "t4g.small"
43+
}
44+
45+
variable "iam_instance_profile" {
46+
description = "IAM instance profile Packer will use for the builder. An empty string (default) means no profile will be assigned."
47+
type = string
48+
default = ""
49+
}
50+
51+
variable "root_volume_size_gb" {
52+
type = number
53+
default = 8
54+
}
55+
56+
variable "ebs_delete_on_termination" {
57+
description = "Indicates whether the EBS volume is deleted on instance termination."
58+
type = bool
59+
default = true
60+
}
61+
62+
variable "global_tags" {
63+
description = "Tags to apply to everything"
64+
type = map(string)
65+
default = {}
66+
}
67+
68+
variable "ami_tags" {
69+
description = "Tags to apply to the AMI"
70+
type = map(string)
71+
default = {}
72+
}
73+
74+
variable "snapshot_tags" {
75+
description = "Tags to apply to the snapshot"
76+
type = map(string)
77+
default = {}
78+
}
79+
80+
variable "custom_shell_commands" {
81+
description = "Additional commands to run on the EC2 instance, to customize the instance, like installing packages"
82+
type = list(string)
83+
default = []
84+
}
85+
86+
variable "temporary_security_group_source_public_ip" {
87+
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."
88+
type = bool
89+
default = false
90+
}
91+
92+
data "http" github_runner_release_json {
93+
url = "https://api.github.com/repos/actions/runner/releases/latest"
94+
request_headers = {
95+
Accept = "application/vnd.github+json"
96+
X-GitHub-Api-Version : "2022-11-28"
97+
}
98+
}
99+
100+
locals {
101+
runner_version = coalesce(var.runner_version, trimprefix(jsondecode(data.http.github_runner_release_json.body).tag_name, "v"))
102+
}
103+
104+
source "amazon-ebs" "githubrunner" {
105+
ami_name = "github-runner-ubuntu-noble-arm64-${formatdate("YYYYMMDDhhmm", timestamp())}"
106+
instance_type = var.instance_type
107+
iam_instance_profile = var.iam_instance_profile
108+
region = var.region
109+
security_group_id = var.security_group_id
110+
subnet_id = var.subnet_id
111+
associate_public_ip_address = var.associate_public_ip_address
112+
temporary_security_group_source_public_ip = var.temporary_security_group_source_public_ip
113+
114+
source_ami_filter {
115+
filters = {
116+
name = "*ubuntu/images/hvm-ssd-gp3/ubuntu-noble-24.04-arm64-server-*"
117+
root-device-type = "ebs"
118+
virtualization-type = "hvm"
119+
}
120+
most_recent = true
121+
owners = ["099720109477"]
122+
}
123+
ssh_username = "ubuntu"
124+
tags = merge(
125+
var.global_tags,
126+
var.ami_tags,
127+
{
128+
OS_Version = "ubuntu-noble"
129+
Release = "Latest"
130+
Base_AMI_Name = "{{ .SourceAMIName }}"
131+
})
132+
snapshot_tags = merge(
133+
var.global_tags,
134+
var.snapshot_tags,
135+
)
136+
137+
launch_block_device_mappings {
138+
device_name = "/dev/sda1"
139+
volume_size = "${var.root_volume_size_gb}"
140+
volume_type = "gp3"
141+
delete_on_termination = "${var.ebs_delete_on_termination}"
142+
}
143+
}
144+
145+
build {
146+
name = "githubactions-runner"
147+
sources = [
148+
"source.amazon-ebs.githubrunner"
149+
]
150+
provisioner "shell" {
151+
environment_vars = [
152+
"DEBIAN_FRONTEND=noninteractive"
153+
]
154+
inline = concat([
155+
"sudo cloud-init status --wait",
156+
"sudo apt-get update",
157+
"sudo apt-get -y install ca-certificates curl gnupg lsb-release",
158+
"sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg",
159+
"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",
160+
"sudo apt-get -y update",
161+
"sudo apt-get -y install docker-ce docker-ce-cli containerd.io jq git unzip build-essential",
162+
"sudo systemctl enable containerd.service",
163+
"sudo service docker start",
164+
"sudo usermod -a -G docker ubuntu",
165+
"sudo curl -f https://s3.amazonaws.com/amazoncloudwatch-agent/ubuntu/arm64/latest/amazon-cloudwatch-agent.deb -o amazon-cloudwatch-agent.deb",
166+
"sudo dpkg -i amazon-cloudwatch-agent.deb",
167+
"sudo systemctl restart amazon-cloudwatch-agent",
168+
"sudo curl -f https://awscli.amazonaws.com/awscli-exe-linux-aarch64.zip -o awscliv2.zip",
169+
"unzip awscliv2.zip",
170+
"sudo ./aws/install",
171+
], var.custom_shell_commands)
172+
}
173+
174+
provisioner "file" {
175+
content = templatefile("../install-runner.sh", {
176+
install_runner = templatefile("../../modules/runners/templates/install-runner.sh", {
177+
ARM_PATCH = ""
178+
S3_LOCATION_RUNNER_DISTRIBUTION = ""
179+
RUNNER_ARCHITECTURE = "arm64"
180+
})
181+
})
182+
destination = "/tmp/install-runner.sh"
183+
}
184+
185+
provisioner "shell" {
186+
environment_vars = [
187+
"RUNNER_TARBALL_URL=https://github.com/actions/runner/releases/download/v${local.runner_version}/actions-runner-linux-arm64-${local.runner_version}.tar.gz"
188+
]
189+
inline = [
190+
"sudo chmod +x /tmp/install-runner.sh",
191+
"echo ubuntu | tee -a /tmp/install-user.txt",
192+
"sudo RUNNER_ARCHITECTURE=arm64 RUNNER_TARBALL_URL=$RUNNER_TARBALL_URL /tmp/install-runner.sh",
193+
"echo ImageOS=ubuntu24 | tee -a /opt/actions-runner/.env"
194+
]
195+
}
196+
197+
provisioner "file" {
198+
content = templatefile("../start-runner.sh", {
199+
start_runner = templatefile("../../modules/runners/templates/start-runner.sh", { metadata_tags = "enabled" })
200+
})
201+
destination = "/tmp/start-runner.sh"
202+
}
203+
204+
provisioner "shell" {
205+
inline = [
206+
"sudo mv /tmp/start-runner.sh /var/lib/cloud/scripts/per-boot/start-runner.sh",
207+
"sudo chmod +x /var/lib/cloud/scripts/per-boot/start-runner.sh",
208+
]
209+
}
210+
211+
post-processor "manifest" {
212+
output = "manifest.json"
213+
strip_path = true
214+
}
215+
}

0 commit comments

Comments
 (0)