infra/terraform/main.tf
Jeremie Fraeys 8ac79d3300
feat(terraform): add services-ssh DNS record
Add non-proxied Cloudflare A/AAAA records for services-ssh to support infra-controller SSH access.
2026-01-21 14:43:43 -05:00

295 lines
7.4 KiB
HCL

terraform {
required_version = ">= 1.5.0"
required_providers {
linode = {
source = "linode/linode"
version = "~> 2.0"
}
cloudflare = {
source = "cloudflare/cloudflare"
version = "~> 4.0"
}
}
}
provider "linode" {
token = var.linode_token
}
provider "cloudflare" {
api_token = var.cloudflare_api_token
}
resource "linode_stackscript" "essentials" {
label = "essentials"
description = "Baseline server init (SSH hardening, UFW, Docker, Ansible, etc.)"
images = [var.image]
rev_note = "managed by terraform"
script = file("${path.module}/../stackscripts/essentials.sh")
}
resource "linode_stackscript" "services" {
label = "services"
description = "Services node init (runs essentials + services specific steps)"
images = [var.image]
rev_note = "managed by terraform"
script = replace(
file("${path.module}/../stackscripts/services.sh"),
"__ESSENTIALS_STACKSCRIPT_ID__",
tostring(linode_stackscript.essentials.id)
)
}
resource "linode_instance" "web" {
label = var.web_label
region = var.region
type = var.instance_type
image = var.image
root_pass = var.root_pass
authorized_keys = [var.ssh_public_key]
stackscript_id = linode_stackscript.essentials.id
stackscript_data = {
NAME = var.web_label
GROUP = var.group
SSH_USER = var.user
USER_PASSWORD = var.user_password
SSH_PUBLIC_KEY = var.ssh_public_key
SSH_PORT = var.ssh_port
TIMEZONE = var.timezone
ADD_CLOUDFLARE_IPS = var.add_cloudflare_ips
}
lifecycle {
ignore_changes = [
root_pass,
stackscript_id,
stackscript_data,
]
}
}
resource "linode_instance" "services" {
label = var.services_label
region = var.region
type = var.instance_type
image = var.image
root_pass = var.root_pass
authorized_keys = [var.ssh_public_key]
stackscript_id = linode_stackscript.services.id
stackscript_data = {
NAME = var.services_label
GROUP = var.group
SSH_USER = var.user
USER_PASSWORD = var.user_password
SSH_PUBLIC_KEY = var.ssh_public_key
SSH_PORT = var.ssh_port
TIMEZONE = var.timezone
ADD_CLOUDFLARE_IPS = var.add_cloudflare_ips
}
lifecycle {
ignore_changes = [
root_pass,
stackscript_id,
stackscript_data,
]
}
}
resource "cloudflare_record" "root_a" {
count = var.enable_cloudflare_dns ? 1 : 0
zone_id = var.cloudflare_zone_id
name = "@"
type = "A"
content = sort(tolist(linode_instance.web.ipv4))[0]
ttl = 1
proxied = true
}
resource "cloudflare_record" "root_aaaa" {
count = var.enable_cloudflare_dns ? 1 : 0
zone_id = var.cloudflare_zone_id
name = "@"
type = "AAAA"
content = split("/", linode_instance.web.ipv6)[0]
ttl = 1
proxied = true
}
resource "cloudflare_record" "www_a" {
count = var.enable_cloudflare_dns ? 1 : 0
zone_id = var.cloudflare_zone_id
name = "www"
type = "A"
content = sort(tolist(linode_instance.web.ipv4))[0]
ttl = 1
proxied = true
}
resource "cloudflare_record" "www_aaaa" {
count = var.enable_cloudflare_dns ? 1 : 0
zone_id = var.cloudflare_zone_id
name = "www"
type = "AAAA"
content = split("/", linode_instance.web.ipv6)[0]
ttl = 1
proxied = true
}
resource "cloudflare_record" "services_a" {
count = var.enable_cloudflare_dns ? 1 : 0
zone_id = var.cloudflare_zone_id
name = "services"
type = "A"
content = sort(tolist(linode_instance.services.ipv4))[0]
ttl = 1
proxied = true
}
resource "cloudflare_record" "services_aaaa" {
count = var.enable_cloudflare_dns ? 1 : 0
zone_id = var.cloudflare_zone_id
name = "services"
type = "AAAA"
content = split("/", linode_instance.services.ipv6)[0]
ttl = 1
proxied = true
}
resource "cloudflare_record" "services_ssh_a" {
count = var.enable_cloudflare_dns ? 1 : 0
zone_id = var.cloudflare_zone_id
name = "services-ssh"
type = "A"
content = sort(tolist(linode_instance.services.ipv4))[0]
ttl = 1
proxied = false
}
resource "cloudflare_record" "services_ssh_aaaa" {
count = var.enable_cloudflare_dns ? 1 : 0
zone_id = var.cloudflare_zone_id
name = "services-ssh"
type = "AAAA"
content = split("/", linode_instance.services.ipv6)[0]
ttl = 1
proxied = false
}
resource "cloudflare_record" "grafana_a" {
count = var.enable_cloudflare_dns ? 1 : 0
zone_id = var.cloudflare_zone_id
name = "grafana"
type = "A"
content = sort(tolist(linode_instance.services.ipv4))[0]
ttl = 1
proxied = true
}
resource "cloudflare_record" "grafana_aaaa" {
count = var.enable_cloudflare_dns ? 1 : 0
zone_id = var.cloudflare_zone_id
name = "grafana"
type = "AAAA"
content = split("/", linode_instance.services.ipv6)[0]
ttl = 1
proxied = true
}
resource "cloudflare_record" "auth_a" {
count = var.enable_cloudflare_dns ? 1 : 0
zone_id = var.cloudflare_zone_id
name = "auth"
type = "A"
content = sort(tolist(linode_instance.services.ipv4))[0]
ttl = 1
proxied = false
}
resource "cloudflare_record" "auth_aaaa" {
count = var.enable_cloudflare_dns ? 1 : 0
zone_id = var.cloudflare_zone_id
name = "auth"
type = "AAAA"
content = split("/", linode_instance.services.ipv6)[0]
ttl = 1
proxied = false
}
resource "cloudflare_record" "git_a" {
count = var.enable_cloudflare_dns ? 1 : 0
zone_id = var.cloudflare_zone_id
name = "git"
type = "A"
content = sort(tolist(linode_instance.services.ipv4))[0]
ttl = 1
proxied = false
}
resource "cloudflare_record" "git_aaaa" {
count = var.enable_cloudflare_dns ? 1 : 0
zone_id = var.cloudflare_zone_id
name = "git"
type = "AAAA"
content = split("/", linode_instance.services.ipv6)[0]
ttl = 1
proxied = false
}
resource "cloudflare_record" "mail_a" {
count = var.enable_cloudflare_dns ? 1 : 0
zone_id = var.cloudflare_zone_id
name = "mail"
type = "A"
content = sort(tolist(linode_instance.web.ipv4))[0]
ttl = var.cloudflare_ttl
proxied = false
}
resource "cloudflare_record" "mail_aaaa" {
count = var.enable_cloudflare_dns ? 1 : 0
zone_id = var.cloudflare_zone_id
name = "mail"
type = "AAAA"
content = split("/", linode_instance.web.ipv6)[0]
ttl = var.cloudflare_ttl
proxied = false
}
resource "cloudflare_record" "services_wildcard_a" {
count = (var.enable_cloudflare_dns && var.enable_services_wildcard) ? 1 : 0
zone_id = var.cloudflare_zone_id
name = "*.services"
type = "A"
content = sort(tolist(linode_instance.services.ipv4))[0]
ttl = 1
proxied = false
}
resource "cloudflare_record" "services_wildcard_aaaa" {
count = (var.enable_cloudflare_dns && var.enable_services_wildcard) ? 1 : 0
zone_id = var.cloudflare_zone_id
name = "*.services"
type = "AAAA"
content = split("/", linode_instance.services.ipv6)[0]
ttl = 1
proxied = false
}
resource "cloudflare_record" "blizzard_cname" {
count = (var.enable_cloudflare_dns && length(var.object_storage_bucket) > 0 && length(var.object_storage_region) > 0) ? 1 : 0
zone_id = var.cloudflare_zone_id
name = "blizzard"
type = "CNAME"
content = "${var.object_storage_bucket}.${var.object_storage_region}.linodeobjects.com"
ttl = var.cloudflare_ttl
proxied = false
}