From c5231f1311bfaabf12ab5592e94bb51af30093e5 Mon Sep 17 00:00:00 2001 From: Joey Hafner Date: Thu, 15 Aug 2024 15:04:13 -0700 Subject: [PATCH] #5 Init Terraform Cloudflare DNS IaC - Import existing records via cf-terraforming utility - Rename resources to human-readable names - Move aws and cloudflare terraform roots to their own directories --- homelab/sellswords/{ => aws}/aws.tf | 0 .../cloudflare/cf-terraforming_import.sh | 31 ++++ homelab/sellswords/cloudflare/cloudflare.tf | 59 +++++++ homelab/sellswords/cloudflare/jafner.chat.tf | 18 ++ homelab/sellswords/cloudflare/jafner.dev.tf | 156 ++++++++++++++++++ homelab/sellswords/cloudflare/jafner.net.tf | 101 ++++++++++++ homelab/sellswords/cloudflare/jafner.tools.tf | 18 ++ 7 files changed, 383 insertions(+) rename homelab/sellswords/{ => aws}/aws.tf (100%) create mode 100755 homelab/sellswords/cloudflare/cf-terraforming_import.sh create mode 100644 homelab/sellswords/cloudflare/cloudflare.tf create mode 100644 homelab/sellswords/cloudflare/jafner.chat.tf create mode 100644 homelab/sellswords/cloudflare/jafner.dev.tf create mode 100644 homelab/sellswords/cloudflare/jafner.net.tf create mode 100644 homelab/sellswords/cloudflare/jafner.tools.tf diff --git a/homelab/sellswords/aws.tf b/homelab/sellswords/aws/aws.tf similarity index 100% rename from homelab/sellswords/aws.tf rename to homelab/sellswords/aws/aws.tf diff --git a/homelab/sellswords/cloudflare/cf-terraforming_import.sh b/homelab/sellswords/cloudflare/cf-terraforming_import.sh new file mode 100755 index 00000000..92d13d90 --- /dev/null +++ b/homelab/sellswords/cloudflare/cf-terraforming_import.sh @@ -0,0 +1,31 @@ +#!/bin/bash + +# Set CLOUDFLARE_API_TOKEN +source secrets.env + +ZONES_LIST="jafner.net jafner.dev jafner.tools jafner.chat" +function get_zone_id () { + # Takes one zone name (e.g. jafner.net) as a positional argument + # Returns the zone ID to stdout + ZONE_NAME=$1 + curl -s\ + -X GET "https://api.cloudflare.com/client/v4/zones" \ + -H "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \ + -H "Content-Type:application/json" |\ + jq -r --arg ZONE_NAME "$ZONE_NAME" '.[].[] | select(.name==$ZONE_NAME) | .id' 2>/dev/null +} + +for ZONE_NAME in $(echo "$ZONES_LIST"); do + ZONE_ID=$(get_zone_id $ZONE_NAME) + TF_FILE_NAME="${ZONE_NAME}.import.tf" + cf-terraforming generate \ + --resource-type "cloudflare_record" \ + --zone $ZONE_ID > $TF_FILE_NAME + sleep 2 + cf-terraforming import \ + --resource-type "cloudflare_record" \ + --zone $ZONE_ID >> /tmp/cf-terraforming-commands + sleep 2 +done + +source /tmp/cf-terraforming-commands diff --git a/homelab/sellswords/cloudflare/cloudflare.tf b/homelab/sellswords/cloudflare/cloudflare.tf new file mode 100644 index 00000000..660a137a --- /dev/null +++ b/homelab/sellswords/cloudflare/cloudflare.tf @@ -0,0 +1,59 @@ +terraform { + required_providers { + cloudflare = { + source = "cloudflare/cloudflare" + version = "~> 4.0" + } + dns = { + source = "hashicorp/dns" + version = "3.4.1" + } + } +} + +locals { + envs = { for tuple in regexall("(.*)=(.*)", file("secrets.env")) : tuple[0] => sensitive(tuple[1]) } +} + +provider "cloudflare" { + api_token = local.envs.CLOUDFLARE_API_TOKEN +} + +# Below allows us to reference public IP of TF execution environment +# with `data.http.myip.body` +data "http" "myip" { + url = "https://ipv4.icanhazip.com" +} + +# Below allows us to reference DNS A-records for the listed domains +# with `data.dns_a_record_set..addrs` +data "dns_a_record_set" "jafner_net" { + host = "jafner.net" +} +data "dns_a_record_set" "jafner_dev" { + host = "jafner.dev" +} +data "dns_a_record_set" "jafner_chat" { + host = "jafner.chat" +} +data "dns_a_record_set" "jafner_tools" { + host = "jafner.tools" +} + +# Zone IDs +data "cloudflare_zone" "jafner_net" { + name = "jafner.net" +} + +data "cloudflare_zone" "jafner_dev" { + name = "jafner.dev" +} + +data "cloudflare_zone" "jafner_tools" { + name = "jafner.tools" +} + +data "cloudflare_zone" "jafner_chat" { + name = "jafner.chat" +} + diff --git a/homelab/sellswords/cloudflare/jafner.chat.tf b/homelab/sellswords/cloudflare/jafner.chat.tf new file mode 100644 index 00000000..59b98180 --- /dev/null +++ b/homelab/sellswords/cloudflare/jafner.chat.tf @@ -0,0 +1,18 @@ +resource "cloudflare_record" "any_jafner_chat" { + content = "174.21.59.108" + name = "*" + proxied = false + ttl = 1 + type = "A" + zone_id = data.cloudflare_zone.jafner_chat.id +} + +resource "cloudflare_record" "root_jafner_chat" { + content = "174.21.59.108" + name = "jafner.chat" + proxied = false + ttl = 1 + type = "A" + zone_id = data.cloudflare_zone.jafner_chat.id +} + diff --git a/homelab/sellswords/cloudflare/jafner.dev.tf b/homelab/sellswords/cloudflare/jafner.dev.tf new file mode 100644 index 00000000..343228fe --- /dev/null +++ b/homelab/sellswords/cloudflare/jafner.dev.tf @@ -0,0 +1,156 @@ +resource "cloudflare_record" "ipv4_1_githubpages_jafner_dev" { + content = "185.199.108.153" + name = "jafner.dev" + proxied = false + ttl = 1 + type = "A" + zone_id = data.cloudflare_zone.jafner_dev.id +} + +resource "cloudflare_record" "ipv4_2_githubpages_jafner_dev" { + content = "185.199.109.153" + name = "jafner.dev" + proxied = false + ttl = 1 + type = "A" + zone_id = data.cloudflare_zone.jafner_dev.id +} + +resource "cloudflare_record" "ipv4_3_githubpages_jafner_dev" { + content = "185.199.110.153" + name = "jafner.dev" + proxied = false + ttl = 1 + type = "A" + zone_id = data.cloudflare_zone.jafner_dev.id +} + +resource "cloudflare_record" "ipv4_4_githubpages_jafner_dev" { + content = "185.199.111.153" + name = "jafner.dev" + proxied = false + ttl = 1 + type = "A" + zone_id = data.cloudflare_zone.jafner_dev.id +} + +resource "cloudflare_record" "ipv6_1_githubpages_jafner_dev" { + content = "2606:50c0:8000::153" + name = "jafner.dev" + proxied = false + ttl = 1 + type = "AAAA" + zone_id = data.cloudflare_zone.jafner_dev.id +} + +resource "cloudflare_record" "ipv6_2_githubpages_jafner_dev" { + content = "2606:50c0:8001::153" + name = "jafner.dev" + proxied = false + ttl = 1 + type = "AAAA" + zone_id = data.cloudflare_zone.jafner_dev.id +} + +resource "cloudflare_record" "ipv6_3_githubpages_jafner_dev" { + content = "2606:50c0:8002::153" + name = "jafner.dev" + proxied = false + ttl = 1 + type = "AAAA" + zone_id = data.cloudflare_zone.jafner_dev.id +} + +resource "cloudflare_record" "ipv6_4_githubpages_jafner_dev" { + content = "2606:50c0:8003::153" + name = "jafner.dev" + proxied = false + ttl = 1 + type = "AAAA" + zone_id = data.cloudflare_zone.jafner_dev.id +} + +resource "cloudflare_record" "nginx1_jafner_dev" { + content = "174.21.59.108" + name = "nginx1" + proxied = false + ttl = 1 + type = "A" + zone_id = data.cloudflare_zone.jafner_dev.id +} + +resource "cloudflare_record" "www_jafner_dev" { + content = "jafner.dev" + name = "www" + proxied = false + ttl = 1 + type = "CNAME" + zone_id = data.cloudflare_zone.jafner_dev.id +} + +resource "cloudflare_record" "verify_protonmail_jafner_dev" { + content = "protonmail-verification=5a6c959042fa2f5094a7203c11050d0091c3c74d" + name = "jafner.dev" + proxied = false + ttl = 1 + type = "TXT" + zone_id = data.cloudflare_zone.jafner_dev.id +} + +resource "cloudflare_record" "mx_protonmail_jafner_dev" { + content = "mail.protonmail.ch" + name = "jafner.dev" + proxied = false + type = "MX" + priority = "10" + zone_id = data.cloudflare_zone.jafner_dev.id +} + +resource "cloudflare_record" "mxsecure_protonmail_jafner_dev" { + content = "mailsec.protonmail.ch" + name = "jafner.dev" + proxied = false + type = "MX" + priority = "20" + zone_id = data.cloudflare_zone.jafner_dev.id +} + +resource "cloudflare_record" "spf_protonmail_jafner_dev" { + content = "v=spf1 include:_spf.protonmail.ch ~all" + name = "jafner.dev" + proxied = false + type = "TXT" + zone_id = data.cloudflare_zone.jafner_dev.id +} + +resource "cloudflare_record" "dkim1_protonmail_jafner_dev" { + content = "protonmail.domainkey.ds7tmy256idh6c2lnaagep4h2kui25dtk6euypz3i4niemc6fbygq.domains.proton.ch." + name = "protonmail._domainkey" + proxied = false + type = "CNAME" + zone_id = data.cloudflare_zone.jafner_dev.id +} + +resource "cloudflare_record" "dkim2_protonmail_jafner_dev" { + content = "protonmail2.domainkey.ds7tmy256idh6c2lnaagep4h2kui25dtk6euypz3i4niemc6fbygq.domains.proton.ch." + name = "protonmail2._domainkey" + proxied = false + type = "CNAME" + zone_id = data.cloudflare_zone.jafner_dev.id +} + +resource "cloudflare_record" "dkim3_protonmail_jafner_dev" { + content = "protonmail3.domainkey.ds7tmy256idh6c2lnaagep4h2kui25dtk6euypz3i4niemc6fbygq.domains.proton.ch." + name = "protonmail3._domainkey" + proxied = false + type = "CNAME" + zone_id = data.cloudflare_zone.jafner_dev.id +} + +resource "cloudflare_record" "dmarc_protonmail_jafner_dev" { + content = "v=DMARC1; p=quarantine" + name = "_dmarc" + proxied = false + type = "TXT" + zone_id = data.cloudflare_zone.jafner_dev.id +} \ No newline at end of file diff --git a/homelab/sellswords/cloudflare/jafner.net.tf b/homelab/sellswords/cloudflare/jafner.net.tf new file mode 100644 index 00000000..628d4cbe --- /dev/null +++ b/homelab/sellswords/cloudflare/jafner.net.tf @@ -0,0 +1,101 @@ +resource "cloudflare_record" "a5e_jafner_net" { + content = "34.49.168.203" + name = "5e" + proxied = false + ttl = 1 + type = "A" + zone_id = data.cloudflare_zone.jafner_net.id +} + +resource "cloudflare_record" "root_jafner_net" { + content = "174.21.59.108" + name = "jafner.net" + proxied = false + ttl = 1 + type = "A" + zone_id = data.cloudflare_zone.jafner_net.id +} + +resource "cloudflare_record" "any_jafner_net" { + content = "jafner.net" + name = "*" + proxied = false + ttl = 1 + type = "CNAME" + zone_id = data.cloudflare_zone.jafner_net.id +} + +resource "cloudflare_record" "dkim1_protonmail_jafner_net" { + content = "protonmail.domainkey.djxxgyo3stmnxbea3zrilgfg6ubqvox2hrpxff2krv5dd57kqd4ga.domains.proton.ch" + name = "protonmail._domainkey" + proxied = false + ttl = 1 + type = "CNAME" + zone_id = data.cloudflare_zone.jafner_net.id +} + +resource "cloudflare_record" "dkim2_protonmail_jafner_net" { + content = "protonmail2.domainkey.djxxgyo3stmnxbea3zrilgfg6ubqvox2hrpxff2krv5dd57kqd4ga.domains.proton.ch" + name = "protonmail2._domainkey" + proxied = false + ttl = 1 + type = "CNAME" + zone_id = data.cloudflare_zone.jafner_net.id +} + +resource "cloudflare_record" "dkim3_protonmail_jafner_net" { + content = "protonmail3.domainkey.djxxgyo3stmnxbea3zrilgfg6ubqvox2hrpxff2krv5dd57kqd4ga.domains.proton.ch" + name = "protonmail3._domainkey" + proxied = false + ttl = 1 + type = "CNAME" + zone_id = data.cloudflare_zone.jafner_net.id +} + +resource "cloudflare_record" "mx_protonmail_jafner_net" { + content = "mail.protonmail.ch" + name = "jafner.net" + priority = 10 + proxied = false + ttl = 1 + type = "MX" + zone_id = data.cloudflare_zone.jafner_net.id +} + +resource "cloudflare_record" "mxsecure_protonmail_jafner_net" { + content = "mailsec.protonmail.ch" + name = "jafner.net" + priority = 20 + proxied = false + ttl = 1 + type = "MX" + zone_id = data.cloudflare_zone.jafner_net.id +} + +resource "cloudflare_record" "dmarc_protonmail_jafner_net" { + content = "v=DMARC1; p=quarantine" + name = "_dmarc" + proxied = false + ttl = 1 + type = "TXT" + zone_id = data.cloudflare_zone.jafner_net.id +} + +resource "cloudflare_record" "spf_protonmail_jafner_net" { + content = "v=spf1 include:_spf.protonmail.ch ~all" + name = "jafner.net" + proxied = false + ttl = 1 + type = "TXT" + zone_id = data.cloudflare_zone.jafner_net.id +} + +resource "cloudflare_record" "verify_protonmail_jafner_net" { + content = "protonmail-verification=9ace10d9bb99433b56318ee90826fbff3b80fb91" + name = "jafner.net" + proxied = false + ttl = 1 + type = "TXT" + zone_id = data.cloudflare_zone.jafner_net.id +} + diff --git a/homelab/sellswords/cloudflare/jafner.tools.tf b/homelab/sellswords/cloudflare/jafner.tools.tf new file mode 100644 index 00000000..feb467fb --- /dev/null +++ b/homelab/sellswords/cloudflare/jafner.tools.tf @@ -0,0 +1,18 @@ +resource "cloudflare_record" "any_jafner_tools" { + content = "143.110.151.123" + name = "*" + proxied = false + ttl = 1 + type = "A" + zone_id = data.cloudflare_zone.jafner_tools.id +} + +resource "cloudflare_record" "root_jafner_tools" { + content = "143.110.151.123" + name = "jafner.tools" + proxied = false + ttl = 1 + type = "A" + zone_id = data.cloudflare_zone.jafner_tools.id +} +