# ============================================================================= # CLOUDFLARE : Access : Policies # ============================================================================= # resource "cloudflare_zero_trust_access_policy" "policies" { for_each = var.access_policies account_id = var.cloudflare_account_id decision = "allow" name = each.value.name session_duration = "0s" # Purpose justification purpose_justification_prompt = try(each.value.purpose_justification_prompt, null) purpose_justification_required = try(each.value.purpose_justification, false) # Include groups include = concat( # Groups (both SAML and composite groups via mapping) [ for group in each.value.include_groups : { group = { id = var.policy_groups[group] } } ], # Email domain (for contractors) try(each.value.include_email_domain, false) ? [{ email_domain = { domain = var.cf_email_domain } }] : [] ) # Require conditions require = concat( # Device posture (always required if specified) try(each.value.require_posture, false) ? [{ device_posture = { integration_uid = var.cf_gateway_posture_id } }] : [], # MFA requirement try(each.value.require_mfa, false) ? [{ auth_method = { auth_method = "mfa" } }] : [], # Login method (for specific policies) try(each.value.require_login_method, false) ? [{ login_method = { id = var.cf_okta_identity_provider_id } }] : [], # Country requirements try(each.value.require_country, false) ? [{ group = { id = cloudflare_zero_trust_access_group.country_requirements_rule_group.id } }] : [], # OS version requirements try(each.value.require_os_version, false) ? [{ group = { id = cloudflare_zero_trust_access_group.latest_os_version_requirements_rule_group.id } }] : [], # External evaluation requirements try(each.value.require_external_evaluation, false) ? [{ external_evaluation = { evaluate_url = each.value.external_evaluation_url keys_url = each.value.external_evaluation_keys_url } }] : [] ) # Exclude SMS (for MFA policies) exclude = try(each.value.require_mfa, false) ? [{ auth_method = { auth_method = "sms" } }] : [] # Explicit dependencies to ensure proper destruction order: # Policies → Composite Groups → Individual SAML Groups depends_on = [ cloudflare_zero_trust_access_group.employees_rule_group, cloudflare_zero_trust_access_group.sales_team_rule_group, cloudflare_zero_trust_access_group.admins_rule_group, cloudflare_zero_trust_access_group.contractors_rule_group, cloudflare_zero_trust_access_group.saml_groups ] # Note: lifecycle blocks cannot be conditional in for_each resources }