feat(dns): setup cloudflared tunnel and DNS records
This commit is contained in:
35
cloudflare/.terraform.lock.hcl
generated
Normal file
35
cloudflare/.terraform.lock.hcl
generated
Normal file
@@ -0,0 +1,35 @@
|
||||
# This file is maintained automatically by "tofu init".
|
||||
# Manual edits may be lost in future updates.
|
||||
|
||||
provider "registry.opentofu.org/cloudflare/cloudflare" {
|
||||
version = "5.10.1"
|
||||
constraints = "~> 5.0"
|
||||
hashes = [
|
||||
"h1:fZArdZ2UjlXNHB4cEsnUKDRS1+rxX2MOauNC8SFarQo=",
|
||||
"zh:0f127587ae7a20a3de23bbb05b0859eb3e418912a6e2adef95f53f225f4f9da1",
|
||||
"zh:2ba095c6f7aa71fd140e0f57866b3a5b34152354f13de53f99037cc8386d9803",
|
||||
"zh:2d46cc0bc820e455e6386e3cf834b5876f9cacc8554733fd61ce4c758ca43d81",
|
||||
"zh:47b9996d6e99e4b9a26d390baaa1dcc2e5c846c6a1423c2aed1bc945c4f447ad",
|
||||
"zh:97c49f130edaac5ed4c17bd93706be88d5061a80b77484ae2e8f83d25df9b8ba",
|
||||
"zh:bd6af14ffdb1330eb8fd31a7b5e5362b08390bec53c75eda448203a473e5b36a",
|
||||
"zh:f77a6cc61754ee4406c765f198d13a465f9457ed546749cd3f49b8fe8378dfab",
|
||||
"zh:f809ab383cca0a5f83072981c64208cbd7fa67e986a86ee02dd2c82333221e32",
|
||||
"zh:f9324dc4f2e0a2e6abcd9ecabdd0a09dbb00e4ad9aa24437dfe1ea7a219fb2c8",
|
||||
]
|
||||
}
|
||||
|
||||
provider "registry.opentofu.org/hashicorp/cloudflare" {
|
||||
version = "5.10.1"
|
||||
hashes = [
|
||||
"h1:fZArdZ2UjlXNHB4cEsnUKDRS1+rxX2MOauNC8SFarQo=",
|
||||
"zh:0f127587ae7a20a3de23bbb05b0859eb3e418912a6e2adef95f53f225f4f9da1",
|
||||
"zh:2ba095c6f7aa71fd140e0f57866b3a5b34152354f13de53f99037cc8386d9803",
|
||||
"zh:2d46cc0bc820e455e6386e3cf834b5876f9cacc8554733fd61ce4c758ca43d81",
|
||||
"zh:47b9996d6e99e4b9a26d390baaa1dcc2e5c846c6a1423c2aed1bc945c4f447ad",
|
||||
"zh:97c49f130edaac5ed4c17bd93706be88d5061a80b77484ae2e8f83d25df9b8ba",
|
||||
"zh:bd6af14ffdb1330eb8fd31a7b5e5362b08390bec53c75eda448203a473e5b36a",
|
||||
"zh:f77a6cc61754ee4406c765f198d13a465f9457ed546749cd3f49b8fe8378dfab",
|
||||
"zh:f809ab383cca0a5f83072981c64208cbd7fa67e986a86ee02dd2c82333221e32",
|
||||
"zh:f9324dc4f2e0a2e6abcd9ecabdd0a09dbb00e4ad9aa24437dfe1ea7a219fb2c8",
|
||||
]
|
||||
}
|
||||
13
cloudflare/README.md
Normal file
13
cloudflare/README.md
Normal file
@@ -0,0 +1,13 @@
|
||||
# README
|
||||
|
||||
## TODO
|
||||
- don't forget to mention namecheap -> cloudflare NS
|
||||
NS lloyd.ns.cloudflare.com
|
||||
NS meadow.ns.cloudflare.com
|
||||
|
||||
Create token
|
||||
https://developers.cloudflare.com/fundamentals/api/get-started/account-owned-tokens/
|
||||
|
||||
Token access
|
||||
Kostiantyn Bukliei - Cloudflare Tunnel:Edit, Zero Trust:Edit, Access: Apps and Policies:Edit
|
||||
madunde.ad - DNS:Edit
|
||||
20
cloudflare/dns/main.tf
Normal file
20
cloudflare/dns/main.tf
Normal file
@@ -0,0 +1,20 @@
|
||||
# Root A Record
|
||||
resource "cloudflare_dns_record" "root_dns_record" {
|
||||
zone_id = var.cloudflare_zone_id
|
||||
name = "madunde.ad"
|
||||
ttl = 3600
|
||||
type = "A"
|
||||
content = "193.93.217.193"
|
||||
proxied = false
|
||||
}
|
||||
|
||||
# CNAME Records for each service declared in services module
|
||||
resource "cloudflare_dns_record" "cname_record" {
|
||||
for_each = var.services
|
||||
zone_id = var.cloudflare_zone_id
|
||||
name = "${each.value.subdomain}.madunde.ad"
|
||||
content = "${var.cloudflare_tunnel_id}.cfargotunnel.com"
|
||||
type = "CNAME"
|
||||
ttl = 1
|
||||
proxied = true
|
||||
}
|
||||
20
cloudflare/dns/variables.tf
Normal file
20
cloudflare/dns/variables.tf
Normal file
@@ -0,0 +1,20 @@
|
||||
variable "cloudflare_zone_id" {
|
||||
description = "Cloudflare Zone ID"
|
||||
type = string
|
||||
sensitive = true
|
||||
}
|
||||
|
||||
variable "cloudflare_tunnel_id" {
|
||||
description = "Cloudflare Zone ID"
|
||||
type = string
|
||||
sensitive = true
|
||||
}
|
||||
|
||||
variable "services" {
|
||||
description = "Services to expose to the outside world"
|
||||
type = map(object({
|
||||
subdomain = string
|
||||
service = string
|
||||
policy = string
|
||||
}))
|
||||
}
|
||||
60
cloudflare/main.tf
Normal file
60
cloudflare/main.tf
Normal file
@@ -0,0 +1,60 @@
|
||||
terraform {
|
||||
required_providers {
|
||||
cloudflare = {
|
||||
source = "cloudflare/cloudflare"
|
||||
version = "~> 5"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
provider "cloudflare" {
|
||||
api_token = var.cloudflare_api_token
|
||||
}
|
||||
|
||||
module "services" {
|
||||
source = "./services"
|
||||
}
|
||||
|
||||
module "dns" {
|
||||
source = "./dns"
|
||||
services = module.services.services
|
||||
cloudflare_zone_id = var.cloudflare_zone_id
|
||||
cloudflare_tunnel_id = cloudflare_zero_trust_tunnel_cloudflared.ratchet_tunnel.id
|
||||
}
|
||||
|
||||
module "policies" {
|
||||
source = "./policies"
|
||||
cloudflare_zone_id = var.cloudflare_zone_id
|
||||
cloudflare_account_id = var.cloudflare_account_id
|
||||
cloudflare_email = var.cloudflare_email
|
||||
}
|
||||
|
||||
resource "cloudflare_zero_trust_tunnel_cloudflared" "ratchet_tunnel" {
|
||||
account_id = var.cloudflare_account_id
|
||||
tunnel_secret = var.cloudflared_tunnel_secret
|
||||
name = "cloudflare > ratchet tunnel"
|
||||
config_src = "cloudflare"
|
||||
}
|
||||
|
||||
resource "cloudflare_zero_trust_tunnel_cloudflared_config" "ratchet_tunnel_config" {
|
||||
account_id = var.cloudflare_account_id
|
||||
tunnel_id = cloudflare_zero_trust_tunnel_cloudflared.ratchet_tunnel.id
|
||||
config = {
|
||||
ingress = concat([for k, v in module.services.services : { hostname = "${v.subdomain}.madunde.ad", service = v.service }], [{ service = "http_status:404" }])
|
||||
}
|
||||
}
|
||||
|
||||
resource "cloudflare_zero_trust_access_application" "access_application" {
|
||||
for_each = module.services.services
|
||||
account_id = var.cloudflare_account_id
|
||||
zone_id = var.cloudflare_zone_id
|
||||
domain = "${each.value.subdomain}.madunde.ad"
|
||||
type = "self_hosted"
|
||||
name = "Access application for ${each.value.subdomain}.madunde.ad"
|
||||
policies = [
|
||||
{
|
||||
id = module.policies[each.value.policy].id
|
||||
precedence = 1
|
||||
}
|
||||
]
|
||||
}
|
||||
5
cloudflare/output.tf
Normal file
5
cloudflare/output.tf
Normal file
@@ -0,0 +1,5 @@
|
||||
output "tunnel_secret" {
|
||||
description = "TODO"
|
||||
value = cloudflare_zero_trust_tunnel_cloudflared.ratchet_tunnel.tunnel_secret
|
||||
sensitive = true
|
||||
}
|
||||
46
cloudflare/policies/main.tf
Normal file
46
cloudflare/policies/main.tf
Normal file
@@ -0,0 +1,46 @@
|
||||
resource "cloudflare_zero_trust_list" "family_emails" {
|
||||
account_id = var.cloudflare_account_id
|
||||
name = "Me & Family"
|
||||
type = "EMAIL"
|
||||
items = [
|
||||
{
|
||||
value = "madundead@gmail.com",
|
||||
},
|
||||
{
|
||||
value = "mail.elenka@gmail.com"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
resource "cloudflare_zero_trust_access_policy" "allow_myself" {
|
||||
account_id = var.cloudflare_account_id
|
||||
name = "Allow myself, by OTP via email"
|
||||
decision = "allow"
|
||||
include = [
|
||||
{
|
||||
email = {
|
||||
email = var.cloudflare_email
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
resource "cloudflare_zero_trust_access_policy" "allow_myself_and_family" {
|
||||
account_id = var.cloudflare_account_id
|
||||
name = "Allow myself & Olena by OTP via email"
|
||||
decision = "allow"
|
||||
include = [
|
||||
{
|
||||
email_list = cloudflare_zero_trust_list.family_emails
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
resource "cloudflare_zero_trust_access_policy" "allow_everyone" {
|
||||
account_id = var.cloudflare_account_id
|
||||
name = "Allow everyone"
|
||||
decision = "bypass"
|
||||
include = [{
|
||||
everyone = {}
|
||||
}]
|
||||
}
|
||||
15
cloudflare/policies/output.tf
Normal file
15
cloudflare/policies/output.tf
Normal file
@@ -0,0 +1,15 @@
|
||||
output "allow_myself" {
|
||||
description = "Allow madundead@gmail.com via OTP"
|
||||
value = cloudflare_zero_trust_access_policy.allow_myself
|
||||
}
|
||||
|
||||
output "allow_myself_and_family" {
|
||||
description = "Allow emails listed in cloudflare_zero_trust_list.family_emails"
|
||||
value = cloudflare_zero_trust_access_policy.allow_myself_and_family
|
||||
}
|
||||
|
||||
|
||||
output "allow_everyone" {
|
||||
description = "Allow everyone"
|
||||
value = cloudflare_zero_trust_access_policy.allow_everyone
|
||||
}
|
||||
14
cloudflare/policies/variables.tf
Normal file
14
cloudflare/policies/variables.tf
Normal file
@@ -0,0 +1,14 @@
|
||||
variable "cloudflare_zone_id" {
|
||||
type = string
|
||||
sensitive = true
|
||||
}
|
||||
|
||||
variable "cloudflare_account_id" {
|
||||
type = string
|
||||
sensitive = true
|
||||
}
|
||||
|
||||
variable "cloudflare_email" {
|
||||
type = string
|
||||
sensitive = true
|
||||
}
|
||||
4
cloudflare/services/output.tf
Normal file
4
cloudflare/services/output.tf
Normal file
@@ -0,0 +1,4 @@
|
||||
output "services" {
|
||||
description = "Services to expose to the outside world"
|
||||
value = local.services
|
||||
}
|
||||
14
cloudflare/services/services.tf
Normal file
14
cloudflare/services/services.tf
Normal file
@@ -0,0 +1,14 @@
|
||||
locals {
|
||||
services = {
|
||||
homer = {
|
||||
subdomain = "home"
|
||||
service = "http://192.168.0.101:8888"
|
||||
policy = "allow_myself_and_family"
|
||||
},
|
||||
gitea = {
|
||||
subdomain = "git"
|
||||
service = "http://192.168.0.101:3000"
|
||||
policy = "allow_everyone"
|
||||
}
|
||||
}
|
||||
}
|
||||
27
cloudflare/variables.tf
Normal file
27
cloudflare/variables.tf
Normal file
@@ -0,0 +1,27 @@
|
||||
variable "cloudflare_zone_id" {
|
||||
description = "Zone ID for your domain"
|
||||
type = string
|
||||
}
|
||||
|
||||
variable "cloudflare_account_id" {
|
||||
description = "Account ID for your Cloudflare account"
|
||||
type = string
|
||||
sensitive = true
|
||||
}
|
||||
|
||||
variable "cloudflare_email" {
|
||||
description = "Email address for your Cloudflare account"
|
||||
type = string
|
||||
}
|
||||
|
||||
variable "cloudflare_api_token" {
|
||||
description = "Cloudflare API token"
|
||||
type = string
|
||||
sensitive = true
|
||||
}
|
||||
|
||||
variable "cloudflared_tunnel_secret" {
|
||||
description = "Cloudflare cloudflared auth secret"
|
||||
type = string
|
||||
sensitive = true
|
||||
}
|
||||
Reference in New Issue
Block a user