From b5df47efc9cd0da69a56b8e94eb0d561cc1eac6d Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Tue, 17 Feb 2015 15:48:15 -0800 Subject: [PATCH 1/2] providers/aws: support updating ASG launch config [GH-904] --- builtin/providers/aws/resource_aws_autoscaling_group.go | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/builtin/providers/aws/resource_aws_autoscaling_group.go b/builtin/providers/aws/resource_aws_autoscaling_group.go index 69faf309c..e15132948 100644 --- a/builtin/providers/aws/resource_aws_autoscaling_group.go +++ b/builtin/providers/aws/resource_aws_autoscaling_group.go @@ -29,7 +29,6 @@ func resourceAwsAutoscalingGroup() *schema.Resource { "launch_configuration": &schema.Schema{ Type: schema.TypeString, Required: true, - ForceNew: true, }, "desired_capacity": &schema.Schema{ @@ -214,6 +213,10 @@ func resourceAwsAutoscalingGroupUpdate(d *schema.ResourceData, meta interface{}) opts.SetDesiredCapacity = true } + if d.HasChange("launch_configuration") { + opts.LaunchConfigurationName = d.Get("launch_configuration").(string) + } + if d.HasChange("min_size") { opts.MinSize = d.Get("min_size").(int) opts.SetMinSize = true From 5a64d0900b66f4771f3f4b49c03a742b70136dd4 Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Tue, 17 Feb 2015 16:12:02 -0800 Subject: [PATCH 2/2] providers/aws: test for allowing in-place lC update --- .../aws/resource_aws_autoscaling_group.go | 6 +++--- .../aws/resource_aws_autoscaling_group_test.go | 12 +++++++++++- helper/resource/testing.go | 9 +++++++++ helper/schema/resource_data.go | 18 +++++++++++------- 4 files changed, 34 insertions(+), 11 deletions(-) diff --git a/builtin/providers/aws/resource_aws_autoscaling_group.go b/builtin/providers/aws/resource_aws_autoscaling_group.go index e15132948..d51e47865 100644 --- a/builtin/providers/aws/resource_aws_autoscaling_group.go +++ b/builtin/providers/aws/resource_aws_autoscaling_group.go @@ -149,17 +149,17 @@ func resourceAwsAutoscalingGroupCreate(d *schema.ResourceData, meta interface{}) autoScalingGroupOpts.SetHealthCheckGracePeriod = true } - if v, ok := d.GetOk("load_balancers"); ok { + if v, ok := d.GetOk("load_balancers"); ok && v.(*schema.Set).Len() > 0 { autoScalingGroupOpts.LoadBalancerNames = expandStringList( v.(*schema.Set).List()) } - if v, ok := d.GetOk("vpc_zone_identifier"); ok { + if v, ok := d.GetOk("vpc_zone_identifier"); ok && v.(*schema.Set).Len() > 0 { autoScalingGroupOpts.VPCZoneIdentifier = expandStringList( v.(*schema.Set).List()) } - if v, ok := d.GetOk("termination_policies"); ok { + if v, ok := d.GetOk("termination_policies"); ok && v.(*schema.Set).Len() > 0 { autoScalingGroupOpts.TerminationPolicies = expandStringList( v.(*schema.Set).List()) } diff --git a/builtin/providers/aws/resource_aws_autoscaling_group_test.go b/builtin/providers/aws/resource_aws_autoscaling_group_test.go index fde9f31ad..531d51843 100644 --- a/builtin/providers/aws/resource_aws_autoscaling_group_test.go +++ b/builtin/providers/aws/resource_aws_autoscaling_group_test.go @@ -11,6 +11,7 @@ import ( func TestAccAWSAutoScalingGroup_basic(t *testing.T) { var group autoscaling.AutoScalingGroup + var lc autoscaling.LaunchConfiguration resource.Test(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, @@ -47,8 +48,11 @@ func TestAccAWSAutoScalingGroup_basic(t *testing.T) { Config: testAccAWSAutoScalingGroupConfigUpdate, Check: resource.ComposeTestCheckFunc( testAccCheckAWSAutoScalingGroupExists("aws_autoscaling_group.bar", &group), + testAccCheckAWSLaunchConfigurationExists("aws_launch_configuration.new", &lc), resource.TestCheckResourceAttr( "aws_autoscaling_group.bar", "desired_capacity", "5"), + resource.TestCheckResourceAttrPtr( + "aws_autoscaling_group.bar", "launch_configuration", &lc.Name), ), }, }, @@ -217,6 +221,12 @@ resource "aws_launch_configuration" "foobar" { instance_type = "t1.micro" } +resource "aws_launch_configuration" "new" { + name = "foobarautoscaling-terraform-test-new" + image_id = "ami-21f78e11" + instance_type = "t1.micro" +} + resource "aws_autoscaling_group" "bar" { availability_zones = ["us-west-2a"] name = "foobar3-terraform-test" @@ -227,7 +237,7 @@ resource "aws_autoscaling_group" "bar" { desired_capacity = 5 force_delete = true - launch_configuration = "${aws_launch_configuration.foobar.name}" + launch_configuration = "${aws_launch_configuration.new.name}" } ` diff --git a/helper/resource/testing.go b/helper/resource/testing.go index 89b73e200..cedadfc72 100644 --- a/helper/resource/testing.go +++ b/helper/resource/testing.go @@ -275,6 +275,15 @@ func TestCheckResourceAttr(name, key, value string) TestCheckFunc { } } +// TestCheckResourceAttrPtr is like TestCheckResourceAttr except the +// value is a pointer so that it can be updated while the test is running. +// It will only be dereferenced at the point this step is run. +func TestCheckResourceAttrPtr(name string, key string, value *string) TestCheckFunc { + return func(s *terraform.State) error { + return TestCheckResourceAttr(name, key, *value)(s) + } +} + // TestT is the interface used to handle the test lifecycle of a test. // // Users should just use a *testing.T object, which implements this. diff --git a/helper/schema/resource_data.go b/helper/schema/resource_data.go index b4feff220..892fcedcf 100644 --- a/helper/schema/resource_data.go +++ b/helper/schema/resource_data.go @@ -70,13 +70,14 @@ func (d *ResourceData) GetChange(key string) (interface{}, interface{}) { } // GetOk returns the data for the given key and whether or not the key -// has been set. +// has been set to a non-zero value at some point. // // The first result will not necessarilly be nil if the value doesn't exist. // The second result should be checked to determine this information. func (d *ResourceData) GetOk(key string) (interface{}, bool) { r := d.getRaw(key, getSourceSet) - return r.Value, r.Exists && !r.Computed + exists := r.Exists && !r.Computed + return r.Value, exists } func (d *ResourceData) getRaw(key string, level getSource) getResult { @@ -361,11 +362,13 @@ func (d *ResourceData) get(addr []string, source getSource) getResult { } // If the result doesn't exist, then we set the value to the zero value - if result.Value == nil { - if schemaL := addrToSchema(addr, d.schema); len(schemaL) > 0 { - schema := schemaL[len(schemaL)-1] - result.Value = result.ValueOrZero(schema) - } + var schema *Schema + if schemaL := addrToSchema(addr, d.schema); len(schemaL) > 0 { + schema = schemaL[len(schemaL)-1] + } + + if result.Value == nil && schema != nil { + result.Value = result.ValueOrZero(schema) } // Transform the FieldReadResult into a getResult. It might be worth @@ -375,5 +378,6 @@ func (d *ResourceData) get(addr []string, source getSource) getResult { ValueProcessed: result.ValueProcessed, Computed: result.Computed, Exists: result.Exists, + Schema: schema, } }