Files
homelab-infra/infrastructure/incus/terraform/main.tf
T
panxiao81andClaude Opus 5.5 9f7b1b98dd
ansible / collection-test (pull_request) Successful in 13m34s
yaml / yaml (pull_request) Successful in 14m10s
ansible / lint (pull_request) Successful in 14m24s
terraform / validate (pull_request) Successful in 15m12s
Ayatori 容器镜像改为跟随 24.04 cloud 最新构建
固定指纹会随上游下架而无法重建(2026-10-01 已发生),同一发行版的构建之间
只差安全更新,固定它没有收益。镜像只在创建时使用,ignore_changes 避免改写
别名时触发重建现有实例。

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-01 17:12:49 +00:00

128 lines
3.7 KiB
Terraform
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
terraform {
required_version = ">= 1.10.0"
required_providers {
incus = {
source = "lxc/incus"
version = "1.2.0"
}
}
}
provider "incus" {
default_remote = "local"
remote {
name = "local"
address = "unix://"
}
remote {
name = "images"
address = "https://images.linuxcontainers.org"
protocol = "simplestreams"
public = true
}
}
# 专用子 dataset,不接管整个宿主 data 池。
resource "incus_storage_pool" "ayatori" {
name = "ayatori"
driver = "zfs"
config = {
source = "data/incus-ayatori"
}
lifecycle {
prevent_destroy = true
}
}
# 地址只在 records.yml 声明一次,AD DNS(ansible/dns.yml)与此处同源读取;
# 须位于 NEC IX DHCP 池(.128–.250)之外,池由路由器手工维护,无法声明 reservation。
locals {
ayatori_ipv4 = {
for r in yamldecode(file("${path.module}/../../dns/records.yml")).homelab_dns.samba.records :
trimprefix(r.name, "ayatori-") => r.values[0]
if r.zone == "ad.ddupan.top" && startswith(r.name, "ayatori-")
}
}
resource "incus_instance" "ayatori" {
for_each = toset(["dev", "prod"])
name = "ayatori-${each.key}"
description = "Ayatori ${each.key} 基础容器;应用由独立部署流程管理"
# 跟随 24.04 cloud 最新构建:同一发行版的构建只差安全更新,固定指纹会随上游下架而无法重建。
image = "images:ubuntu/24.04/cloud"
type = "container"
profiles = []
running = true
config = {
"boot.autostart" = "true"
"security.privileged" = "false"
"security.nesting" = "false"
"limits.cpu" = "2"
"limits.memory" = "2GiB"
"limits.memory.swap" = "false"
# ⚠ 镜像模板只在 create/copy 时渲染 cloud-init seed(when: [create, copy]),
# 对已有实例修改此键不会生效,重启或 cloud-init clean 也不会;改地址须重建实例。
# 网关与 resolver 沿用 LAN DHCP 下发值:.1 网关;Blocky .127 优先、路由器 .1 兜底。
"cloud-init.network-config" = yamlencode({
version = 2
ethernets = {
eth0 = {
addresses = ["${local.ayatori_ipv4[each.key]}/24"]
routes = [{ to = "default", via = "192.168.10.1" }]
nameservers = { addresses = ["192.168.10.127", "192.168.10.1"] }
}
}
})
"cloud-init.user-data" = "#cloud-config\n${yamlencode({
hostname = "ayatori-${each.key}"
manage_etc_hosts = true
ssh_pwauth = false
disable_root = true
users = [{
name = "panxiao81"
groups = ["sudo"]
shell = "/bin/bash"
sudo = ["ALL=(ALL) NOPASSWD:ALL"]
lock_passwd = true
ssh_authorized_keys = [trimspace(file("${path.module}/../ansible/files/panxiao81.pub"))]
}]
})}"
}
device {
name = "root"
type = "disk"
properties = {
path = "/"
pool = incus_storage_pool.ayatori.name
size = "20GiB"
}
}
device {
name = "eth0"
type = "nic"
properties = {
name = "eth0"
nictype = "bridged"
parent = "br0"
hwaddr = each.key == "dev" ? "02:16:3e:aa:00:01" : "02:16:3e:aa:00:02"
}
}
wait_for {
type = "ipv4"
nic = "eth0"
}
lifecycle {
# 镜像只在创建时使用;provider 按字符串比较,改写它不应触发重建现有实例。
ignore_changes = [image]
prevent_destroy = true
}
}
output "containers" {
value = { for env, instance in incus_instance.ayatori : env => {
name = instance.name
ipv4 = instance.ipv4_address
mac = instance.mac_address
} }
}