diff --git a/.changelog/2159.txt b/.changelog/2159.txt
new file mode 100644
index 0000000000..761b0ef936
--- /dev/null
+++ b/.changelog/2159.txt
@@ -0,0 +1,3 @@
+```release-note:enhancement
+resource/cloudflare_teams_rules: adds egress rule settings.
+```
\ No newline at end of file
diff --git a/docs/resources/teams_rule.md b/docs/resources/teams_rule.md
index 75a8dc2652..64ec37ab8c 100644
--- a/docs/resources/teams_rule.md
+++ b/docs/resources/teams_rule.md
@@ -32,7 +32,7 @@ resource "cloudflare_teams_rule" "example" {
### Required
- `account_id` (String) The account identifier to target for the resource.
-- `action` (String) The action executed by matched teams rule. Available values: `allow`, `block`, `safesearch`, `ytrestricted`, `on`, `off`, `scan`, `noscan`, `isolate`, `noisolate`, `override`, `l4_override`.
+- `action` (String) The action executed by matched teams rule. Available values: `allow`, `block`, `safesearch`, `ytrestricted`, `on`, `off`, `scan`, `noscan`, `isolate`, `noisolate`, `override`, `l4_override`, `egress`.
- `description` (String) The description of the teams rule.
- `name` (String) The name of the teams rule.
- `precedence` (Number) The evaluation precedence of the teams rule.
@@ -61,6 +61,7 @@ Optional:
- `block_page_enabled` (Boolean) Indicator of block page enablement.
- `block_page_reason` (String) The displayed reason for a user being blocked.
- `check_session` (Block List, Max: 1) Configure how session check behaves. (see [below for nested schema](#nestedblock--rule_settings--check_session))
+- `egress` (Block List, Max: 1) Configure how Proxy traffic egresses. Can be set for rules with Egress action and Egress filter. Can be omitted to indicate local egress via Warp IPs. (see [below for nested schema](#nestedblock--rule_settings--egress))
- `insecure_disable_dnssec_validation` (Boolean) Disable DNSSEC validation (must be Allow rule).
- `l4override` (Block List, Max: 1) Settings to forward layer 4 traffic. (see [below for nested schema](#nestedblock--rule_settings--l4override))
- `override_host` (String) The host to override matching DNS queries with.
@@ -87,6 +88,19 @@ Required:
- `enforce` (Boolean) Enable session enforcement for this rule.
+
+### Nested Schema for `rule_settings.egress`
+
+Required:
+
+- `ipv4` (String) The IPv4 address to be used for egress.
+- `ipv6` (String) The IPv6 range to be used for egress.
+
+Optional:
+
+- `ipv4_fallback` (String) The IPv4 address to be used for egress in the event of an error egressing with the primary IPv4. Can be '0.0.0.0' to indicate local egreass via Warp IPs.
+
+
### Nested Schema for `rule_settings.l4override`
diff --git a/internal/provider/resource_cloudflare_teams_rules.go b/internal/provider/resource_cloudflare_teams_rules.go
index cd7c439ab3..4b873bda59 100644
--- a/internal/provider/resource_cloudflare_teams_rules.go
+++ b/internal/provider/resource_cloudflare_teams_rules.go
@@ -205,6 +205,7 @@ func flattenTeamsRuleSettings(settings *cloudflare.TeamsRuleSettings) []interfac
"check_session": flattenTeamsCheckSessionSettings(settings.CheckSession),
"add_headers": flattenTeamsAddHeaders(settings.AddHeaders),
"insecure_disable_dnssec_validation": settings.InsecureDisableDNSSECValidation,
+ "egress": flattenTeamsEgressSettings(settings.EgressSettings),
}}
}
@@ -230,6 +231,7 @@ func inflateTeamsRuleSettings(settings interface{}) *cloudflare.TeamsRuleSetting
checkSessionSettings := inflateTeamsCheckSessionSettings(settingsMap["check_session"].([]interface{}))
addHeaders := inflateTeamsAddHeaders(settingsMap["add_headers"].(map[string]interface{}))
insecureDisableDNSSECValidation := settingsMap["insecure_disable_dnssec_validation"].(bool)
+ egressSettings := inflateTeamsEgressSettings(settingsMap["egress"].([]interface{}))
return &cloudflare.TeamsRuleSettings{
BlockPageEnabled: enabled,
@@ -241,6 +243,7 @@ func inflateTeamsRuleSettings(settings interface{}) *cloudflare.TeamsRuleSetting
CheckSession: checkSessionSettings,
AddHeaders: addHeaders,
InsecureDisableDNSSECValidation: insecureDisableDNSSECValidation,
+ EgressSettings: egressSettings,
}
}
@@ -363,6 +366,33 @@ func inflateTeamsL4Override(settings interface{}) *cloudflare.TeamsL4OverrideSet
}
}
+func flattenTeamsEgressSettings(settings *cloudflare.EgressSettings) []interface{} {
+ if settings == nil {
+ return nil
+ }
+ return []interface{}{map[string]interface{}{
+ "ipv4": settings.Ipv4,
+ "ipv6": settings.Ipv6Range,
+ "ipv4_fallback": settings.Ipv4Fallback,
+ }}
+}
+
+func inflateTeamsEgressSettings(settings interface{}) *cloudflare.EgressSettings {
+ settingsList := settings.([]interface{})
+ if len(settingsList) != 1 {
+ return nil
+ }
+ settingsMap := settingsList[0].(map[string]interface{})
+ ipv4 := settingsMap["ipv4"].(string)
+ ipv6 := settingsMap["ipv6"].(string)
+ ipv4Fallback := settingsMap["ipv4_fallback"].(string)
+ return &cloudflare.EgressSettings{
+ Ipv4: ipv4,
+ Ipv6Range: ipv6,
+ Ipv4Fallback: ipv4Fallback,
+ }
+}
+
func providerToApiRulePrecedence(provided int64, ruleName string) int64 {
return provided*rulePrecedenceFactor + int64(hashCodeString(ruleName))%rulePrecedenceFactor
}
diff --git a/internal/provider/resource_cloudflare_teams_rules_test.go b/internal/provider/resource_cloudflare_teams_rules_test.go
index b1ec7436a7..678185c566 100644
--- a/internal/provider/resource_cloudflare_teams_rules_test.go
+++ b/internal/provider/resource_cloudflare_teams_rules_test.go
@@ -43,6 +43,8 @@ func TestAccCloudflareTeamsRuleBasic(t *testing.T) {
resource.TestCheckResourceAttr(name, "rule_settings.0.block_page_enabled", "false"),
resource.TestCheckResourceAttr(name, "rule_settings.0.block_page_reason", "cuz"),
resource.TestCheckResourceAttr(name, "rule_settings.0.insecure_disable_dnssec_validation", "false"),
+ resource.TestCheckResourceAttr(name, "rule_settings.0.egress.0.ipv4", "203.0.113.1"),
+ resource.TestCheckResourceAttr(name, "rule_settings.0.egress.0.ipv6", "2001:db8::/32"),
),
},
},
@@ -63,6 +65,10 @@ resource "cloudflare_teams_rule" "%[1]s" {
block_page_enabled = false
block_page_reason = "cuz"
insecure_disable_dnssec_validation = false
+ egress {
+ ipv4 = "203.0.113.1"
+ ipv6 = "2001:db8::/32"
+ }
}
}
`, rnd, accountID)
diff --git a/internal/provider/schema_cloudflare_teams_rules.go b/internal/provider/schema_cloudflare_teams_rules.go
index 1cd8706753..36710c8289 100644
--- a/internal/provider/schema_cloudflare_teams_rules.go
+++ b/internal/provider/schema_cloudflare_teams_rules.go
@@ -140,6 +140,33 @@ var teamsRuleSettings = map[string]*schema.Schema{
Optional: true,
Description: "Disable DNSSEC validation (must be Allow rule).",
},
+ "egress": {
+ Type: schema.TypeList,
+ MaxItems: 1,
+ Optional: true,
+ Elem: &schema.Resource{
+ Schema: egressSettings,
+ },
+ Description: "Configure how Proxy traffic egresses. Can be set for rules with Egress action and Egress filter. Can be omitted to indicate local egress via Warp IPs.",
+ },
+}
+
+var egressSettings = map[string]*schema.Schema{
+ "ipv6": {
+ Type: schema.TypeString,
+ Required: true,
+ Description: "The IPv6 range to be used for egress.",
+ },
+ "ipv4": {
+ Type: schema.TypeString,
+ Required: true,
+ Description: "The IPv4 address to be used for egress.",
+ },
+ "ipv4_fallback": {
+ Type: schema.TypeString,
+ Optional: true,
+ Description: "The IPv4 address to be used for egress in the event of an error egressing with the primary IPv4. Can be '0.0.0.0' to indicate local egreass via Warp IPs.",
+ },
}
var teamsL4OverrideSettings = map[string]*schema.Schema{