Skip to content

Instantly share code, notes, and snippets.

@kierdavis
Created December 5, 2024 13:36
Show Gist options
  • Save kierdavis/35be27c9cdcb6321ab38c92e4c3af34f to your computer and use it in GitHub Desktop.
Save kierdavis/35be27c9cdcb6321ab38c92e4c3af34f to your computer and use it in GitHub Desktop.
terraform {
required_providers {
cloudflare = {
source = "cloudflare/cloudflare"
}
linode = {
source = "linode/linode"
}
remote = {
source = "tenstad/remote"
}
time = {
source = "hashicorp/time"
}
tls = {
source = "hashicorp/tls"
}
}
}
locals {
headscale_version = "0.22.3"
headscale_sha256 = "41eb475ba94d2f4efdd5b90ca76d3926a0fc0b561baabf6190ca32335c9102d2"
globals = yamldecode(file("${path.module}/../globals.yaml"))
headscale_config = {
# ...
}
headscale_acls = {
# ...
}
}
provider "cloudflare" {
api_token = local.globals.cloudflare.token
}
provider "linode" {
token = local.globals.linode.token
}
resource "tls_private_key" "ssh" {
algorithm = "ED25519"
}
resource "linode_instance" "main" {
label = # ...
region = "gb-lon"
type = "g6-nanode-1"
private_ip = false
}
resource "linode_stackscript" "main" {
label = # ...
description = # ...
images = ["linode/rocky9"]
is_public = false
script = # ...
}
locals {
total_size = linode_instance.main.specs[0].disk
os_size = 10 * 1024
swap_size = 1024
persistent_size = local.total_size - local.os_size - local.swap_size
}
resource "linode_instance_disk" "os" {
label = "os"
linode_id = linode_instance.main.id
size = local.os_size
image = "linode/rocky9"
stackscript_id = linode_stackscript.main.id
authorized_keys = toset(local.globals.authorized_ssh.public_keys)
lifecycle {
replace_triggered_by = [linode_stackscript.main.script]
}
}
resource "linode_instance_disk" "swap" {
label = "swap"
linode_id = linode_instance.main.id
size = local.swap_size
filesystem = "swap"
}
resource "linode_instance_disk" "persistent" {
label = "persistent"
linode_id = linode_instance.main.id
size = local.persistent_size
filesystem = "ext4"
}
resource "linode_instance_config" "main" {
label = "main"
linode_id = linode_instance.main.id
root_device = "/dev/sda"
booted = true
device {
device_name = "sda"
disk_id = linode_instance_disk.os.id
}
device {
device_name = "sdb"
disk_id = linode_instance_disk.swap.id
}
device {
device_name = "sdc"
disk_id = linode_instance_disk.persistent.id
}
}
resource "linode_firewall" "main" {
label = # ...
linodes = [linode_instance.main.id]
disabled = false
inbound_policy = "DROP"
outbound_policy = "ACCEPT"
inbound {
# ...
}
inbound {
# ...
}
inbound {
# ...
}
}
resource "cloudflare_record" "main" {
zone_id = local.globals.cloudflare.zone_id
name = "myserver"
type = "A"
value = linode_instance.main.ip_address
proxied = false
}
resource "cloudflare_record" "headscale" {
zone_id = local.globals.cloudflare.zone_id
name = "headscale"
type = "CNAME"
value = "${cloudflare_record.main.name}.mydomain"
proxied = false
}
resource "time_sleep" "boot" {
create_duration = "30s"
lifecycle {
replace_triggered_by = [linode_instance_config.main]
}
}
data "remote_file" "api_key" {
path = "/persistent/terraform_api_key"
conn {
host = linode_instance.main.ip_address
user = "terraform"
private_key = tls_private_key.ssh.private_key_openssh
timeout = 3000 # ms
}
depends_on = [time_sleep.boot]
}
output "headscale" {
value = {
endpoint = "https://${cloudflare_record.headscale.name}.mydomain/"
api_key = trimspace(sensitive(data.remote_file.api_key.content))
}
sensitive = true
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment