Skip to content

Commit dcc5f13

Browse files
committed
feat(images): support optional Talos image ID overrides
Add talos_image_id_x86 and talos_image_id_arm as optional inputs. When set, the module skips hcloud image selector lookups and uses provided image IDs directly. When unset, existing os=talos most_recent behavior remains. Architecture disable flags remain authoritative, so explicit IDs are ignored when that architecture is disabled. README usage now documents the optional image-ID path. Closes: #371
1 parent 1722dcf commit dcc5f13

File tree

3 files changed

+51
-7
lines changed

3 files changed

+51
-7
lines changed

README.md

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,11 @@ This repository contains a Terraform module for creating a Kubernetes cluster wi
147147

148148
## Usage
149149

150-
### 1. Build Talos Images with Packer
150+
### 1. Build Talos Images with Packer (Optional)
151+
152+
> [!TIP]
153+
> You can also use official Hetzner Talos images directly by setting `talos_image_id_x86` and/or `talos_image_id_arm`.
154+
> Check the Hetzner changelog for current Talos image IDs: https://docs.hetzner.cloud/changelog
151155
152156
Before deploying with Terraform, you need Talos OS images (snapshots) available in your Hetzner Cloud project. This module provides Packer configurations to build these images.
153157

@@ -184,6 +188,10 @@ module "talos" {
184188
185189
talos_version = "v1.12.2" # The version of talos features to use in generated machine configurations
186190
191+
# Optional: use official Hetzner Talos image IDs (no custom Packer image required)
192+
# talos_image_id_x86 = "<x86-image-id>"
193+
# talos_image_id_arm = "<arm-image-id>"
194+
187195
hcloud_token = "your-hcloud-token"
188196
# If true, the current IP address will be used as the source for the firewall rules.
189197
# ATTENTION: to determine the current IP, a request to a public service (https://ipv4.icanhazip.com) is made.

server.tf

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
data "hcloud_image" "arm" {
2-
count = var.disable_arm ? 0 : 1
2+
count = var.disable_arm || var.talos_image_id_arm != null ? 0 : 1
33
with_selector = "os=talos"
44
with_architecture = "arm"
55
most_recent = true
66
}
77

88
data "hcloud_image" "x86" {
9-
count = var.disable_x86 ? 0 : 1
9+
count = var.disable_x86 || var.talos_image_id_x86 != null ? 0 : 1
1010
with_selector = "os=talos"
1111
with_architecture = "x86"
1212
most_recent = true
@@ -15,6 +15,16 @@ data "hcloud_image" "x86" {
1515
locals {
1616
cluster_prefix = var.cluster_prefix ? "${var.cluster_name}-" : ""
1717

18+
arm_image_id = (
19+
var.talos_image_id_arm != null ? var.talos_image_id_arm :
20+
(var.disable_arm || length(data.hcloud_image.arm) == 0 ? null : data.hcloud_image.arm[0].id)
21+
)
22+
23+
x86_image_id = (
24+
var.talos_image_id_x86 != null ? var.talos_image_id_x86 :
25+
(var.disable_x86 || length(data.hcloud_image.x86) == 0 ? null : data.hcloud_image.x86[0].id)
26+
)
27+
1828
control_plane_count = length(var.control_plane_nodes)
1929
worker_count = length(var.worker_nodes)
2030

@@ -28,8 +38,8 @@ locals {
2838
server_type = local.control_plane_nodes_by_id[i].type
2939
image_id = (
3040
substr(local.control_plane_nodes_by_id[i].type, 0, 3) == "cax" ?
31-
(var.disable_arm ? null : data.hcloud_image.arm[0].id) :
32-
(var.disable_x86 ? null : data.hcloud_image.x86[0].id)
41+
local.arm_image_id :
42+
local.x86_image_id
3343
)
3444
ipv4_public = local.control_plane_public_ipv4_list[i - 1]
3545
ipv6_public = var.enable_ipv6 ? local.control_plane_public_ipv6_list[i - 1] : null
@@ -47,8 +57,8 @@ locals {
4757
server_type = local.worker_nodes_by_id[i].type
4858
image_id = (
4959
substr(local.worker_nodes_by_id[i].type, 0, 3) == "cax" ?
50-
(var.disable_arm ? null : data.hcloud_image.arm[0].id) :
51-
(var.disable_x86 ? null : data.hcloud_image.x86[0].id)
60+
local.arm_image_id :
61+
local.x86_image_id
5262
)
5363
ipv4_public = local.worker_public_ipv4_list[i - 1]
5464
ipv6_public = var.enable_ipv6 ? local.worker_public_ipv6_list[i - 1] : null

variables.tf

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -437,6 +437,32 @@ variable "disable_arm" {
437437
description = "If true, arm images will not be used."
438438
}
439439

440+
variable "talos_image_id_x86" {
441+
type = string
442+
default = null
443+
description = <<EOF
444+
Optional Hetzner Cloud image ID for x86_64 architecture.
445+
If set, this ID is used directly and the module skips the "os=talos" image selector lookup.
446+
EOF
447+
validation {
448+
condition = var.talos_image_id_x86 == null || can(regex("^[0-9]+$", var.talos_image_id_x86))
449+
error_message = "talos_image_id_x86 must be a numeric image ID string (for example: \"122630\") or null."
450+
}
451+
}
452+
453+
variable "talos_image_id_arm" {
454+
type = string
455+
default = null
456+
description = <<EOF
457+
Optional Hetzner Cloud image ID for arm64 architecture.
458+
If set, this ID is used directly and the module skips the "os=talos" image selector lookup.
459+
EOF
460+
validation {
461+
condition = var.talos_image_id_arm == null || can(regex("^[0-9]+$", var.talos_image_id_arm))
462+
error_message = "talos_image_id_arm must be a numeric image ID string (for example: \"122629\") or null."
463+
}
464+
}
465+
440466
# Talos
441467
variable "kubelet_extra_args" {
442468
type = map(string)

0 commit comments

Comments
 (0)