diff --git a/docs/resources/firewall_config.md b/docs/resources/firewall_config.md index 96d16aa2..8fd15565 100644 --- a/docs/resources/firewall_config.md +++ b/docs/resources/firewall_config.md @@ -158,7 +158,7 @@ resource "vercel_firewall_config" "managed" { gen = { action = "deny" } } - bot_filter { + bot_protection { action = "log" active = true } @@ -241,7 +241,8 @@ Read-Only: Optional: - `ai_bots` (Block, Optional) Enable the ai_bots managed ruleset and select action (see [below for nested schema](#nestedblock--managed_rulesets--ai_bots)) -- `bot_filter` (Block, Optional) Enable the bot_filter managed ruleset and select action (see [below for nested schema](#nestedblock--managed_rulesets--bot_filter)) +- `bot_filter` (Block, Optional, Deprecated) DEPRECATED: Use bot_protection instead. This block will be removed in a future release. (see [below for nested schema](#nestedblock--managed_rulesets--bot_filter)) +- `bot_protection` (Block, Optional) Enable the bot_protection managed ruleset and select action (see [below for nested schema](#nestedblock--managed_rulesets--bot_protection)) - `owasp` (Block, Optional) Enable the owasp managed rulesets and select ruleset behaviors (see [below for nested schema](#nestedblock--managed_rulesets--owasp)) @@ -262,6 +263,15 @@ Optional: - `active` (Boolean) + +### Nested Schema for `managed_rulesets.bot_protection` + +Optional: + +- `action` (String) +- `active` (Boolean) + + ### Nested Schema for `managed_rulesets.owasp` diff --git a/examples/resources/vercel_firewall_config/resource.tf b/examples/resources/vercel_firewall_config/resource.tf index 8c45d2a3..e42e9754 100644 --- a/examples/resources/vercel_firewall_config/resource.tf +++ b/examples/resources/vercel_firewall_config/resource.tf @@ -143,7 +143,7 @@ resource "vercel_firewall_config" "managed" { gen = { action = "deny" } } - bot_filter { + bot_protection { action = "log" active = true } diff --git a/vercel/resource_firewall_config.go b/vercel/resource_firewall_config.go index ec4e9101..502c8e4e 100644 --- a/vercel/resource_firewall_config.go +++ b/vercel/resource_firewall_config.go @@ -5,6 +5,7 @@ import ( "fmt" "github.com/hashicorp/terraform-plugin-framework-validators/listvalidator" + "github.com/hashicorp/terraform-plugin-framework-validators/objectvalidator" "github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator" "github.com/hashicorp/terraform-plugin-framework/attr" "github.com/hashicorp/terraform-plugin-framework/path" @@ -170,8 +171,26 @@ Define Custom Rules to shape the way your traffic is handled by the Vercel Edge }, }, }, + "bot_protection": schema.SingleNestedBlock{ + Description: "Enable the bot_protection managed ruleset and select action", + Validators: []validator.Object{ + objectvalidator.ConflictsWith(path.MatchRelative().AtParent().AtName("bot_filter")), + }, + Attributes: map[string]schema.Attribute{ + "active": schema.BoolAttribute{ + Optional: true, + }, + "action": schema.StringAttribute{ + Optional: true, + }, + }, + }, "bot_filter": schema.SingleNestedBlock{ - Description: "Enable the bot_filter managed ruleset and select action", + Description: "DEPRECATED: Use bot_protection instead. This block will be removed in a future release.", + DeprecationMessage: "The 'bot_filter' block is deprecated. Please use 'bot_protection' instead.", + Validators: []validator.Object{ + objectvalidator.ConflictsWith(path.MatchRelative().AtParent().AtName("bot_protection")), + }, Attributes: map[string]schema.Attribute{ "active": schema.BoolAttribute{ Optional: true, @@ -465,9 +484,10 @@ type FirewallConfig struct { } type FirewallManagedRulesets struct { - OWASP *CRSRule `tfsdk:"owasp"` - BotFilter *BotFilterConfig `tfsdk:"bot_filter"` - AiBots *AiBotsConfig `tfsdk:"ai_bots"` + OWASP *CRSRule `tfsdk:"owasp"` + BotProtection *BotProtectionConfig `tfsdk:"bot_protection"` + BotFilter *BotFilterConfig `tfsdk:"bot_filter"` // Deprecated + AiBots *AiBotsConfig `tfsdk:"ai_bots"` } type CRSRule struct { @@ -503,6 +523,11 @@ type CRSRuleConfig struct { Action types.String `tfsdk:"action"` } +type BotProtectionConfig struct { + Active types.Bool `tfsdk:"active"` + Action types.String `tfsdk:"action"` +} + type BotFilterConfig struct { Active types.Bool `tfsdk:"active"` Action types.String `tfsdk:"action"` @@ -879,13 +904,22 @@ func fromClient(conf client.FirewallConfig, state FirewallConfig) (FirewallConfi cfg.ManagedRulesets.OWASP = fromCRS(conf.CRS, state.ManagedRulesets) } - botFilter, botFilterExist := conf.ManagedRulesets["bot_filter"] - if botFilterExist { - botFilterConf := &BotFilterConfig{ - Active: types.BoolValue(botFilter.Active), - Action: types.StringValue(botFilter.Action), + if state.ManagedRulesets != nil && state.ManagedRulesets.BotProtection != nil { + botFilter, botFilterExist := conf.ManagedRulesets["bot_filter"] + if botFilterExist { + cfg.ManagedRulesets.BotProtection = &BotProtectionConfig{ + Active: types.BoolValue(botFilter.Active), + Action: types.StringValue(botFilter.Action), + } + } + } else if state.ManagedRulesets != nil && state.ManagedRulesets.BotFilter != nil { + botFilter, botFilterExist := conf.ManagedRulesets["bot_filter"] + if botFilterExist { + cfg.ManagedRulesets.BotFilter = &BotFilterConfig{ + Active: types.BoolValue(botFilter.Active), + Action: types.StringValue(botFilter.Action), + } } - cfg.ManagedRulesets.BotFilter = botFilterConf } aiBots, aiBotsExist := conf.ManagedRulesets["ai_bots"] @@ -925,8 +959,15 @@ func (f *FirewallConfig) toClient() (client.FirewallConfig, error) { } } + botProtection := f.ManagedRulesets.BotProtection botFilter := f.ManagedRulesets.BotFilter - if botFilter != nil { + + if botProtection != nil { + conf.ManagedRulesets["bot_protection"] = client.ManagedRule{ + Active: botProtection.Active.ValueBool(), + Action: botProtection.Action.ValueString(), + } + } else if botFilter != nil { conf.ManagedRulesets["bot_filter"] = client.ManagedRule{ Active: botFilter.Active.ValueBool(), Action: botFilter.Action.ValueString(), diff --git a/vercel/resource_firewall_config_test.go b/vercel/resource_firewall_config_test.go index dccfb04f..9808106e 100644 --- a/vercel/resource_firewall_config_test.go +++ b/vercel/resource_firewall_config_test.go @@ -170,12 +170,12 @@ func TestAcc_FirewallConfigResource(t *testing.T) { "ip_rules.rule.2.hostname", "*"), resource.TestCheckResourceAttr( - "vercel_firewall_config.botfilter", - "managed_rulesets.bot_filter.action", + "vercel_firewall_config.botprotection", + "managed_rulesets.bot_protection.action", "challenge"), resource.TestCheckResourceAttr( - "vercel_firewall_config.botfilter", - "managed_rulesets.bot_filter.active", + "vercel_firewall_config.botprotection", + "managed_rulesets.bot_protection.active", "true"), resource.TestCheckResourceAttr( "vercel_firewall_config.aibots", @@ -204,8 +204,8 @@ func TestAcc_FirewallConfigResource(t *testing.T) { }, { ImportState: true, - ResourceName: "vercel_firewall_config.botfilter", - ImportStateIdFunc: getFirewallImportID("vercel_firewall_config.botfilter"), + ResourceName: "vercel_firewall_config.botprotection", + ImportStateIdFunc: getFirewallImportID("vercel_firewall_config.botprotection"), }, { ImportState: true, @@ -356,12 +356,12 @@ func TestAcc_FirewallConfigResource(t *testing.T) { "ip_rules.rule.2.hostname", "*"), resource.TestCheckResourceAttr( - "vercel_firewall_config.botfilter", - "managed_rulesets.bot_filter.action", + "vercel_firewall_config.botprotection", + "managed_rulesets.bot_protection.action", "deny"), resource.TestCheckResourceAttr( - "vercel_firewall_config.botfilter", - "managed_rulesets.bot_filter.active", + "vercel_firewall_config.botprotection", + "managed_rulesets.bot_protection.active", "false"), resource.TestCheckResourceAttr( "vercel_firewall_config.aibots", @@ -521,15 +521,15 @@ resource "vercel_firewall_config" "ips" { } } -resource "vercel_project" "botfilter" { - name = "test-acc-%[1]s-botfilter" +resource "vercel_project" "botprotection" { + name = "test-acc-%[1]s-botprotection" } -resource "vercel_firewall_config" "botfilter" { - project_id = vercel_project.botfilter.id +resource "vercel_firewall_config" "botprotection" { + project_id = vercel_project.botprotection.id managed_rulesets { - bot_filter { + bot_protection { action = "challenge" active = true } @@ -714,15 +714,15 @@ resource "vercel_firewall_config" "neg" { } } -resource "vercel_project" "botfilter" { - name = "test-acc-%[1]s-botfilter" +resource "vercel_project" "botprotection" { + name = "test-acc-%[1]s-botprotection" } -resource "vercel_firewall_config" "botfilter" { - project_id = vercel_project.botfilter.id +resource "vercel_firewall_config" "botprotection" { + project_id = vercel_project.botprotection.id managed_rulesets { - bot_filter { + bot_protection { action = "deny" active = false }