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  }