github.com/ezbercih/terraform@v0.1.1-0.20140729011846-3c33865e0839/builtin/providers/aws/resource_aws_autoscaling_group.go (about) 1 package aws 2 3 import ( 4 "fmt" 5 "log" 6 "strconv" 7 8 "github.com/hashicorp/terraform/flatmap" 9 "github.com/hashicorp/terraform/helper/config" 10 "github.com/hashicorp/terraform/helper/diff" 11 "github.com/hashicorp/terraform/terraform" 12 "github.com/mitchellh/goamz/autoscaling" 13 ) 14 15 func resource_aws_autoscaling_group_create( 16 s *terraform.ResourceState, 17 d *terraform.ResourceDiff, 18 meta interface{}) (*terraform.ResourceState, error) { 19 p := meta.(*ResourceProvider) 20 autoscalingconn := p.autoscalingconn 21 22 // Merge the diff into the state so that we have all the attributes 23 // properly. 24 rs := s.MergeDiff(d) 25 26 var err error 27 autoScalingGroupOpts := autoscaling.CreateAutoScalingGroup{} 28 29 if rs.Attributes["min_size"] != "" { 30 autoScalingGroupOpts.MinSize, err = strconv.Atoi(rs.Attributes["min_size"]) 31 autoScalingGroupOpts.SetMinSize = true 32 } 33 34 if rs.Attributes["max_size"] != "" { 35 autoScalingGroupOpts.MaxSize, err = strconv.Atoi(rs.Attributes["max_size"]) 36 autoScalingGroupOpts.SetMaxSize = true 37 } 38 39 if rs.Attributes["default_cooldown"] != "" { 40 autoScalingGroupOpts.DefaultCooldown, err = strconv.Atoi(rs.Attributes["default_cooldown"]) 41 autoScalingGroupOpts.SetDefaultCooldown = true 42 } 43 44 if rs.Attributes["desired_capicity"] != "" { 45 autoScalingGroupOpts.DesiredCapacity, err = strconv.Atoi(rs.Attributes["desired_capicity"]) 46 autoScalingGroupOpts.SetDesiredCapacity = true 47 } 48 49 if rs.Attributes["health_check_grace_period"] != "" { 50 autoScalingGroupOpts.HealthCheckGracePeriod, err = strconv.Atoi(rs.Attributes["health_check_grace_period"]) 51 autoScalingGroupOpts.SetHealthCheckGracePeriod = true 52 } 53 54 if err != nil { 55 return nil, fmt.Errorf("Error parsing configuration: %s", err) 56 } 57 58 if _, ok := rs.Attributes["availability_zones.#"]; ok { 59 autoScalingGroupOpts.AvailZone = expandStringList(flatmap.Expand( 60 rs.Attributes, "availability_zones").([]interface{})) 61 } 62 63 if _, ok := rs.Attributes["load_balancers.#"]; ok { 64 autoScalingGroupOpts.LoadBalancerNames = expandStringList(flatmap.Expand( 65 rs.Attributes, "load_balancers").([]interface{})) 66 } 67 68 if _, ok := rs.Attributes["vpc_identifier.#"]; ok { 69 autoScalingGroupOpts.VPCZoneIdentifier = expandStringList(flatmap.Expand( 70 rs.Attributes, "vpc_identifier").([]interface{})) 71 } 72 73 autoScalingGroupOpts.Name = rs.Attributes["name"] 74 autoScalingGroupOpts.HealthCheckType = rs.Attributes["health_check_type"] 75 autoScalingGroupOpts.LaunchConfigurationName = rs.Attributes["launch_configuration"] 76 77 log.Printf("[DEBUG] AutoScaling Group create configuration: %#v", autoScalingGroupOpts) 78 _, err = autoscalingconn.CreateAutoScalingGroup(&autoScalingGroupOpts) 79 if err != nil { 80 return nil, fmt.Errorf("Error creating AutoScaling Group: %s", err) 81 } 82 83 rs.ID = rs.Attributes["name"] 84 rs.Dependencies = []terraform.ResourceDependency{ 85 terraform.ResourceDependency{ID: rs.Attributes["launch_configuration"]}, 86 } 87 88 log.Printf("[INFO] AutoScaling Group ID: %s", rs.ID) 89 90 g, err := resource_aws_autoscaling_group_retrieve(rs.ID, autoscalingconn) 91 if err != nil { 92 return rs, err 93 } 94 95 return resource_aws_autoscaling_group_update_state(rs, g) 96 } 97 98 func resource_aws_autoscaling_group_update( 99 s *terraform.ResourceState, 100 d *terraform.ResourceDiff, 101 meta interface{}) (*terraform.ResourceState, error) { 102 p := meta.(*ResourceProvider) 103 autoscalingconn := p.autoscalingconn 104 rs := s.MergeDiff(d) 105 106 opts := autoscaling.UpdateAutoScalingGroup{ 107 Name: rs.ID, 108 } 109 110 var err error 111 112 if _, ok := d.Attributes["min_size"]; ok { 113 opts.MinSize, err = strconv.Atoi(rs.Attributes["min_size"]) 114 opts.SetMinSize = true 115 } 116 117 if _, ok := d.Attributes["max_size"]; ok { 118 opts.MaxSize, err = strconv.Atoi(rs.Attributes["max_size"]) 119 opts.SetMaxSize = true 120 } 121 122 if err != nil { 123 return s, fmt.Errorf("Error parsing configuration: %s", err) 124 } 125 126 log.Printf("[DEBUG] AutoScaling Group update configuration: %#v", opts) 127 128 _, err = autoscalingconn.UpdateAutoScalingGroup(&opts) 129 130 if err != nil { 131 return rs, fmt.Errorf("Error updating AutoScaling group: %s", err) 132 } 133 134 g, err := resource_aws_autoscaling_group_retrieve(rs.ID, autoscalingconn) 135 136 if err != nil { 137 return rs, err 138 } 139 140 return resource_aws_autoscaling_group_update_state(rs, g) 141 } 142 143 func resource_aws_autoscaling_group_destroy( 144 s *terraform.ResourceState, 145 meta interface{}) error { 146 p := meta.(*ResourceProvider) 147 autoscalingconn := p.autoscalingconn 148 149 log.Printf("[DEBUG] AutoScaling Group destroy: %v", s.ID) 150 151 deleteopts := autoscaling.DeleteAutoScalingGroup{Name: s.ID} 152 153 // You can force an autoscaling group to delete 154 // even if it's in the process of scaling a resource. 155 // Normally, you would set the min-size and max-size to 0,0 156 // and then delete the group. This bypasses that and leaves 157 // resources potentially dangling. 158 if s.Attributes["force_delete"] != "" { 159 deleteopts.ForceDelete = true 160 } 161 162 _, err := autoscalingconn.DeleteAutoScalingGroup(&deleteopts) 163 164 if err != nil { 165 autoscalingerr, ok := err.(*autoscaling.Error) 166 if ok && autoscalingerr.Code == "InvalidGroup.NotFound" { 167 return nil 168 } 169 return err 170 } 171 172 return nil 173 } 174 175 func resource_aws_autoscaling_group_refresh( 176 s *terraform.ResourceState, 177 meta interface{}) (*terraform.ResourceState, error) { 178 p := meta.(*ResourceProvider) 179 autoscalingconn := p.autoscalingconn 180 181 g, err := resource_aws_autoscaling_group_retrieve(s.ID, autoscalingconn) 182 183 if err != nil { 184 return s, err 185 } 186 187 return resource_aws_autoscaling_group_update_state(s, g) 188 } 189 190 func resource_aws_autoscaling_group_diff( 191 s *terraform.ResourceState, 192 c *terraform.ResourceConfig, 193 meta interface{}) (*terraform.ResourceDiff, error) { 194 195 b := &diff.ResourceBuilder{ 196 Attrs: map[string]diff.AttrType{ 197 "availability_zone": diff.AttrTypeCreate, 198 "default_cooldown": diff.AttrTypeCreate, 199 "desired_capicity": diff.AttrTypeCreate, 200 "force_delete": diff.AttrTypeCreate, 201 "health_check_grace_period": diff.AttrTypeCreate, 202 "health_check_type": diff.AttrTypeCreate, 203 "launch_configuration": diff.AttrTypeCreate, 204 "load_balancers": diff.AttrTypeCreate, 205 "name": diff.AttrTypeCreate, 206 "vpc_zone_identifier": diff.AttrTypeCreate, 207 208 "max_size": diff.AttrTypeUpdate, 209 "min_size": diff.AttrTypeUpdate, 210 }, 211 212 ComputedAttrs: []string{ 213 "health_check_grace_period", 214 "health_check_type", 215 "default_cooldown", 216 "vpc_zone_identifier", 217 "desired_capicity", 218 "force_delete", 219 }, 220 } 221 222 return b.Diff(s, c) 223 } 224 225 func resource_aws_autoscaling_group_update_state( 226 s *terraform.ResourceState, 227 g *autoscaling.AutoScalingGroup) (*terraform.ResourceState, error) { 228 229 s.Attributes["min_size"] = strconv.Itoa(g.MinSize) 230 s.Attributes["max_size"] = strconv.Itoa(g.MaxSize) 231 s.Attributes["default_cooldown"] = strconv.Itoa(g.DefaultCooldown) 232 s.Attributes["name"] = g.Name 233 s.Attributes["desired_capacity"] = strconv.Itoa(g.DesiredCapacity) 234 s.Attributes["health_check_grace_period"] = strconv.Itoa(g.HealthCheckGracePeriod) 235 s.Attributes["health_check_type"] = g.HealthCheckType 236 s.Attributes["launch_configuration"] = g.LaunchConfigurationName 237 s.Attributes["vpc_zone_identifier"] = g.VPCZoneIdentifier 238 239 // Flatten our group values 240 toFlatten := make(map[string]interface{}) 241 242 // Special case the return of amazons load balancers names in the XML having 243 // a blank entry 244 if len(g.LoadBalancerNames) > 0 && g.LoadBalancerNames[0].LoadBalancerName != "" { 245 toFlatten["load_balancers"] = flattenLoadBalancers(g.LoadBalancerNames) 246 } 247 248 toFlatten["availability_zones"] = flattenAvailabilityZones(g.AvailabilityZones) 249 250 for k, v := range flatmap.Flatten(toFlatten) { 251 s.Attributes[k] = v 252 } 253 254 return s, nil 255 } 256 257 // Returns a single group by it's ID 258 func resource_aws_autoscaling_group_retrieve(id string, autoscalingconn *autoscaling.AutoScaling) (*autoscaling.AutoScalingGroup, error) { 259 describeOpts := autoscaling.DescribeAutoScalingGroups{ 260 Names: []string{id}, 261 } 262 263 log.Printf("[DEBUG] AutoScaling Group describe configuration: %#v", describeOpts) 264 265 describeGroups, err := autoscalingconn.DescribeAutoScalingGroups(&describeOpts) 266 267 if err != nil { 268 return nil, fmt.Errorf("Error retrieving AutoScaling groups: %s", err) 269 } 270 271 // Verify AWS returned our sg 272 if len(describeGroups.AutoScalingGroups) != 1 || 273 describeGroups.AutoScalingGroups[0].Name != id { 274 if err != nil { 275 return nil, fmt.Errorf("Unable to find AutoScaling group: %#v", describeGroups.AutoScalingGroups) 276 } 277 } 278 279 g := describeGroups.AutoScalingGroups[0] 280 281 return &g, nil 282 } 283 284 func resource_aws_autoscaling_group_validation() *config.Validator { 285 return &config.Validator{ 286 Required: []string{ 287 "name", 288 "max_size", 289 "min_size", 290 "availability_zones.*", 291 "launch_configuration", 292 }, 293 Optional: []string{ 294 "health_check_grace_period", 295 "health_check_type", 296 "desired_capicity", 297 "force_delete", 298 }, 299 } 300 }