github.com/danp/terraform@v0.9.5-0.20170426144147-39d740081351/builtin/providers/aws/resource_aws_waf_web_acl.go (about) 1 package aws 2 3 import ( 4 "fmt" 5 "log" 6 7 "github.com/aws/aws-sdk-go/aws" 8 "github.com/aws/aws-sdk-go/aws/awserr" 9 "github.com/aws/aws-sdk-go/service/waf" 10 "github.com/hashicorp/terraform/helper/schema" 11 ) 12 13 func resourceAwsWafWebAcl() *schema.Resource { 14 return &schema.Resource{ 15 Create: resourceAwsWafWebAclCreate, 16 Read: resourceAwsWafWebAclRead, 17 Update: resourceAwsWafWebAclUpdate, 18 Delete: resourceAwsWafWebAclDelete, 19 20 Schema: map[string]*schema.Schema{ 21 "name": &schema.Schema{ 22 Type: schema.TypeString, 23 Required: true, 24 ForceNew: true, 25 }, 26 "default_action": &schema.Schema{ 27 Type: schema.TypeSet, 28 Required: true, 29 MaxItems: 1, 30 Elem: &schema.Resource{ 31 Schema: map[string]*schema.Schema{ 32 "type": &schema.Schema{ 33 Type: schema.TypeString, 34 Required: true, 35 }, 36 }, 37 }, 38 }, 39 "metric_name": &schema.Schema{ 40 Type: schema.TypeString, 41 Required: true, 42 ForceNew: true, 43 ValidateFunc: validateWafMetricName, 44 }, 45 "rules": &schema.Schema{ 46 Type: schema.TypeSet, 47 Optional: true, 48 Elem: &schema.Resource{ 49 Schema: map[string]*schema.Schema{ 50 "action": &schema.Schema{ 51 Type: schema.TypeSet, 52 Required: true, 53 MaxItems: 1, 54 Elem: &schema.Resource{ 55 Schema: map[string]*schema.Schema{ 56 "type": &schema.Schema{ 57 Type: schema.TypeString, 58 Required: true, 59 }, 60 }, 61 }, 62 }, 63 "priority": &schema.Schema{ 64 Type: schema.TypeInt, 65 Required: true, 66 }, 67 "rule_id": &schema.Schema{ 68 Type: schema.TypeString, 69 Required: true, 70 }, 71 }, 72 }, 73 }, 74 }, 75 } 76 } 77 78 func resourceAwsWafWebAclCreate(d *schema.ResourceData, meta interface{}) error { 79 conn := meta.(*AWSClient).wafconn 80 81 wr := newWafRetryer(conn, "global") 82 out, err := wr.RetryWithToken(func(token *string) (interface{}, error) { 83 params := &waf.CreateWebACLInput{ 84 ChangeToken: token, 85 DefaultAction: expandDefaultAction(d), 86 MetricName: aws.String(d.Get("metric_name").(string)), 87 Name: aws.String(d.Get("name").(string)), 88 } 89 90 return conn.CreateWebACL(params) 91 }) 92 if err != nil { 93 return err 94 } 95 resp := out.(*waf.CreateWebACLOutput) 96 d.SetId(*resp.WebACL.WebACLId) 97 return resourceAwsWafWebAclUpdate(d, meta) 98 } 99 100 func resourceAwsWafWebAclRead(d *schema.ResourceData, meta interface{}) error { 101 conn := meta.(*AWSClient).wafconn 102 params := &waf.GetWebACLInput{ 103 WebACLId: aws.String(d.Id()), 104 } 105 106 resp, err := conn.GetWebACL(params) 107 if err != nil { 108 if awsErr, ok := err.(awserr.Error); ok && awsErr.Code() == "WAFNonexistentItemException" { 109 log.Printf("[WARN] WAF ACL (%s) not found, error code (404)", d.Id()) 110 d.SetId("") 111 return nil 112 } 113 114 return err 115 } 116 117 defaultAction := flattenDefaultAction(resp.WebACL.DefaultAction) 118 if defaultAction != nil { 119 if err := d.Set("default_action", defaultAction); err != nil { 120 return fmt.Errorf("error setting default_action: %s", err) 121 } 122 } 123 d.Set("name", resp.WebACL.Name) 124 d.Set("metric_name", resp.WebACL.MetricName) 125 126 return nil 127 } 128 129 func resourceAwsWafWebAclUpdate(d *schema.ResourceData, meta interface{}) error { 130 err := updateWebAclResource(d, meta, waf.ChangeActionInsert) 131 if err != nil { 132 return fmt.Errorf("Error Updating WAF ACL: %s", err) 133 } 134 return resourceAwsWafWebAclRead(d, meta) 135 } 136 137 func resourceAwsWafWebAclDelete(d *schema.ResourceData, meta interface{}) error { 138 conn := meta.(*AWSClient).wafconn 139 err := updateWebAclResource(d, meta, waf.ChangeActionDelete) 140 if err != nil { 141 return fmt.Errorf("Error Removing WAF ACL Rules: %s", err) 142 } 143 144 wr := newWafRetryer(conn, "global") 145 _, err = wr.RetryWithToken(func(token *string) (interface{}, error) { 146 req := &waf.DeleteWebACLInput{ 147 ChangeToken: token, 148 WebACLId: aws.String(d.Id()), 149 } 150 151 log.Printf("[INFO] Deleting WAF ACL") 152 return conn.DeleteWebACL(req) 153 }) 154 if err != nil { 155 return fmt.Errorf("Error Deleting WAF ACL: %s", err) 156 } 157 return nil 158 } 159 160 func updateWebAclResource(d *schema.ResourceData, meta interface{}, ChangeAction string) error { 161 conn := meta.(*AWSClient).wafconn 162 163 wr := newWafRetryer(conn, "global") 164 _, err := wr.RetryWithToken(func(token *string) (interface{}, error) { 165 req := &waf.UpdateWebACLInput{ 166 ChangeToken: token, 167 WebACLId: aws.String(d.Id()), 168 } 169 170 if d.HasChange("default_action") { 171 req.DefaultAction = expandDefaultAction(d) 172 } 173 174 rules := d.Get("rules").(*schema.Set) 175 for _, rule := range rules.List() { 176 aclRule := rule.(map[string]interface{}) 177 action := aclRule["action"].(*schema.Set).List()[0].(map[string]interface{}) 178 aclRuleUpdate := &waf.WebACLUpdate{ 179 Action: aws.String(ChangeAction), 180 ActivatedRule: &waf.ActivatedRule{ 181 Priority: aws.Int64(int64(aclRule["priority"].(int))), 182 RuleId: aws.String(aclRule["rule_id"].(string)), 183 Action: &waf.WafAction{Type: aws.String(action["type"].(string))}, 184 }, 185 } 186 req.Updates = append(req.Updates, aclRuleUpdate) 187 } 188 return conn.UpdateWebACL(req) 189 }) 190 if err != nil { 191 return fmt.Errorf("Error Updating WAF ACL: %s", err) 192 } 193 return nil 194 } 195 196 func expandDefaultAction(d *schema.ResourceData) *waf.WafAction { 197 set, ok := d.GetOk("default_action") 198 if !ok { 199 return nil 200 } 201 202 s := set.(*schema.Set).List() 203 if s == nil || len(s) == 0 { 204 return nil 205 } 206 207 if s[0] == nil { 208 log.Printf("[ERR] First element of Default Action is set to nil") 209 return nil 210 } 211 212 dA := s[0].(map[string]interface{}) 213 214 return &waf.WafAction{ 215 Type: aws.String(dA["type"].(string)), 216 } 217 } 218 219 func flattenDefaultAction(n *waf.WafAction) []map[string]interface{} { 220 if n == nil { 221 return nil 222 } 223 224 m := setMap(make(map[string]interface{})) 225 226 m.SetString("type", n.Type) 227 return m.MapList() 228 }