diff --git a/.changelog/37006.txt b/.changelog/37006.txt new file mode 100644 index 000000000000..49562bbb5ca7 --- /dev/null +++ b/.changelog/37006.txt @@ -0,0 +1,3 @@ +```release-note:enhancement +resource/aws_wafv2_web_acl: Add `enable_machine_learning` to `aws_managed_rules_bot_control_rule_set` configuration block +``` \ No newline at end of file diff --git a/internal/service/wafv2/flex.go b/internal/service/wafv2/flex.go index 653dd7b78b79..884bd87f1ae2 100644 --- a/internal/service/wafv2/flex.go +++ b/internal/service/wafv2/flex.go @@ -1282,7 +1282,8 @@ func expandManagedRulesBotControlRuleSet(tfList []interface{}) *awstypes.AWSMana m := tfList[0].(map[string]interface{}) out := awstypes.AWSManagedRulesBotControlRuleSet{ - InspectionLevel: awstypes.InspectionLevel(m["inspection_level"].(string)), + EnableMachineLearning: aws.Bool(m["enable_machine_learning"].(bool)), + InspectionLevel: awstypes.InspectionLevel(m["inspection_level"].(string)), } return &out @@ -1775,7 +1776,7 @@ func flattenAssociationConfig(config *awstypes.AssociationConfig) interface{} { for _, resourceType := range wafv2.AssociatedResourceType_Values() { if requestBodyAssociatedResourceTypeConfig, ok := config.RequestBody[resourceType]; ok { requestBodyConfig[strings.ToLower(resourceType)] = []map[string]interface{}{{ - "default_size_inspection_limit": string(requestBodyAssociatedResourceTypeConfig.DefaultSizeInspectionLimit), + "default_size_inspection_limit": requestBodyAssociatedResourceTypeConfig.DefaultSizeInspectionLimit, }} } } @@ -1826,7 +1827,7 @@ func flattenCustomResponseBodies(b map[string]awstypes.CustomResponseBody) inter out[i] = map[string]interface{}{ names.AttrKey: key, names.AttrContent: aws.ToString(body.Content), - names.AttrContentType: string(body.ContentType), + names.AttrContentType: body.ContentType, } i += 1 } @@ -1998,7 +1999,7 @@ func flattenByteMatchStatement(b *awstypes.ByteMatchStatement) interface{} { m := map[string]interface{}{ "field_to_match": flattenFieldToMatch(b.FieldToMatch), - "positional_constraint": string(b.PositionalConstraint), + "positional_constraint": b.PositionalConstraint, "search_string": string(b.SearchString), "text_transformation": flattenTextTransformations(b.TextTransformations), } @@ -2070,7 +2071,7 @@ func flattenForwardedIPConfig(f *awstypes.ForwardedIPConfig) interface{} { } m := map[string]interface{}{ - "fallback_behavior": string(f.FallbackBehavior), + "fallback_behavior": f.FallbackBehavior, "header_name": aws.ToString(f.HeaderName), } @@ -2083,9 +2084,9 @@ func flattenIPSetForwardedIPConfig(i *awstypes.IPSetForwardedIPConfig) interface } m := map[string]interface{}{ - "fallback_behavior": string(i.FallbackBehavior), + "fallback_behavior": i.FallbackBehavior, "header_name": aws.ToString(i.HeaderName), - "position": string(i.Position), + "position": i.Position, } return []interface{}{m} @@ -2097,8 +2098,8 @@ func flattenCookies(c *awstypes.Cookies) interface{} { } m := map[string]interface{}{ - "match_scope": string(c.MatchScope), - "oversize_handling": string(c.OversizeHandling), + "match_scope": c.MatchScope, + "oversize_handling": c.OversizeHandling, "match_pattern": flattenCookiesMatchPattern(c.MatchPattern), } @@ -2128,7 +2129,7 @@ func flattenJA3Fingerprint(j *awstypes.JA3Fingerprint) interface{} { } m := map[string]interface{}{ - "fallback_behavior": string(j.FallbackBehavior), + "fallback_behavior": j.FallbackBehavior, } return []interface{}{m} @@ -2140,10 +2141,10 @@ func flattenJSONBody(b *awstypes.JsonBody) interface{} { } m := map[string]interface{}{ - "invalid_fallback_behavior": string(b.InvalidFallbackBehavior), + "invalid_fallback_behavior": b.InvalidFallbackBehavior, "match_pattern": flattenJSONMatchPattern(b.MatchPattern), - "match_scope": string(b.MatchScope), - "oversize_handling": string(b.OversizeHandling), + "match_scope": b.MatchScope, + "oversize_handling": b.OversizeHandling, } return []interface{}{m} @@ -2155,7 +2156,7 @@ func flattenBody(b *awstypes.Body) interface{} { } m := map[string]interface{}{ - "oversize_handling": string(b.OversizeHandling), + "oversize_handling": b.OversizeHandling, } return []interface{}{m} @@ -2167,7 +2168,7 @@ func flattenJSONMatchPattern(p *awstypes.JsonMatchPattern) []interface{} { } m := map[string]interface{}{ - "included_paths": flex.FlattenStringValueList(p.IncludedPaths), + "included_paths": p.IncludedPaths, } if p.All != nil { @@ -2206,7 +2207,7 @@ func flattenTextTransformations(l []awstypes.TextTransformation) []interface{} { for i, t := range l { m := make(map[string]interface{}) m[names.AttrPriority] = t.Priority - m[names.AttrType] = string(t.Type) + m[names.AttrType] = t.Type out[i] = m } return out @@ -2231,21 +2232,13 @@ func flattenGeoMatchStatement(g *awstypes.GeoMatchStatement) interface{} { } m := map[string]interface{}{ - "country_codes": flattenCountryCodes(g.CountryCodes), + "country_codes": g.CountryCodes, "forwarded_ip_config": flattenForwardedIPConfig(g.ForwardedIPConfig), } return []interface{}{m} } -func flattenCountryCodes(list []awstypes.CountryCode) []interface{} { - result := make([]interface{}, 0, len(list)) - for _, v := range list { - result = append(result, string(v)) - } - return result -} - func flattenLabelMatchStatement(l *awstypes.LabelMatchStatement) interface{} { if l == nil { return []interface{}{} @@ -2253,7 +2246,7 @@ func flattenLabelMatchStatement(l *awstypes.LabelMatchStatement) interface{} { m := map[string]interface{}{ names.AttrKey: aws.ToString(l.Key), - names.AttrScope: string(l.Scope), + names.AttrScope: l.Scope, } return []interface{}{m} @@ -2317,7 +2310,7 @@ func flattenSizeConstraintStatement(s *awstypes.SizeConstraintStatement) interfa } m := map[string]interface{}{ - "comparison_operator": string(s.ComparisonOperator), + "comparison_operator": s.ComparisonOperator, "field_to_match": flattenFieldToMatch(s.FieldToMatch), names.AttrSize: s.Size, "text_transformation": flattenTextTransformations(s.TextTransformations), @@ -2373,7 +2366,7 @@ func flattenHeaderOrder(s *awstypes.HeaderOrder) interface{} { } m := map[string]interface{}{ - "oversize_handling": string(s.OversizeHandling), + "oversize_handling": s.OversizeHandling, } return []interface{}{m} @@ -2385,9 +2378,9 @@ func flattenHeaders(s *awstypes.Headers) interface{} { } m := map[string]interface{}{ - "match_scope": string(s.MatchScope), + "match_scope": s.MatchScope, "match_pattern": flattenHeaderMatchPattern(s.MatchPattern), - "oversize_handling": string(s.OversizeHandling), + "oversize_handling": s.OversizeHandling, } return []interface{}{m} @@ -2405,11 +2398,11 @@ func flattenHeaderMatchPattern(s *awstypes.HeaderMatchPattern) interface{} { } if s.ExcludedHeaders != nil { - m["excluded_headers"] = flex.FlattenStringValueList(s.ExcludedHeaders) + m["excluded_headers"] = s.ExcludedHeaders } if s.IncludedHeaders != nil { - m["included_headers"] = flex.FlattenStringValueList(s.IncludedHeaders) + m["included_headers"] = s.IncludedHeaders } return []interface{}{m} @@ -2603,7 +2596,7 @@ func flattenManagedRuleGroupConfigs(c []awstypes.ManagedRuleGroupConfig) []inter m["login_path"] = aws.ToString(config.LoginPath) } - m["payload_type"] = string(config.PayloadType) + m["payload_type"] = config.PayloadType if config.PasswordField != nil { m["password_field"] = flattenPasswordField(config.PasswordField) @@ -2694,7 +2687,8 @@ func flattenManagedRulesBotControlRuleSet(apiObject *awstypes.AWSManagedRulesBot } m := map[string]interface{}{ - "inspection_level": string(apiObject.InspectionLevel), + "enable_machine_learning": aws.ToBool(apiObject.EnableMachineLearning), + "inspection_level": apiObject.InspectionLevel, } return []interface{}{m} @@ -2748,7 +2742,7 @@ func flattenRequestInspectionACFP(apiObject *awstypes.RequestInspectionACFP) []i "address_fields": flattenAddressFields(apiObject.AddressFields), "email_field": flattenEmailField(apiObject.EmailField), "password_field": flattenPasswordField(apiObject.PasswordField), - "payload_type": string(apiObject.PayloadType), + "payload_type": apiObject.PayloadType, "phone_number_fields": flattenPhoneNumberFields(apiObject.PhoneNumberFields), "username_field": flattenUsernameField(apiObject.UsernameField), } @@ -2763,7 +2757,7 @@ func flattenRequestInspection(apiObject *awstypes.RequestInspection) []interface m := map[string]interface{}{ "password_field": flattenPasswordField(apiObject.PasswordField), - "payload_type": string(apiObject.PayloadType), + "payload_type": apiObject.PayloadType, "username_field": flattenUsernameField(apiObject.UsernameField), } @@ -2798,8 +2792,8 @@ func flattenBodyContains(apiObject *awstypes.ResponseInspectionBodyContains) []i } m := map[string]interface{}{ - "failure_strings": flex.FlattenStringValueSet(apiObject.FailureStrings), - "success_strings": flex.FlattenStringValueSet(apiObject.SuccessStrings), + "failure_strings": apiObject.FailureStrings, + "success_strings": apiObject.SuccessStrings, } return []interface{}{m} @@ -2811,8 +2805,8 @@ func flattenHeader(apiObject *awstypes.ResponseInspectionHeader) []interface{} { } m := map[string]interface{}{ - "failure_values": flex.FlattenStringValueSet(apiObject.FailureValues), - "success_values": flex.FlattenStringValueSet(apiObject.SuccessValues), + "failure_values": apiObject.FailureValues, + "success_values": apiObject.SuccessValues, } return []interface{}{m} @@ -2824,9 +2818,9 @@ func flattenResponseInspectionJSON(apiObject *awstypes.ResponseInspectionJson) [ } m := map[string]interface{}{ - "failure_values": flex.FlattenStringValueSet(apiObject.FailureValues), + "failure_values": apiObject.FailureValues, names.AttrIdentifier: aws.ToString(apiObject.Identifier), - "success_values": flex.FlattenStringValueSet(apiObject.SuccessValues), + "success_values": apiObject.SuccessValues, } return []interface{}{m} @@ -2967,7 +2961,7 @@ func flattenRateBasedStatement(apiObject *awstypes.RateBasedStatement) interface } tfMap := map[string]interface{}{ - "aggregate_key_type": string(apiObject.AggregateKeyType), + "aggregate_key_type": apiObject.AggregateKeyType, "evaluation_window_sec": apiObject.EvaluationWindowSec, } diff --git a/internal/service/wafv2/schemas.go b/internal/service/wafv2/schemas.go index b354b7f1e8dc..3b77d40c68b9 100644 --- a/internal/service/wafv2/schemas.go +++ b/internal/service/wafv2/schemas.go @@ -1277,6 +1277,11 @@ func managedRuleGroupConfigSchema() *schema.Schema { MaxItems: 1, Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ + "enable_machine_learning": { + Type: schema.TypeBool, + Optional: true, + Default: true, + }, "inspection_level": { Type: schema.TypeString, Required: true, diff --git a/internal/service/wafv2/web_acl_test.go b/internal/service/wafv2/web_acl_test.go index 319f58fec426..e6b920a1a158 100644 --- a/internal/service/wafv2/web_acl_test.go +++ b/internal/service/wafv2/web_acl_test.go @@ -941,7 +941,8 @@ func TestAccWAFV2WebACL_ManagedRuleGroup_ManagedRuleGroupConfig_BotControl(t *te "statement.0.managed_rule_group_statement.#": acctest.Ct1, "statement.0.managed_rule_group_statement.0.name": "AWSManagedRulesBotControlRuleSet", "statement.0.managed_rule_group_statement.0.vendor_name": "AWS", - "statement.0.managed_rule_group_statement.0.managed_rule_group_configs.0.aws_managed_rules_bot_control_rule_set.0.inspection_level": "TARGETED", + "statement.0.managed_rule_group_statement.0.managed_rule_group_configs.0.aws_managed_rules_bot_control_rule_set.0.inspection_level": "TARGETED", + "statement.0.managed_rule_group_statement.0.managed_rule_group_configs.0.aws_managed_rules_bot_control_rule_set.0.enable_machine_learning": acctest.CtFalse, }), ), }, @@ -4599,7 +4600,8 @@ resource "aws_wafv2_web_acl" "test" { managed_rule_group_configs { aws_managed_rules_bot_control_rule_set { - inspection_level = "TARGETED" + inspection_level = "TARGETED" + enable_machine_learning = false } } } diff --git a/website/docs/r/wafv2_web_acl.html.markdown b/website/docs/r/wafv2_web_acl.html.markdown index 432636c588a5..89ceef7b8708 100644 --- a/website/docs/r/wafv2_web_acl.html.markdown +++ b/website/docs/r/wafv2_web_acl.html.markdown @@ -789,6 +789,7 @@ The `managed_rule_group_configs` block support the following arguments: ### `aws_managed_rules_bot_control_rule_set` Block +* `enable_machine_learning` - (Optional) Applies only to the targeted inspection level. Determines whether to use machine learning (ML) to analyze your web traffic for bot-related activity. Defaults to `true`. * `inspection_level` - (Optional) The inspection level to use for the Bot Control rule group. ### `aws_managed_rules_acfp_rule_set` Block