Files
homelab-infra/infrastructure/incus/terraform/main.tf
T
panxiao81andClaude Opus 5.5 094b38b4b5
terraform / validate (pull_request) Failing after 10m47s
yaml / yaml (pull_request) Failing after 10m49s
ansible / lint (pull_request) Successful in 12m6s
ansible / collection-test (pull_request) Successful in 12m35s
改由 cloud-init 声明 Ayatori 容器静态地址
- Terraform 写 cloud-init.network-config,地址从 records.yml 读取,与 AD DNS 同源
- 撤销 Ansible 直接改 netplan 的做法;镜像模板只在 create/copy 渲染 seed,
  故两台空容器已用 -replace 重建
- 固定指纹已从上游 images: 下架,改从 local: 缓存创建
- sshd -t 前预建 /run/sshd:新装 24.04 只有 ssh.socket 运行,目录尚不存在

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

128 lines
3.8 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} 基础容器;应用由独立部署流程管理"
# Ubuntu 24.04 cloud amd64,20260924_07:42;固定指纹避免重建时静默更换镜像。
# 上游 images: 已不再提供该构建(2026-10-01 重建时 "image couldn't be found"),只能取本机缓存;
# ⚠ 缓存镜像闲置超过 images.remote_cache_expiry(默认 10 天)会被 Incus 自动删除。
image = "local:b39d3d56c30738ad74c507066cc5d410e1c0f1647bdcdff398be1ee51d63862a"
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 {
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
} }
}