From 3cd56088b8e47b3afc03b5d5ea69ab1d99fc868b Mon Sep 17 00:00:00 2001 From: Brian Flad Date: Thu, 26 Jul 2018 01:36:43 -0400 Subject: [PATCH] resource/aws_waf(regional)_web_acl: Properly read rules into Terraform state --- aws/resource_aws_waf_web_acl.go | 38 ++++++++++--------- aws/resource_aws_waf_web_acl_test.go | 15 +------- aws/resource_aws_wafregional_web_acl.go | 48 ++++++++++++------------ website/docs/r/waf_web_acl.html.markdown | 2 - 4 files changed, 47 insertions(+), 56 deletions(-) diff --git a/aws/resource_aws_waf_web_acl.go b/aws/resource_aws_waf_web_acl.go index b688ea44d49..af7203eb7bd 100644 --- a/aws/resource_aws_waf_web_acl.go +++ b/aws/resource_aws_waf_web_acl.go @@ -5,7 +5,6 @@ import ( "log" "github.com/aws/aws-sdk-go/aws" - "github.com/aws/aws-sdk-go/aws/awserr" "github.com/aws/aws-sdk-go/service/waf" "github.com/hashicorp/terraform/helper/schema" "github.com/hashicorp/terraform/helper/validation" @@ -22,66 +21,66 @@ func resourceAwsWafWebAcl() *schema.Resource { }, Schema: map[string]*schema.Schema{ - "name": &schema.Schema{ + "name": { Type: schema.TypeString, Required: true, ForceNew: true, }, - "default_action": &schema.Schema{ + "default_action": { Type: schema.TypeSet, Required: true, MaxItems: 1, Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ - "type": &schema.Schema{ + "type": { Type: schema.TypeString, Required: true, }, }, }, }, - "metric_name": &schema.Schema{ + "metric_name": { Type: schema.TypeString, Required: true, ForceNew: true, ValidateFunc: validateWafMetricName, }, - "rules": &schema.Schema{ + "rules": { Type: schema.TypeSet, Optional: true, Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ - "action": &schema.Schema{ - Type: schema.TypeSet, + "action": { + Type: schema.TypeList, Optional: true, MaxItems: 1, Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ - "type": &schema.Schema{ + "type": { Type: schema.TypeString, Required: true, }, }, }, }, - "override_action": &schema.Schema{ - Type: schema.TypeSet, + "override_action": { + Type: schema.TypeList, Optional: true, MaxItems: 1, Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ - "type": &schema.Schema{ + "type": { Type: schema.TypeString, Required: true, }, }, }, }, - "priority": &schema.Schema{ + "priority": { Type: schema.TypeInt, Required: true, }, - "type": &schema.Schema{ + "type": { Type: schema.TypeString, Optional: true, Default: waf.WafRuleTypeRegular, @@ -91,7 +90,7 @@ func resourceAwsWafWebAcl() *schema.Resource { waf.WafRuleTypeGroup, }, false), }, - "rule_id": &schema.Schema{ + "rule_id": { Type: schema.TypeString, Required: true, }, @@ -132,7 +131,7 @@ func resourceAwsWafWebAclRead(d *schema.ResourceData, meta interface{}) error { resp, err := conn.GetWebACL(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok && awsErr.Code() == "WAFNonexistentItemException" { + if isAWSErr(err, waf.ErrCodeNonexistentItemException, "") { log.Printf("[WARN] WAF ACL (%s) not found, removing from state", d.Id()) d.SetId("") return nil @@ -149,6 +148,9 @@ func resourceAwsWafWebAclRead(d *schema.ResourceData, meta interface{}) error { } d.Set("name", resp.WebACL.Name) d.Set("metric_name", resp.WebACL.MetricName) + if err := d.Set("rules", flattenWafWebAclRules(resp.WebACL.Rules)); err != nil { + return fmt.Errorf("error setting rules: %s", err) + } return nil } @@ -205,7 +207,7 @@ func updateWebAclResource(d *schema.ResourceData, meta interface{}, ChangeAction var aclRuleUpdate *waf.WebACLUpdate switch aclRule["type"].(string) { case waf.WafRuleTypeGroup: - overrideAction := aclRule["override_action"].(*schema.Set).List()[0].(map[string]interface{}) + overrideAction := aclRule["override_action"].([]interface{})[0].(map[string]interface{}) aclRuleUpdate = &waf.WebACLUpdate{ Action: aws.String(ChangeAction), ActivatedRule: &waf.ActivatedRule{ @@ -216,7 +218,7 @@ func updateWebAclResource(d *schema.ResourceData, meta interface{}, ChangeAction }, } default: - action := aclRule["action"].(*schema.Set).List()[0].(map[string]interface{}) + action := aclRule["action"].([]interface{})[0].(map[string]interface{}) aclRuleUpdate = &waf.WebACLUpdate{ Action: aws.String(ChangeAction), ActivatedRule: &waf.ActivatedRule{ diff --git a/aws/resource_aws_waf_web_acl_test.go b/aws/resource_aws_waf_web_acl_test.go index ef47c8d4a31..0e1ba7eefb5 100644 --- a/aws/resource_aws_waf_web_acl_test.go +++ b/aws/resource_aws_waf_web_acl_test.go @@ -8,7 +8,6 @@ import ( "github.com/hashicorp/terraform/terraform" "github.com/aws/aws-sdk-go/aws" - "github.com/aws/aws-sdk-go/aws/awserr" "github.com/aws/aws-sdk-go/service/waf" "github.com/hashicorp/terraform/helper/acctest" ) @@ -43,8 +42,6 @@ func TestAccAWSWafWebAcl_basic(t *testing.T) { ResourceName: resourceName, ImportState: true, ImportStateVerify: true, - // The WAF ACL rule resource doesn't GET rules - ImportStateVerifyIgnore: []string{"rules"}, }, }, }) @@ -80,8 +77,6 @@ func TestAccAWSWafWebAcl_group(t *testing.T) { ResourceName: resourceName, ImportState: true, ImportStateVerify: true, - // The WAF ACL rule resource doesn't GET rules - ImportStateVerifyIgnore: []string{"rules"}, }, }, }) @@ -134,8 +129,6 @@ func TestAccAWSWafWebAcl_changeNameForceNew(t *testing.T) { ResourceName: resourceName, ImportState: true, ImportStateVerify: true, - // The WAF ACL rule resource doesn't GET rules - ImportStateVerifyIgnore: []string{"rules"}, }, }, }) @@ -188,8 +181,6 @@ func TestAccAWSWafWebAcl_changeDefaultAction(t *testing.T) { ResourceName: resourceName, ImportState: true, ImportStateVerify: true, - // The WAF ACL rule resource doesn't GET rules - ImportStateVerifyIgnore: []string{"rules"}, }, }, }) @@ -279,10 +270,8 @@ func testAccCheckAWSWafWebAclDestroy(s *terraform.State) error { } // Return nil if the WebACL is already destroyed - if awsErr, ok := err.(awserr.Error); ok { - if awsErr.Code() == "WAFNonexistentItemException" { - return nil - } + if isAWSErr(err, waf.ErrCodeNonexistentItemException, "") { + continue } return err diff --git a/aws/resource_aws_wafregional_web_acl.go b/aws/resource_aws_wafregional_web_acl.go index 3a57eff5674..c9f0f38b3e6 100644 --- a/aws/resource_aws_wafregional_web_acl.go +++ b/aws/resource_aws_wafregional_web_acl.go @@ -19,65 +19,65 @@ func resourceAwsWafRegionalWebAcl() *schema.Resource { Delete: resourceAwsWafRegionalWebAclDelete, Schema: map[string]*schema.Schema{ - "name": &schema.Schema{ + "name": { Type: schema.TypeString, Required: true, ForceNew: true, }, - "default_action": &schema.Schema{ + "default_action": { Type: schema.TypeList, Required: true, MaxItems: 1, Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ - "type": &schema.Schema{ + "type": { Type: schema.TypeString, Required: true, }, }, }, }, - "metric_name": &schema.Schema{ + "metric_name": { Type: schema.TypeString, Required: true, ForceNew: true, }, - "rule": &schema.Schema{ + "rule": { Type: schema.TypeSet, Optional: true, Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ - "action": &schema.Schema{ + "action": { Type: schema.TypeList, Optional: true, MaxItems: 1, Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ - "type": &schema.Schema{ + "type": { Type: schema.TypeString, Required: true, }, }, }, }, - "override_action": &schema.Schema{ + "override_action": { Type: schema.TypeList, Optional: true, MaxItems: 1, Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ - "type": &schema.Schema{ + "type": { Type: schema.TypeString, Required: true, }, }, }, }, - "priority": &schema.Schema{ + "priority": { Type: schema.TypeInt, Required: true, }, - "type": &schema.Schema{ + "type": { Type: schema.TypeString, Optional: true, Default: waf.WafRuleTypeRegular, @@ -87,7 +87,7 @@ func resourceAwsWafRegionalWebAcl() *schema.Resource { waf.WafRuleTypeGroup, }, false), }, - "rule_id": &schema.Schema{ + "rule_id": { Type: schema.TypeString, Required: true, }, @@ -141,7 +141,9 @@ func resourceAwsWafRegionalWebAclRead(d *schema.ResourceData, meta interface{}) d.Set("default_action", flattenDefaultActionWR(resp.WebACL.DefaultAction)) d.Set("name", resp.WebACL.Name) d.Set("metric_name", resp.WebACL.MetricName) - d.Set("rule", flattenWafWebAclRules(resp.WebACL.Rules)) + if err := d.Set("rule", flattenWafWebAclRules(resp.WebACL.Rules)); err != nil { + return fmt.Errorf("error setting rule: %s", err) + } return nil } @@ -238,27 +240,27 @@ func flattenDefaultActionWR(n *waf.WafAction) []map[string]interface{} { return m.MapList() } -func flattenWafWebAclRules(ts []*waf.ActivatedRule) []interface{} { - out := make([]interface{}, len(ts), len(ts)) +func flattenWafWebAclRules(ts []*waf.ActivatedRule) []map[string]interface{} { + out := make([]map[string]interface{}, len(ts), len(ts)) for i, r := range ts { m := make(map[string]interface{}) - switch *r.Type { + switch aws.StringValue(r.Type) { case waf.WafRuleTypeGroup: actionMap := map[string]interface{}{ - "type": *r.OverrideAction.Type, + "type": aws.StringValue(r.OverrideAction.Type), } - m["override_action"] = []interface{}{actionMap} + m["override_action"] = []map[string]interface{}{actionMap} default: actionMap := map[string]interface{}{ - "type": *r.Action.Type, + "type": aws.StringValue(r.Action.Type), } - m["action"] = []interface{}{actionMap} + m["action"] = []map[string]interface{}{actionMap} } - m["priority"] = *r.Priority - m["rule_id"] = *r.RuleId - m["type"] = *r.Type + m["priority"] = int(aws.Int64Value(r.Priority)) + m["rule_id"] = aws.StringValue(r.RuleId) + m["type"] = aws.StringValue(r.Type) out[i] = m } return out diff --git a/website/docs/r/waf_web_acl.html.markdown b/website/docs/r/waf_web_acl.html.markdown index b3eb89ffd9b..05103b15f09 100644 --- a/website/docs/r/waf_web_acl.html.markdown +++ b/website/docs/r/waf_web_acl.html.markdown @@ -100,5 +100,3 @@ WAF Web ACL can be imported using the `id`, e.g. ``` $ terraform import aws_waf_web_acl.main 0c8e583e-18f3-4c13-9e2a-67c4805d2f94 ``` - -~> **Note:** The `rules` will not be imported.