github.com/vtorhonen/terraform@v0.9.0-beta2.0.20170307220345-5d894e4ffda7/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 }, 44 "rules": &schema.Schema{ 45 Type: schema.TypeSet, 46 Optional: true, 47 Elem: &schema.Resource{ 48 Schema: map[string]*schema.Schema{ 49 "action": &schema.Schema{ 50 Type: schema.TypeSet, 51 Required: true, 52 MaxItems: 1, 53 Elem: &schema.Resource{ 54 Schema: map[string]*schema.Schema{ 55 "type": &schema.Schema{ 56 Type: schema.TypeString, 57 Required: true, 58 }, 59 }, 60 }, 61 }, 62 "priority": &schema.Schema{ 63 Type: schema.TypeInt, 64 Required: true, 65 }, 66 "rule_id": &schema.Schema{ 67 Type: schema.TypeString, 68 Required: true, 69 }, 70 }, 71 }, 72 }, 73 }, 74 } 75 } 76 77 func resourceAwsWafWebAclCreate(d *schema.ResourceData, meta interface{}) error { 78 conn := meta.(*AWSClient).wafconn 79 80 // ChangeToken 81 var ct *waf.GetChangeTokenInput 82 83 res, err := conn.GetChangeToken(ct) 84 if err != nil { 85 return fmt.Errorf("Error getting change token: %s", err) 86 } 87 88 params := &waf.CreateWebACLInput{ 89 ChangeToken: res.ChangeToken, 90 DefaultAction: expandDefaultAction(d), 91 MetricName: aws.String(d.Get("metric_name").(string)), 92 Name: aws.String(d.Get("name").(string)), 93 } 94 95 resp, err := conn.CreateWebACL(params) 96 if err != nil { 97 return err 98 } 99 d.SetId(*resp.WebACL.WebACLId) 100 return resourceAwsWafWebAclUpdate(d, meta) 101 } 102 103 func resourceAwsWafWebAclRead(d *schema.ResourceData, meta interface{}) error { 104 conn := meta.(*AWSClient).wafconn 105 params := &waf.GetWebACLInput{ 106 WebACLId: aws.String(d.Id()), 107 } 108 109 resp, err := conn.GetWebACL(params) 110 if err != nil { 111 if awsErr, ok := err.(awserr.Error); ok && awsErr.Code() == "WAFNonexistentItemException" { 112 log.Printf("[WARN] WAF ACL (%s) not found, error code (404)", d.Id()) 113 d.SetId("") 114 return nil 115 } 116 117 return err 118 } 119 120 defaultAction := flattenDefaultAction(resp.WebACL.DefaultAction) 121 if defaultAction != nil { 122 if err := d.Set("default_action", defaultAction); err != nil { 123 return fmt.Errorf("error setting default_action: %s", err) 124 } 125 } 126 d.Set("name", resp.WebACL.Name) 127 d.Set("metric_name", resp.WebACL.MetricName) 128 129 return nil 130 } 131 132 func resourceAwsWafWebAclUpdate(d *schema.ResourceData, meta interface{}) error { 133 err := updateWebAclResource(d, meta, waf.ChangeActionInsert) 134 if err != nil { 135 return fmt.Errorf("Error Updating WAF ACL: %s", err) 136 } 137 return resourceAwsWafWebAclRead(d, meta) 138 } 139 140 func resourceAwsWafWebAclDelete(d *schema.ResourceData, meta interface{}) error { 141 conn := meta.(*AWSClient).wafconn 142 err := updateWebAclResource(d, meta, waf.ChangeActionDelete) 143 if err != nil { 144 return fmt.Errorf("Error Removing WAF ACL Rules: %s", err) 145 } 146 147 var ct *waf.GetChangeTokenInput 148 149 resp, err := conn.GetChangeToken(ct) 150 151 req := &waf.DeleteWebACLInput{ 152 ChangeToken: resp.ChangeToken, 153 WebACLId: aws.String(d.Id()), 154 } 155 156 log.Printf("[INFO] Deleting WAF ACL") 157 _, err = conn.DeleteWebACL(req) 158 159 if err != nil { 160 return fmt.Errorf("Error Deleting WAF ACL: %s", err) 161 } 162 return nil 163 } 164 165 func updateWebAclResource(d *schema.ResourceData, meta interface{}, ChangeAction string) error { 166 conn := meta.(*AWSClient).wafconn 167 // ChangeToken 168 var ct *waf.GetChangeTokenInput 169 170 resp, err := conn.GetChangeToken(ct) 171 if err != nil { 172 return fmt.Errorf("Error getting change token: %s", err) 173 } 174 175 req := &waf.UpdateWebACLInput{ 176 ChangeToken: resp.ChangeToken, 177 WebACLId: aws.String(d.Id()), 178 } 179 180 if d.HasChange("default_action") { 181 req.DefaultAction = expandDefaultAction(d) 182 } 183 184 rules := d.Get("rules").(*schema.Set) 185 for _, rule := range rules.List() { 186 aclRule := rule.(map[string]interface{}) 187 action := aclRule["action"].(*schema.Set).List()[0].(map[string]interface{}) 188 aclRuleUpdate := &waf.WebACLUpdate{ 189 Action: aws.String(ChangeAction), 190 ActivatedRule: &waf.ActivatedRule{ 191 Priority: aws.Int64(int64(aclRule["priority"].(int))), 192 RuleId: aws.String(aclRule["rule_id"].(string)), 193 Action: &waf.WafAction{Type: aws.String(action["type"].(string))}, 194 }, 195 } 196 req.Updates = append(req.Updates, aclRuleUpdate) 197 } 198 _, err = conn.UpdateWebACL(req) 199 if err != nil { 200 return fmt.Errorf("Error Updating WAF ACL: %s", err) 201 } 202 return nil 203 } 204 205 func expandDefaultAction(d *schema.ResourceData) *waf.WafAction { 206 set, ok := d.GetOk("default_action") 207 if !ok { 208 return nil 209 } 210 211 s := set.(*schema.Set).List() 212 if s == nil || len(s) == 0 { 213 return nil 214 } 215 216 if s[0] == nil { 217 log.Printf("[ERR] First element of Default Action is set to nil") 218 return nil 219 } 220 221 dA := s[0].(map[string]interface{}) 222 223 return &waf.WafAction{ 224 Type: aws.String(dA["type"].(string)), 225 } 226 } 227 228 func flattenDefaultAction(n *waf.WafAction) []map[string]interface{} { 229 if n == nil { 230 return nil 231 } 232 233 m := setMap(make(map[string]interface{})) 234 235 m.SetString("type", n.Type) 236 return m.MapList() 237 }