So I'm currently new to terraform and I'm using CSVs as inputs to generate different types of resources. Some of these resources have conditions meaning that they should only be created if these conditions are met. Below is the piece of code that I wrote. This code works, but not exactly the way is required.
locals {
csv_data1 = <<-CSV
short_hostname,tunnel,fqdn,access_app_type,service_url,no_tls_verify
fralinuxhost1,fratest-tunnel01,fralinuxhost1.example.com,ssh,ssh://fralinuxhost1.example.com,false
fralinuxhost2,fratest-tunnel01,fralinuxhost1.example.com,ssh,ssh://fralinuxhost2.example.com,false
sjclinuxhost2,sjctest-tunnel01,sjclinuxhost2.example.com,ssh,ssh://sjclinuxhost2.example.com,false
CSV
csv_data2 = <<-CSV
tunnelnameref,secret
fratest-tunnel01,secretblahblah1
sjctest-tunnel01,secretblahblah2
CSV
publichost = csvdecode(local.csv_data1)
tunnelnameref = csvdecode(local.csv_data2)
}
resource "cloudflare_zone" "example_com" {
account_id = var.account_id
paused = false
plan = "free"
type = "full"
zone = "example.com"
}
resource "cloudflare_access_group" "test_users_and_require_warp" {
account_id = var.account_id
name = "test_users_and_require_warp"
include {
any_valid_service_token = false
certificate = false
device_posture = []
email = [
"[email protected]",
"[email protected]",
]
email_domain = []
everyone = false
geo = []
group = []
ip = []
ip_list = []
login_method = []
service_token = []
}
require {
any_valid_service_token = false
certificate = false
device_posture = [
"1234567890-102001203-3194aaa",
]
email = []
email_domain = []
everyone = false
geo = []
group = []
ip = []
ip_list = []
login_method = []
service_token = []
}
}
resource "cloudflare_tunnel" "example" {
for_each = { for host in local.tunnelnameref : host.tunnelnameref => host }
account_id = var.account_id
name = each.value.tunnelnameref
secret = each.value.secret
}
resource "cloudflare_access_application" "example" {
for_each = { for host in local.publichost : host.short_hostname => host }
account_id = var.account_id
allowed_idps = []
app_launcher_visible = true
auto_redirect_to_identity = false
custom_pages = []
domain = each.value["fqdn"]
enable_binding_cookie = false
http_only_cookie_attribute = true
name = each.value.short_hostname
service_auth_401_redirect = false
session_duration = "24h"
skip_interstitial = true
tags = []
type = each.value["access_app_type"]
}
resource "cloudflare_record" "example" {
for_each = { for host in local.publichost : host.short_hostname => host }
zone_id = cloudflare_zone.example_com.id
name = each.value["short_hostname"]
value = "${cloudflare_tunnel.example[each.value.tunnel].id}.cfargotunnel.com"
type = "CNAME"
proxied = true
}
resource "cloudflare_access_policy" "example" {
for_each = { for host in local.publichost : host.short_hostname => host }
application_id = cloudflare_access_application.example[each.value.short_hostname].id
zone_id = cloudflare_zone.example_com.id
name = each.value["fqdn"]
precedence = "1"
decision = "allow"
include {
group = [
cloudflare_access_group.test_users_and_require_warp.id
]
}
}
resource "cloudflare_tunnel_config" "example" {
for_each = { for host in local.tunnelnameref : host.tunnelnameref => host }
account_id = var.account_id
tunnel_id = cloudflare_tunnel.example[each.value.tunnelnameref].id
config {
dynamic "ingress_rule" {
for_each = local.publichost
content {
hostname = ingress_rule.value["fqdn"]
service = ingress_rule.value["service_url"]
origin_request {
bastion_mode = false
disable_chunked_encoding = false
http2_origin = false
keep_alive_connections = 0
no_happy_eyeballs = false
no_tls_verify = ingress_rule.value["no_tls_verify"]
proxy_port = 0
}
}
}
ingress_rule {
service = "http_status:404"
}
warp_routing {
enabled = true
}
}
}
I tried depends_on, but since I'm using a for_each that isn't possible. for_each has some syntax for conditionals, but I can't seem to figure out how to make it work in this scenario using CSV data to generate resources.
The output looks correct, but the last resource or the cloudflare_tunnel_config resource gets generated for the csv_data1 times the csv_data2. In other words the output for that section looks like below
# cloudflare_tunnel_config.example["fratest-tunnel01"] will be created
+ resource "cloudflare_tunnel_config" "example" {
+ account_id = "blah"
+ id = (known after apply)
+ tunnel_id = (known after apply)
+ config {
+ ingress_rule {
+ hostname = "fralinuxhost1.example.com"
+ service = "ssh://fralinuxhost1.example.com"
+ origin_request {
+ bastion_mode = false
+ connect_timeout = "30s"
+ disable_chunked_encoding = false
+ http2_origin = false
+ keep_alive_connections = 0
+ keep_alive_timeout = "1m30s"
+ no_happy_eyeballs = false
+ no_tls_verify = false
+ proxy_address = "127.0.0.1"
+ proxy_port = 0
+ tcp_keep_alive = "30s"
+ tls_timeout = "10s"
}
}
+ ingress_rule {
+ hostname = "fralinuxhost2.example.com"
+ service = "ssh://fralinuxhost2.example.com"
+ origin_request {
+ bastion_mode = false
+ connect_timeout = "30s"
+ disable_chunked_encoding = false
+ http2_origin = false
+ keep_alive_connections = 0
+ keep_alive_timeout = "1m30s"
+ no_happy_eyeballs = false
+ no_tls_verify = false
+ proxy_address = "127.0.0.1"
+ proxy_port = 0
+ tcp_keep_alive = "30s"
+ tls_timeout = "10s"
}
}
+ ingress_rule {
+ hostname = "sjclinuxhost2.example.com"
+ service = "ssh://sjclinuxhost2.example.com"
+ origin_request {
+ bastion_mode = false
+ connect_timeout = "30s"
+ disable_chunked_encoding = false
+ http2_origin = false
+ keep_alive_connections = 0
+ keep_alive_timeout = "1m30s"
+ no_happy_eyeballs = false
+ no_tls_verify = false
+ proxy_address = "127.0.0.1"
+ proxy_port = 0
+ tcp_keep_alive = "30s"
+ tls_timeout = "10s"
}
}
+ ingress_rule {
+ service = "http_status:404"
}
+ warp_routing {
+ enabled = true
}
}
}
# cloudflare_tunnel_config.example["sjctest-tunnel01"] will be created
+ resource "cloudflare_tunnel_config" "example" {
+ account_id = "blah"
+ id = (known after apply)
+ tunnel_id = (known after apply)
+ config {
+ ingress_rule {
+ hostname = "fralinuxhost1.example.com"
+ service = "ssh://fralinuxhost1.example.com"
+ origin_request {
+ bastion_mode = false
+ connect_timeout = "30s"
+ disable_chunked_encoding = false
+ http2_origin = false
+ keep_alive_connections = 0
+ keep_alive_timeout = "1m30s"
+ no_happy_eyeballs = false
+ no_tls_verify = false
+ proxy_address = "127.0.0.1"
+ proxy_port = 0
+ tcp_keep_alive = "30s"
+ tls_timeout = "10s"
}
}
+ ingress_rule {
+ hostname = "fralinuxhost2.example.com"
+ service = "ssh://fralinuxhost2.example.com"
+ origin_request {
+ bastion_mode = false
+ connect_timeout = "30s"
+ disable_chunked_encoding = false
+ http2_origin = false
+ keep_alive_connections = 0
+ keep_alive_timeout = "1m30s"
+ no_happy_eyeballs = false
+ no_tls_verify = false
+ proxy_address = "127.0.0.1"
+ proxy_port = 0
+ tcp_keep_alive = "30s"
+ tls_timeout = "10s"
}
}
+ ingress_rule {
+ hostname = "sjclinuxhost2.example.com"
+ service = "ssh://sjclinuxhost2.example.com"
+ origin_request {
+ bastion_mode = false
+ connect_timeout = "30s"
+ disable_chunked_encoding = false
+ http2_origin = false
+ keep_alive_connections = 0
+ keep_alive_timeout = "1m30s"
+ no_happy_eyeballs = false
+ no_tls_verify = false
+ proxy_address = "127.0.0.1"
+ proxy_port = 0
+ tcp_keep_alive = "30s"
+ tls_timeout = "10s"
}
}
+ ingress_rule {
+ service = "http_status:404"
}
+ warp_routing {
+ enabled = true
}
}
}
But the output should look like the one below:
# cloudflare_tunnel_config.example["fratest-tunnel01"] will be created
+ resource "cloudflare_tunnel_config" "example" {
+ account_id = "blah"
+ id = (known after apply)
+ tunnel_id = (known after apply)
+ config {
+ ingress_rule {
+ hostname = "fralinuxhost1.example.com"
+ service = "ssh://fralinuxhost1.example.com"
+ origin_request {
+ bastion_mode = false
+ connect_timeout = "30s"
+ disable_chunked_encoding = false
+ http2_origin = false
+ keep_alive_connections = 0
+ keep_alive_timeout = "1m30s"
+ no_happy_eyeballs = false
+ no_tls_verify = false
+ proxy_address = "127.0.0.1"
+ proxy_port = 0
+ tcp_keep_alive = "30s"
+ tls_timeout = "10s"
}
}
+ ingress_rule {
+ hostname = "fralinuxhost2.example.com"
+ service = "ssh://fralinuxhost2.example.com"
+ origin_request {
+ bastion_mode = false
+ connect_timeout = "30s"
+ disable_chunked_encoding = false
+ http2_origin = false
+ keep_alive_connections = 0
+ keep_alive_timeout = "1m30s"
+ no_happy_eyeballs = false
+ no_tls_verify = false
+ proxy_address = "127.0.0.1"
+ proxy_port = 0
+ tcp_keep_alive = "30s"
+ tls_timeout = "10s"
}
}
+ ingress_rule {
+ service = "http_status:404"
}
+ warp_routing {
+ enabled = true
}
}
}
# cloudflare_tunnel_config.example["sjctest-tunnel01"] will be created
+ resource "cloudflare_tunnel_config" "example" {
+ account_id = "blah"
+ id = (known after apply)
+ tunnel_id = (known after apply)
+ config {
+ ingress_rule {
+ hostname = "sjclinuxhost2.example.com"
+ service = "ssh://sjclinuxhost2.example.com"
+ origin_request {
+ bastion_mode = false
+ connect_timeout = "30s"
+ disable_chunked_encoding = false
+ http2_origin = false
+ keep_alive_connections = 0
+ keep_alive_timeout = "1m30s"
+ no_happy_eyeballs = false
+ no_tls_verify = false
+ proxy_address = "127.0.0.1"
+ proxy_port = 0
+ tcp_keep_alive = "30s"
+ tls_timeout = "10s"
}
}
+ ingress_rule {
+ service = "http_status:404"
}
+ warp_routing {
+ enabled = true
}
}
}
How would I be able to accomplish this?
You can specify conditions to perform some filtering while in a
for. You should do something like this: