Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions docs/resources/alb_waf_managed_rule_set.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,19 @@ resource "stackit_alb_waf_managed_rule_set" "example" {
name = "example-managed-rule-set"
type = "TYPE_OWASP_CRS"
}

# Set individual rules to a different mode, keyed by rule ID. Only the
# listed rules are managed; a rule removed from the map goes back to
# MODE_ENABLED.
resource "stackit_alb_waf_managed_rule_set" "with_rule_modes" {
project_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
name = "example-managed-rule-set-modes"
type = "TYPE_OWASP_CRS"
rule_modes = {
"911100" = "MODE_LOG_ONLY" # allow PUT and DELETE through method enforcement
"920450" = "MODE_DISABLED"
}
}
```

<!-- schema generated by tfplugindocs -->
Expand All @@ -32,6 +45,7 @@ resource "stackit_alb_waf_managed_rule_set" "example" {
### Optional

- `region` (String) STACKIT region name the resource is located in. If not defined, the provider region is used.
- `rule_modes` (Map of String) Modes for individual rules of the rule set, keyed by rule ID (e.g. `911100`). Only the listed rules are managed; every other rule keeps the mode the API gives it. A rule removed from this map is set back to `MODE_ENABLED`. Possible values are: `MODE_ENABLED`, `MODE_DISABLED`, `MODE_LOG_ONLY`.

### Read-Only

Expand Down
13 changes: 13 additions & 0 deletions examples/resources/stackit_alb_waf_managed_rule_set/resource.tf
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,16 @@ resource "stackit_alb_waf_managed_rule_set" "example" {
name = "example-managed-rule-set"
type = "TYPE_OWASP_CRS"
}

# Set individual rules to a different mode, keyed by rule ID. Only the
# listed rules are managed; a rule removed from the map goes back to
# MODE_ENABLED.
resource "stackit_alb_waf_managed_rule_set" "with_rule_modes" {
project_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
name = "example-managed-rule-set-modes"
type = "TYPE_OWASP_CRS"
rule_modes = {
"911100" = "MODE_LOG_ONLY" # allow PUT and DELETE through method enforcement
"920450" = "MODE_DISABLED"
}
}
57 changes: 57 additions & 0 deletions stackit/internal/services/albwaf/albwaf_acc_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,9 @@ var (
//go:embed testdata/managed-rule-set.tf
managedRuleSetConfig string

//go:embed testdata/managed-rule-set-rule-modes.tf
managedRuleSetRuleModesConfig string

//go:embed testdata/resource-max.tf
wafMaxConfig string

Expand Down Expand Up @@ -467,6 +470,60 @@ func TestAccManagedRuleSet(t *testing.T) {
})
}

func testManagedRuleSetRuleModes(modes map[string]string) config.Variables {

@SerseusWasTaken SerseusWasTaken Oct 22, 2026 •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this should be named the max test case now, the other MRS test the min, similar to other resources' acc tests do it.
Also, you can copy the testManagedRuleSet variable for this test as you do a few lines below, but you should probably use a different name since they may collide

vars := config.Variables{}
maps.Copy(vars, testManagedRuleSet)
values := map[string]config.Variable{}
for rule, mode := range modes {
values[rule] = config.StringVariable(mode)
}
vars["rule_modes"] = config.MapVariable(values)
return vars
}

// ruleModeInGroups checks the mode of a rule in the computed groups inventory.
func ruleModeInGroups(group, rule, mode string) resource.TestCheckFunc {
return resource.TestCheckResourceAttr("stackit_alb_waf_managed_rule_set.managed_rule_set", fmt.Sprintf("groups.%s.rules.%s.mode", group, rule), mode)
}

func TestAccManagedRuleSetRuleModes(t *testing.T) {
cfg := fmt.Sprintf("%s\n%s", testutil.NewConfigBuilder().BuildProviderConfig(), managedRuleSetRuleModesConfig)
resource.Test(t, resource.TestCase{
ProtoV6ProviderFactories: testutil.TestAccProtoV6ProviderFactories,
CheckDestroy: testAccCheckDestroy,
Steps: []resource.TestStep{
// Creation with rule modes
{
ConfigVariables: testManagedRuleSetRuleModes(map[string]string{"911100": "MODE_LOG_ONLY", "920450": "MODE_LOG_ONLY"}),
Config: cfg,
Check: resource.ComposeAggregateTestCheckFunc(
resource.TestCheckResourceAttr("stackit_alb_waf_managed_rule_set.managed_rule_set", "rule_modes.911100", "MODE_LOG_ONLY"),
resource.TestCheckResourceAttr("stackit_alb_waf_managed_rule_set.managed_rule_set", "rule_modes.920450", "MODE_LOG_ONLY"),
ruleModeInGroups("911", "911100", "MODE_LOG_ONLY"),
ruleModeInGroups("920", "920450", "MODE_LOG_ONLY"),
),
},
// Change in place: one rule removed (back to enabled), one changed
{
ConfigVariables: testManagedRuleSetRuleModes(map[string]string{"920450": "MODE_DISABLED"}),
Config: cfg,
ConfigPlanChecks: resource.ConfigPlanChecks{
PreApply: []plancheck.PlanCheck{
plancheck.ExpectResourceAction("stackit_alb_waf_managed_rule_set.managed_rule_set", plancheck.ResourceActionUpdate),
},
},
Check: resource.ComposeAggregateTestCheckFunc(
resource.TestCheckNoResourceAttr("stackit_alb_waf_managed_rule_set.managed_rule_set", "rule_modes.911100"),
resource.TestCheckResourceAttr("stackit_alb_waf_managed_rule_set.managed_rule_set", "rule_modes.920450", "MODE_DISABLED"),
ruleModeInGroups("911", "911100", "MODE_ENABLED"),
ruleModeInGroups("920", "920450", "MODE_DISABLED"),
),
},
// Deletion is done by the framework implicitly
},
})
}

func TestAccWafConfigurationMin(t *testing.T) {
resource.Test(t, resource.TestCase{
ProtoV6ProviderFactories: testutil.TestAccProtoV6ProviderFactories,
Expand Down
Loading