222 lines
7.4 KiB
Terraform
222 lines
7.4 KiB
Terraform
variable "cloudflare_api_token" {
|
|||
|
|
description = "Cloudflare API token with Zone:DNS:Edit and, for tunnel config, Account:Cloudflare Tunnel:Edit."
|
||
|
|
type = string
|
||
|
|
sensitive = true
|
||
|
|
default = null
|
||
|
|
}
|
||
|
|
|
||
|
|
variable "cloudflare_zone_id" {
|
||
|
|
description = "Zone ID of the existing public zone (riotpiao.com)."
|
||
|
|
type = string
|
||
|
|
}
|
||
|
|
|
||
|
|
variable "cloudflare_account_id" {
|
||
|
|
description = "Account ID. Required only when manage_tunnel_config is true."
|
||
|
|
type = string
|
||
|
|
default = null
|
||
|
|
}
|
||
|
|
|
||
|
|
variable "tunnel_id" {
|
||
|
|
description = "UUID of the cloudflared tunnel that the DNS records point at."
|
||
|
|
type = string
|
||
|
|
}
|
||
|
|
|
||
|
|
# The dashboard remains the source of truth for the remotely-managed tunnel
|
||
|
|
# today. Setting this true hands that config to Terraform, which then rewrites
|
||
|
|
# the whole ingress list: every hostname not listed in tunnel_ingress is
|
||
|
|
# removed from the tunnel. Import first and read the plan before applying.
|
||
|
|
variable "manage_tunnel_config" {
|
||
|
|
description = "Take ownership of the remotely-managed tunnel configuration."
|
||
|
|
type = bool
|
||
|
|
default = false
|
||
|
|
}
|
||
|
|
|
||
|
|
variable "tunnel_ingress" {
|
||
|
|
description = "hostname => origin service, used only when manage_tunnel_config is true."
|
||
|
|
type = map(string)
|
||
|
|
default = {}
|
||
|
|
}
|
||
|
|
|
||
|
|
# ── DNS records managed in the Cloudflare zone ───────────────────────────────
|
||
|
|
# These names already exist, created by hand in the dashboard. Adopt them with
|
||
|
|
# `terraform import` before the first apply, or Terraform will try to create a
|
||
|
|
# second record with the same name and Cloudflare will reject it.
|
||
|
|
variable "cloudflare_tunnel_hostnames" {
|
||
|
|
description = "Hostnames in the Cloudflare zone that must CNAME to the tunnel."
|
||
|
|
type = list(string)
|
||
|
|
default = []
|
||
|
|||
|
|
validation {
|
||
|
|
condition = alltrue([for h in var.cloudflare_tunnel_hostnames : can(regex("^[a-zA-Z0-9._-]+$", h))])
|
||
|
|
error_message = "cloudflare_tunnel_hostnames entries must be DNS labels or relative names (letters, digits, dot, underscore, hyphen)."
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
variable "cloudflare_dns_ttl" {
|
||
|
|
description = "TTL for tunnel CNAME records. 1 means automatic, which is required when proxied is true."
|
||
|
|
type = number
|
||
|
|
default = 1
|
||
|
|
}
|
||
|
|
|
||
|
|
variable "cloudflare_dns_proxied" {
|
||
|
|
description = "Whether tunnel CNAME records are proxied through Cloudflare. Must stay true for a tunnel origin."
|
||
|
|
type = bool
|
||
|
|
default = true
|
||
}
|
|||
|
|
|
||
|
|
# ── China edge ───────────────────────────────────────────────────────────────
|
||
|
|
variable "china_domain" {
|
||
|
|
description = "The .cn domain served from Tencent Cloud, without a trailing dot."
|
||
|
|
type = string
|
||
|
|
}
|
||
|
|
|
||
|
|
variable "china_hostnames" {
|
||
|
|
description = "Subdomains of china_domain that point at the Tencent relay."
|
||
|
|
type = list(string)
|
||
|
|
default = ["paperless", "img"]
|
||
|
|
}
|
||
|
|
|
||
|
|
variable "tencent_secret_id" {
|
||
|
|
description = "Tencent Cloud SecretId. Prefer TENCENTCLOUD_SECRET_ID in the environment."
|
||
|
|
type = string
|
||
|
|
sensitive = true
|
||
|
|
default = null
|
||
|
|
}
|
||
|
|
|
||
|
|
variable "tencent_secret_key" {
|
||
|
|
description = "Tencent Cloud SecretKey. Prefer TENCENTCLOUD_SECRET_KEY in the environment."
|
||
|
|
type = string
|
||
|
|
sensitive = true
|
||
|
|
default = null
|
||
|
|
}
|
||
|
|
|
||
|
|
variable "tencent_region" {
|
||
|
|
description = "Tencent Cloud region for the relay. Mainland regions need an ICP filing for the domain."
|
||
|
|
type = string
|
||
|
|
default = "ap-guangzhou"
|
||
|
|
}
|
||
|
|
|
||
|
|
variable "tencent_availability_zone" {
|
||
|
|
description = "Availability zone inside tencent_region."
|
||
|
|
type = string
|
||
|
|
default = "ap-guangzhou-6"
|
||
|
|
}
|
||
|
|
|
||
|
|
variable "relay_instance_type" {
|
||
|
|
description = "CVM spec for the relay. A relay only terminates TLS and forwards bytes."
|
||
|
|
type = string
|
||
|
|
default = "S5.SMALL2"
|
||
|
|
}
|
||
|
|
|
||
|
|
variable "relay_image_id" {
|
||
|
|
description = "CVM image ID. Find one with: tencentcloud images --image-name 'Ubuntu 24.04' (or the console)."
|
||
|
|
type = string
|
||
|
|
}
|
||
|
|
|
||
|
|
variable "relay_ssh_public_key" {
|
||
|
|
description = "Public key injected into the relay for break-glass SSH. Never the private key."
|
||
|
|
type = string
|
||
|
|
}
|
||
|
|
|
||
|
|
variable "relay_admin_cidr" {
|
||
description = "CIDR allowed to reach SSH and WireGuard on the relay. Keep it to the operator, not 0.0.0.0/0."
|
|||
type = string
|
|||
|
|||
|
|
validation {
|
||
|
|
condition = var.relay_admin_cidr != "0.0.0.0/0" && var.relay_admin_cidr != "::/0"
|
||
|
|
error_message = "relay_admin_cidr must not be the whole internet. Set the operator's egress CIDR."
|
||
|
|
}
|
||
}
|
|||
|
|
|
||
|
|
variable "wireguard_port" {
|
||
|
|
description = "UDP port of the WireGuard listener on the relay."
|
||
|
|
type = number
|
||
|
|
default = 51820
|
||
|
|
}
|
||
|
|
|
||
|
|
variable "wireguard_relay_private_key" {
|
||
|
|
description = "WireGuard private key of the relay side. Generate with `wg genkey`; pass via TF_VAR_wireguard_relay_private_key."
|
||
|
|
type = string
|
||
|
|
sensitive = true
|
||
|
|
}
|
||
|
|
|
||
|
|
variable "wireguard_homelab_public_key" {
|
||
|
|
description = "WireGuard public key of the homelab peer that dials the relay."
|
||
|
|
type = string
|
||
|
|
}
|
||
|
|
|
||
|
|
variable "wireguard_relay_address" {
|
||
|
|
description = "Tunnel address of the relay side."
|
||
|
|
type = string
|
||
|
|
default = "10.88.0.1/24"
|
||
|
|
}
|
||
|
|
|
||
|
|
variable "wireguard_homelab_address" {
|
||
|
|
description = "Tunnel address of the homelab side."
|
||
|
|
type = string
|
||
|
|
default = "10.88.0.2/24"
|
||
|
|
}
|
||
|
|||
|
|
# ── Relay networking / sizing ───────────────────────────────────────────────
|
||
|
|
variable "edge_vpc_cidr" {
|
||
|
|
description = "CIDR of the relay VPC."
|
||
|
|
type = string
|
||
|
|
default = "10.66.0.0/16"
|
||
|
|
}
|
||
|
|
|
||
|
|
variable "edge_subnet_cidr" {
|
||
|
|
description = "CIDR of the relay subnet."
|
||
|
|
type = string
|
||
|
|
default = "10.66.1.0/24"
|
||
|
|
}
|
||
|
|
|
||
|
|
variable "relay_internet_max_bandwidth_out" {
|
||
|
|
description = "Peak outbound bandwidth in Mbps. The relay only terminates TLS and forwards bytes."
|
||
|
|
type = number
|
||
|
|
default = 20
|
||
|
|
}
|
||
|
|
|
||
|
|
variable "relay_system_disk_type" {
|
||
|
|
description = "System disk type for the relay."
|
||
|
|
type = string
|
||
|
|
default = "CLOUD_PREMIUM"
|
||
|
|
}
|
||
|
|
|
||
|
|
variable "relay_system_disk_size" {
|
||
|
|
description = "System disk size in GB for the relay."
|
||
|
|
type = number
|
||
|
|
default = 50
|
||
|
|
}
|
||
|
|
|
||
|
|
# ── DNS records ──────────────────────────────────────────────────────────────
|
||
|
|
variable "china_dns_ttl" {
|
||
|
|
description = "TTL in seconds for the .cn A records."
|
||
|
|
type = number
|
||
|
|
default = 600
|
||
|
|
}
|
||
|
|
|
||
|
|
variable "china_dns_record_line" {
|
||
|
|
description = "DNSPod line for the .cn A records. Use 默认 for the default line."
|
||
|
|
type = string
|
||
|
|
default = "默认"
|
||
|
|
}
|
||
|
|
|
||
|
|
# ── Caddy reverse proxy ──────────────────────────────────────────────────────
|
||
|
|
variable "wireguard_homelab_allowed_ips" {
|
||
|
|
description = "AllowedIPs for the homelab peer. Must include the homelab LAN so Caddy can reach ingress-nginx over the tunnel."
|
||
|
|
type = string
|
||
|
|
default = "10.88.0.2/32,192.168.1.0/24"
|
||
|
|
}
|
||
|
|
|
||
|
|
variable "ingress_upstream" {
|
||
|
|
description = "Upstream URL Caddy proxies to over WireGuard (the homelab ingress-nginx)."
|
||
|
|
type = string
|
||
|
|
default = "http://192.168.1.160:80"
|
||
|
|
}
|
||
|
|
|
||
|
|
variable "acme_email" {
|
||
|
|
description = "Contact email for Caddy ACME (Let's Encrypt)."
|
||
|
|
type = string
|
||
|
|
default = "[email protected]"
|
||
|
|
}
|