github.com/ottenhoff/terraform@v0.7.0-rc1.0.20160607213102-ac2d195cc560/builtin/providers/aws/resource_aws_instance_test.go (about) 1 package aws 2 3 import ( 4 "fmt" 5 "reflect" 6 "testing" 7 8 "github.com/aws/aws-sdk-go/aws" 9 "github.com/aws/aws-sdk-go/aws/awserr" 10 "github.com/aws/aws-sdk-go/service/ec2" 11 "github.com/hashicorp/terraform/helper/resource" 12 "github.com/hashicorp/terraform/helper/schema" 13 "github.com/hashicorp/terraform/terraform" 14 ) 15 16 func TestAccAWSInstance_basic(t *testing.T) { 17 var v ec2.Instance 18 var vol *ec2.Volume 19 20 testCheck := func(*terraform.State) error { 21 if *v.Placement.AvailabilityZone != "us-west-2a" { 22 return fmt.Errorf("bad availability zone: %#v", *v.Placement.AvailabilityZone) 23 } 24 25 if len(v.SecurityGroups) == 0 { 26 return fmt.Errorf("no security groups: %#v", v.SecurityGroups) 27 } 28 if *v.SecurityGroups[0].GroupName != "tf_test_foo" { 29 return fmt.Errorf("no security groups: %#v", v.SecurityGroups) 30 } 31 32 return nil 33 } 34 35 resource.Test(t, resource.TestCase{ 36 PreCheck: func() { testAccPreCheck(t) }, 37 38 // We ignore security groups because even with EC2 classic 39 // we'll import as VPC security groups, which is fine. We verify 40 // VPC security group import in other tests 41 IDRefreshName: "aws_instance.foo", 42 IDRefreshIgnore: []string{"user_data", "security_groups", "vpc_security_group_ids"}, 43 44 Providers: testAccProviders, 45 CheckDestroy: testAccCheckInstanceDestroy, 46 Steps: []resource.TestStep{ 47 // Create a volume to cover #1249 48 resource.TestStep{ 49 // Need a resource in this config so the provisioner will be available 50 Config: testAccInstanceConfig_pre, 51 Check: func(*terraform.State) error { 52 conn := testAccProvider.Meta().(*AWSClient).ec2conn 53 var err error 54 vol, err = conn.CreateVolume(&ec2.CreateVolumeInput{ 55 AvailabilityZone: aws.String("us-west-2a"), 56 Size: aws.Int64(int64(5)), 57 }) 58 return err 59 }, 60 }, 61 62 resource.TestStep{ 63 Config: testAccInstanceConfig, 64 Check: resource.ComposeTestCheckFunc( 65 testAccCheckInstanceExists( 66 "aws_instance.foo", &v), 67 testCheck, 68 resource.TestCheckResourceAttr( 69 "aws_instance.foo", 70 "user_data", 71 "3dc39dda39be1205215e776bad998da361a5955d"), 72 resource.TestCheckResourceAttr( 73 "aws_instance.foo", "ebs_block_device.#", "0"), 74 ), 75 }, 76 77 // We repeat the exact same test so that we can be sure 78 // that the user data hash stuff is working without generating 79 // an incorrect diff. 80 resource.TestStep{ 81 Config: testAccInstanceConfig, 82 Check: resource.ComposeTestCheckFunc( 83 testAccCheckInstanceExists( 84 "aws_instance.foo", &v), 85 testCheck, 86 resource.TestCheckResourceAttr( 87 "aws_instance.foo", 88 "user_data", 89 "3dc39dda39be1205215e776bad998da361a5955d"), 90 resource.TestCheckResourceAttr( 91 "aws_instance.foo", "ebs_block_device.#", "0"), 92 ), 93 }, 94 95 // Clean up volume created above 96 resource.TestStep{ 97 Config: testAccInstanceConfig, 98 Check: func(*terraform.State) error { 99 conn := testAccProvider.Meta().(*AWSClient).ec2conn 100 _, err := conn.DeleteVolume(&ec2.DeleteVolumeInput{VolumeId: vol.VolumeId}) 101 return err 102 }, 103 }, 104 }, 105 }) 106 } 107 108 func TestAccAWSInstance_blockDevices(t *testing.T) { 109 var v ec2.Instance 110 111 testCheck := func() resource.TestCheckFunc { 112 return func(*terraform.State) error { 113 114 // Map out the block devices by name, which should be unique. 115 blockDevices := make(map[string]*ec2.InstanceBlockDeviceMapping) 116 for _, blockDevice := range v.BlockDeviceMappings { 117 blockDevices[*blockDevice.DeviceName] = blockDevice 118 } 119 120 // Check if the root block device exists. 121 if _, ok := blockDevices["/dev/sda1"]; !ok { 122 return fmt.Errorf("block device doesn't exist: /dev/sda1") 123 } 124 125 // Check if the secondary block device exists. 126 if _, ok := blockDevices["/dev/sdb"]; !ok { 127 return fmt.Errorf("block device doesn't exist: /dev/sdb") 128 } 129 130 // Check if the third block device exists. 131 if _, ok := blockDevices["/dev/sdc"]; !ok { 132 return fmt.Errorf("block device doesn't exist: /dev/sdc") 133 } 134 135 // Check if the encrypted block device exists 136 if _, ok := blockDevices["/dev/sdd"]; !ok { 137 return fmt.Errorf("block device doesn't exist: /dev/sdd") 138 } 139 140 return nil 141 } 142 } 143 144 resource.Test(t, resource.TestCase{ 145 PreCheck: func() { testAccPreCheck(t) }, 146 IDRefreshName: "aws_instance.foo", 147 IDRefreshIgnore: []string{ 148 "ephemeral_block_device", "user_data", "security_groups", "vpc_security_groups"}, 149 Providers: testAccProviders, 150 CheckDestroy: testAccCheckInstanceDestroy, 151 Steps: []resource.TestStep{ 152 resource.TestStep{ 153 Config: testAccInstanceConfigBlockDevices, 154 Check: resource.ComposeTestCheckFunc( 155 testAccCheckInstanceExists( 156 "aws_instance.foo", &v), 157 resource.TestCheckResourceAttr( 158 "aws_instance.foo", "root_block_device.#", "1"), 159 resource.TestCheckResourceAttr( 160 "aws_instance.foo", "root_block_device.0.volume_size", "11"), 161 resource.TestCheckResourceAttr( 162 "aws_instance.foo", "root_block_device.0.volume_type", "gp2"), 163 resource.TestCheckResourceAttr( 164 "aws_instance.foo", "ebs_block_device.#", "3"), 165 resource.TestCheckResourceAttr( 166 "aws_instance.foo", "ebs_block_device.2576023345.device_name", "/dev/sdb"), 167 resource.TestCheckResourceAttr( 168 "aws_instance.foo", "ebs_block_device.2576023345.volume_size", "9"), 169 resource.TestCheckResourceAttr( 170 "aws_instance.foo", "ebs_block_device.2576023345.volume_type", "standard"), 171 resource.TestCheckResourceAttr( 172 "aws_instance.foo", "ebs_block_device.2554893574.device_name", "/dev/sdc"), 173 resource.TestCheckResourceAttr( 174 "aws_instance.foo", "ebs_block_device.2554893574.volume_size", "10"), 175 resource.TestCheckResourceAttr( 176 "aws_instance.foo", "ebs_block_device.2554893574.volume_type", "io1"), 177 resource.TestCheckResourceAttr( 178 "aws_instance.foo", "ebs_block_device.2554893574.iops", "100"), 179 resource.TestCheckResourceAttr( 180 "aws_instance.foo", "ebs_block_device.2634515331.device_name", "/dev/sdd"), 181 resource.TestCheckResourceAttr( 182 "aws_instance.foo", "ebs_block_device.2634515331.encrypted", "true"), 183 resource.TestCheckResourceAttr( 184 "aws_instance.foo", "ebs_block_device.2634515331.volume_size", "12"), 185 resource.TestCheckResourceAttr( 186 "aws_instance.foo", "ephemeral_block_device.#", "1"), 187 resource.TestCheckResourceAttr( 188 "aws_instance.foo", "ephemeral_block_device.1692014856.device_name", "/dev/sde"), 189 resource.TestCheckResourceAttr( 190 "aws_instance.foo", "ephemeral_block_device.1692014856.virtual_name", "ephemeral0"), 191 testCheck(), 192 ), 193 }, 194 }, 195 }) 196 } 197 198 func TestAccAWSInstance_sourceDestCheck(t *testing.T) { 199 var v ec2.Instance 200 201 testCheck := func(enabled bool) resource.TestCheckFunc { 202 return func(*terraform.State) error { 203 if v.SourceDestCheck == nil { 204 return fmt.Errorf("bad source_dest_check: got nil") 205 } 206 if *v.SourceDestCheck != enabled { 207 return fmt.Errorf("bad source_dest_check: %#v", *v.SourceDestCheck) 208 } 209 210 return nil 211 } 212 } 213 214 resource.Test(t, resource.TestCase{ 215 PreCheck: func() { testAccPreCheck(t) }, 216 IDRefreshName: "aws_instance.foo", 217 Providers: testAccProviders, 218 CheckDestroy: testAccCheckInstanceDestroy, 219 Steps: []resource.TestStep{ 220 resource.TestStep{ 221 Config: testAccInstanceConfigSourceDestDisable, 222 Check: resource.ComposeTestCheckFunc( 223 testAccCheckInstanceExists("aws_instance.foo", &v), 224 testCheck(false), 225 ), 226 }, 227 228 resource.TestStep{ 229 Config: testAccInstanceConfigSourceDestEnable, 230 Check: resource.ComposeTestCheckFunc( 231 testAccCheckInstanceExists("aws_instance.foo", &v), 232 testCheck(true), 233 ), 234 }, 235 236 resource.TestStep{ 237 Config: testAccInstanceConfigSourceDestDisable, 238 Check: resource.ComposeTestCheckFunc( 239 testAccCheckInstanceExists("aws_instance.foo", &v), 240 testCheck(false), 241 ), 242 }, 243 }, 244 }) 245 } 246 247 func TestAccAWSInstance_disableApiTermination(t *testing.T) { 248 var v ec2.Instance 249 250 checkDisableApiTermination := func(expected bool) resource.TestCheckFunc { 251 return func(*terraform.State) error { 252 conn := testAccProvider.Meta().(*AWSClient).ec2conn 253 r, err := conn.DescribeInstanceAttribute(&ec2.DescribeInstanceAttributeInput{ 254 InstanceId: v.InstanceId, 255 Attribute: aws.String("disableApiTermination"), 256 }) 257 if err != nil { 258 return err 259 } 260 got := *r.DisableApiTermination.Value 261 if got != expected { 262 return fmt.Errorf("expected: %t, got: %t", expected, got) 263 } 264 return nil 265 } 266 } 267 268 resource.Test(t, resource.TestCase{ 269 PreCheck: func() { testAccPreCheck(t) }, 270 IDRefreshName: "aws_instance.foo", 271 Providers: testAccProviders, 272 CheckDestroy: testAccCheckInstanceDestroy, 273 Steps: []resource.TestStep{ 274 resource.TestStep{ 275 Config: testAccInstanceConfigDisableAPITermination(true), 276 Check: resource.ComposeTestCheckFunc( 277 testAccCheckInstanceExists("aws_instance.foo", &v), 278 checkDisableApiTermination(true), 279 ), 280 }, 281 282 resource.TestStep{ 283 Config: testAccInstanceConfigDisableAPITermination(false), 284 Check: resource.ComposeTestCheckFunc( 285 testAccCheckInstanceExists("aws_instance.foo", &v), 286 checkDisableApiTermination(false), 287 ), 288 }, 289 }, 290 }) 291 } 292 293 func TestAccAWSInstance_vpc(t *testing.T) { 294 var v ec2.Instance 295 296 resource.Test(t, resource.TestCase{ 297 PreCheck: func() { testAccPreCheck(t) }, 298 IDRefreshName: "aws_instance.foo", 299 IDRefreshIgnore: []string{"associate_public_ip_address", "user_data"}, 300 Providers: testAccProviders, 301 CheckDestroy: testAccCheckInstanceDestroy, 302 Steps: []resource.TestStep{ 303 resource.TestStep{ 304 Config: testAccInstanceConfigVPC, 305 Check: resource.ComposeTestCheckFunc( 306 testAccCheckInstanceExists( 307 "aws_instance.foo", &v), 308 resource.TestCheckResourceAttr( 309 "aws_instance.foo", 310 "user_data", 311 "2fad308761514d9d73c3c7fdc877607e06cf950d"), 312 ), 313 }, 314 }, 315 }) 316 } 317 318 func TestAccAWSInstance_multipleRegions(t *testing.T) { 319 var v ec2.Instance 320 321 // record the initialized providers so that we can use them to 322 // check for the instances in each region 323 var providers []*schema.Provider 324 providerFactories := map[string]terraform.ResourceProviderFactory{ 325 "aws": func() (terraform.ResourceProvider, error) { 326 p := Provider() 327 providers = append(providers, p.(*schema.Provider)) 328 return p, nil 329 }, 330 } 331 332 resource.Test(t, resource.TestCase{ 333 PreCheck: func() { testAccPreCheck(t) }, 334 ProviderFactories: providerFactories, 335 CheckDestroy: testAccCheckInstanceDestroyWithProviders(&providers), 336 Steps: []resource.TestStep{ 337 resource.TestStep{ 338 Config: testAccInstanceConfigMultipleRegions, 339 Check: resource.ComposeTestCheckFunc( 340 testAccCheckInstanceExistsWithProviders( 341 "aws_instance.foo", &v, &providers), 342 testAccCheckInstanceExistsWithProviders( 343 "aws_instance.bar", &v, &providers), 344 ), 345 }, 346 }, 347 }) 348 } 349 350 func TestAccAWSInstance_NetworkInstanceSecurityGroups(t *testing.T) { 351 var v ec2.Instance 352 353 resource.Test(t, resource.TestCase{ 354 PreCheck: func() { testAccPreCheck(t) }, 355 IDRefreshName: "aws_instance.foo_instance", 356 IDRefreshIgnore: []string{"associate_public_ip_address"}, 357 Providers: testAccProviders, 358 CheckDestroy: testAccCheckInstanceDestroy, 359 Steps: []resource.TestStep{ 360 resource.TestStep{ 361 Config: testAccInstanceNetworkInstanceSecurityGroups, 362 Check: resource.ComposeTestCheckFunc( 363 testAccCheckInstanceExists( 364 "aws_instance.foo_instance", &v), 365 ), 366 }, 367 }, 368 }) 369 } 370 371 func TestAccAWSInstance_NetworkInstanceVPCSecurityGroupIDs(t *testing.T) { 372 var v ec2.Instance 373 374 resource.Test(t, resource.TestCase{ 375 PreCheck: func() { testAccPreCheck(t) }, 376 IDRefreshName: "aws_instance.foo_instance", 377 Providers: testAccProviders, 378 CheckDestroy: testAccCheckInstanceDestroy, 379 Steps: []resource.TestStep{ 380 resource.TestStep{ 381 Config: testAccInstanceNetworkInstanceVPCSecurityGroupIDs, 382 Check: resource.ComposeTestCheckFunc( 383 testAccCheckInstanceExists( 384 "aws_instance.foo_instance", &v), 385 resource.TestCheckResourceAttr( 386 "aws_instance.foo_instance", "security_groups.#", "0"), 387 resource.TestCheckResourceAttr( 388 "aws_instance.foo_instance", "vpc_security_group_ids.#", "1"), 389 ), 390 }, 391 }, 392 }) 393 } 394 395 func TestAccAWSInstance_tags(t *testing.T) { 396 var v ec2.Instance 397 398 resource.Test(t, resource.TestCase{ 399 PreCheck: func() { testAccPreCheck(t) }, 400 Providers: testAccProviders, 401 CheckDestroy: testAccCheckInstanceDestroy, 402 Steps: []resource.TestStep{ 403 resource.TestStep{ 404 Config: testAccCheckInstanceConfigTags, 405 Check: resource.ComposeTestCheckFunc( 406 testAccCheckInstanceExists("aws_instance.foo", &v), 407 testAccCheckTags(&v.Tags, "foo", "bar"), 408 // Guard against regression of https://github.com/hashicorp/terraform/issues/914 409 testAccCheckTags(&v.Tags, "#", ""), 410 ), 411 }, 412 413 resource.TestStep{ 414 Config: testAccCheckInstanceConfigTagsUpdate, 415 Check: resource.ComposeTestCheckFunc( 416 testAccCheckInstanceExists("aws_instance.foo", &v), 417 testAccCheckTags(&v.Tags, "foo", ""), 418 testAccCheckTags(&v.Tags, "bar", "baz"), 419 ), 420 }, 421 }, 422 }) 423 } 424 425 func TestAccAWSInstance_privateIP(t *testing.T) { 426 var v ec2.Instance 427 428 testCheckPrivateIP := func() resource.TestCheckFunc { 429 return func(*terraform.State) error { 430 if *v.PrivateIpAddress != "10.1.1.42" { 431 return fmt.Errorf("bad private IP: %s", *v.PrivateIpAddress) 432 } 433 434 return nil 435 } 436 } 437 438 resource.Test(t, resource.TestCase{ 439 PreCheck: func() { testAccPreCheck(t) }, 440 IDRefreshName: "aws_instance.foo", 441 Providers: testAccProviders, 442 CheckDestroy: testAccCheckInstanceDestroy, 443 Steps: []resource.TestStep{ 444 resource.TestStep{ 445 Config: testAccInstanceConfigPrivateIP, 446 Check: resource.ComposeTestCheckFunc( 447 testAccCheckInstanceExists("aws_instance.foo", &v), 448 testCheckPrivateIP(), 449 ), 450 }, 451 }, 452 }) 453 } 454 455 func TestAccAWSInstance_associatePublicIPAndPrivateIP(t *testing.T) { 456 var v ec2.Instance 457 458 testCheckPrivateIP := func() resource.TestCheckFunc { 459 return func(*terraform.State) error { 460 if *v.PrivateIpAddress != "10.1.1.42" { 461 return fmt.Errorf("bad private IP: %s", *v.PrivateIpAddress) 462 } 463 464 return nil 465 } 466 } 467 468 resource.Test(t, resource.TestCase{ 469 PreCheck: func() { testAccPreCheck(t) }, 470 IDRefreshName: "aws_instance.foo", 471 IDRefreshIgnore: []string{"associate_public_ip_address"}, 472 Providers: testAccProviders, 473 CheckDestroy: testAccCheckInstanceDestroy, 474 Steps: []resource.TestStep{ 475 resource.TestStep{ 476 Config: testAccInstanceConfigAssociatePublicIPAndPrivateIP, 477 Check: resource.ComposeTestCheckFunc( 478 testAccCheckInstanceExists("aws_instance.foo", &v), 479 testCheckPrivateIP(), 480 ), 481 }, 482 }, 483 }) 484 } 485 486 // Guard against regression with KeyPairs 487 // https://github.com/hashicorp/terraform/issues/2302 488 func TestAccAWSInstance_keyPairCheck(t *testing.T) { 489 var v ec2.Instance 490 491 testCheckKeyPair := func(keyName string) resource.TestCheckFunc { 492 return func(*terraform.State) error { 493 if v.KeyName == nil { 494 return fmt.Errorf("No Key Pair found, expected(%s)", keyName) 495 } 496 if v.KeyName != nil && *v.KeyName != keyName { 497 return fmt.Errorf("Bad key name, expected (%s), got (%s)", keyName, *v.KeyName) 498 } 499 500 return nil 501 } 502 } 503 504 resource.Test(t, resource.TestCase{ 505 PreCheck: func() { testAccPreCheck(t) }, 506 IDRefreshName: "aws_instance.foo", 507 IDRefreshIgnore: []string{"source_dest_check"}, 508 Providers: testAccProviders, 509 CheckDestroy: testAccCheckInstanceDestroy, 510 Steps: []resource.TestStep{ 511 resource.TestStep{ 512 Config: testAccInstanceConfigKeyPair, 513 Check: resource.ComposeTestCheckFunc( 514 testAccCheckInstanceExists("aws_instance.foo", &v), 515 testCheckKeyPair("tmp-key"), 516 ), 517 }, 518 }, 519 }) 520 } 521 522 func TestAccAWSInstance_rootBlockDeviceMismatch(t *testing.T) { 523 var v ec2.Instance 524 525 resource.Test(t, resource.TestCase{ 526 PreCheck: func() { testAccPreCheck(t) }, 527 Providers: testAccProviders, 528 CheckDestroy: testAccCheckInstanceDestroy, 529 Steps: []resource.TestStep{ 530 resource.TestStep{ 531 Config: testAccInstanceConfigRootBlockDeviceMismatch, 532 Check: resource.ComposeTestCheckFunc( 533 testAccCheckInstanceExists("aws_instance.foo", &v), 534 resource.TestCheckResourceAttr( 535 "aws_instance.foo", "root_block_device.0.volume_size", "13"), 536 ), 537 }, 538 }, 539 }) 540 } 541 542 // This test reproduces the bug here: 543 // https://github.com/hashicorp/terraform/issues/1752 544 // 545 // I wish there were a way to exercise resources built with helper.Schema in a 546 // unit context, in which case this test could be moved there, but for now this 547 // will cover the bugfix. 548 // 549 // The following triggers "diffs didn't match during apply" without the fix in to 550 // set NewRemoved on the .# field when it changes to 0. 551 func TestAccAWSInstance_forceNewAndTagsDrift(t *testing.T) { 552 var v ec2.Instance 553 554 resource.Test(t, resource.TestCase{ 555 PreCheck: func() { testAccPreCheck(t) }, 556 IDRefreshName: "aws_instance.foo", 557 Providers: testAccProviders, 558 CheckDestroy: testAccCheckInstanceDestroy, 559 Steps: []resource.TestStep{ 560 resource.TestStep{ 561 Config: testAccInstanceConfigForceNewAndTagsDrift, 562 Check: resource.ComposeTestCheckFunc( 563 testAccCheckInstanceExists("aws_instance.foo", &v), 564 driftTags(&v), 565 ), 566 ExpectNonEmptyPlan: true, 567 }, 568 resource.TestStep{ 569 Config: testAccInstanceConfigForceNewAndTagsDrift_Update, 570 Check: resource.ComposeTestCheckFunc( 571 testAccCheckInstanceExists("aws_instance.foo", &v), 572 ), 573 }, 574 }, 575 }) 576 } 577 578 func testAccCheckInstanceDestroy(s *terraform.State) error { 579 return testAccCheckInstanceDestroyWithProvider(s, testAccProvider) 580 } 581 582 func testAccCheckInstanceDestroyWithProviders(providers *[]*schema.Provider) resource.TestCheckFunc { 583 return func(s *terraform.State) error { 584 for _, provider := range *providers { 585 if provider.Meta() == nil { 586 continue 587 } 588 if err := testAccCheckInstanceDestroyWithProvider(s, provider); err != nil { 589 return err 590 } 591 } 592 return nil 593 } 594 } 595 596 func testAccCheckInstanceDestroyWithProvider(s *terraform.State, provider *schema.Provider) error { 597 conn := provider.Meta().(*AWSClient).ec2conn 598 599 for _, rs := range s.RootModule().Resources { 600 if rs.Type != "aws_instance" { 601 continue 602 } 603 604 // Try to find the resource 605 resp, err := conn.DescribeInstances(&ec2.DescribeInstancesInput{ 606 InstanceIds: []*string{aws.String(rs.Primary.ID)}, 607 }) 608 if err == nil { 609 for _, r := range resp.Reservations { 610 for _, i := range r.Instances { 611 if i.State != nil && *i.State.Name != "terminated" { 612 return fmt.Errorf("Found unterminated instance: %s", i) 613 } 614 } 615 } 616 } 617 618 // Verify the error is what we want 619 if ae, ok := err.(awserr.Error); ok && ae.Code() == "InvalidInstanceID.NotFound" { 620 continue 621 } 622 623 return err 624 } 625 626 return nil 627 } 628 629 func testAccCheckInstanceExists(n string, i *ec2.Instance) resource.TestCheckFunc { 630 providers := []*schema.Provider{testAccProvider} 631 return testAccCheckInstanceExistsWithProviders(n, i, &providers) 632 } 633 634 func testAccCheckInstanceExistsWithProviders(n string, i *ec2.Instance, providers *[]*schema.Provider) resource.TestCheckFunc { 635 return func(s *terraform.State) error { 636 rs, ok := s.RootModule().Resources[n] 637 if !ok { 638 return fmt.Errorf("Not found: %s", n) 639 } 640 641 if rs.Primary.ID == "" { 642 return fmt.Errorf("No ID is set") 643 } 644 for _, provider := range *providers { 645 // Ignore if Meta is empty, this can happen for validation providers 646 if provider.Meta() == nil { 647 continue 648 } 649 650 conn := provider.Meta().(*AWSClient).ec2conn 651 resp, err := conn.DescribeInstances(&ec2.DescribeInstancesInput{ 652 InstanceIds: []*string{aws.String(rs.Primary.ID)}, 653 }) 654 if ec2err, ok := err.(awserr.Error); ok && ec2err.Code() == "InvalidInstanceID.NotFound" { 655 continue 656 } 657 if err != nil { 658 return err 659 } 660 661 if len(resp.Reservations) > 0 { 662 *i = *resp.Reservations[0].Instances[0] 663 return nil 664 } 665 } 666 667 return fmt.Errorf("Instance not found") 668 } 669 } 670 671 func TestInstanceTenancySchema(t *testing.T) { 672 actualSchema := resourceAwsInstance().Schema["tenancy"] 673 expectedSchema := &schema.Schema{ 674 Type: schema.TypeString, 675 Optional: true, 676 Computed: true, 677 ForceNew: true, 678 } 679 if !reflect.DeepEqual(actualSchema, expectedSchema) { 680 t.Fatalf( 681 "Got:\n\n%#v\n\nExpected:\n\n%#v\n", 682 actualSchema, 683 expectedSchema) 684 } 685 } 686 687 func driftTags(instance *ec2.Instance) resource.TestCheckFunc { 688 return func(s *terraform.State) error { 689 conn := testAccProvider.Meta().(*AWSClient).ec2conn 690 _, err := conn.CreateTags(&ec2.CreateTagsInput{ 691 Resources: []*string{instance.InstanceId}, 692 Tags: []*ec2.Tag{ 693 &ec2.Tag{ 694 Key: aws.String("Drift"), 695 Value: aws.String("Happens"), 696 }, 697 }, 698 }) 699 return err 700 } 701 } 702 703 const testAccInstanceConfig_pre = ` 704 resource "aws_security_group" "tf_test_foo" { 705 name = "tf_test_foo" 706 description = "foo" 707 708 ingress { 709 protocol = "icmp" 710 from_port = -1 711 to_port = -1 712 cidr_blocks = ["0.0.0.0/0"] 713 } 714 } 715 ` 716 717 const testAccInstanceConfig = ` 718 resource "aws_security_group" "tf_test_foo" { 719 name = "tf_test_foo" 720 description = "foo" 721 722 ingress { 723 protocol = "icmp" 724 from_port = -1 725 to_port = -1 726 cidr_blocks = ["0.0.0.0/0"] 727 } 728 } 729 730 resource "aws_instance" "foo" { 731 # us-west-2 732 ami = "ami-4fccb37f" 733 availability_zone = "us-west-2a" 734 735 instance_type = "m1.small" 736 security_groups = ["${aws_security_group.tf_test_foo.name}"] 737 user_data = "foo:-with-character's" 738 } 739 ` 740 741 const testAccInstanceConfigBlockDevices = ` 742 resource "aws_instance" "foo" { 743 # us-west-2 744 ami = "ami-55a7ea65" 745 746 # In order to attach an encrypted volume to an instance you need to have an 747 # m3.medium or larger. See "Supported Instance Types" in: 748 # http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/EBSEncryption.html 749 instance_type = "m3.medium" 750 751 root_block_device { 752 volume_type = "gp2" 753 volume_size = 11 754 } 755 ebs_block_device { 756 device_name = "/dev/sdb" 757 volume_size = 9 758 } 759 ebs_block_device { 760 device_name = "/dev/sdc" 761 volume_size = 10 762 volume_type = "io1" 763 iops = 100 764 } 765 766 # Encrypted ebs block device 767 ebs_block_device { 768 device_name = "/dev/sdd" 769 volume_size = 12 770 encrypted = true 771 } 772 773 ephemeral_block_device { 774 device_name = "/dev/sde" 775 virtual_name = "ephemeral0" 776 } 777 } 778 ` 779 780 const testAccInstanceConfigSourceDestEnable = ` 781 resource "aws_vpc" "foo" { 782 cidr_block = "10.1.0.0/16" 783 } 784 785 resource "aws_subnet" "foo" { 786 cidr_block = "10.1.1.0/24" 787 vpc_id = "${aws_vpc.foo.id}" 788 } 789 790 resource "aws_instance" "foo" { 791 # us-west-2 792 ami = "ami-4fccb37f" 793 instance_type = "m1.small" 794 subnet_id = "${aws_subnet.foo.id}" 795 } 796 ` 797 798 const testAccInstanceConfigSourceDestDisable = ` 799 resource "aws_vpc" "foo" { 800 cidr_block = "10.1.0.0/16" 801 } 802 803 resource "aws_subnet" "foo" { 804 cidr_block = "10.1.1.0/24" 805 vpc_id = "${aws_vpc.foo.id}" 806 } 807 808 resource "aws_instance" "foo" { 809 # us-west-2 810 ami = "ami-4fccb37f" 811 instance_type = "m1.small" 812 subnet_id = "${aws_subnet.foo.id}" 813 source_dest_check = false 814 } 815 ` 816 817 func testAccInstanceConfigDisableAPITermination(val bool) string { 818 return fmt.Sprintf(` 819 resource "aws_vpc" "foo" { 820 cidr_block = "10.1.0.0/16" 821 } 822 823 resource "aws_subnet" "foo" { 824 cidr_block = "10.1.1.0/24" 825 vpc_id = "${aws_vpc.foo.id}" 826 } 827 828 resource "aws_instance" "foo" { 829 # us-west-2 830 ami = "ami-4fccb37f" 831 instance_type = "m1.small" 832 subnet_id = "${aws_subnet.foo.id}" 833 disable_api_termination = %t 834 } 835 `, val) 836 } 837 838 const testAccInstanceConfigVPC = ` 839 resource "aws_vpc" "foo" { 840 cidr_block = "10.1.0.0/16" 841 } 842 843 resource "aws_subnet" "foo" { 844 cidr_block = "10.1.1.0/24" 845 vpc_id = "${aws_vpc.foo.id}" 846 } 847 848 resource "aws_instance" "foo" { 849 # us-west-2 850 ami = "ami-4fccb37f" 851 instance_type = "m1.small" 852 subnet_id = "${aws_subnet.foo.id}" 853 associate_public_ip_address = true 854 tenancy = "dedicated" 855 # pre-encoded base64 data 856 user_data = "3dc39dda39be1205215e776bad998da361a5955d" 857 } 858 ` 859 860 const testAccInstanceConfigMultipleRegions = ` 861 provider "aws" { 862 alias = "west" 863 region = "us-west-2" 864 } 865 866 provider "aws" { 867 alias = "east" 868 region = "us-east-1" 869 } 870 871 resource "aws_instance" "foo" { 872 # us-west-2 873 provider = "aws.west" 874 ami = "ami-4fccb37f" 875 instance_type = "m1.small" 876 } 877 878 resource "aws_instance" "bar" { 879 # us-east-1 880 provider = "aws.east" 881 ami = "ami-8c6ea9e4" 882 instance_type = "m1.small" 883 } 884 ` 885 886 const testAccCheckInstanceConfigTags = ` 887 resource "aws_instance" "foo" { 888 ami = "ami-4fccb37f" 889 instance_type = "m1.small" 890 tags { 891 foo = "bar" 892 } 893 } 894 ` 895 896 const testAccCheckInstanceConfigTagsUpdate = ` 897 resource "aws_instance" "foo" { 898 ami = "ami-4fccb37f" 899 instance_type = "m1.small" 900 tags { 901 bar = "baz" 902 } 903 } 904 ` 905 906 const testAccInstanceConfigPrivateIP = ` 907 resource "aws_vpc" "foo" { 908 cidr_block = "10.1.0.0/16" 909 } 910 911 resource "aws_subnet" "foo" { 912 cidr_block = "10.1.1.0/24" 913 vpc_id = "${aws_vpc.foo.id}" 914 } 915 916 resource "aws_instance" "foo" { 917 ami = "ami-c5eabbf5" 918 instance_type = "t2.micro" 919 subnet_id = "${aws_subnet.foo.id}" 920 private_ip = "10.1.1.42" 921 } 922 ` 923 924 const testAccInstanceConfigAssociatePublicIPAndPrivateIP = ` 925 resource "aws_vpc" "foo" { 926 cidr_block = "10.1.0.0/16" 927 } 928 929 resource "aws_subnet" "foo" { 930 cidr_block = "10.1.1.0/24" 931 vpc_id = "${aws_vpc.foo.id}" 932 } 933 934 resource "aws_instance" "foo" { 935 ami = "ami-c5eabbf5" 936 instance_type = "t2.micro" 937 subnet_id = "${aws_subnet.foo.id}" 938 associate_public_ip_address = true 939 private_ip = "10.1.1.42" 940 } 941 ` 942 943 const testAccInstanceNetworkInstanceSecurityGroups = ` 944 resource "aws_internet_gateway" "gw" { 945 vpc_id = "${aws_vpc.foo.id}" 946 } 947 948 resource "aws_vpc" "foo" { 949 cidr_block = "10.1.0.0/16" 950 tags { 951 Name = "tf-network-test" 952 } 953 } 954 955 resource "aws_security_group" "tf_test_foo" { 956 name = "tf_test_foo" 957 description = "foo" 958 vpc_id="${aws_vpc.foo.id}" 959 960 ingress { 961 protocol = "icmp" 962 from_port = -1 963 to_port = -1 964 cidr_blocks = ["0.0.0.0/0"] 965 } 966 } 967 968 resource "aws_subnet" "foo" { 969 cidr_block = "10.1.1.0/24" 970 vpc_id = "${aws_vpc.foo.id}" 971 } 972 973 resource "aws_instance" "foo_instance" { 974 ami = "ami-21f78e11" 975 instance_type = "t1.micro" 976 vpc_security_group_ids = ["${aws_security_group.tf_test_foo.id}"] 977 subnet_id = "${aws_subnet.foo.id}" 978 associate_public_ip_address = true 979 depends_on = ["aws_internet_gateway.gw"] 980 } 981 982 resource "aws_eip" "foo_eip" { 983 instance = "${aws_instance.foo_instance.id}" 984 vpc = true 985 depends_on = ["aws_internet_gateway.gw"] 986 } 987 ` 988 989 const testAccInstanceNetworkInstanceVPCSecurityGroupIDs = ` 990 resource "aws_internet_gateway" "gw" { 991 vpc_id = "${aws_vpc.foo.id}" 992 } 993 994 resource "aws_vpc" "foo" { 995 cidr_block = "10.1.0.0/16" 996 tags { 997 Name = "tf-network-test" 998 } 999 } 1000 1001 resource "aws_security_group" "tf_test_foo" { 1002 name = "tf_test_foo" 1003 description = "foo" 1004 vpc_id="${aws_vpc.foo.id}" 1005 1006 ingress { 1007 protocol = "icmp" 1008 from_port = -1 1009 to_port = -1 1010 cidr_blocks = ["0.0.0.0/0"] 1011 } 1012 } 1013 1014 resource "aws_subnet" "foo" { 1015 cidr_block = "10.1.1.0/24" 1016 vpc_id = "${aws_vpc.foo.id}" 1017 } 1018 1019 resource "aws_instance" "foo_instance" { 1020 ami = "ami-21f78e11" 1021 instance_type = "t1.micro" 1022 vpc_security_group_ids = ["${aws_security_group.tf_test_foo.id}"] 1023 subnet_id = "${aws_subnet.foo.id}" 1024 depends_on = ["aws_internet_gateway.gw"] 1025 } 1026 1027 resource "aws_eip" "foo_eip" { 1028 instance = "${aws_instance.foo_instance.id}" 1029 vpc = true 1030 depends_on = ["aws_internet_gateway.gw"] 1031 } 1032 ` 1033 1034 const testAccInstanceConfigKeyPair = ` 1035 provider "aws" { 1036 region = "us-east-1" 1037 } 1038 1039 resource "aws_key_pair" "debugging" { 1040 key_name = "tmp-key" 1041 public_key = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQD3F6tyPEFEzV0LX3X8BsXdMsQz1x2cEikKDEY0aIj41qgxMCP/iteneqXSIFZBp5vizPvaoIR3Um9xK7PGoW8giupGn+EPuxIA4cDM4vzOqOkiMPhz5XK0whEjkVzTo4+S0puvDZuwIsdiW9mxhJc7tgBNL0cYlWSYVkz4G/fslNfRPW5mYAM49f4fhtxPb5ok4Q2Lg9dPKVHO/Bgeu5woMc7RY0p1ej6D4CKFE6lymSDJpW0YHX/wqE9+cfEauh7xZcG0q9t2ta6F6fmX0agvpFyZo8aFbXeUBr7osSCJNgvavWbM/06niWrOvYX2xwWdhXmXSrbX8ZbabVohBK41 phodgson@thoughtworks.com" 1042 } 1043 1044 resource "aws_instance" "foo" { 1045 ami = "ami-408c7f28" 1046 instance_type = "t1.micro" 1047 key_name = "${aws_key_pair.debugging.key_name}" 1048 tags { 1049 Name = "testAccInstanceConfigKeyPair_TestAMI" 1050 } 1051 } 1052 ` 1053 1054 const testAccInstanceConfigRootBlockDeviceMismatch = ` 1055 resource "aws_vpc" "foo" { 1056 cidr_block = "10.1.0.0/16" 1057 } 1058 1059 resource "aws_subnet" "foo" { 1060 cidr_block = "10.1.1.0/24" 1061 vpc_id = "${aws_vpc.foo.id}" 1062 } 1063 1064 resource "aws_instance" "foo" { 1065 // This is an AMI with RootDeviceName: "/dev/sda1"; actual root: "/dev/sda" 1066 ami = "ami-ef5b69df" 1067 instance_type = "t1.micro" 1068 subnet_id = "${aws_subnet.foo.id}" 1069 root_block_device { 1070 volume_size = 13 1071 } 1072 } 1073 ` 1074 1075 const testAccInstanceConfigForceNewAndTagsDrift = ` 1076 resource "aws_vpc" "foo" { 1077 cidr_block = "10.1.0.0/16" 1078 } 1079 1080 resource "aws_subnet" "foo" { 1081 cidr_block = "10.1.1.0/24" 1082 vpc_id = "${aws_vpc.foo.id}" 1083 } 1084 1085 resource "aws_instance" "foo" { 1086 ami = "ami-22b9a343" 1087 instance_type = "t2.nano" 1088 subnet_id = "${aws_subnet.foo.id}" 1089 } 1090 ` 1091 1092 const testAccInstanceConfigForceNewAndTagsDrift_Update = ` 1093 resource "aws_vpc" "foo" { 1094 cidr_block = "10.1.0.0/16" 1095 } 1096 1097 resource "aws_subnet" "foo" { 1098 cidr_block = "10.1.1.0/24" 1099 vpc_id = "${aws_vpc.foo.id}" 1100 } 1101 1102 resource "aws_instance" "foo" { 1103 ami = "ami-22b9a343" 1104 instance_type = "t2.micro" 1105 subnet_id = "${aws_subnet.foo.id}" 1106 } 1107 `