diff --git a/Access_Controls-Applications-Infrastructure.tf b/Access_Controls-Applications-Infrastructure.tf index 4380da6..e25b4f9 100644 --- a/Access_Controls-Applications-Infrastructure.tf +++ b/Access_Controls-Applications-Infrastructure.tf @@ -7,13 +7,13 @@ #====================================================== # Creating the Target -resource "cloudflare_zero_trust_access_infrastructure_target" "gcp_ssh_target" { +resource "cloudflare_zero_trust_access_infrastructure_target" "aws_ssh_target" { account_id = local.cloudflare_account_id - hostname = var.cloudflare_target_ssh_name + hostname = var.cloudflare_aws_target_ssh_name ip = { ipv4 = { - ip_addr = var.gcp_vm_internal_ip + ip_addr = var.aws_vm_internal_ip } } } @@ -33,7 +33,101 @@ resource "cloudflare_zero_trust_access_application" "cloudflare_aws_app_ssh_infr port = "22", protocol = "SSH" target_attributes = { - hostname = [var.cloudflare_target_ssh_name] + hostname = [var.cloudflare_aws_target_ssh_name] + }, + }] + + policies = [{ + name = "SSH GCP Infrastructure Policy" + decision = "allow" + + allowed_idps = [ + cloudflare_zero_trust_access_identity_provider.authentik_oidc.id, + ] + auto_redirect_to_identity = true + allow_authenticate_via_warp = false + + include = [ + { + saml = { + identity_provider_id = var.cloudflare_okta_identity_provider_id + attribute_name = "groups" + attribute_value = var.okta_infra_admin_saml_group_name + } + }, + { + saml = { + identity_provider_id = var.cloudflare_okta_identity_provider_id + attribute_name = "groups" + attribute_value = var.okta_contractors_saml_group_name + } + }, + { + email_domain = { + domain = var.cloudflare_email_domain + } + } + ] + require = [ + { + device_posture = { + integration_uid = var.cloudflare_gateway_posture_id + } + }, + { + auth_method = { + auth_method = "mfa" + } + } + ] + exclude = [ + { + auth_method = { + auth_method = "sms" + } + } + ] + connection_rules = { + ssh = { + allow_email_alias = true + usernames = [] # None + } + } + }] +} + +#====================================================== +# INFRASTRUCTURE APP: MySQL Database (Infrastructure) +#====================================================== + +# Creating the Target +resource "cloudflare_zero_trust_access_infrastructure_target" "gcp_ssh_target" { + account_id = local.cloudflare_account_id + + hostname = var.cloudflare_gcp_target_ssh_name + ip = { + ipv4 = { + ip_addr = var.gcp_vm_internal_ip + } + } +} + +# Creating the infrastructure Application +resource "cloudflare_zero_trust_access_application" "cloudflare_gcp_app_ssh_infra" { + account_id = local.cloudflare_account_id + + type = "infrastructure" + name = var.cloudflare_gcp_infra_app_name + logo_url = "https://upload.wikimedia.org/wikipedia/commons/0/01/Google-cloud-platform.svg" + tags = [cloudflare_zero_trust_access_tag.tags["engineers"].name] + custom_deny_url = "https://denied.tips-of-mine.org/" + custom_non_identity_deny_url = "https://denied.tips-of-mine.org/" + + target_criteria = [{ + port = "22", + protocol = "SSH" + target_attributes = { + hostname = [var.cloudflare_gcp_target_ssh_name] }, }] diff --git a/Access_Controls-Applications-rdp.tf b/Access_Controls-Applications-rdp.tf index d2122fd..6d598ab 100644 --- a/Access_Controls-Applications-rdp.tf +++ b/Access_Controls-Applications-rdp.tf @@ -7,10 +7,10 @@ #====================================================== # Creating the Target -resource "cloudflare_zero_trust_access_infrastructure_target" "gcp_rdp_target" { +resource "cloudflare_zero_trust_access_infrastructure_target" "aws_rdp_target" { account_id = local.cloudflare_account_id - hostname = var.cloudflare_target_rdp_name + hostname = var.cloudflare_aws_target_rdp_name ip = { ipv4 = { ip_addr = var.gcp_windows_vm_internal_ip @@ -39,7 +39,68 @@ resource "cloudflare_zero_trust_access_application" "cloudflare_aws_app_rdp_doma port = 3389 protocol = "RDP" target_attributes = { - hostname = [var.cloudflare_target_rdp_name] # This will be "Domain-Controller" + hostname = [var.cloudflare_aws_target_rdp_name] # This will be "Domain-Controller" + } + }] + + # Identity provider settings + allowed_idps = [ + cloudflare_zero_trust_access_identity_provider.authentik_oidc.id, + ] + auto_redirect_to_identity = true + enable_binding_cookie = false + http_only_cookie_attribute = false + options_preflight_bypass = false + + # Reference the policy from cloudflare-app-policies.tf + policies = [{ + id = cloudflare_zero_trust_access_policy.policies["domain_controller"].id + }] + + # Depends on the existing target + depends_on = [ + cloudflare_zero_trust_access_infrastructure_target.aws_rdp_target + ] +} + +#====================================================== +# SELF-HOSTED APP: Domain Controller +#====================================================== + +# Creating the Target +resource "cloudflare_zero_trust_access_infrastructure_target" "gcp_rdp_target" { + account_id = local.cloudflare_account_id + + hostname = var.cloudflare_gcp_target_rdp_name + ip = { + ipv4 = { + ip_addr = var.gcp_windows_vm_internal_ip + } + } +} + +# Domain Controller Browser-Rendered RDP Application +resource "cloudflare_zero_trust_access_application" "cloudflare_gcp_app_rdp_domain" { + account_id = local.cloudflare_account_id + + type = "rdp" + name = var.cloudflare_gcp_browser_rdp_app_name + app_launcher_visible = true + logo_url = "https://www.kevinsubileau.fr/wp-content/uploads/2016/05/RDP_icon.png" + tags = [cloudflare_zero_trust_access_tag.tags["engineers"].name] + session_duration = "0s" + custom_deny_url = "https://denied.tips-of-mine.org/" + custom_non_identity_deny_url = "https://denied.tips-of-mine.org/" + + # Public hostname for browser rendering + domain = var.cloudflare_subdomain_rdp + + # Target criteria - references the existing gcp_rdp_target + target_criteria = [{ + port = 3389 + protocol = "RDP" + target_attributes = { + hostname = [var.cloudflare_gcp_target_rdp_name] # This will be "Domain-Controller" } }] diff --git a/Access_Controls-Applications-ssh.tf b/Access_Controls-Applications-ssh.tf index 98424ae..58c2edd 100644 --- a/Access_Controls-Applications-ssh.tf +++ b/Access_Controls-Applications-ssh.tf @@ -3,7 +3,7 @@ # ============================================================================= #====================================================== -# SELF-HOSTED APP: DB Server +# SELF-HOSTED APP: DB Server AWS #====================================================== # Creating the Self-hosted Application for Browser rendering SSH @@ -40,3 +40,42 @@ resource "cloudflare_zero_trust_access_application" "cloudflare_aws_app_ssh_brow } ] } + +#====================================================== +# SELF-HOSTED APP: DB Server GCP +#====================================================== + +# Creating the Self-hosted Application for Browser rendering SSH +resource "cloudflare_zero_trust_access_application" "cloudflare_gcp_app_ssh_browser" { + account_id = local.cloudflare_account_id + + type = "ssh" + name = var.cloudflare_gcp_browser_ssh_app_name + app_launcher_visible = true + logo_url = "https://cdn.iconscout.com/icon/free/png-256/free-database-icon-download-in-svg-png-gif-file-formats--ui-elements-pack-user-interface-icons-444649.png" + tags = [cloudflare_zero_trust_access_tag.tags["engineers"].name] + session_duration = "0s" + custom_deny_url = "https://denied.tips-of-mine.org/" + custom_non_identity_deny_url = "https://denied.tips-of-mine.org/" + + destinations = [{ + type = "public" + uri = var.cloudflare_subdomain_ssh + }] + + allowed_idps = [ + cloudflare_zero_trust_access_identity_provider.gmail.id, + cloudflare_zero_trust_access_identity_provider.authentik_oidc.id, + ] + auto_redirect_to_identity = false + allow_authenticate_via_warp = false + + policies = [ + { + id = cloudflare_zero_trust_access_policy.policies["employees_browser_rendering"].id + }, + { + id = cloudflare_zero_trust_access_policy.policies["contractors_browser_rendering"].id + } + ] +} diff --git a/Access_Controls-Applications-vnc.tf b/Access_Controls-Applications-vnc.tf index befac4c..a67158a 100644 --- a/Access_Controls-Applications-vnc.tf +++ b/Access_Controls-Applications-vnc.tf @@ -5,8 +5,8 @@ #====================================================== # SELF-HOSTED APP: PostgresDB Admin #====================================================== -# Creating the Self-hosted Application for Browser rendering VNC +# Creating the Self-hosted Application for Browser rendering VNC resource "cloudflare_zero_trust_access_application" "cloudflare_aws_app_vnc_browser" { account_id = local.cloudflare_account_id @@ -35,3 +35,37 @@ resource "cloudflare_zero_trust_access_application" "cloudflare_aws_app_vnc_brow id = cloudflare_zero_trust_access_policy.policies["employees_browser_rendering"].id }] } + +#====================================================== +# SELF-HOSTED APP: PostgresDB Admin +#====================================================== + +# Creating the Self-hosted Application for Browser rendering VNC +resource "cloudflare_zero_trust_access_application" "cloudflare_gcp_app_vnc_browser" { + account_id = local.cloudflare_account_id + + type = "vnc" + name = var.cloudflare_gcp_browser_vnc_app_name + app_launcher_visible = true + logo_url = "https://blog.zwindler.fr/2015/07/vnc.png" + tags = [cloudflare_zero_trust_access_tag.tags["engineers"].name] + session_duration = "0s" + custom_deny_url = "https://denied.tips-of-mine.org/" + custom_non_identity_deny_url = "https://denied.tips-of-mine.org/" + + destinations = [{ + type = "public" + uri = var.cloudflare_subdomain_vnc + }] + + allowed_idps = [ + cloudflare_zero_trust_access_identity_provider.gmail.id, + cloudflare_zero_trust_access_identity_provider.authentik_oidc.id, + ] + auto_redirect_to_identity = false + allow_authenticate_via_warp = false + + policies = [{ + id = cloudflare_zero_trust_access_policy.policies["employees_browser_rendering"].id + }] +} diff --git a/variables.auto.tfvars b/variables.auto.tfvars index d87d290..b0d23e7 100644 --- a/variables.auto.tfvars +++ b/variables.auto.tfvars @@ -195,12 +195,14 @@ okta_bob_user_linux_password = "bob" # aws_private_cidr = "10.10.15.0/24" # aws_public_cidr = "10.10.20.0/24" -aws_vpc_cidr = "10.10.0.0/20" -aws_public_cidr = "10.10.0.0/24" -aws_private_cidr = "10.10.1.0/24" -aws_infra_cidr = "10.10.10.0/24" -aws_warp_cidr = "10.10.15.0/24" -aws_windows_rdp_cidr = "10.10.20.0/24" +aws_vpc_cidr = "10.10.0.0/20" +aws_public_cidr = "10.10.0.0/24" +aws_private_cidr = "10.10.1.0/24" +aws_infra_cidr = "10.10.10.0/24" +aws_warp_cidr = "10.10.15.0/24" +aws_windows_rdp_cidr = "10.10.20.0/24" +gcp_vm_internal_ip = "10.10.20.10" +aws_windows_vm_internal_ip = "10.10.20.10" #===================================== # GCP Variables diff --git a/variables.tf b/variables.tf index 163e2d8..10f9b7f 100644 --- a/variables.tf +++ b/variables.tf @@ -348,6 +348,11 @@ variable "cloudflare_domain_controller_rdp_port" { # GCP Networking #====================================================== +variable "aws_vm_internal_ip" { + description = "Internal Private IP of AWS Compute Engine Instance" + type = string +} + variable "gcp_vm_internal_ip" { description = "Internal Private IP of GCP Compute Engine Instance" type = string @@ -382,6 +387,11 @@ variable "aws_vpc_cidr" { type = string } +variable "aws_windows_vm_internal_ip" { + description = "Internal Private IP of AWS Compute Engine Instance running Windows RDP" + type = string +} + variable "aws_private_cidr" { description = "AWS private subnet, subnet for VMs in AWS" type = string @@ -502,12 +512,22 @@ variable "cloudflare_subdomain_training_status" { # CLOUDFLARE TARGET NAMES #====================================================== -variable "cloudflare_target_ssh_name" { +variable "cloudflare_aws_target_ssh_name" { description = "Friendly name for the Target hostname in Infrastructure App" type = string } -variable "cloudflare_target_rdp_name" { +variable "cloudflare_gcp_target_ssh_name" { + description = "Friendly name for the Target hostname in Infrastructure App" + type = string +} + +variable "cloudflare_aws_target_rdp_name" { + description = "Friendly name for the Target hostname in RDP windows browser rendered App" + type = string +} + +variable "cloudflare_gcp_target_rdp_name" { description = "Friendly name for the Target hostname in RDP windows browser rendered App" type = string }