ce7cb702218693d08ea6d83464d2457c9250027c
This commit is contained in:
commit
34c5f8963c
6 changed files with 145336 additions and 0 deletions
63
terraform/external/cloudflare/.terraform.lock.hcl
generated
vendored
Normal file
63
terraform/external/cloudflare/.terraform.lock.hcl
generated
vendored
Normal file
|
|
@ -0,0 +1,63 @@
|
|||
# This file is maintained automatically by "tofu init".
|
||||
# Manual edits may be lost in future updates.
|
||||
|
||||
provider "registry.opentofu.org/cloudflare/cloudflare" {
|
||||
version = "5.22.0"
|
||||
constraints = "~> 5.0"
|
||||
hashes = [
|
||||
"h1:EOm3pWL+XqsFNVhupvcedWz7XrYurk52G6ElTSJ+Fxk=",
|
||||
"h1:H3XmcpcMLeDyuGU6QsBXeVOB2CQGnIVRt6PJf7hfrtE=",
|
||||
"h1:IqMMtu1KnqHhdRt3He18R1VZ6yijKjCVGL+qvGh5wbM=",
|
||||
"h1:Mj/TBYAK+oLz4qkb3RBX6qMnCPA215ToNzH1b5VRIE8=",
|
||||
"h1:RPY1abVjmPNOL79CeRmh1wgpgxoSXskz11HOU01ZX9c=",
|
||||
"h1:bEk4C6AqKLPIUFijHpzP4yxim+hybvDX15smKqhlL1M=",
|
||||
"h1:dEU3MBWyHJQh3OHGYi4QTiBxWtcuQKtijYa403txMaM=",
|
||||
"h1:u3j/+0nmwTHvVg4lTziT8c9YvzGLlJOmFEOv/42yPuQ=",
|
||||
"zh:45f3b7c50254b1da1dc21e77e03cd1e931cab40fb75c7cba822a53ed54cd232e",
|
||||
"zh:8437138c0af1a1a557b516ca42dae54499933cc81072396abe7eefd267218f79",
|
||||
"zh:9140044a3c909e1a2767c8b2dd95370b8152bcbc7cb26c47e376e81f75512d32",
|
||||
"zh:b69a80d2bb33059e93dec94490065fe210c621d8bdf32d745b1d1972aa85abbf",
|
||||
"zh:ca4bf16742a7e59319a482f003d32f6f6abbc5fbf862916ce1a136278e6d420d",
|
||||
"zh:cd767016ea7382e384e560f6ddb302637ecb1b53ece15c9326032010effe6c33",
|
||||
"zh:d952f92ae1a688ed376757127ae1aa3b625571bf1fc606214a5822eae98213e0",
|
||||
"zh:f5213814c8ca0d736623438b283143b9a7f98e72ca4992eb906966e7f8cc383b",
|
||||
"zh:f809ab383cca0a5f83072981c64208cbd7fa67e986a86ee02dd2c82333221e32",
|
||||
]
|
||||
}
|
||||
|
||||
provider "registry.opentofu.org/hashicorp/vault" {
|
||||
version = "5.10.1"
|
||||
constraints = "5.10.1"
|
||||
hashes = [
|
||||
"h1:/wVGPEJV4FjoW9C4h3M0pqN4Ie9b03anjUJWeylaciU=",
|
||||
"h1:2kBWbk7XTUlZv6SkvGEkIKXtp7iUeHCcxX8u/bVaq5w=",
|
||||
"h1:4TgeO1IDWziuoDs8zeB2WG2qovoJu6b8HLAg2b4hzF8=",
|
||||
"h1:HsmCwrH+qhRXcU3CIAB316NLPiw0t3alufc0MCJVzus=",
|
||||
"h1:Jv/4vkNUymS3yTTwA72G59IN74auixEOq9C6dN12ZIM=",
|
||||
"h1:WUy6Ea+dhkj8k79vo0qz9/vAyjripwTsf6DqIzzk5Y4=",
|
||||
"h1:bX8M1tM4MD/ZRiazv9JUG0vzZG2IFOHeEDkvE9vVoMY=",
|
||||
"h1:hu9CF1CrQGOCEF9sZEendFKRqbEXuHY4Rz2enypS/FE=",
|
||||
"h1:id6Hv41s6c/JBc1iK/HUA/0L36nQ8MNTnmoXosQRyGU=",
|
||||
"h1:nrNJNXmVUnx/gp6dG24S5Wx6gJJmQ5IpUBdJldWNsgk=",
|
||||
"h1:swXi7Yx24kZY53o7fuWeUe7QX4rNOGixx/fLL9sO3bE=",
|
||||
"h1:tcy+THs72hvdeNLgYicSgK0kA7dpgymaF1ylkg8Bjvw=",
|
||||
"h1:tp2AHrZv9QWX70YYqsk9EFcRJdXm0M4lMEpHE7MoxeI=",
|
||||
"h1:uxfYlF3C4XEdD3a2hEN7aoaEYeTg+bQuvjBePp6H0nU=",
|
||||
"h1:wo5cTkl/1nlxMfdn1yEDIHNoRLMczuK6COH2Id4/zeY=",
|
||||
"zh:0abf976c01f0c0732d0ccc6481e52008be5ee9c8e3d9b5eba0573c640fcf7019",
|
||||
"zh:2aff4d7ee7ba9eb3de2cd5cda16ba92b4ec7a2b43232aec180984241a323b216",
|
||||
"zh:2cc186fd0bfc44e100a22b0b40ae8ddcd0ec210a53c1da65d310ee758b1d2b08",
|
||||
"zh:3f8fb8594736b34af4b26437dd4df4dd4042ad4905223995cfebb8a1f10682ec",
|
||||
"zh:47fb41b18b74073f557dbcd6aad2183e416293405ccd70c0691a279cfe97f8cd",
|
||||
"zh:517e2f2764d671c22d22def0384fdfc521b456458189189c0363375495d114dc",
|
||||
"zh:5a49a2003636f2b8a547d494a6c06d43d62a68299775305408c52eff22b1c11f",
|
||||
"zh:66d4e716920ada84b0c768f4aca4c8948388995462923349a01bd3818d82b618",
|
||||
"zh:7599f652e89a3f18fa4b76a59d115cc63255cc36ce6b273850509ba25031abca",
|
||||
"zh:9c3e38ae7e670de973b6255d7050f526cd2b3ca7c383d7ba7226fc204d97c507",
|
||||
"zh:d04b046023fa9fd69def678f27e001c298ea34fc99ba51f835cda82e496fdb57",
|
||||
"zh:d9acd8810f6660cd51bb4c25596632984ae18e93340c82a102d074c6eac95151",
|
||||
"zh:e161bcb9a22607270b980eeff2ba693335fb62d6978516dff93dd4c91cda99b3",
|
||||
"zh:ef47502f08cfcb5311b7b16a7905e0052bf28359e07cc00ed080ef454e0946cf",
|
||||
"zh:f0640ddb52e7e90c5006ff571f6ad0554e593665320c764c57a3d8b7ec31b490",
|
||||
]
|
||||
}
|
||||
162
terraform/external/cloudflare/dns.tf
vendored
Normal file
162
terraform/external/cloudflare/dns.tf
vendored
Normal file
|
|
@ -0,0 +1,162 @@
|
|||
data "terraform_remote_state" "oci_relay" {
|
||||
backend = "pg"
|
||||
config = {
|
||||
conn_str = "postgres://10.234.158.153:5432/tf_state?sslmode=require"
|
||||
schema_name = "ext_oci_relay"
|
||||
}
|
||||
}
|
||||
|
||||
locals {
|
||||
mta_sts_policy = "version: STSv1\nmode: testing\nmx: mail.quorate.dev\nmax_age: 86400\n"
|
||||
mta_sts_policy_id = substr(sha256(local.mta_sts_policy), 0, 16)
|
||||
}
|
||||
|
||||
data "cloudflare_dns_records" "zitadel" {
|
||||
zone_id = var.zone_id
|
||||
match = "all"
|
||||
name = {
|
||||
exact = "auth.quorate.dev"
|
||||
}
|
||||
}
|
||||
|
||||
data "cloudflare_dns_records" "forge_git" {
|
||||
zone_id = var.zone_id
|
||||
match = "all"
|
||||
name = {
|
||||
exact = "git.quorate.dev"
|
||||
}
|
||||
}
|
||||
|
||||
data "cloudflare_dns_records" "mail" {
|
||||
zone_id = var.zone_id
|
||||
match = "all"
|
||||
name = {
|
||||
exact = "mail.quorate.dev"
|
||||
}
|
||||
}
|
||||
|
||||
resource "cloudflare_dns_record" "zitadel" {
|
||||
zone_id = var.zone_id
|
||||
name = "auth.quorate.dev"
|
||||
type = "A"
|
||||
content = data.terraform_remote_state.oci_relay.outputs.public_ip
|
||||
ttl = 120
|
||||
proxied = false
|
||||
}
|
||||
|
||||
resource "cloudflare_dns_record" "mail" {
|
||||
count = var.mail_a_enabled ? 1 : 0
|
||||
|
||||
zone_id = var.zone_id
|
||||
name = "mail.quorate.dev"
|
||||
type = "A"
|
||||
content = data.terraform_remote_state.oci_relay.outputs.public_ip
|
||||
ttl = 120
|
||||
proxied = false
|
||||
}
|
||||
|
||||
resource "cloudflare_dns_record" "mail_mx" {
|
||||
count = var.mail_mx_enabled ? 1 : 0
|
||||
|
||||
zone_id = var.zone_id
|
||||
name = "quorate.dev"
|
||||
type = "MX"
|
||||
content = "mail.quorate.dev"
|
||||
priority = 10
|
||||
ttl = 120
|
||||
}
|
||||
|
||||
resource "cloudflare_dns_record" "mail_dkim" {
|
||||
zone_id = var.zone_id
|
||||
name = trimsuffix(data.terraform_remote_state.oci_relay.outputs.email_dkim_dns_name, ".")
|
||||
type = "CNAME"
|
||||
content = data.terraform_remote_state.oci_relay.outputs.email_dkim_cname_target
|
||||
ttl = 120
|
||||
proxied = false
|
||||
}
|
||||
|
||||
resource "cloudflare_dns_record" "mail_spf" {
|
||||
zone_id = var.zone_id
|
||||
name = "quorate.dev"
|
||||
type = "TXT"
|
||||
content = "v=spf1 include:ap.rp.oracleemaildelivery.com ~all"
|
||||
ttl = 120
|
||||
}
|
||||
|
||||
resource "cloudflare_dns_record" "google_postmaster" {
|
||||
zone_id = var.zone_id
|
||||
name = "quorate.dev"
|
||||
type = "TXT"
|
||||
content = "google-site-verification=********"
|
||||
ttl = 120
|
||||
}
|
||||
|
||||
resource "cloudflare_dns_record" "mail_dmarc" {
|
||||
zone_id = var.zone_id
|
||||
name = "_dmarc.quorate.dev"
|
||||
type = "TXT"
|
||||
content = "v=DMARC1; p=none; rua=mailto:[email protected]"
|
||||
ttl = 120
|
||||
}
|
||||
|
||||
resource "cloudflare_dns_record" "mail_mta_sts" {
|
||||
zone_id = var.zone_id
|
||||
name = "_mta-sts.quorate.dev"
|
||||
type = "TXT"
|
||||
content = "v=STSv1; id=${local.mta_sts_policy_id}"
|
||||
ttl = 120
|
||||
}
|
||||
|
||||
resource "cloudflare_dns_record" "mail_tlsrpt" {
|
||||
zone_id = var.zone_id
|
||||
name = "_smtp._tls.quorate.dev"
|
||||
type = "TXT"
|
||||
content = "v=TLSRPTv1; rua=mailto:[email protected]"
|
||||
ttl = 120
|
||||
}
|
||||
|
||||
resource "cloudflare_dns_record" "forge_git" {
|
||||
zone_id = var.zone_id
|
||||
name = "git.quorate.dev"
|
||||
type = "A"
|
||||
content = data.terraform_remote_state.oci_relay.outputs.public_ip
|
||||
ttl = 120
|
||||
proxied = false
|
||||
}
|
||||
|
||||
check "zitadel_has_no_bypass" {
|
||||
assert {
|
||||
condition = (
|
||||
length([for record in data.cloudflare_dns_records.zitadel.result : record if record.type == "A"]) == 1 &&
|
||||
length([for record in data.cloudflare_dns_records.zitadel.result : record if record.type == "AAAA"]) == 0
|
||||
)
|
||||
error_message = "Zitadel must have exactly one A record and no AAAA record."
|
||||
}
|
||||
}
|
||||
|
||||
check "forge_git_has_no_bypass" {
|
||||
assert {
|
||||
condition = (
|
||||
length([for record in data.cloudflare_dns_records.forge_git.result : record if record.type == "A"]) <= 1 &&
|
||||
length([for record in data.cloudflare_dns_records.forge_git.result : record if record.type == "AAAA"]) == 0
|
||||
)
|
||||
error_message = "Authenticated public Forgejo must have at most one A record and no AAAA record before reconciliation."
|
||||
}
|
||||
}
|
||||
|
||||
resource "terraform_data" "mail_dns_activation" {
|
||||
lifecycle {
|
||||
precondition {
|
||||
condition = !var.mail_mx_enabled || var.mail_a_enabled
|
||||
error_message = "The authoritative MX record requires the mail host A record to remain enabled."
|
||||
}
|
||||
|
||||
precondition {
|
||||
condition = (
|
||||
length([for record in data.cloudflare_dns_records.mail.result : record if record.type == "A"]) <= 1 &&
|
||||
length([for record in data.cloudflare_dns_records.mail.result : record if record.type == "AAAA"]) == 0
|
||||
)
|
||||
error_message = "Stalwart must have at most one A record and no AAAA record before reconciliation."
|
||||
}
|
||||
}
|
||||
}
|
||||
16
terraform/external/cloudflare/health.tf
vendored
Normal file
16
terraform/external/cloudflare/health.tf
vendored
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
data "terraform_remote_state" "cf_tunnel" {
|
||||
backend = "pg"
|
||||
config = {
|
||||
conn_str = "postgres://10.234.158.153:5432/tf_state?sslmode=require"
|
||||
schema_name = "ext_cf_tunnel"
|
||||
}
|
||||
}
|
||||
|
||||
resource "cloudflare_dns_record" "health" {
|
||||
zone_id = var.zone_id
|
||||
name = "health.quorate.dev"
|
||||
type = "CNAME"
|
||||
content = "${data.terraform_remote_state.cf_tunnel.outputs.tunnel_id}.cfargotunnel.com"
|
||||
ttl = 1
|
||||
proxied = true
|
||||
}
|
||||
14
terraform/external/cloudflare/outputs.tf
vendored
Normal file
14
terraform/external/cloudflare/outputs.tf
vendored
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
output "zitadel_ipv4" {
|
||||
description = "Declared Zitadel ingress address."
|
||||
value = cloudflare_dns_record.zitadel.content
|
||||
}
|
||||
|
||||
output "forge_git_ipv4" {
|
||||
description = "Declared authenticated public Forgejo ingress address."
|
||||
value = cloudflare_dns_record.forge_git.content
|
||||
}
|
||||
|
||||
output "mail_ipv4" {
|
||||
description = "Declared authoritative mail ingress address."
|
||||
value = try(cloudflare_dns_record.mail[0].content, null)
|
||||
}
|
||||
30
terraform/external/cloudflare/providers.tf
vendored
Normal file
30
terraform/external/cloudflare/providers.tf
vendored
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
terraform {
|
||||
required_version = ">= 1.11.0, < 2.0.0"
|
||||
|
||||
backend "pg" {
|
||||
conn_str = "postgres://10.234.158.153:5432/tf_state?sslmode=require"
|
||||
schema_name = "ext_cloudflare"
|
||||
}
|
||||
|
||||
required_providers {
|
||||
cloudflare = {
|
||||
source = "cloudflare/cloudflare"
|
||||
version = "~> 5.0"
|
||||
}
|
||||
vault = {
|
||||
source = "hashicorp/vault"
|
||||
version = "5.10.1"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
provider "vault" {}
|
||||
|
||||
ephemeral "vault_kv_secret_v2" "cloudflare_oci_relay_dns" {
|
||||
mount = "secret"
|
||||
name = "cloudflare/oci-relay-dns"
|
||||
}
|
||||
|
||||
provider "cloudflare" {
|
||||
api_token = ephemeral.vault_kv_secret_v2.cloudflare_oci_relay_dns.data["api-token"]
|
||||
}
|
||||
17
terraform/external/cloudflare/variables.tf
vendored
Normal file
17
terraform/external/cloudflare/variables.tf
vendored
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
variable "zone_id" {
|
||||
description = "Cloudflare zone identifier for quorate.dev."
|
||||
type = string
|
||||
default = "********"
|
||||
}
|
||||
|
||||
variable "mail_a_enabled" {
|
||||
description = "Publish the mail host A record after direct-IP qualification."
|
||||
type = bool
|
||||
default = true
|
||||
}
|
||||
|
||||
variable "mail_mx_enabled" {
|
||||
description = "Publish the authoritative MX record after mail host qualification."
|
||||
type = bool
|
||||
default = true
|
||||
}
|
||||
Loading…
Reference in a new issue