Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

aws_wafregional_web_acl + aws_web_acl rule group support #5053

Merged
Merged
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
51 changes: 41 additions & 10 deletions aws/resource_aws_waf_web_acl.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,20 @@ func resourceAwsWafWebAcl() *schema.Resource {
Schema: map[string]*schema.Schema{
"action": &schema.Schema{
Type: schema.TypeSet,
Required: true,
Optional: true,
MaxItems: 1,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"type": &schema.Schema{
Type: schema.TypeString,
Required: true,
},
},
},
},
"override_action": &schema.Schema{
Type: schema.TypeSet,
Optional: true,
MaxItems: 1,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
Expand All @@ -72,6 +85,7 @@ func resourceAwsWafWebAcl() *schema.Resource {
ValidateFunc: validation.StringInSlice([]string{
waf.WafRuleTypeRegular,
waf.WafRuleTypeRateBased,
waf.WafRuleTypeGroup,
}, false),
},
"rule_id": &schema.Schema{
Expand Down Expand Up @@ -184,16 +198,33 @@ func updateWebAclResource(d *schema.ResourceData, meta interface{}, ChangeAction
rules := d.Get("rules").(*schema.Set)
for _, rule := range rules.List() {
aclRule := rule.(map[string]interface{})
action := aclRule["action"].(*schema.Set).List()[0].(map[string]interface{})
aclRuleUpdate := &waf.WebACLUpdate{
Action: aws.String(ChangeAction),
ActivatedRule: &waf.ActivatedRule{
Priority: aws.Int64(int64(aclRule["priority"].(int))),
RuleId: aws.String(aclRule["rule_id"].(string)),
Type: aws.String(aclRule["type"].(string)),
Action: &waf.WafAction{Type: aws.String(action["type"].(string))},
},

var aclRuleUpdate *waf.WebACLUpdate
switch aclRule["type"].(string) {
case waf.WafRuleTypeGroup:
overrideAction := aclRule["override_action"].(*schema.Set).List()[0].(map[string]interface{})
aclRuleUpdate = &waf.WebACLUpdate{
Action: aws.String(ChangeAction),
ActivatedRule: &waf.ActivatedRule{
Priority: aws.Int64(int64(aclRule["priority"].(int))),
RuleId: aws.String(aclRule["rule_id"].(string)),
Type: aws.String(aclRule["type"].(string)),
OverrideAction: &waf.WafOverrideAction{Type: aws.String(overrideAction["type"].(string))},
},
}
default:
action := aclRule["action"].(*schema.Set).List()[0].(map[string]interface{})
aclRuleUpdate = &waf.WebACLUpdate{
Action: aws.String(ChangeAction),
ActivatedRule: &waf.ActivatedRule{
Priority: aws.Int64(int64(aclRule["priority"].(int))),
RuleId: aws.String(aclRule["rule_id"].(string)),
Type: aws.String(aclRule["type"].(string)),
Action: &waf.WafAction{Type: aws.String(action["type"].(string))},
},
}
}

req.Updates = append(req.Updates, aclRuleUpdate)
}
return conn.UpdateWebACL(req)
Expand Down
54 changes: 54 additions & 0 deletions aws/resource_aws_waf_web_acl_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,35 @@ func TestAccAWSWafWebAcl_basic(t *testing.T) {
})
}

func TestAccAWSWafWebAcl_group(t *testing.T) {
var v waf.WebACL
wafAclName := fmt.Sprintf("wafaclgroup%s", acctest.RandString(5))

resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckAWSWafWebAclDestroy,
Steps: []resource.TestStep{
resource.TestStep{
Config: testAccAWSWafWebAclGroupConfig(wafAclName),
Check: resource.ComposeTestCheckFunc(
testAccCheckAWSWafWebAclExists("aws_waf_web_acl.waf_acl", &v),
resource.TestCheckResourceAttr(
"aws_waf_web_acl.waf_acl", "default_action.#", "1"),
resource.TestCheckResourceAttr(
"aws_waf_web_acl.waf_acl", "default_action.4234791575.type", "ALLOW"),
resource.TestCheckResourceAttr(
"aws_waf_web_acl.waf_acl", "name", wafAclName),
resource.TestCheckResourceAttr(
"aws_waf_web_acl.waf_acl", "rules.#", "1"),
resource.TestCheckResourceAttr(
"aws_waf_web_acl.waf_acl", "metric_name", wafAclName),
),
},
},
})
}

func TestAccAWSWafWebAcl_changeNameForceNew(t *testing.T) {
var before, after waf.WebACL
wafAclName := fmt.Sprintf("wafacl%s", acctest.RandString(5))
Expand Down Expand Up @@ -294,6 +323,31 @@ resource "aws_waf_web_acl" "waf_acl" {
}`, name, name, name, name, name)
}

func testAccAWSWafWebAclGroupConfig(name string) string {
return fmt.Sprintf(`

resource "aws_waf_rule_group" "wafrulegroup" {
name = "%s"
metric_name = "%s"
}
resource "aws_waf_web_acl" "waf_acl" {
depends_on = ["aws_waf_rule_group.wafrulegroup"]
name = "%s"
metric_name = "%s"
default_action {
type = "ALLOW"
}
rules {
override_action {
type = "NONE"
}
type = "GROUP"
priority = 1
rule_id = "${aws_waf_rule_group.wafrulegroup.id}"
}
}`, name, name, name, name)
}

func testAccAWSWafWebAclConfigChangeName(name string) string {
return fmt.Sprintf(`resource "aws_waf_ipset" "ipset" {
name = "%s"
Expand Down
60 changes: 49 additions & 11 deletions aws/resource_aws_wafregional_web_acl.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,20 @@ func resourceAwsWafRegionalWebAcl() *schema.Resource {
Schema: map[string]*schema.Schema{
"action": &schema.Schema{
Type: schema.TypeList,
Required: true,
Optional: true,
MaxItems: 1,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"type": &schema.Schema{
Type: schema.TypeString,
Required: true,
},
},
},
},
"override_action": &schema.Schema{
Type: schema.TypeList,
Optional: true,
MaxItems: 1,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
Expand All @@ -71,6 +84,7 @@ func resourceAwsWafRegionalWebAcl() *schema.Resource {
ValidateFunc: validation.StringInSlice([]string{
waf.WafRuleTypeRegular,
waf.WafRuleTypeRateBased,
waf.WafRuleTypeGroup,
}, false),
},
"rule_id": &schema.Schema{
Expand Down Expand Up @@ -227,11 +241,21 @@ func flattenDefaultActionWR(n *waf.WafAction) []map[string]interface{} {
func flattenWafWebAclRules(ts []*waf.ActivatedRule) []interface{} {
out := make([]interface{}, len(ts), len(ts))
for i, r := range ts {
actionMap := map[string]interface{}{
"type": *r.Action.Type,
}
m := make(map[string]interface{})
m["action"] = []interface{}{actionMap}

switch *r.Type {
case waf.WafRuleTypeGroup:
actionMap := map[string]interface{}{
"type": *r.OverrideAction.Type,
}
m["override_action"] = []interface{}{actionMap}
default:
actionMap := map[string]interface{}{
"type": *r.Action.Type,
}
m["action"] = []interface{}{actionMap}
}

m["priority"] = *r.Priority
m["rule_id"] = *r.RuleId
m["type"] = *r.Type
Expand All @@ -241,13 +265,27 @@ func flattenWafWebAclRules(ts []*waf.ActivatedRule) []interface{} {
}

func expandWafWebAclUpdate(updateAction string, aclRule map[string]interface{}) *waf.WebACLUpdate {
ruleAction := aclRule["action"].([]interface{})[0].(map[string]interface{})
var rule *waf.ActivatedRule

switch aclRule["type"].(string) {
case waf.WafRuleTypeGroup:
ruleAction := aclRule["override_action"].([]interface{})[0].(map[string]interface{})

rule := &waf.ActivatedRule{
Action: &waf.WafAction{Type: aws.String(ruleAction["type"].(string))},
Priority: aws.Int64(int64(aclRule["priority"].(int))),
RuleId: aws.String(aclRule["rule_id"].(string)),
Type: aws.String(aclRule["type"].(string)),
rule = &waf.ActivatedRule{
OverrideAction: &waf.WafOverrideAction{Type: aws.String(ruleAction["type"].(string))},
Priority: aws.Int64(int64(aclRule["priority"].(int))),
RuleId: aws.String(aclRule["rule_id"].(string)),
Type: aws.String(aclRule["type"].(string)),
}
default:
ruleAction := aclRule["action"].([]interface{})[0].(map[string]interface{})

rule = &waf.ActivatedRule{
Action: &waf.WafAction{Type: aws.String(ruleAction["type"].(string))},
Priority: aws.Int64(int64(aclRule["priority"].(int))),
RuleId: aws.String(aclRule["rule_id"].(string)),
Type: aws.String(aclRule["type"].(string)),
}
}

update := &waf.WebACLUpdate{
Expand Down
63 changes: 59 additions & 4 deletions aws/resource_aws_wafregional_web_acl_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,35 @@ func TestAccAWSWafRegionalWebAcl_createRateBased(t *testing.T) {
})
}

func TestAccAWSWafRegionalWebAcl_createGroup(t *testing.T) {
var v waf.WebACL
wafAclName := fmt.Sprintf("wafacl%s", acctest.RandString(5))

resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckAWSWafRegionalWebAclDestroy,
Steps: []resource.TestStep{
resource.TestStep{
Config: testAccAWSWafRegionalWebAclConfigGroup(wafAclName),
Check: resource.ComposeTestCheckFunc(
testAccCheckAWSWafRegionalWebAclExists("aws_wafregional_web_acl.waf_acl", &v),
resource.TestCheckResourceAttr(
"aws_wafregional_web_acl.waf_acl", "default_action.#", "1"),
resource.TestCheckResourceAttr(
"aws_wafregional_web_acl.waf_acl", "default_action.0.type", "ALLOW"),
resource.TestCheckResourceAttr(
"aws_wafregional_web_acl.waf_acl", "name", wafAclName),
resource.TestCheckResourceAttr(
"aws_wafregional_web_acl.waf_acl", "rule.#", "1"),
resource.TestCheckResourceAttr(
"aws_wafregional_web_acl.waf_acl", "metric_name", wafAclName),
),
},
},
})
}

func TestAccAWSWafRegionalWebAcl_changeNameForceNew(t *testing.T) {
var before, after waf.WebACL
wafAclName := fmt.Sprintf("wafacl%s", acctest.RandString(5))
Expand Down Expand Up @@ -266,10 +295,11 @@ func computeWafRegionalWebAclRuleIndex(ruleId **string, priority int, ruleType s
"type": actionType,
}
m := map[string]interface{}{
"rule_id": **ruleId,
"type": ruleType,
"priority": priority,
"action": []interface{}{actionMap},
"rule_id": **ruleId,
"type": ruleType,
"priority": priority,
"action": []interface{}{actionMap},
"override_action": []interface{}{},
}

f := schema.HashResource(ruleResource)
Expand Down Expand Up @@ -432,6 +462,31 @@ resource "aws_wafregional_web_acl" "waf_acl" {
}`, name, name, name, name)
}

func testAccAWSWafRegionalWebAclConfigGroup(name string) string {
return fmt.Sprintf(`

resource "aws_wafregional_rule_group" "wafrulegroup" {
name = "%s"
metric_name = "%s"
}

resource "aws_wafregional_web_acl" "waf_acl" {
name = "%s"
metric_name = "%s"
default_action {
type = "ALLOW"
}
rule {
override_action {
type = "NONE"
}
priority = 1
type = "GROUP"
rule_id = "${aws_wafregional_rule_group.wafrulegroup.id}" # todo
}
}`, name, name, name, name)
}

func testAccAWSWafRegionalWebAclConfig_changeName(name string) string {
return fmt.Sprintf(`
resource "aws_wafregional_rule" "wafrule" {
Expand Down
5 changes: 3 additions & 2 deletions website/docs/r/waf_web_acl.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -80,11 +80,12 @@ See [docs](http://docs.aws.amazon.com/waf/latest/APIReference/API_ActivatedRule.
#### Arguments

* `action` - (Required) The action that CloudFront or AWS WAF takes when a web request matches the conditions in the rule.
e.g. `ALLOW`, `BLOCK` or `COUNT`
e.g. `ALLOW`, `BLOCK` or `COUNT`. Not used if `type` is `GROUP`.
* `override_action` - (Required) Override the action that a group requests CloudFront or AWS WAF takes when a web request matches the conditions in the rule. Only used if `type` is `GROUP`.
* `priority` - (Required) Specifies the order in which the rules in a WebACL are evaluated.
Rules with a lower value are evaluated before rules with a higher value.
* `rule_id` - (Required) ID of the associated [rule](/docs/providers/aws/r/waf_rule.html)
* `type` - (Optional) The rule type, either `REGULAR`, as defined by [Rule](http://docs.aws.amazon.com/waf/latest/APIReference/API_Rule.html), or `RATE_BASED`, as defined by [RateBasedRule](http://docs.aws.amazon.com/waf/latest/APIReference/API_RateBasedRule.html). The default is REGULAR. If you add a RATE_BASED rule, you need to set `type` as `RATE_BASED`.
* `type` - (Optional) The rule type, either `REGULAR`, as defined by [Rule](http://docs.aws.amazon.com/waf/latest/APIReference/API_Rule.html), `RATE_BASED`, as defined by [RateBasedRule](http://docs.aws.amazon.com/waf/latest/APIReference/API_RateBasedRule.html), or `GROUP`, as defined by [RuleGroup](https://docs.aws.amazon.com/waf/latest/APIReference/API_RuleGroup.html). The default is REGULAR. If you add a RATE_BASED rule, you need to set `type` as `RATE_BASED`. If you add a GROUP rule, you need to set `type` as `GROUP`.

## Attributes Reference

Expand Down
5 changes: 3 additions & 2 deletions website/docs/r/wafregional_web_acl.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -70,11 +70,12 @@ See [docs](https://docs.aws.amazon.com/waf/latest/APIReference/API_regional_Acti

#### Arguments

* `action` - (Required) The action that CloudFront or AWS WAF takes when a web request matches the conditions in the rule.
* `action` - (Required) The action that CloudFront or AWS WAF takes when a web request matches the conditions in the rule. Not used if `type` is `GROUP`.
* `override_action` - (Required) Override the action that a group requests CloudFront or AWS WAF takes when a web request matches the conditions in the rule. Only used if `type` is `GROUP`.
* `priority` - (Required) Specifies the order in which the rules in a WebACL are evaluated.
Rules with a lower value are evaluated before rules with a higher value.
* `rule_id` - (Required) ID of the associated [rule](/docs/providers/aws/r/wafregional_rule.html)
* `type` - (Optional) The rule type, either `REGULAR`, as defined by [Rule](http://docs.aws.amazon.com/waf/latest/APIReference/API_Rule.html), or `RATE_BASED`, as defined by [RateBasedRule](http://docs.aws.amazon.com/waf/latest/APIReference/API_RateBasedRule.html). The default is REGULAR. If you add a RATE_BASED rule, you need to set `type` as `RATE_BASED`.
* `type` - (Optional) The rule type, either `REGULAR`, as defined by [Rule](http://docs.aws.amazon.com/waf/latest/APIReference/API_Rule.html), `RATE_BASED`, as defined by [RateBasedRule](http://docs.aws.amazon.com/waf/latest/APIReference/API_RateBasedRule.html), or `GROUP`, as defined by [RuleGroup](https://docs.aws.amazon.com/waf/latest/APIReference/API_RuleGroup.html). The default is REGULAR. If you add a RATE_BASED rule, you need to set `type` as `RATE_BASED`. If you add a GROUP rule, you need to set `type` as `GROUP`.

### `default_action` / `action`

Expand Down