From a0e6f777ef4e0e8e0de78ae6f3a0efd867afd0ca Mon Sep 17 00:00:00 2001 From: Adrien Date: Thu, 23 Feb 2023 14:07:05 +0100 Subject: [PATCH 01/12] Add captcha config to wafv2 --- internal/service/wafv2/flex.go | 47 +++++++++++++++++++ internal/service/wafv2/rule_group.go | 2 + internal/service/wafv2/schemas.go | 25 ++++++++++ internal/service/wafv2/web_acl.go | 7 +++ internal/service/wafv2/web_acl_test.go | 16 +++++++ website/docs/r/wafv2_rule_group.html.markdown | 25 ++++++++++ 6 files changed, 122 insertions(+) diff --git a/internal/service/wafv2/flex.go b/internal/service/wafv2/flex.go index 1ddbf4da499..985c1accffd 100644 --- a/internal/service/wafv2/flex.go +++ b/internal/service/wafv2/flex.go @@ -35,6 +35,7 @@ func expandRule(m map[string]interface{}) *wafv2.Rule { Action: expandRuleAction(m["action"].([]interface{})), Statement: expandRuleGroupRootStatement(m["statement"].([]interface{})), VisibilityConfig: expandVisibilityConfig(m["visibility_config"].([]interface{})), + CaptchaConfig: expandCaptchaConfig(m["captcha_config"].([]interface{})), } if v, ok := m["rule_label"].(*schema.Set); ok && v.Len() > 0 { @@ -44,6 +45,32 @@ func expandRule(m map[string]interface{}) *wafv2.Rule { return rule } +func expandCaptchaConfig(l []interface{}) *wafv2.CaptchaConfig { + configuration := &wafv2.CaptchaConfig{} + + if len(l) == 0 || l[0] == nil { + return configuration + } + + m := l[0].(map[string]interface{}) + if v, ok := m["immunity_time_property"]; ok { + inner := v.([]interface{}) + if len(inner) == 0 || inner[0] == nil { + return configuration + } + + m = inner[0].(map[string]interface{}) + + if v, ok := m["immunity_time"]; ok { + configuration.ImmunityTimeProperty = &wafv2.ImmunityTimeProperty{ + ImmunityTime: aws.Int64(int64(v.(int))), + } + } + } + + return configuration +} + func expandRuleLabels(l []interface{}) []*wafv2.Label { if len(l) == 0 || l[0] == nil { return nil @@ -838,6 +865,7 @@ func expandWebACLRule(m map[string]interface{}) *wafv2.Rule { OverrideAction: expandOverrideAction(m["override_action"].([]interface{})), Statement: expandWebACLRootStatement(m["statement"].([]interface{})), VisibilityConfig: expandVisibilityConfig(m["visibility_config"].([]interface{})), + CaptchaConfig: expandCaptchaConfig(m["captcha_config"].([]interface{})), } if v, ok := m["rule_label"].(*schema.Set); ok && v.Len() > 0 { @@ -1116,6 +1144,7 @@ func flattenRules(r []*wafv2.Rule) interface{} { m["rule_label"] = flattenRuleLabels(rule.RuleLabels) m["statement"] = flattenRuleGroupRootStatement(rule.Statement) m["visibility_config"] = flattenVisibilityConfig(rule.VisibilityConfig) + m["captcha_config"] = flattenCaptchaConfig(rule.CaptchaConfig) out[i] = m } @@ -1193,6 +1222,23 @@ func flattenCaptcha(a *wafv2.CaptchaAction) []interface{} { return []interface{}{m} } +func flattenCaptchaConfig(config *wafv2.CaptchaConfig) interface{} { + if config == nil { + return []interface{}{} + } + if config.ImmunityTimeProperty == nil { + return []interface{}{} + } + + m := map[string]interface{}{ + "immunity_time_property": []interface{}{map[string]interface{}{ + "immunity_time": aws.Int64Value(config.ImmunityTimeProperty.ImmunityTime), + }}, + } + + return []interface{}{m} +} + func flattenChallenge(a *wafv2.ChallengeAction) []interface{} { if a == nil { return []interface{}{} @@ -1856,6 +1902,7 @@ func flattenWebACLRules(r []*wafv2.Rule) interface{} { m["rule_label"] = flattenRuleLabels(rule.RuleLabels) m["statement"] = flattenWebACLRootStatement(rule.Statement) m["visibility_config"] = flattenVisibilityConfig(rule.VisibilityConfig) + m["captcha_config"] = flattenCaptchaConfig(rule.CaptchaConfig) out[i] = m } diff --git a/internal/service/wafv2/rule_group.go b/internal/service/wafv2/rule_group.go index 80b4226e6ca..4ad09567254 100644 --- a/internal/service/wafv2/rule_group.go +++ b/internal/service/wafv2/rule_group.go @@ -110,6 +110,7 @@ func ResourceRuleGroup() *schema.Resource { "rule_label": ruleLabelsSchema(), "statement": ruleGroupRootStatementSchema(ruleGroupRootStatementSchemaLevel), "visibility_config": visibilityConfigSchema(), + "captcha_config": outerCaptchaConfigSchema(), }, }, }, @@ -122,6 +123,7 @@ func ResourceRuleGroup() *schema.Resource { "tags": tftags.TagsSchema(), "tags_all": tftags.TagsSchemaComputed(), "visibility_config": visibilityConfigSchema(), + "captcha_config": outerCaptchaConfigSchema(), }, CustomizeDiff: verify.SetTagsDiff, diff --git a/internal/service/wafv2/schemas.go b/internal/service/wafv2/schemas.go index 830492766b2..30fbe73af8a 100644 --- a/internal/service/wafv2/schemas.go +++ b/internal/service/wafv2/schemas.go @@ -549,6 +549,31 @@ func captchaConfigSchema() *schema.Schema { } } +func outerCaptchaConfigSchema() *schema.Schema { + return &schema.Schema{ + Type: schema.TypeList, + Optional: true, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "immunity_time_property": { + Type: schema.TypeList, + Optional: true, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "immunity_time": { + Type: schema.TypeInt, + Optional: true, + }, + }, + }, + }, + }, + }, + } +} + func challengeConfigSchema() *schema.Schema { return &schema.Schema{ Type: schema.TypeList, diff --git a/internal/service/wafv2/web_acl.go b/internal/service/wafv2/web_acl.go index 78fab219d9e..e738e59aa71 100644 --- a/internal/service/wafv2/web_acl.go +++ b/internal/service/wafv2/web_acl.go @@ -131,6 +131,7 @@ func ResourceWebACL() *schema.Resource { "rule_label": ruleLabelsSchema(), "statement": webACLRootStatementSchema(webACLRootStatementSchemaLevel), "visibility_config": visibilityConfigSchema(), + "captcha_config": outerCaptchaConfigSchema(), }, }, }, @@ -143,6 +144,7 @@ func ResourceWebACL() *schema.Resource { "tags": tftags.TagsSchema(), "tags_all": tftags.TagsSchemaComputed(), "visibility_config": visibilityConfigSchema(), + "captcha_config": outerCaptchaConfigSchema(), }, CustomizeDiff: verify.SetTagsDiff, @@ -161,6 +163,7 @@ func resourceWebACLCreate(ctx context.Context, d *schema.ResourceData, meta inte Rules: expandWebACLRules(d.Get("rule").(*schema.Set).List()), Scope: aws.String(d.Get("scope").(string)), VisibilityConfig: expandVisibilityConfig(d.Get("visibility_config").([]interface{})), + CaptchaConfig: expandCaptchaConfig(d.Get("captcha_config").([]interface{})), } if v, ok := d.GetOk("custom_response_body"); ok && v.(*schema.Set).Len() > 0 { @@ -227,6 +230,9 @@ func resourceWebACLRead(ctx context.Context, d *schema.ResourceData, meta interf if err := d.Set("visibility_config", flattenVisibilityConfig(webACL.VisibilityConfig)); err != nil { return diag.Errorf("setting visibility_config: %s", err) } + if err := d.Set("captcha_config", flattenCaptchaConfig(webACL.CaptchaConfig)); err != nil { + return diag.Errorf("setting captcha_config: %s", err) + } tags, err := ListTagsWithContext(ctx, conn, arn) @@ -260,6 +266,7 @@ func resourceWebACLUpdate(ctx context.Context, d *schema.ResourceData, meta inte Rules: expandWebACLRules(d.Get("rule").(*schema.Set).List()), Scope: aws.String(d.Get("scope").(string)), VisibilityConfig: expandVisibilityConfig(d.Get("visibility_config").([]interface{})), + CaptchaConfig: expandCaptchaConfig(d.Get("captcha_config").([]interface{})), } if v, ok := d.GetOk("custom_response_body"); ok && v.(*schema.Set).Len() > 0 { diff --git a/internal/service/wafv2/web_acl_test.go b/internal/service/wafv2/web_acl_test.go index 57435b7b129..66ea6d350af 100644 --- a/internal/service/wafv2/web_acl_test.go +++ b/internal/service/wafv2/web_acl_test.go @@ -1543,11 +1543,15 @@ func TestAccWAFV2WebACL_Custom_requestHandling(t *testing.T) { "action.0.captcha.0.custom_request_handling.0.insert_header.1.value": "test-value-2", "action.0.count.#": "0", "priority": "1", + "captcha_config.#": "1", + "captcha_config.0.immunity_time_property.0.immunity_time": "240", }), resource.TestCheckResourceAttr(resourceName, "visibility_config.#", "1"), resource.TestCheckResourceAttr(resourceName, "visibility_config.0.cloudwatch_metrics_enabled", "false"), resource.TestCheckResourceAttr(resourceName, "visibility_config.0.metric_name", "friendly-metric-name"), resource.TestCheckResourceAttr(resourceName, "visibility_config.0.sampled_requests_enabled", "false"), + resource.TestCheckResourceAttr(resourceName, "captcha_config.#", "1"), + resource.TestCheckResourceAttr(resourceName, "captcha_config.0.immunity_time_property.0.immunity_time", "120"), ), }, { @@ -2401,6 +2405,12 @@ resource "aws_wafv2_web_acl" "test" { cloudwatch_metrics_enabled = false metric_name = "friendly-rule-metric-name" sampled_requests_enabled = false + } + + captcha_config { + immunity_time_property { + immunity_time = 240 + } } } @@ -2409,6 +2419,12 @@ resource "aws_wafv2_web_acl" "test" { metric_name = "friendly-metric-name" sampled_requests_enabled = false } + + captcha_config { + immunity_time_property { + immunity_time = 120 + } + } } `, name, firstHeader, secondHeader) } diff --git a/website/docs/r/wafv2_rule_group.html.markdown b/website/docs/r/wafv2_rule_group.html.markdown index 6534be707f6..2d57b1535b8 100644 --- a/website/docs/r/wafv2_rule_group.html.markdown +++ b/website/docs/r/wafv2_rule_group.html.markdown @@ -206,6 +206,12 @@ resource "aws_wafv2_rule_group" "example" { metric_name = "rule-2" sampled_requests_enabled = false } + + captcha_config { + immunity_time_property { + immunity_time = 240 + } + } } rule { @@ -293,6 +299,12 @@ resource "aws_wafv2_rule_group" "example" { sampled_requests_enabled = false } + captcha_config { + immunity_time_property { + immunity_time = 120 + } + } + tags = { Name = "example-and-statement" Code = "123456" @@ -654,6 +666,19 @@ The `visibility_config` block supports the following arguments: * `metric_name` - (Required, Forces new resource) A friendly name of the CloudWatch metric. The name can contain only alphanumeric characters (A-Z, a-z, 0-9) hyphen(-) and underscore (_), with length from one to 128 characters. It can't contain whitespace or metric names reserved for AWS WAF, for example `All` and `Default_Action`. * `sampled_requests_enabled` - (Required) A boolean indicating whether AWS WAF should store a sampling of the web requests that match the rules. You can view the sampled requests through the AWS WAF console. +### Captcha Configuration + +The `captcha_config` block supports the following arguments: + +* `immunity_time_property` - (Optional) Defines custom immunity time. See [Immunity Time Property](#immunity-time-property) below for details. + +### Immunity Time Property + +The `immunity_time_property` block supports the following arguments: + +* `immunity_time` - (Optional) The amount of time, in seconds, that a CAPTCHA or challenge timestamp is considered valid by AWS WAF. The default setting is 300. + + ## Attributes Reference In addition to all arguments above, the following attributes are exported: From 2667736e02baeca3fa06b984550059704ec8aa69 Mon Sep 17 00:00:00 2001 From: Adrien Date: Thu, 23 Feb 2023 14:48:13 +0100 Subject: [PATCH 02/12] Add changelog --- .changelog/29608.txt | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 .changelog/29608.txt diff --git a/.changelog/29608.txt b/.changelog/29608.txt new file mode 100644 index 00000000000..9a8883afc61 --- /dev/null +++ b/.changelog/29608.txt @@ -0,0 +1,4 @@ +```release-note:enhancement +resource/aws_wafv2_rule_group: Add `captcha_config` argument +resource/aws_wafv2_web_acl: Add `captcha_config` argument +``` From 43ffa214bda84276917c2a58fa367d9fd98ae4c0 Mon Sep 17 00:00:00 2001 From: Adrien Date: Tue, 11 Apr 2023 15:10:44 +0200 Subject: [PATCH 03/12] Update internal/service/wafv2/web_acl_test.go Co-authored-by: Vitalii Bondiuk --- internal/service/wafv2/web_acl_test.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/internal/service/wafv2/web_acl_test.go b/internal/service/wafv2/web_acl_test.go index 66ea6d350af..ac03ebefb9c 100644 --- a/internal/service/wafv2/web_acl_test.go +++ b/internal/service/wafv2/web_acl_test.go @@ -2407,9 +2407,9 @@ resource "aws_wafv2_web_acl" "test" { sampled_requests_enabled = false } - captcha_config { - immunity_time_property { - immunity_time = 240 + captcha_config { + immunity_time_property { + immunity_time = 240 } } } From 3aba2cc663f2dcff10631b58870ddb89a9554ccd Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Thu, 20 Apr 2023 13:54:06 -0400 Subject: [PATCH 04/12] Tweak CHANGELOG entries. --- .changelog/29608.txt | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/.changelog/29608.txt b/.changelog/29608.txt index 9a8883afc61..263980a213e 100644 --- a/.changelog/29608.txt +++ b/.changelog/29608.txt @@ -1,4 +1,7 @@ ```release-note:enhancement -resource/aws_wafv2_rule_group: Add `captcha_config` argument -resource/aws_wafv2_web_acl: Add `captcha_config` argument +resource/aws_wafv2_rule_group: Add `captcha_config` and `rule.captcha_config` arguments ``` + +```release-note:enhancement +resource/aws_wafv2_web_acl: Add `captcha_config` and `rule.captcha_config` arguments +``` \ No newline at end of file From 08481dcea4e3e7ddd5340926e2cb7258c93cde4e Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Thu, 20 Apr 2023 13:55:20 -0400 Subject: [PATCH 05/12] r/aws_wafv2_rule_group: Alphabetize attributes. --- internal/service/wafv2/rule_group.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/internal/service/wafv2/rule_group.go b/internal/service/wafv2/rule_group.go index c0a016e4480..346e68fe875 100644 --- a/internal/service/wafv2/rule_group.go +++ b/internal/service/wafv2/rule_group.go @@ -64,6 +64,7 @@ func ResourceRuleGroup() *schema.Resource { ForceNew: true, ValidateFunc: validation.IntAtLeast(1), }, + "captcha_config": outerCaptchaConfigSchema(), "custom_response_body": customResponseBodySchema(), "description": { Type: schema.TypeString, @@ -96,11 +97,12 @@ func ResourceRuleGroup() *schema.Resource { Schema: map[string]*schema.Schema{ "allow": allowConfigSchema(), "block": blockConfigSchema(), - "count": countConfigSchema(), "captcha": captchaConfigSchema(), + "count": countConfigSchema(), }, }, }, + "captcha_config": outerCaptchaConfigSchema(), "name": { Type: schema.TypeString, Required: true, @@ -113,7 +115,6 @@ func ResourceRuleGroup() *schema.Resource { "rule_label": ruleLabelsSchema(), "statement": ruleGroupRootStatementSchema(ruleGroupRootStatementSchemaLevel), "visibility_config": visibilityConfigSchema(), - "captcha_config": outerCaptchaConfigSchema(), }, }, }, @@ -126,7 +127,6 @@ func ResourceRuleGroup() *schema.Resource { names.AttrTags: tftags.TagsSchema(), names.AttrTagsAll: tftags.TagsSchemaComputed(), "visibility_config": visibilityConfigSchema(), - "captcha_config": outerCaptchaConfigSchema(), }, CustomizeDiff: verify.SetTagsDiff, From 4a7d36c2cecc30161f4b34f0cca5b14ec286010c Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Thu, 20 Apr 2023 13:56:20 -0400 Subject: [PATCH 06/12] r/aws_wafv2_web_acl: Alphabetize attributes. --- internal/service/wafv2/web_acl.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/internal/service/wafv2/web_acl.go b/internal/service/wafv2/web_acl.go index c60c7318381..7883612ed1e 100644 --- a/internal/service/wafv2/web_acl.go +++ b/internal/service/wafv2/web_acl.go @@ -62,6 +62,7 @@ func ResourceWebACL() *schema.Resource { Type: schema.TypeInt, Computed: true, }, + "captcha_config": outerCaptchaConfigSchema(), "custom_response_body": customResponseBodySchema(), "default_action": { Type: schema.TypeList, @@ -111,6 +112,7 @@ func ResourceWebACL() *schema.Resource { }, }, }, + "captcha_config": outerCaptchaConfigSchema(), "name": { Type: schema.TypeString, Required: true, @@ -134,7 +136,6 @@ func ResourceWebACL() *schema.Resource { "rule_label": ruleLabelsSchema(), "statement": webACLRootStatementSchema(webACLRootStatementSchemaLevel), "visibility_config": visibilityConfigSchema(), - "captcha_config": outerCaptchaConfigSchema(), }, }, }, @@ -147,7 +148,6 @@ func ResourceWebACL() *schema.Resource { names.AttrTags: tftags.TagsSchema(), names.AttrTagsAll: tftags.TagsSchemaComputed(), "visibility_config": visibilityConfigSchema(), - "captcha_config": outerCaptchaConfigSchema(), }, CustomizeDiff: verify.SetTagsDiff, From 5ca70376ea5531aa2d18beb987e1d46218e5b2a3 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Thu, 20 Apr 2023 13:59:58 -0400 Subject: [PATCH 07/12] r/aws_wafv2_web_acl: Cosmetics. --- internal/service/wafv2/web_acl.go | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/internal/service/wafv2/web_acl.go b/internal/service/wafv2/web_acl.go index 7883612ed1e..ddf81c9fa90 100644 --- a/internal/service/wafv2/web_acl.go +++ b/internal/service/wafv2/web_acl.go @@ -159,13 +159,13 @@ func resourceWebACLCreate(ctx context.Context, d *schema.ResourceData, meta inte name := d.Get("name").(string) input := &wafv2.CreateWebACLInput{ + CaptchaConfig: expandCaptchaConfig(d.Get("captcha_config").([]interface{})), DefaultAction: expandDefaultAction(d.Get("default_action").([]interface{})), Name: aws.String(name), Rules: expandWebACLRules(d.Get("rule").(*schema.Set).List()), Scope: aws.String(d.Get("scope").(string)), Tags: GetTagsIn(ctx), VisibilityConfig: expandVisibilityConfig(d.Get("visibility_config").([]interface{})), - CaptchaConfig: expandCaptchaConfig(d.Get("captcha_config").([]interface{})), } if v, ok := d.GetOk("custom_response_body"); ok && v.(*schema.Set).Len() > 0 { @@ -210,6 +210,9 @@ func resourceWebACLRead(ctx context.Context, d *schema.ResourceData, meta interf arn := aws.StringValue(webACL.ARN) d.Set("arn", arn) d.Set("capacity", webACL.Capacity) + if err := d.Set("captcha_config", flattenCaptchaConfig(webACL.CaptchaConfig)); err != nil { + return diag.Errorf("setting captcha_config: %s", err) + } if err := d.Set("custom_response_body", flattenCustomResponseBodies(webACL.CustomResponseBodies)); err != nil { return diag.Errorf("setting custom_response_body: %s", err) } @@ -226,9 +229,6 @@ func resourceWebACLRead(ctx context.Context, d *schema.ResourceData, meta interf if err := d.Set("visibility_config", flattenVisibilityConfig(webACL.VisibilityConfig)); err != nil { return diag.Errorf("setting visibility_config: %s", err) } - if err := d.Set("captcha_config", flattenCaptchaConfig(webACL.CaptchaConfig)); err != nil { - return diag.Errorf("setting captcha_config: %s", err) - } return nil } @@ -238,6 +238,7 @@ func resourceWebACLUpdate(ctx context.Context, d *schema.ResourceData, meta inte if d.HasChangesExcept("tags", "tags_all") { input := &wafv2.UpdateWebACLInput{ + CaptchaConfig: expandCaptchaConfig(d.Get("captcha_config").([]interface{})), DefaultAction: expandDefaultAction(d.Get("default_action").([]interface{})), Id: aws.String(d.Id()), LockToken: aws.String(d.Get("lock_token").(string)), @@ -245,7 +246,6 @@ func resourceWebACLUpdate(ctx context.Context, d *schema.ResourceData, meta inte Rules: expandWebACLRules(d.Get("rule").(*schema.Set).List()), Scope: aws.String(d.Get("scope").(string)), VisibilityConfig: expandVisibilityConfig(d.Get("visibility_config").([]interface{})), - CaptchaConfig: expandCaptchaConfig(d.Get("captcha_config").([]interface{})), } if v, ok := d.GetOk("custom_response_body"); ok && v.(*schema.Set).Len() > 0 { From 03cc7587cf121b4d2b8af5eb3cec13f348c07878 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Thu, 20 Apr 2023 14:01:14 -0400 Subject: [PATCH 08/12] r/aws_wafv2_rule_group: No top-level 'captcha_config' argument. --- .changelog/29608.txt | 2 +- internal/service/wafv2/rule_group.go | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/.changelog/29608.txt b/.changelog/29608.txt index 263980a213e..86867c98b11 100644 --- a/.changelog/29608.txt +++ b/.changelog/29608.txt @@ -1,5 +1,5 @@ ```release-note:enhancement -resource/aws_wafv2_rule_group: Add `captcha_config` and `rule.captcha_config` arguments +resource/aws_wafv2_rule_group: Add `rule.captcha_config` argument ``` ```release-note:enhancement diff --git a/internal/service/wafv2/rule_group.go b/internal/service/wafv2/rule_group.go index 346e68fe875..be64481e90e 100644 --- a/internal/service/wafv2/rule_group.go +++ b/internal/service/wafv2/rule_group.go @@ -64,7 +64,6 @@ func ResourceRuleGroup() *schema.Resource { ForceNew: true, ValidateFunc: validation.IntAtLeast(1), }, - "captcha_config": outerCaptchaConfigSchema(), "custom_response_body": customResponseBodySchema(), "description": { Type: schema.TypeString, From 6558b8ff0d5c82cb10fdfdced0c84633246918b8 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Thu, 20 Apr 2023 14:02:33 -0400 Subject: [PATCH 09/12] Cosmetics. --- internal/service/wafv2/flex.go | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/internal/service/wafv2/flex.go b/internal/service/wafv2/flex.go index 460af246a63..c43c6c49246 100644 --- a/internal/service/wafv2/flex.go +++ b/internal/service/wafv2/flex.go @@ -30,12 +30,12 @@ func expandRule(m map[string]interface{}) *wafv2.Rule { } rule := &wafv2.Rule{ + Action: expandRuleAction(m["action"].([]interface{})), + CaptchaConfig: expandCaptchaConfig(m["captcha_config"].([]interface{})), Name: aws.String(m["name"].(string)), Priority: aws.Int64(int64(m["priority"].(int))), - Action: expandRuleAction(m["action"].([]interface{})), Statement: expandRuleGroupRootStatement(m["statement"].([]interface{})), VisibilityConfig: expandVisibilityConfig(m["visibility_config"].([]interface{})), - CaptchaConfig: expandCaptchaConfig(m["captcha_config"].([]interface{})), } if v, ok := m["rule_label"].(*schema.Set); ok && v.Len() > 0 { @@ -875,13 +875,13 @@ func expandWebACLRule(m map[string]interface{}) *wafv2.Rule { } rule := &wafv2.Rule{ - Name: aws.String(m["name"].(string)), - Priority: aws.Int64(int64(m["priority"].(int))), Action: expandRuleAction(m["action"].([]interface{})), + CaptchaConfig: expandCaptchaConfig(m["captcha_config"].([]interface{})), + Name: aws.String(m["name"].(string)), OverrideAction: expandOverrideAction(m["override_action"].([]interface{})), + Priority: aws.Int64(int64(m["priority"].(int))), Statement: expandWebACLRootStatement(m["statement"].([]interface{})), VisibilityConfig: expandVisibilityConfig(m["visibility_config"].([]interface{})), - CaptchaConfig: expandCaptchaConfig(m["captcha_config"].([]interface{})), } if v, ok := m["rule_label"].(*schema.Set); ok && v.Len() > 0 { @@ -1351,12 +1351,12 @@ func flattenRules(r []*wafv2.Rule) interface{} { for i, rule := range r { m := make(map[string]interface{}) m["action"] = flattenRuleAction(rule.Action) + m["captcha_config"] = flattenCaptchaConfig(rule.CaptchaConfig) m["name"] = aws.StringValue(rule.Name) m["priority"] = int(aws.Int64Value(rule.Priority)) m["rule_label"] = flattenRuleLabels(rule.RuleLabels) m["statement"] = flattenRuleGroupRootStatement(rule.Statement) m["visibility_config"] = flattenVisibilityConfig(rule.VisibilityConfig) - m["captcha_config"] = flattenCaptchaConfig(rule.CaptchaConfig) out[i] = m } @@ -2120,13 +2120,13 @@ func flattenWebACLRules(r []*wafv2.Rule) interface{} { for i, rule := range r { m := make(map[string]interface{}) m["action"] = flattenRuleAction(rule.Action) + m["captcha_config"] = flattenCaptchaConfig(rule.CaptchaConfig) m["override_action"] = flattenOverrideAction(rule.OverrideAction) m["name"] = aws.StringValue(rule.Name) m["priority"] = int(aws.Int64Value(rule.Priority)) m["rule_label"] = flattenRuleLabels(rule.RuleLabels) m["statement"] = flattenWebACLRootStatement(rule.Statement) m["visibility_config"] = flattenVisibilityConfig(rule.VisibilityConfig) - m["captcha_config"] = flattenCaptchaConfig(rule.CaptchaConfig) out[i] = m } From 44520248012c8f8335d8382af2fcbef2f51a8789 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Thu, 20 Apr 2023 14:08:02 -0400 Subject: [PATCH 10/12] Complete documentation. --- website/docs/r/wafv2_rule_group.html.markdown | 2 +- website/docs/r/wafv2_web_acl.html.markdown | 13 +++++++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/website/docs/r/wafv2_rule_group.html.markdown b/website/docs/r/wafv2_rule_group.html.markdown index 2d57b1535b8..bc303638744 100644 --- a/website/docs/r/wafv2_rule_group.html.markdown +++ b/website/docs/r/wafv2_rule_group.html.markdown @@ -338,6 +338,7 @@ Each `custom_response_body` block supports the following arguments: Each `rule` supports the following arguments: * `action` - (Required) The action that AWS WAF should take on a web request when it matches the rule's statement. Settings at the `aws_wafv2_web_acl` level can override the rule action setting. See [Action](#action) below for details. +* `captcha_config` - (Optional) Specifies how AWS WAF should handle CAPTCHA evaluations. See [Captcha Configuration](#captcha-configuration) below for details. * `name` - (Required, Forces new resource) A friendly name of the rule. * `priority` - (Required) If you define more than one Rule in a WebACL, AWS WAF evaluates each request against the `rules` in order based on the value of `priority`. AWS WAF processes rules with lower priority first. * `rule_label` - (Optional) Labels to apply to web requests that match the rule match statement. See [Rule Label](#rule-label) below for details. @@ -678,7 +679,6 @@ The `immunity_time_property` block supports the following arguments: * `immunity_time` - (Optional) The amount of time, in seconds, that a CAPTCHA or challenge timestamp is considered valid by AWS WAF. The default setting is 300. - ## Attributes Reference In addition to all arguments above, the following attributes are exported: diff --git a/website/docs/r/wafv2_web_acl.html.markdown b/website/docs/r/wafv2_web_acl.html.markdown index 35cd3acf8c5..9f6d6832924 100644 --- a/website/docs/r/wafv2_web_acl.html.markdown +++ b/website/docs/r/wafv2_web_acl.html.markdown @@ -371,6 +371,7 @@ The `default_action` block supports the following arguments: Each `rule` supports the following arguments: * `action` - (Optional) Action that AWS WAF should take on a web request when it matches the rule's statement. This is used only for rules whose **statements do not reference a rule group**. See [`action`](#action) below for details. +* `captcha_config` - (Optional) Specifies how AWS WAF should handle CAPTCHA evaluations. See [Captcha Configuration](#captcha-configuration) below for details. * `name` - (Required) Friendly name of the rule. **NOTE:** The provider assumes that rules with names matching this pattern, `^ShieldMitigationRuleGroup___.*`, are AWS-added for [automatic application layer DDoS mitigation activities](https://docs.aws.amazon.com/waf/latest/developerguide/ddos-automatic-app-layer-response-rg.html). Such rules will be ignored by the provider unless you explicitly include them in your configuration (for example, by using the AWS CLI to discover their properties and creating matching configuration). However, since these rules are owned and managed by AWS, you may get permission errors. * `override_action` - (Optional) Override action to apply to the rules in a rule group. Used only for rule **statements that reference a rule group**, like `rule_group_reference_statement` and `managed_rule_group_statement`. See [`override_action`](#override_action) below for details. * `priority` - (Required) If you define more than one Rule in a WebACL, AWS WAF evaluates each request against the `rules` in order based on the value of `priority`. AWS WAF processes rules with lower priority first. @@ -835,6 +836,18 @@ The `visibility_config` block supports the following arguments: * `metric_name` - (Required) A friendly name of the CloudWatch metric. The name can contain only alphanumeric characters (A-Z, a-z, 0-9) hyphen(-) and underscore (\_), with length from one to 128 characters. It can't contain whitespace or metric names reserved for AWS WAF, for example `All` and `Default_Action`. * `sampled_requests_enabled` - (Required) Whether AWS WAF should store a sampling of the web requests that match the rules. You can view the sampled requests through the AWS WAF console. +### Captcha Configuration + +The `captcha_config` block supports the following arguments: + +* `immunity_time_property` - (Optional) Defines custom immunity time. See [Immunity Time Property](#immunity-time-property) below for details. + +### Immunity Time Property + +The `immunity_time_property` block supports the following arguments: + +* `immunity_time` - (Optional) The amount of time, in seconds, that a CAPTCHA or challenge timestamp is considered valid by AWS WAF. The default setting is 300. + ## Attributes Reference In addition to all arguments above, the following attributes are exported: From e505a2937a19d0411f08d27446c21f6ebc869d97 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Thu, 20 Apr 2023 14:11:05 -0400 Subject: [PATCH 11/12] Format acceptance test configuration. --- internal/service/wafv2/web_acl_test.go | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/internal/service/wafv2/web_acl_test.go b/internal/service/wafv2/web_acl_test.go index de2648f1a95..1556ab3f540 100644 --- a/internal/service/wafv2/web_acl_test.go +++ b/internal/service/wafv2/web_acl_test.go @@ -49,6 +49,7 @@ func TestAccWAFV2WebACL_basic(t *testing.T) { resource.TestCheckResourceAttr(resourceName, "description", webACLName), resource.TestCheckResourceAttr(resourceName, "rule.#", "0"), resource.TestCheckResourceAttr(resourceName, "scope", wafv2.ScopeRegional), + resource.TestCheckResourceAttr(resourceName, "captcha_config.#", "0"), resource.TestCheckResourceAttr(resourceName, "default_action.#", "1"), resource.TestCheckResourceAttr(resourceName, "default_action.0.allow.#", "1"), resource.TestCheckResourceAttr(resourceName, "default_action.0.block.#", "0"), @@ -2956,9 +2957,9 @@ resource "aws_wafv2_web_acl" "test" { sampled_requests_enabled = false } - captcha_config { - immunity_time_property { - immunity_time = 240 + captcha_config { + immunity_time_property { + immunity_time = 240 } } } From c217cb556010ec3cdbc72224866c60799b086dcd Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Thu, 20 Apr 2023 14:12:58 -0400 Subject: [PATCH 12/12] Fix website terrafmt error. --- website/docs/r/wafv2_rule_group.html.markdown | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/docs/r/wafv2_rule_group.html.markdown b/website/docs/r/wafv2_rule_group.html.markdown index bc303638744..fce7336e4e4 100644 --- a/website/docs/r/wafv2_rule_group.html.markdown +++ b/website/docs/r/wafv2_rule_group.html.markdown @@ -206,7 +206,7 @@ resource "aws_wafv2_rule_group" "example" { metric_name = "rule-2" sampled_requests_enabled = false } - + captcha_config { immunity_time_property { immunity_time = 240