provider/aws: Improved Auto Scaling Groups updates

- availability zones are optional if you specify a VPC Zone Identifier (subnet)
- availability zones can be updated in place
This commit is contained in:
Clint Shryock 2015-07-14 10:19:10 -05:00
parent e28671490a
commit ed98e02e4a
2 changed files with 179 additions and 11 deletions

View File

@ -91,8 +91,7 @@ func resourceAwsAutoscalingGroup() *schema.Resource {
"availability_zones": &schema.Schema{
Type: schema.TypeSet,
Required: true,
ForceNew: true,
Optional: true,
Elem: &schema.Schema{Type: schema.TypeString},
Set: schema.HashString,
},
@ -108,7 +107,6 @@ func resourceAwsAutoscalingGroup() *schema.Resource {
Type: schema.TypeSet,
Optional: true,
Computed: true,
ForceNew: true,
Elem: &schema.Schema{Type: schema.TypeString},
Set: schema.HashString,
},
@ -135,8 +133,11 @@ func resourceAwsAutoscalingGroupCreate(d *schema.ResourceData, meta interface{})
autoScalingGroupOpts.LaunchConfigurationName = aws.String(d.Get("launch_configuration").(string))
autoScalingGroupOpts.MinSize = aws.Long(int64(d.Get("min_size").(int)))
autoScalingGroupOpts.MaxSize = aws.Long(int64(d.Get("max_size").(int)))
autoScalingGroupOpts.AvailabilityZones = expandStringList(
d.Get("availability_zones").(*schema.Set).List())
// Availability Zones are optional if VPC Zone Identifer(s) are specified
if v, ok := d.GetOk("availability_zones"); ok && v.(*schema.Set).Len() > 0 {
autoScalingGroupOpts.AvailabilityZones = expandStringList(v.(*schema.Set).List())
}
if v, ok := d.GetOk("tag"); ok {
autoScalingGroupOpts.Tags = autoscalingTagsFromMap(
@ -165,12 +166,7 @@ func resourceAwsAutoscalingGroupCreate(d *schema.ResourceData, meta interface{})
}
if v, ok := d.GetOk("vpc_zone_identifier"); ok && v.(*schema.Set).Len() > 0 {
exp := expandStringList(v.(*schema.Set).List())
strs := make([]string, len(exp))
for _, s := range exp {
strs = append(strs, *s)
}
autoScalingGroupOpts.VPCZoneIdentifier = aws.String(strings.Join(strs, ","))
autoScalingGroupOpts.VPCZoneIdentifier = expandVpcZoneIdentifiers(v.(*schema.Set).List())
}
if v, ok := d.GetOk("termination_policies"); ok && v.(*schema.Set).Len() > 0 {
@ -256,6 +252,16 @@ func resourceAwsAutoscalingGroupUpdate(d *schema.ResourceData, meta interface{})
opts.HealthCheckType = aws.String(d.Get("health_check_type").(string))
}
if d.HasChange("vpc_zone_identifier") {
opts.VPCZoneIdentifier = expandVpcZoneIdentifiers(d.Get("vpc_zone_identifier").(*schema.Set).List())
}
if d.HasChange("availability_zones") {
if v, ok := d.GetOk("availability_zones"); ok && v.(*schema.Set).Len() > 0 {
opts.AvailabilityZones = expandStringList(d.Get("availability_zones").(*schema.Set).List())
}
}
if err := setAutoscalingTags(conn, d); err != nil {
return err
} else {
@ -538,3 +544,11 @@ func getLBInstanceStates(g *autoscaling.Group, meta interface{}) (map[string]map
return lbInstanceStates, nil
}
func expandVpcZoneIdentifiers(list []interface{}) *string {
strs := make([]string, len(list))
for _, s := range list {
strs = append(strs, s.(string))
}
return aws.String(strings.Join(strs, ","))
}

View File

@ -101,6 +101,32 @@ func TestAccAWSAutoScalingGroup_tags(t *testing.T) {
})
}
func TestAccAWSAutoScalingGroup_VpcUpdates(t *testing.T) {
var group autoscaling.Group
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckAWSAutoScalingGroupDestroy,
Steps: []resource.TestStep{
resource.TestStep{
Config: testAccAWSAutoScalingGroupConfigWithAZ,
Check: resource.ComposeTestCheckFunc(
testAccCheckAWSAutoScalingGroupExists("aws_autoscaling_group.bar", &group),
),
},
resource.TestStep{
Config: testAccAWSAutoScalingGroupConfigWithVPCIdent,
Check: resource.ComposeTestCheckFunc(
testAccCheckAWSAutoScalingGroupExists("aws_autoscaling_group.bar", &group),
testAccCheckAWSAutoScalingGroupAttributesVPCZoneIdentifer(&group),
),
},
},
})
}
func TestAccAWSAutoScalingGroup_WithLoadBalancer(t *testing.T) {
var group autoscaling.Group
@ -284,6 +310,39 @@ func testAccCheckAWSAutoScalingGroupHealthyCapacity(
}
}
func testAccCheckAWSAutoScalingGroupAttributesVPCZoneIdentifer(group *autoscaling.Group) resource.TestCheckFunc {
return func(s *terraform.State) error {
// Grab Subnet Ids
var subnets []string
for _, rs := range s.RootModule().Resources {
if rs.Type != "aws_subnet" {
continue
}
subnets = append(subnets, rs.Primary.Attributes["id"])
}
if group.VPCZoneIdentifier == nil || *group.VPCZoneIdentifier != "" {
return fmt.Errorf("Bad VPC Zone Identifier\nexpected: %s\ngot nil", subnets)
}
zones := strings.Split(*group.VPCZoneIdentifier, ",")
remaining := len(zones)
for _, z := range zones {
for _, s := range subnets {
if z == s {
remaining--
}
}
}
if remaining != 0 {
return fmt.Errorf("Bad VPC Zone Identifier match\nexpected: %s\ngot:%s", zones, subnets)
}
return nil
}
}
const testAccAWSAutoScalingGroupConfig = `
resource "aws_launch_configuration" "foobar" {
image_id = "ami-21f78e11"
@ -421,3 +480,98 @@ resource "aws_autoscaling_group" "bar" {
load_balancers = ["${aws_elb.bar.name}"]
}
`
const testAccAWSAutoScalingGroupConfigWithAZ = `
resource "aws_vpc" "default" {
cidr_block = "10.0.0.0/16"
tags {
Name = "terraform-test"
}
}
resource "aws_subnet" "main" {
vpc_id = "${aws_vpc.default.id}"
cidr_block = "10.0.1.0/24"
availability_zone = "us-west-2a"
tags {
Name = "terraform-test"
}
}
resource "aws_subnet" "alt" {
vpc_id = "${aws_vpc.default.id}"
cidr_block = "10.0.2.0/24"
availability_zone = "us-west-2b"
tags {
Name = "asg-vpc-thing"
}
}
resource "aws_launch_configuration" "foobar" {
name = "vpc-asg-test"
image_id = "ami-b5b3fc85"
instance_type = "t2.micro"
}
resource "aws_autoscaling_group" "bar" {
availability_zones = ["us-west-2a"]
name = "vpc-asg-test"
max_size = 1
min_size = 1
health_check_grace_period = 300
health_check_type = "ELB"
desired_capacity = 1
force_delete = true
termination_policies = ["OldestInstance"]
launch_configuration = "${aws_launch_configuration.foobar.name}"
}
`
const testAccAWSAutoScalingGroupConfigWithVPCIdent = `
resource "aws_vpc" "default" {
cidr_block = "10.0.0.0/16"
tags {
Name = "terraform-test"
}
}
resource "aws_subnet" "main" {
vpc_id = "${aws_vpc.default.id}"
cidr_block = "10.0.1.0/24"
availability_zone = "us-west-2a"
tags {
Name = "terraform-test"
}
}
resource "aws_subnet" "alt" {
vpc_id = "${aws_vpc.default.id}"
cidr_block = "10.0.2.0/24"
availability_zone = "us-west-2b"
tags {
Name = "asg-vpc-thing"
}
}
resource "aws_launch_configuration" "foobar" {
name = "vpc-asg-test"
image_id = "ami-b5b3fc85"
instance_type = "t2.micro"
}
resource "aws_autoscaling_group" "bar" {
vpc_zone_identifier = [
"${aws_subnet.main.id}",
"${aws_subnet.alt.id}",
]
name = "vpc-asg-test"
max_size = 1
min_size = 1
health_check_grace_period = 300
health_check_type = "ELB"
desired_capacity = 1
force_delete = true
termination_policies = ["OldestInstance"]
launch_configuration = "${aws_launch_configuration.foobar.name}"
}
`