github.com/vtorhonen/terraform@v0.9.0-beta2.0.20170307220345-5d894e4ffda7/builtin/providers/aws/resource_aws_autoscaling_notification.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/autoscaling" 10 "github.com/hashicorp/terraform/helper/schema" 11 ) 12 13 func resourceAwsAutoscalingNotification() *schema.Resource { 14 return &schema.Resource{ 15 Create: resourceAwsAutoscalingNotificationCreate, 16 Read: resourceAwsAutoscalingNotificationRead, 17 Update: resourceAwsAutoscalingNotificationUpdate, 18 Delete: resourceAwsAutoscalingNotificationDelete, 19 20 Schema: map[string]*schema.Schema{ 21 "topic_arn": &schema.Schema{ 22 Type: schema.TypeString, 23 Required: true, 24 ForceNew: true, 25 }, 26 27 "group_names": &schema.Schema{ 28 Type: schema.TypeSet, 29 Required: true, 30 Elem: &schema.Schema{Type: schema.TypeString}, 31 Set: schema.HashString, 32 }, 33 34 "notifications": &schema.Schema{ 35 Type: schema.TypeSet, 36 Required: true, 37 Elem: &schema.Schema{Type: schema.TypeString}, 38 Set: schema.HashString, 39 }, 40 }, 41 } 42 } 43 44 func resourceAwsAutoscalingNotificationCreate(d *schema.ResourceData, meta interface{}) error { 45 conn := meta.(*AWSClient).autoscalingconn 46 gl := convertSetToList(d.Get("group_names").(*schema.Set)) 47 nl := convertSetToList(d.Get("notifications").(*schema.Set)) 48 49 topic := d.Get("topic_arn").(string) 50 if err := addNotificationConfigToGroupsWithTopic(conn, gl, nl, topic); err != nil { 51 return err 52 } 53 54 // ARNs are unique, and these notifications are per ARN, so we re-use the ARN 55 // here as the ID 56 d.SetId(topic) 57 return resourceAwsAutoscalingNotificationRead(d, meta) 58 } 59 60 func resourceAwsAutoscalingNotificationRead(d *schema.ResourceData, meta interface{}) error { 61 conn := meta.(*AWSClient).autoscalingconn 62 gl := convertSetToList(d.Get("group_names").(*schema.Set)) 63 64 opts := &autoscaling.DescribeNotificationConfigurationsInput{ 65 AutoScalingGroupNames: gl, 66 } 67 68 topic := d.Get("topic_arn").(string) 69 // Grab all applicable notifcation configurations for this Topic. 70 // Each NotificationType will have a record, so 1 Group with 3 Types results 71 // in 3 records, all with the same Group name 72 gRaw := make(map[string]bool) 73 nRaw := make(map[string]bool) 74 75 i := 0 76 err := conn.DescribeNotificationConfigurationsPages(opts, func(resp *autoscaling.DescribeNotificationConfigurationsOutput, lastPage bool) bool { 77 if resp != nil { 78 i++ 79 log.Printf("[DEBUG] Paging DescribeNotificationConfigurations for (%s), page: %d", d.Id(), i) 80 } else { 81 log.Printf("[DEBUG] Paging finished for DescribeNotificationConfigurations (%s)", d.Id()) 82 } 83 84 for _, n := range resp.NotificationConfigurations { 85 if *n.TopicARN == topic { 86 gRaw[*n.AutoScalingGroupName] = true 87 nRaw[*n.NotificationType] = true 88 } 89 } 90 return true // return false to stop paging 91 }) 92 if err != nil { 93 return err 94 } 95 96 // Grab the keys here as the list of Groups 97 var gList []string 98 for k, _ := range gRaw { 99 gList = append(gList, k) 100 } 101 102 // Grab the keys here as the list of Types 103 var nList []string 104 for k, _ := range nRaw { 105 nList = append(nList, k) 106 } 107 108 if err := d.Set("group_names", gList); err != nil { 109 return err 110 } 111 if err := d.Set("notifications", nList); err != nil { 112 return err 113 } 114 115 return nil 116 } 117 118 func resourceAwsAutoscalingNotificationUpdate(d *schema.ResourceData, meta interface{}) error { 119 conn := meta.(*AWSClient).autoscalingconn 120 121 // Notifications API call is a PUT, so we don't need to diff the list, just 122 // push whatever it is and AWS sorts it out 123 nl := convertSetToList(d.Get("notifications").(*schema.Set)) 124 125 o, n := d.GetChange("group_names") 126 if o == nil { 127 o = new(schema.Set) 128 } 129 if n == nil { 130 n = new(schema.Set) 131 } 132 133 os := o.(*schema.Set) 134 ns := n.(*schema.Set) 135 remove := convertSetToList(os.Difference(ns)) 136 add := convertSetToList(ns.Difference(os)) 137 138 topic := d.Get("topic_arn").(string) 139 140 if err := removeNotificationConfigToGroupsWithTopic(conn, remove, topic); err != nil { 141 return err 142 } 143 144 var update []*string 145 if d.HasChange("notifications") { 146 update = convertSetToList(d.Get("group_names").(*schema.Set)) 147 } else { 148 update = add 149 } 150 151 if err := addNotificationConfigToGroupsWithTopic(conn, update, nl, topic); err != nil { 152 return err 153 } 154 155 return resourceAwsAutoscalingNotificationRead(d, meta) 156 } 157 158 func addNotificationConfigToGroupsWithTopic(conn *autoscaling.AutoScaling, groups []*string, nl []*string, topic string) error { 159 for _, a := range groups { 160 opts := &autoscaling.PutNotificationConfigurationInput{ 161 AutoScalingGroupName: a, 162 NotificationTypes: nl, 163 TopicARN: aws.String(topic), 164 } 165 166 _, err := conn.PutNotificationConfiguration(opts) 167 if err != nil { 168 if awsErr, ok := err.(awserr.Error); ok { 169 return fmt.Errorf("[WARN] Error creating Autoscaling Group Notification for Group %s, error: \"%s\", code: \"%s\"", *a, awsErr.Message(), awsErr.Code()) 170 } 171 return err 172 } 173 } 174 return nil 175 } 176 177 func removeNotificationConfigToGroupsWithTopic(conn *autoscaling.AutoScaling, groups []*string, topic string) error { 178 for _, r := range groups { 179 opts := &autoscaling.DeleteNotificationConfigurationInput{ 180 AutoScalingGroupName: r, 181 TopicARN: aws.String(topic), 182 } 183 184 _, err := conn.DeleteNotificationConfiguration(opts) 185 if err != nil { 186 return fmt.Errorf("[WARN] Error deleting notification configuration for ASG \"%s\", Topic ARN \"%s\"", *r, topic) 187 } 188 } 189 return nil 190 } 191 192 func resourceAwsAutoscalingNotificationDelete(d *schema.ResourceData, meta interface{}) error { 193 conn := meta.(*AWSClient).autoscalingconn 194 gl := convertSetToList(d.Get("group_names").(*schema.Set)) 195 196 topic := d.Get("topic_arn").(string) 197 if err := removeNotificationConfigToGroupsWithTopic(conn, gl, topic); err != nil { 198 return err 199 } 200 201 return nil 202 } 203 204 func convertSetToList(s *schema.Set) (nl []*string) { 205 l := s.List() 206 for _, n := range l { 207 nl = append(nl, aws.String(n.(string))) 208 } 209 210 return nl 211 }