github.com/joshgarnett/terraform@v0.5.4-0.20160219181435-92dc20bb3594/builtin/providers/aws/resource_aws_autoscaling_group_test.go (about) 1 package aws 2 3 import ( 4 "fmt" 5 "reflect" 6 "regexp" 7 "strings" 8 "testing" 9 10 "github.com/aws/aws-sdk-go/aws" 11 "github.com/aws/aws-sdk-go/aws/awserr" 12 "github.com/aws/aws-sdk-go/service/autoscaling" 13 "github.com/hashicorp/terraform/helper/resource" 14 "github.com/hashicorp/terraform/terraform" 15 ) 16 17 func TestAccAWSAutoScalingGroup_basic(t *testing.T) { 18 var group autoscaling.Group 19 var lc autoscaling.LaunchConfiguration 20 21 resource.Test(t, resource.TestCase{ 22 PreCheck: func() { testAccPreCheck(t) }, 23 Providers: testAccProviders, 24 CheckDestroy: testAccCheckAWSAutoScalingGroupDestroy, 25 Steps: []resource.TestStep{ 26 resource.TestStep{ 27 Config: testAccAWSAutoScalingGroupConfig, 28 Check: resource.ComposeTestCheckFunc( 29 testAccCheckAWSAutoScalingGroupExists("aws_autoscaling_group.bar", &group), 30 testAccCheckAWSAutoScalingGroupHealthyCapacity(&group, 2), 31 testAccCheckAWSAutoScalingGroupAttributes(&group), 32 resource.TestCheckResourceAttr( 33 "aws_autoscaling_group.bar", "availability_zones.2487133097", "us-west-2a"), 34 resource.TestCheckResourceAttr( 35 "aws_autoscaling_group.bar", "name", "foobar3-terraform-test"), 36 resource.TestCheckResourceAttr( 37 "aws_autoscaling_group.bar", "max_size", "5"), 38 resource.TestCheckResourceAttr( 39 "aws_autoscaling_group.bar", "min_size", "2"), 40 resource.TestCheckResourceAttr( 41 "aws_autoscaling_group.bar", "health_check_grace_period", "300"), 42 resource.TestCheckResourceAttr( 43 "aws_autoscaling_group.bar", "health_check_type", "ELB"), 44 resource.TestCheckResourceAttr( 45 "aws_autoscaling_group.bar", "desired_capacity", "4"), 46 resource.TestCheckResourceAttr( 47 "aws_autoscaling_group.bar", "force_delete", "true"), 48 resource.TestCheckResourceAttr( 49 "aws_autoscaling_group.bar", "termination_policies.0", "OldestInstance"), 50 resource.TestCheckResourceAttr( 51 "aws_autoscaling_group.bar", "termination_policies.1", "ClosestToNextInstanceHour"), 52 ), 53 }, 54 55 resource.TestStep{ 56 Config: testAccAWSAutoScalingGroupConfigUpdate, 57 Check: resource.ComposeTestCheckFunc( 58 testAccCheckAWSAutoScalingGroupExists("aws_autoscaling_group.bar", &group), 59 testAccCheckAWSLaunchConfigurationExists("aws_launch_configuration.new", &lc), 60 resource.TestCheckResourceAttr( 61 "aws_autoscaling_group.bar", "desired_capacity", "5"), 62 resource.TestCheckResourceAttr( 63 "aws_autoscaling_group.bar", "termination_policies.0", "ClosestToNextInstanceHour"), 64 testLaunchConfigurationName("aws_autoscaling_group.bar", &lc), 65 testAccCheckAutoscalingTags(&group.Tags, "Bar", map[string]interface{}{ 66 "value": "bar-foo", 67 "propagate_at_launch": true, 68 }), 69 ), 70 }, 71 }, 72 }) 73 } 74 75 func TestAccAWSAutoScalingGroup_autoGeneratedName(t *testing.T) { 76 asgNameRegexp := regexp.MustCompile("^tf-asg-") 77 78 resource.Test(t, resource.TestCase{ 79 PreCheck: func() { testAccPreCheck(t) }, 80 Providers: testAccProviders, 81 CheckDestroy: testAccCheckAWSAutoScalingGroupDestroy, 82 Steps: []resource.TestStep{ 83 resource.TestStep{ 84 Config: testAccAWSAutoScalingGroupConfig_autoGeneratedName, 85 Check: resource.ComposeTestCheckFunc( 86 resource.TestMatchResourceAttr( 87 "aws_autoscaling_group.bar", "name", asgNameRegexp), 88 ), 89 }, 90 }, 91 }) 92 } 93 94 func TestAccAWSAutoScalingGroup_tags(t *testing.T) { 95 var group autoscaling.Group 96 97 resource.Test(t, resource.TestCase{ 98 PreCheck: func() { testAccPreCheck(t) }, 99 Providers: testAccProviders, 100 CheckDestroy: testAccCheckAWSAutoScalingGroupDestroy, 101 Steps: []resource.TestStep{ 102 resource.TestStep{ 103 Config: testAccAWSAutoScalingGroupConfig, 104 Check: resource.ComposeTestCheckFunc( 105 testAccCheckAWSAutoScalingGroupExists("aws_autoscaling_group.bar", &group), 106 testAccCheckAutoscalingTags(&group.Tags, "Foo", map[string]interface{}{ 107 "value": "foo-bar", 108 "propagate_at_launch": true, 109 }), 110 ), 111 }, 112 113 resource.TestStep{ 114 Config: testAccAWSAutoScalingGroupConfigUpdate, 115 Check: resource.ComposeTestCheckFunc( 116 testAccCheckAWSAutoScalingGroupExists("aws_autoscaling_group.bar", &group), 117 testAccCheckAutoscalingTagNotExists(&group.Tags, "Foo"), 118 testAccCheckAutoscalingTags(&group.Tags, "Bar", map[string]interface{}{ 119 "value": "bar-foo", 120 "propagate_at_launch": true, 121 }), 122 ), 123 }, 124 }, 125 }) 126 } 127 128 func TestAccAWSAutoScalingGroup_VpcUpdates(t *testing.T) { 129 var group autoscaling.Group 130 131 resource.Test(t, resource.TestCase{ 132 PreCheck: func() { testAccPreCheck(t) }, 133 Providers: testAccProviders, 134 CheckDestroy: testAccCheckAWSAutoScalingGroupDestroy, 135 Steps: []resource.TestStep{ 136 resource.TestStep{ 137 Config: testAccAWSAutoScalingGroupConfigWithAZ, 138 Check: resource.ComposeTestCheckFunc( 139 testAccCheckAWSAutoScalingGroupExists("aws_autoscaling_group.bar", &group), 140 resource.TestCheckResourceAttr( 141 "aws_autoscaling_group.bar", "availability_zones.#", "1"), 142 resource.TestCheckResourceAttr( 143 "aws_autoscaling_group.bar", "availability_zones.2487133097", "us-west-2a"), 144 resource.TestCheckResourceAttr( 145 "aws_autoscaling_group.bar", "vpc_zone_identifier.#", "1"), 146 ), 147 }, 148 149 resource.TestStep{ 150 Config: testAccAWSAutoScalingGroupConfigWithVPCIdent, 151 Check: resource.ComposeTestCheckFunc( 152 testAccCheckAWSAutoScalingGroupExists("aws_autoscaling_group.bar", &group), 153 testAccCheckAWSAutoScalingGroupAttributesVPCZoneIdentifer(&group), 154 resource.TestCheckResourceAttr( 155 "aws_autoscaling_group.bar", "availability_zones.#", "1"), 156 resource.TestCheckResourceAttr( 157 "aws_autoscaling_group.bar", "availability_zones.2487133097", "us-west-2a"), 158 resource.TestCheckResourceAttr( 159 "aws_autoscaling_group.bar", "vpc_zone_identifier.#", "1"), 160 ), 161 }, 162 }, 163 }) 164 } 165 166 func TestAccAWSAutoScalingGroup_WithLoadBalancer(t *testing.T) { 167 var group autoscaling.Group 168 169 resource.Test(t, resource.TestCase{ 170 PreCheck: func() { testAccPreCheck(t) }, 171 Providers: testAccProviders, 172 CheckDestroy: testAccCheckAWSAutoScalingGroupDestroy, 173 Steps: []resource.TestStep{ 174 resource.TestStep{ 175 Config: fmt.Sprintf(testAccAWSAutoScalingGroupConfigWithLoadBalancer), 176 Check: resource.ComposeTestCheckFunc( 177 testAccCheckAWSAutoScalingGroupExists("aws_autoscaling_group.bar", &group), 178 testAccCheckAWSAutoScalingGroupAttributesLoadBalancer(&group), 179 ), 180 }, 181 }, 182 }) 183 } 184 185 func TestAccAWSAutoScalingGroup_withPlacementGroup(t *testing.T) { 186 var group autoscaling.Group 187 188 resource.Test(t, resource.TestCase{ 189 PreCheck: func() { testAccPreCheck(t) }, 190 Providers: testAccProviders, 191 CheckDestroy: testAccCheckAWSAutoScalingGroupDestroy, 192 Steps: []resource.TestStep{ 193 resource.TestStep{ 194 Config: testAccAWSAutoScalingGroupConfig_withPlacementGroup, 195 Check: resource.ComposeTestCheckFunc( 196 testAccCheckAWSAutoScalingGroupExists("aws_autoscaling_group.bar", &group), 197 resource.TestCheckResourceAttr( 198 "aws_autoscaling_group.bar", "placement_group", "test"), 199 ), 200 }, 201 }, 202 }) 203 } 204 205 func testAccCheckAWSAutoScalingGroupDestroy(s *terraform.State) error { 206 conn := testAccProvider.Meta().(*AWSClient).autoscalingconn 207 208 for _, rs := range s.RootModule().Resources { 209 if rs.Type != "aws_autoscaling_group" { 210 continue 211 } 212 213 // Try to find the Group 214 describeGroups, err := conn.DescribeAutoScalingGroups( 215 &autoscaling.DescribeAutoScalingGroupsInput{ 216 AutoScalingGroupNames: []*string{aws.String(rs.Primary.ID)}, 217 }) 218 219 if err == nil { 220 if len(describeGroups.AutoScalingGroups) != 0 && 221 *describeGroups.AutoScalingGroups[0].AutoScalingGroupName == rs.Primary.ID { 222 return fmt.Errorf("AutoScaling Group still exists") 223 } 224 } 225 226 // Verify the error 227 ec2err, ok := err.(awserr.Error) 228 if !ok { 229 return err 230 } 231 if ec2err.Code() != "InvalidGroup.NotFound" { 232 return err 233 } 234 } 235 236 return nil 237 } 238 239 func testAccCheckAWSAutoScalingGroupAttributes(group *autoscaling.Group) resource.TestCheckFunc { 240 return func(s *terraform.State) error { 241 if *group.AvailabilityZones[0] != "us-west-2a" { 242 return fmt.Errorf("Bad availability_zones: %#v", group.AvailabilityZones[0]) 243 } 244 245 if *group.AutoScalingGroupName != "foobar3-terraform-test" { 246 return fmt.Errorf("Bad name: %s", *group.AutoScalingGroupName) 247 } 248 249 if *group.MaxSize != 5 { 250 return fmt.Errorf("Bad max_size: %d", *group.MaxSize) 251 } 252 253 if *group.MinSize != 2 { 254 return fmt.Errorf("Bad max_size: %d", *group.MinSize) 255 } 256 257 if *group.HealthCheckType != "ELB" { 258 return fmt.Errorf("Bad health_check_type,\nexpected: %s\ngot: %s", "ELB", *group.HealthCheckType) 259 } 260 261 if *group.HealthCheckGracePeriod != 300 { 262 return fmt.Errorf("Bad health_check_grace_period: %d", *group.HealthCheckGracePeriod) 263 } 264 265 if *group.DesiredCapacity != 4 { 266 return fmt.Errorf("Bad desired_capacity: %d", *group.DesiredCapacity) 267 } 268 269 if *group.LaunchConfigurationName == "" { 270 return fmt.Errorf("Bad launch configuration name: %s", *group.LaunchConfigurationName) 271 } 272 273 t := &autoscaling.TagDescription{ 274 Key: aws.String("Foo"), 275 Value: aws.String("foo-bar"), 276 PropagateAtLaunch: aws.Bool(true), 277 ResourceType: aws.String("auto-scaling-group"), 278 ResourceId: group.AutoScalingGroupName, 279 } 280 281 if !reflect.DeepEqual(group.Tags[0], t) { 282 return fmt.Errorf( 283 "Got:\n\n%#v\n\nExpected:\n\n%#v\n", 284 group.Tags[0], 285 t) 286 } 287 288 return nil 289 } 290 } 291 292 func testAccCheckAWSAutoScalingGroupAttributesLoadBalancer(group *autoscaling.Group) resource.TestCheckFunc { 293 return func(s *terraform.State) error { 294 if len(group.LoadBalancerNames) != 1 { 295 return fmt.Errorf("Bad load_balancers: %v", group.LoadBalancerNames) 296 } 297 298 return nil 299 } 300 } 301 302 func testAccCheckAWSAutoScalingGroupExists(n string, group *autoscaling.Group) resource.TestCheckFunc { 303 return func(s *terraform.State) error { 304 rs, ok := s.RootModule().Resources[n] 305 if !ok { 306 return fmt.Errorf("Not found: %s", n) 307 } 308 309 if rs.Primary.ID == "" { 310 return fmt.Errorf("No AutoScaling Group ID is set") 311 } 312 313 conn := testAccProvider.Meta().(*AWSClient).autoscalingconn 314 315 describeGroups, err := conn.DescribeAutoScalingGroups( 316 &autoscaling.DescribeAutoScalingGroupsInput{ 317 AutoScalingGroupNames: []*string{aws.String(rs.Primary.ID)}, 318 }) 319 320 if err != nil { 321 return err 322 } 323 324 if len(describeGroups.AutoScalingGroups) != 1 || 325 *describeGroups.AutoScalingGroups[0].AutoScalingGroupName != rs.Primary.ID { 326 return fmt.Errorf("AutoScaling Group not found") 327 } 328 329 *group = *describeGroups.AutoScalingGroups[0] 330 331 return nil 332 } 333 } 334 335 func testLaunchConfigurationName(n string, lc *autoscaling.LaunchConfiguration) resource.TestCheckFunc { 336 return func(s *terraform.State) error { 337 rs, ok := s.RootModule().Resources[n] 338 if !ok { 339 return fmt.Errorf("Not found: %s", n) 340 } 341 342 if *lc.LaunchConfigurationName != rs.Primary.Attributes["launch_configuration"] { 343 return fmt.Errorf("Launch configuration names do not match") 344 } 345 346 return nil 347 } 348 } 349 350 func testAccCheckAWSAutoScalingGroupHealthyCapacity( 351 g *autoscaling.Group, exp int) resource.TestCheckFunc { 352 return func(s *terraform.State) error { 353 healthy := 0 354 for _, i := range g.Instances { 355 if i.HealthStatus == nil { 356 continue 357 } 358 if strings.EqualFold(*i.HealthStatus, "Healthy") { 359 healthy++ 360 } 361 } 362 if healthy < exp { 363 return fmt.Errorf("Expected at least %d healthy, got %d.", exp, healthy) 364 } 365 return nil 366 } 367 } 368 369 func testAccCheckAWSAutoScalingGroupAttributesVPCZoneIdentifer(group *autoscaling.Group) resource.TestCheckFunc { 370 return func(s *terraform.State) error { 371 // Grab Subnet Ids 372 var subnets []string 373 for _, rs := range s.RootModule().Resources { 374 if rs.Type != "aws_subnet" { 375 continue 376 } 377 subnets = append(subnets, rs.Primary.Attributes["id"]) 378 } 379 380 if group.VPCZoneIdentifier == nil { 381 return fmt.Errorf("Bad VPC Zone Identifier\nexpected: %s\ngot nil", subnets) 382 } 383 384 zones := strings.Split(*group.VPCZoneIdentifier, ",") 385 386 remaining := len(zones) 387 for _, z := range zones { 388 for _, s := range subnets { 389 if z == s { 390 remaining-- 391 } 392 } 393 } 394 395 if remaining != 0 { 396 return fmt.Errorf("Bad VPC Zone Identifier match\nexpected: %s\ngot:%s", zones, subnets) 397 } 398 399 return nil 400 } 401 } 402 403 const testAccAWSAutoScalingGroupConfig_autoGeneratedName = ` 404 resource "aws_launch_configuration" "foobar" { 405 image_id = "ami-21f78e11" 406 instance_type = "t1.micro" 407 } 408 409 resource "aws_autoscaling_group" "bar" { 410 availability_zones = ["us-west-2a"] 411 desired_capacity = 0 412 max_size = 0 413 min_size = 0 414 launch_configuration = "${aws_launch_configuration.foobar.name}" 415 } 416 ` 417 418 const testAccAWSAutoScalingGroupConfig = ` 419 resource "aws_launch_configuration" "foobar" { 420 image_id = "ami-21f78e11" 421 instance_type = "t1.micro" 422 } 423 424 resource "aws_placement_group" "test" { 425 name = "test" 426 strategy = "cluster" 427 } 428 429 resource "aws_autoscaling_group" "bar" { 430 availability_zones = ["us-west-2a"] 431 name = "foobar3-terraform-test" 432 max_size = 5 433 min_size = 2 434 health_check_grace_period = 300 435 health_check_type = "ELB" 436 desired_capacity = 4 437 force_delete = true 438 termination_policies = ["OldestInstance","ClosestToNextInstanceHour"] 439 440 launch_configuration = "${aws_launch_configuration.foobar.name}" 441 442 tag { 443 key = "Foo" 444 value = "foo-bar" 445 propagate_at_launch = true 446 } 447 } 448 ` 449 450 const testAccAWSAutoScalingGroupConfigUpdate = ` 451 resource "aws_launch_configuration" "foobar" { 452 image_id = "ami-21f78e11" 453 instance_type = "t1.micro" 454 } 455 456 resource "aws_launch_configuration" "new" { 457 image_id = "ami-21f78e11" 458 instance_type = "t1.micro" 459 } 460 461 resource "aws_autoscaling_group" "bar" { 462 availability_zones = ["us-west-2a"] 463 name = "foobar3-terraform-test" 464 max_size = 5 465 min_size = 2 466 health_check_grace_period = 300 467 health_check_type = "ELB" 468 desired_capacity = 5 469 force_delete = true 470 termination_policies = ["ClosestToNextInstanceHour"] 471 472 launch_configuration = "${aws_launch_configuration.new.name}" 473 474 tag { 475 key = "Bar" 476 value = "bar-foo" 477 propagate_at_launch = true 478 } 479 } 480 ` 481 482 const testAccAWSAutoScalingGroupConfigWithLoadBalancer = ` 483 resource "aws_vpc" "foo" { 484 cidr_block = "10.1.0.0/16" 485 tags { Name = "tf-asg-test" } 486 } 487 488 resource "aws_internet_gateway" "gw" { 489 vpc_id = "${aws_vpc.foo.id}" 490 } 491 492 resource "aws_subnet" "foo" { 493 cidr_block = "10.1.1.0/24" 494 vpc_id = "${aws_vpc.foo.id}" 495 } 496 497 resource "aws_security_group" "foo" { 498 vpc_id="${aws_vpc.foo.id}" 499 500 ingress { 501 protocol = "-1" 502 from_port = 0 503 to_port = 0 504 cidr_blocks = ["0.0.0.0/0"] 505 } 506 507 egress { 508 protocol = "-1" 509 from_port = 0 510 to_port = 0 511 cidr_blocks = ["0.0.0.0/0"] 512 } 513 } 514 515 resource "aws_elb" "bar" { 516 subnets = ["${aws_subnet.foo.id}"] 517 security_groups = ["${aws_security_group.foo.id}"] 518 519 listener { 520 instance_port = 80 521 instance_protocol = "http" 522 lb_port = 80 523 lb_protocol = "http" 524 } 525 526 health_check { 527 healthy_threshold = 2 528 unhealthy_threshold = 2 529 target = "HTTP:80/" 530 interval = 5 531 timeout = 2 532 } 533 534 depends_on = ["aws_internet_gateway.gw"] 535 } 536 537 resource "aws_launch_configuration" "foobar" { 538 // need an AMI that listens on :80 at boot, this is: 539 // bitnami-nginxstack-1.6.1-0-linux-ubuntu-14.04.1-x86_64-hvm-ebs-ami-99f5b1a9-3 540 image_id = "ami-b5b3fc85" 541 instance_type = "t2.micro" 542 security_groups = ["${aws_security_group.foo.id}"] 543 } 544 545 resource "aws_autoscaling_group" "bar" { 546 availability_zones = ["${aws_subnet.foo.availability_zone}"] 547 vpc_zone_identifier = ["${aws_subnet.foo.id}"] 548 name = "foobar3-terraform-test" 549 max_size = 2 550 min_size = 2 551 health_check_grace_period = 300 552 health_check_type = "ELB" 553 wait_for_elb_capacity = 2 554 force_delete = true 555 556 launch_configuration = "${aws_launch_configuration.foobar.name}" 557 load_balancers = ["${aws_elb.bar.name}"] 558 } 559 ` 560 561 const testAccAWSAutoScalingGroupConfigWithAZ = ` 562 resource "aws_vpc" "default" { 563 cidr_block = "10.0.0.0/16" 564 tags { 565 Name = "terraform-test" 566 } 567 } 568 569 resource "aws_subnet" "main" { 570 vpc_id = "${aws_vpc.default.id}" 571 cidr_block = "10.0.1.0/24" 572 availability_zone = "us-west-2a" 573 tags { 574 Name = "terraform-test" 575 } 576 } 577 578 resource "aws_launch_configuration" "foobar" { 579 image_id = "ami-b5b3fc85" 580 instance_type = "t2.micro" 581 } 582 583 resource "aws_autoscaling_group" "bar" { 584 availability_zones = [ 585 "us-west-2a" 586 ] 587 desired_capacity = 0 588 max_size = 0 589 min_size = 0 590 launch_configuration = "${aws_launch_configuration.foobar.name}" 591 } 592 ` 593 594 const testAccAWSAutoScalingGroupConfigWithVPCIdent = ` 595 resource "aws_vpc" "default" { 596 cidr_block = "10.0.0.0/16" 597 tags { 598 Name = "terraform-test" 599 } 600 } 601 602 resource "aws_subnet" "main" { 603 vpc_id = "${aws_vpc.default.id}" 604 cidr_block = "10.0.1.0/24" 605 availability_zone = "us-west-2a" 606 tags { 607 Name = "terraform-test" 608 } 609 } 610 611 resource "aws_launch_configuration" "foobar" { 612 image_id = "ami-b5b3fc85" 613 instance_type = "t2.micro" 614 } 615 616 resource "aws_autoscaling_group" "bar" { 617 vpc_zone_identifier = [ 618 "${aws_subnet.main.id}", 619 ] 620 desired_capacity = 0 621 max_size = 0 622 min_size = 0 623 launch_configuration = "${aws_launch_configuration.foobar.name}" 624 } 625 ` 626 627 const testAccAWSAutoScalingGroupConfig_withPlacementGroup = ` 628 resource "aws_launch_configuration" "foobar" { 629 image_id = "ami-21f78e11" 630 instance_type = "t2.micro" 631 } 632 633 resource "aws_placement_group" "test" { 634 name = "test" 635 strategy = "cluster" 636 } 637 638 resource "aws_autoscaling_group" "bar" { 639 availability_zones = ["us-west-2a"] 640 name = "foobar3-terraform-test" 641 max_size = 1 642 min_size = 1 643 health_check_grace_period = 300 644 health_check_type = "ELB" 645 desired_capacity = 1 646 force_delete = true 647 termination_policies = ["OldestInstance","ClosestToNextInstanceHour"] 648 placement_group = "${aws_placement_group.test.name}" 649 650 launch_configuration = "${aws_launch_configuration.foobar.name}" 651 652 tag { 653 key = "Foo" 654 value = "foo-bar" 655 propagate_at_launch = true 656 } 657 } 658 `