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