# ============================================================================= # CLOUDFLARE : Team & Resources : Devices : Device profiles # ============================================================================= # resource "cloudflare_zero_trust_device_custom_profile" "zero_trust_device_custom_profile_windows" { account_id = local.cloudflare_account_id enabled = true name = "Allow devices Windows" description = "Policy for test teams." precedence = 100 # match = "identity.email == \"test@cloudflare.com\"" match = "os.name == \"windows\"" allow_mode_switch = true allow_updates = true allowed_to_leave = true auto_connect = 0 captive_portal = 180 disable_auto_fallback = true # exclude = [{ # address = "192.0.2.0/24" # description = "Exclude testing domains from the tunnel" # }] exclude_office_ips = true # include = [{ # address = "192.0.2.0/24" # description = "Include testing domains in the tunnel" # }] lan_allow_minutes = 30 lan_allow_subnet_size = 24 register_interface_ip_with_dns = true sccm_vpn_boundary_support = false service_mode_v2 = { mode = "proxy" port = 3000 } support_url = "https://1.1.1.1/help" switch_locked = true tunnel_protocol = "wireguard" } # resource "cloudflare_zero_trust_device_custom_profile" "zero_trust_device_custom_profile_linux" { account_id = local.cloudflare_account_id enabled = true name = "Allow devices Linux" description = "Policy for test teams." precedence = 200 # match = "identity.email == \"test@cloudflare.com\"" match = "os.name == \"linux\"" allow_mode_switch = true allow_updates = true allowed_to_leave = true auto_connect = 0 captive_portal = 180 disable_auto_fallback = true # exclude = [{ # address = "192.0.2.0/24" # description = "Exclude testing domains from the tunnel" # }] exclude_office_ips = true # include = [{ # address = "192.0.2.0/24" # description = "Include testing domains in the tunnel" # }] lan_allow_minutes = 30 lan_allow_subnet_size = 24 register_interface_ip_with_dns = true sccm_vpn_boundary_support = false service_mode_v2 = { mode = "proxy" port = 3000 } support_url = "https://1.1.1.1/help" switch_locked = true tunnel_protocol = "wireguard" } # resource "cloudflare_zero_trust_device_custom_profile" "zero_trust_device_custom_profile_mac" { account_id = local.cloudflare_account_id enabled = true name = "Allow devices Mac" description = "Policy for test teams." precedence = 300 # match = "identity.email == \"test@cloudflare.com\"" match = "os.name == \"mac\"" allow_mode_switch = true allow_updates = true allowed_to_leave = true auto_connect = 0 captive_portal = 180 disable_auto_fallback = true # exclude = [{ # address = "192.0.2.0/24" # description = "Exclude testing domains from the tunnel" # }] exclude_office_ips = true # include = [{ # address = "192.0.2.0/24" # description = "Include testing domains in the tunnel" # }] lan_allow_minutes = 30 lan_allow_subnet_size = 24 register_interface_ip_with_dns = true sccm_vpn_boundary_support = false service_mode_v2 = { mode = "proxy" port = 3000 } support_url = "https://1.1.1.1/help" switch_locked = true tunnel_protocol = "wireguard" } #========================================================== # Device Profile Configurations #========================================================== locals { # Device precedence values device_precedence = { laptop = 10 # Highest priority - specific OS match vm = 20 # Medium priority - group-based match warp_connector = 30 # Lower priority - service account match } # Common profile settings common_profile_settings = { allow_mode_switch = false tunnel_protocol = "masque" switch_locked = false allowed_to_leave = true allow_updates = true auto_connect = 0 disable_auto_fallback = false lan_allow_minutes = 30 lan_allow_subnet_size = 16 exclude_office_ips = true captive_portal = 180 } # Device profiles configuration device_profiles = { laptop = { name = "Zero-Trust demo local laptop (mac)" description = "This profile is for the local laptop (running macos) for my zero-trust demo" precedence = local.device_precedence.laptop match = "os.name == \"${var.cloudflare_device_os}\" and identity.email == \"${var.okta_matthieu_user_login}\"", support_url = "Zero-TrustDemo-LaptopProfile" } vm = { name = "Zero-Trust demo VMs (Ubuntu and Windows 11)" description = "This profile is for my VMs for my zero-trust demo" precedence = local.device_precedence.vm match = "any(identity.saml_attributes[*] in {\"groups=${var.okta_infra_admin_saml_group_name}\"}) or any(identity.saml_attributes[*] in {\"groups=${var.okta_contractors_saml_group_name}\"}) or identity.email matches \"${var.cloudflare_email_domain}\"" support_url = "Zero-TrustDemo-VMProfile" } warp_connector = { name = "Zero-Trust demo WarpConnector" description = "This profile is dedicated for WARP Connector" precedence = local.device_precedence.warp_connector match = "identity.email == \"warp_connector@${var.cloudflare_team_name}.cloudflareaccess.com\"" support_url = "WARPConnectorProfile" } } } #========================================================== # Device Custom Profiles #========================================================== resource "cloudflare_zero_trust_device_custom_profile" "profiles" { for_each = local.device_profiles account_id = local.cloudflare_account_id enabled = true name = each.value.name description = each.value.description precedence = each.value.precedence match = each.value.match support_url = each.value.support_url # Common settings allow_mode_switch = local.common_profile_settings.allow_mode_switch tunnel_protocol = local.common_profile_settings.tunnel_protocol switch_locked = local.common_profile_settings.switch_locked allowed_to_leave = local.common_profile_settings.allowed_to_leave allow_updates = local.common_profile_settings.allow_updates auto_connect = local.common_profile_settings.auto_connect disable_auto_fallback = local.common_profile_settings.disable_auto_fallback lan_allow_minutes = local.common_profile_settings.lan_allow_minutes lan_allow_subnet_size = local.common_profile_settings.lan_allow_subnet_size exclude_office_ips = local.common_profile_settings.exclude_office_ips captive_portal = local.common_profile_settings.captive_portal service_mode_v2 = { mode = "warp" } # Exclude routes configuration exclude = [ for route in values(local.final_exclude_routes) : { address = route.address description = route.description } ] # Apply once and ignore subsequent changes lifecycle { ignore_changes = all } }