github.com/danp/terraform@v0.9.5-0.20170426144147-39d740081351/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/acctest" 12 "github.com/hashicorp/terraform/helper/resource" 13 "github.com/hashicorp/terraform/helper/schema" 14 "github.com/hashicorp/terraform/terraform" 15 ) 16 17 func TestAccAWSInstance_basic(t *testing.T) { 18 var v ec2.Instance 19 var vol *ec2.Volume 20 21 testCheck := func(*terraform.State) error { 22 if *v.Placement.AvailabilityZone != "us-west-2a" { 23 return fmt.Errorf("bad availability zone: %#v", *v.Placement.AvailabilityZone) 24 } 25 26 if len(v.SecurityGroups) == 0 { 27 return fmt.Errorf("no security groups: %#v", v.SecurityGroups) 28 } 29 if *v.SecurityGroups[0].GroupName != "tf_test_foo" { 30 return fmt.Errorf("no security groups: %#v", v.SecurityGroups) 31 } 32 33 return nil 34 } 35 36 resource.Test(t, resource.TestCase{ 37 PreCheck: func() { testAccPreCheck(t) }, 38 39 // We ignore security groups because even with EC2 classic 40 // we'll import as VPC security groups, which is fine. We verify 41 // VPC security group import in other tests 42 IDRefreshName: "aws_instance.foo", 43 IDRefreshIgnore: []string{"security_groups", "vpc_security_group_ids"}, 44 45 Providers: testAccProviders, 46 CheckDestroy: testAccCheckInstanceDestroy, 47 Steps: []resource.TestStep{ 48 // Create a volume to cover #1249 49 { 50 // Need a resource in this config so the provisioner will be available 51 Config: testAccInstanceConfig_pre, 52 Check: func(*terraform.State) error { 53 conn := testAccProvider.Meta().(*AWSClient).ec2conn 54 var err error 55 vol, err = conn.CreateVolume(&ec2.CreateVolumeInput{ 56 AvailabilityZone: aws.String("us-west-2a"), 57 Size: aws.Int64(int64(5)), 58 }) 59 return err 60 }, 61 }, 62 63 { 64 Config: testAccInstanceConfig, 65 Check: resource.ComposeTestCheckFunc( 66 testAccCheckInstanceExists( 67 "aws_instance.foo", &v), 68 testCheck, 69 resource.TestCheckResourceAttr( 70 "aws_instance.foo", 71 "user_data", 72 "3dc39dda39be1205215e776bad998da361a5955d"), 73 resource.TestCheckResourceAttr( 74 "aws_instance.foo", "ebs_block_device.#", "0"), 75 ), 76 }, 77 78 // We repeat the exact same test so that we can be sure 79 // that the user data hash stuff is working without generating 80 // an incorrect diff. 81 { 82 Config: testAccInstanceConfig, 83 Check: resource.ComposeTestCheckFunc( 84 testAccCheckInstanceExists( 85 "aws_instance.foo", &v), 86 testCheck, 87 resource.TestCheckResourceAttr( 88 "aws_instance.foo", 89 "user_data", 90 "3dc39dda39be1205215e776bad998da361a5955d"), 91 resource.TestCheckResourceAttr( 92 "aws_instance.foo", "ebs_block_device.#", "0"), 93 ), 94 }, 95 96 // Clean up volume created above 97 { 98 Config: testAccInstanceConfig, 99 Check: func(*terraform.State) error { 100 conn := testAccProvider.Meta().(*AWSClient).ec2conn 101 _, err := conn.DeleteVolume(&ec2.DeleteVolumeInput{VolumeId: vol.VolumeId}) 102 return err 103 }, 104 }, 105 }, 106 }) 107 } 108 109 func TestAccAWSInstance_GP2IopsDevice(t *testing.T) { 110 var v ec2.Instance 111 112 testCheck := func() resource.TestCheckFunc { 113 return func(*terraform.State) error { 114 115 // Map out the block devices by name, which should be unique. 116 blockDevices := make(map[string]*ec2.InstanceBlockDeviceMapping) 117 for _, blockDevice := range v.BlockDeviceMappings { 118 blockDevices[*blockDevice.DeviceName] = blockDevice 119 } 120 121 // Check if the root block device exists. 122 if _, ok := blockDevices["/dev/sda1"]; !ok { 123 return fmt.Errorf("block device doesn't exist: /dev/sda1") 124 } 125 126 return nil 127 } 128 } 129 130 resource.Test(t, resource.TestCase{ 131 PreCheck: func() { testAccPreCheck(t) }, 132 IDRefreshName: "aws_instance.foo", 133 IDRefreshIgnore: []string{ 134 "ephemeral_block_device", "user_data", "security_groups", "vpc_security_groups"}, 135 Providers: testAccProviders, 136 CheckDestroy: testAccCheckInstanceDestroy, 137 Steps: []resource.TestStep{ 138 { 139 Config: testAccInstanceGP2IopsDevice, 140 //Config: testAccInstanceConfigBlockDevices, 141 Check: resource.ComposeTestCheckFunc( 142 testAccCheckInstanceExists( 143 "aws_instance.foo", &v), 144 resource.TestCheckResourceAttr( 145 "aws_instance.foo", "root_block_device.#", "1"), 146 resource.TestCheckResourceAttr( 147 "aws_instance.foo", "root_block_device.0.volume_size", "11"), 148 resource.TestCheckResourceAttr( 149 "aws_instance.foo", "root_block_device.0.volume_type", "gp2"), 150 resource.TestCheckResourceAttr( 151 "aws_instance.foo", "root_block_device.0.iops", "100"), 152 testCheck(), 153 ), 154 }, 155 }, 156 }) 157 } 158 159 func TestAccAWSInstance_blockDevices(t *testing.T) { 160 var v ec2.Instance 161 162 testCheck := func() resource.TestCheckFunc { 163 return func(*terraform.State) error { 164 165 // Map out the block devices by name, which should be unique. 166 blockDevices := make(map[string]*ec2.InstanceBlockDeviceMapping) 167 for _, blockDevice := range v.BlockDeviceMappings { 168 blockDevices[*blockDevice.DeviceName] = blockDevice 169 } 170 171 // Check if the root block device exists. 172 if _, ok := blockDevices["/dev/sda1"]; !ok { 173 return fmt.Errorf("block device doesn't exist: /dev/sda1") 174 } 175 176 // Check if the secondary block device exists. 177 if _, ok := blockDevices["/dev/sdb"]; !ok { 178 return fmt.Errorf("block device doesn't exist: /dev/sdb") 179 } 180 181 // Check if the third block device exists. 182 if _, ok := blockDevices["/dev/sdc"]; !ok { 183 return fmt.Errorf("block device doesn't exist: /dev/sdc") 184 } 185 186 // Check if the encrypted block device exists 187 if _, ok := blockDevices["/dev/sdd"]; !ok { 188 return fmt.Errorf("block device doesn't exist: /dev/sdd") 189 } 190 191 return nil 192 } 193 } 194 195 resource.Test(t, resource.TestCase{ 196 PreCheck: func() { testAccPreCheck(t) }, 197 IDRefreshName: "aws_instance.foo", 198 IDRefreshIgnore: []string{ 199 "ephemeral_block_device", "security_groups", "vpc_security_groups"}, 200 Providers: testAccProviders, 201 CheckDestroy: testAccCheckInstanceDestroy, 202 Steps: []resource.TestStep{ 203 { 204 Config: testAccInstanceConfigBlockDevices, 205 Check: resource.ComposeTestCheckFunc( 206 testAccCheckInstanceExists( 207 "aws_instance.foo", &v), 208 resource.TestCheckResourceAttr( 209 "aws_instance.foo", "root_block_device.#", "1"), 210 resource.TestCheckResourceAttr( 211 "aws_instance.foo", "root_block_device.0.volume_size", "11"), 212 resource.TestCheckResourceAttr( 213 "aws_instance.foo", "root_block_device.0.volume_type", "gp2"), 214 resource.TestCheckResourceAttr( 215 "aws_instance.foo", "ebs_block_device.#", "3"), 216 resource.TestCheckResourceAttr( 217 "aws_instance.foo", "ebs_block_device.2576023345.device_name", "/dev/sdb"), 218 resource.TestCheckResourceAttr( 219 "aws_instance.foo", "ebs_block_device.2576023345.volume_size", "9"), 220 resource.TestCheckResourceAttr( 221 "aws_instance.foo", "ebs_block_device.2576023345.volume_type", "standard"), 222 resource.TestCheckResourceAttr( 223 "aws_instance.foo", "ebs_block_device.2554893574.device_name", "/dev/sdc"), 224 resource.TestCheckResourceAttr( 225 "aws_instance.foo", "ebs_block_device.2554893574.volume_size", "10"), 226 resource.TestCheckResourceAttr( 227 "aws_instance.foo", "ebs_block_device.2554893574.volume_type", "io1"), 228 resource.TestCheckResourceAttr( 229 "aws_instance.foo", "ebs_block_device.2554893574.iops", "100"), 230 resource.TestCheckResourceAttr( 231 "aws_instance.foo", "ebs_block_device.2634515331.device_name", "/dev/sdd"), 232 resource.TestCheckResourceAttr( 233 "aws_instance.foo", "ebs_block_device.2634515331.encrypted", "true"), 234 resource.TestCheckResourceAttr( 235 "aws_instance.foo", "ebs_block_device.2634515331.volume_size", "12"), 236 resource.TestCheckResourceAttr( 237 "aws_instance.foo", "ephemeral_block_device.#", "1"), 238 resource.TestCheckResourceAttr( 239 "aws_instance.foo", "ephemeral_block_device.1692014856.device_name", "/dev/sde"), 240 resource.TestCheckResourceAttr( 241 "aws_instance.foo", "ephemeral_block_device.1692014856.virtual_name", "ephemeral0"), 242 testCheck(), 243 ), 244 }, 245 }, 246 }) 247 } 248 249 func TestAccAWSInstance_rootInstanceStore(t *testing.T) { 250 var v ec2.Instance 251 252 resource.Test(t, resource.TestCase{ 253 PreCheck: func() { testAccPreCheck(t) }, 254 IDRefreshName: "aws_instance.foo", 255 Providers: testAccProviders, 256 CheckDestroy: testAccCheckInstanceDestroy, 257 Steps: []resource.TestStep{ 258 { 259 Config: ` 260 resource "aws_instance" "foo" { 261 # us-west-2 262 # Amazon Linux HVM Instance Store 64-bit (2016.09.0) 263 # https://aws.amazon.com/amazon-linux-ami 264 ami = "ami-44c36524" 265 266 # Only certain instance types support ephemeral root instance stores. 267 # http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/InstanceStorage.html 268 instance_type = "m3.medium" 269 }`, 270 Check: resource.ComposeTestCheckFunc( 271 testAccCheckInstanceExists( 272 "aws_instance.foo", &v), 273 resource.TestCheckResourceAttr( 274 "aws_instance.foo", "ami", "ami-44c36524"), 275 resource.TestCheckResourceAttr( 276 "aws_instance.foo", "ebs_block_device.#", "0"), 277 resource.TestCheckResourceAttr( 278 "aws_instance.foo", "ebs_optimized", "false"), 279 resource.TestCheckResourceAttr( 280 "aws_instance.foo", "instance_type", "m3.medium"), 281 resource.TestCheckResourceAttr( 282 "aws_instance.foo", "root_block_device.#", "0"), 283 ), 284 }, 285 }, 286 }) 287 } 288 289 func TestAcctABSInstance_noAMIEphemeralDevices(t *testing.T) { 290 var v ec2.Instance 291 292 testCheck := func() resource.TestCheckFunc { 293 return func(*terraform.State) error { 294 295 // Map out the block devices by name, which should be unique. 296 blockDevices := make(map[string]*ec2.InstanceBlockDeviceMapping) 297 for _, blockDevice := range v.BlockDeviceMappings { 298 blockDevices[*blockDevice.DeviceName] = blockDevice 299 } 300 301 // Check if the root block device exists. 302 if _, ok := blockDevices["/dev/sda1"]; !ok { 303 return fmt.Errorf("block device doesn't exist: /dev/sda1") 304 } 305 306 // Check if the secondary block not exists. 307 if _, ok := blockDevices["/dev/sdb"]; ok { 308 return fmt.Errorf("block device exist: /dev/sdb") 309 } 310 311 // Check if the third block device not exists. 312 if _, ok := blockDevices["/dev/sdc"]; ok { 313 return fmt.Errorf("block device exist: /dev/sdc") 314 } 315 return nil 316 } 317 } 318 319 resource.Test(t, resource.TestCase{ 320 PreCheck: func() { testAccPreCheck(t) }, 321 IDRefreshName: "aws_instance.foo", 322 IDRefreshIgnore: []string{ 323 "ephemeral_block_device", "security_groups", "vpc_security_groups"}, 324 Providers: testAccProviders, 325 CheckDestroy: testAccCheckInstanceDestroy, 326 Steps: []resource.TestStep{ 327 { 328 Config: ` 329 resource "aws_instance" "foo" { 330 # us-west-2 331 ami = "ami-01f05461" // This AMI (Ubuntu) contains two ephemerals 332 333 instance_type = "c3.large" 334 335 root_block_device { 336 volume_type = "gp2" 337 volume_size = 11 338 } 339 ephemeral_block_device { 340 device_name = "/dev/sdb" 341 no_device = true 342 } 343 ephemeral_block_device { 344 device_name = "/dev/sdc" 345 no_device = true 346 } 347 }`, 348 Check: resource.ComposeTestCheckFunc( 349 testAccCheckInstanceExists( 350 "aws_instance.foo", &v), 351 resource.TestCheckResourceAttr( 352 "aws_instance.foo", "ami", "ami-01f05461"), 353 resource.TestCheckResourceAttr( 354 "aws_instance.foo", "ebs_optimized", "false"), 355 resource.TestCheckResourceAttr( 356 "aws_instance.foo", "instance_type", "c3.large"), 357 resource.TestCheckResourceAttr( 358 "aws_instance.foo", "root_block_device.#", "1"), 359 resource.TestCheckResourceAttr( 360 "aws_instance.foo", "root_block_device.0.volume_size", "11"), 361 resource.TestCheckResourceAttr( 362 "aws_instance.foo", "root_block_device.0.volume_type", "gp2"), 363 resource.TestCheckResourceAttr( 364 "aws_instance.foo", "ebs_block_device.#", "0"), 365 resource.TestCheckResourceAttr( 366 "aws_instance.foo", "ephemeral_block_device.#", "2"), 367 resource.TestCheckResourceAttr( 368 "aws_instance.foo", "ephemeral_block_device.172787947.device_name", "/dev/sdb"), 369 resource.TestCheckResourceAttr( 370 "aws_instance.foo", "ephemeral_block_device.172787947.no_device", "true"), 371 resource.TestCheckResourceAttr( 372 "aws_instance.foo", "ephemeral_block_device.3336996981.device_name", "/dev/sdc"), 373 resource.TestCheckResourceAttr( 374 "aws_instance.foo", "ephemeral_block_device.3336996981.no_device", "true"), 375 testCheck(), 376 ), 377 }, 378 }, 379 }) 380 } 381 382 func TestAccAWSInstance_sourceDestCheck(t *testing.T) { 383 var v ec2.Instance 384 385 testCheck := func(enabled bool) resource.TestCheckFunc { 386 return func(*terraform.State) error { 387 if v.SourceDestCheck == nil { 388 return fmt.Errorf("bad source_dest_check: got nil") 389 } 390 if *v.SourceDestCheck != enabled { 391 return fmt.Errorf("bad source_dest_check: %#v", *v.SourceDestCheck) 392 } 393 394 return nil 395 } 396 } 397 398 resource.Test(t, resource.TestCase{ 399 PreCheck: func() { testAccPreCheck(t) }, 400 IDRefreshName: "aws_instance.foo", 401 Providers: testAccProviders, 402 CheckDestroy: testAccCheckInstanceDestroy, 403 Steps: []resource.TestStep{ 404 { 405 Config: testAccInstanceConfigSourceDestDisable, 406 Check: resource.ComposeTestCheckFunc( 407 testAccCheckInstanceExists("aws_instance.foo", &v), 408 testCheck(false), 409 ), 410 }, 411 412 { 413 Config: testAccInstanceConfigSourceDestEnable, 414 Check: resource.ComposeTestCheckFunc( 415 testAccCheckInstanceExists("aws_instance.foo", &v), 416 testCheck(true), 417 ), 418 }, 419 420 { 421 Config: testAccInstanceConfigSourceDestDisable, 422 Check: resource.ComposeTestCheckFunc( 423 testAccCheckInstanceExists("aws_instance.foo", &v), 424 testCheck(false), 425 ), 426 }, 427 }, 428 }) 429 } 430 431 func TestAccAWSInstance_disableApiTermination(t *testing.T) { 432 var v ec2.Instance 433 434 checkDisableApiTermination := func(expected bool) resource.TestCheckFunc { 435 return func(*terraform.State) error { 436 conn := testAccProvider.Meta().(*AWSClient).ec2conn 437 r, err := conn.DescribeInstanceAttribute(&ec2.DescribeInstanceAttributeInput{ 438 InstanceId: v.InstanceId, 439 Attribute: aws.String("disableApiTermination"), 440 }) 441 if err != nil { 442 return err 443 } 444 got := *r.DisableApiTermination.Value 445 if got != expected { 446 return fmt.Errorf("expected: %t, got: %t", expected, got) 447 } 448 return nil 449 } 450 } 451 452 resource.Test(t, resource.TestCase{ 453 PreCheck: func() { testAccPreCheck(t) }, 454 IDRefreshName: "aws_instance.foo", 455 Providers: testAccProviders, 456 CheckDestroy: testAccCheckInstanceDestroy, 457 Steps: []resource.TestStep{ 458 { 459 Config: testAccInstanceConfigDisableAPITermination(true), 460 Check: resource.ComposeTestCheckFunc( 461 testAccCheckInstanceExists("aws_instance.foo", &v), 462 checkDisableApiTermination(true), 463 ), 464 }, 465 466 { 467 Config: testAccInstanceConfigDisableAPITermination(false), 468 Check: resource.ComposeTestCheckFunc( 469 testAccCheckInstanceExists("aws_instance.foo", &v), 470 checkDisableApiTermination(false), 471 ), 472 }, 473 }, 474 }) 475 } 476 477 func TestAccAWSInstance_vpc(t *testing.T) { 478 var v ec2.Instance 479 480 resource.Test(t, resource.TestCase{ 481 PreCheck: func() { testAccPreCheck(t) }, 482 IDRefreshName: "aws_instance.foo", 483 IDRefreshIgnore: []string{"associate_public_ip_address"}, 484 Providers: testAccProviders, 485 CheckDestroy: testAccCheckInstanceDestroy, 486 Steps: []resource.TestStep{ 487 { 488 Config: testAccInstanceConfigVPC, 489 Check: resource.ComposeTestCheckFunc( 490 testAccCheckInstanceExists( 491 "aws_instance.foo", &v), 492 resource.TestCheckResourceAttr( 493 "aws_instance.foo", 494 "user_data", 495 "562a3e32810edf6ff09994f050f12e799452379d"), 496 ), 497 }, 498 }, 499 }) 500 } 501 502 func TestAccAWSInstance_ipv6_supportAddressCount(t *testing.T) { 503 var v ec2.Instance 504 505 resource.Test(t, resource.TestCase{ 506 PreCheck: func() { testAccPreCheck(t) }, 507 Providers: testAccProviders, 508 CheckDestroy: testAccCheckInstanceDestroy, 509 Steps: []resource.TestStep{ 510 { 511 Config: testAccInstanceConfigIpv6Support, 512 Check: resource.ComposeTestCheckFunc( 513 testAccCheckInstanceExists( 514 "aws_instance.foo", &v), 515 resource.TestCheckResourceAttr( 516 "aws_instance.foo", 517 "ipv6_address_count", 518 "1"), 519 ), 520 }, 521 }, 522 }) 523 } 524 525 func TestAccAWSInstance_multipleRegions(t *testing.T) { 526 var v ec2.Instance 527 528 // record the initialized providers so that we can use them to 529 // check for the instances in each region 530 var providers []*schema.Provider 531 providerFactories := map[string]terraform.ResourceProviderFactory{ 532 "aws": func() (terraform.ResourceProvider, error) { 533 p := Provider() 534 providers = append(providers, p.(*schema.Provider)) 535 return p, nil 536 }, 537 } 538 539 resource.Test(t, resource.TestCase{ 540 PreCheck: func() { testAccPreCheck(t) }, 541 ProviderFactories: providerFactories, 542 CheckDestroy: testAccCheckInstanceDestroyWithProviders(&providers), 543 Steps: []resource.TestStep{ 544 { 545 Config: testAccInstanceConfigMultipleRegions, 546 Check: resource.ComposeTestCheckFunc( 547 testAccCheckInstanceExistsWithProviders( 548 "aws_instance.foo", &v, &providers), 549 testAccCheckInstanceExistsWithProviders( 550 "aws_instance.bar", &v, &providers), 551 ), 552 }, 553 }, 554 }) 555 } 556 557 func TestAccAWSInstance_NetworkInstanceSecurityGroups(t *testing.T) { 558 var v ec2.Instance 559 560 resource.Test(t, resource.TestCase{ 561 PreCheck: func() { testAccPreCheck(t) }, 562 IDRefreshName: "aws_instance.foo_instance", 563 IDRefreshIgnore: []string{"associate_public_ip_address"}, 564 Providers: testAccProviders, 565 CheckDestroy: testAccCheckInstanceDestroy, 566 Steps: []resource.TestStep{ 567 { 568 Config: testAccInstanceNetworkInstanceSecurityGroups, 569 Check: resource.ComposeTestCheckFunc( 570 testAccCheckInstanceExists( 571 "aws_instance.foo_instance", &v), 572 ), 573 }, 574 }, 575 }) 576 } 577 578 func TestAccAWSInstance_NetworkInstanceVPCSecurityGroupIDs(t *testing.T) { 579 var v ec2.Instance 580 581 resource.Test(t, resource.TestCase{ 582 PreCheck: func() { testAccPreCheck(t) }, 583 IDRefreshName: "aws_instance.foo_instance", 584 Providers: testAccProviders, 585 CheckDestroy: testAccCheckInstanceDestroy, 586 Steps: []resource.TestStep{ 587 { 588 Config: testAccInstanceNetworkInstanceVPCSecurityGroupIDs, 589 Check: resource.ComposeTestCheckFunc( 590 testAccCheckInstanceExists( 591 "aws_instance.foo_instance", &v), 592 resource.TestCheckResourceAttr( 593 "aws_instance.foo_instance", "security_groups.#", "0"), 594 resource.TestCheckResourceAttr( 595 "aws_instance.foo_instance", "vpc_security_group_ids.#", "1"), 596 ), 597 }, 598 }, 599 }) 600 } 601 602 func TestAccAWSInstance_tags(t *testing.T) { 603 var v ec2.Instance 604 605 resource.Test(t, resource.TestCase{ 606 PreCheck: func() { testAccPreCheck(t) }, 607 Providers: testAccProviders, 608 CheckDestroy: testAccCheckInstanceDestroy, 609 Steps: []resource.TestStep{ 610 { 611 Config: testAccCheckInstanceConfigTags, 612 Check: resource.ComposeTestCheckFunc( 613 testAccCheckInstanceExists("aws_instance.foo", &v), 614 testAccCheckTags(&v.Tags, "foo", "bar"), 615 // Guard against regression of https://github.com/hashicorp/terraform/issues/914 616 testAccCheckTags(&v.Tags, "#", ""), 617 ), 618 }, 619 { 620 Config: testAccCheckInstanceConfigTagsUpdate, 621 Check: resource.ComposeTestCheckFunc( 622 testAccCheckInstanceExists("aws_instance.foo", &v), 623 testAccCheckTags(&v.Tags, "foo", ""), 624 testAccCheckTags(&v.Tags, "bar", "baz"), 625 ), 626 }, 627 }, 628 }) 629 } 630 631 func TestAccAWSInstance_volumeTags(t *testing.T) { 632 var v ec2.Instance 633 634 resource.Test(t, resource.TestCase{ 635 PreCheck: func() { testAccPreCheck(t) }, 636 Providers: testAccProviders, 637 CheckDestroy: testAccCheckInstanceDestroy, 638 Steps: []resource.TestStep{ 639 { 640 Config: testAccCheckInstanceConfigNoVolumeTags, 641 Check: resource.ComposeTestCheckFunc( 642 testAccCheckInstanceExists("aws_instance.foo", &v), 643 resource.TestCheckNoResourceAttr( 644 "aws_instance.foo", "volume_tags"), 645 ), 646 }, 647 { 648 Config: testAccCheckInstanceConfigWithVolumeTags, 649 Check: resource.ComposeTestCheckFunc( 650 testAccCheckInstanceExists("aws_instance.foo", &v), 651 resource.TestCheckResourceAttr( 652 "aws_instance.foo", "volume_tags.%", "1"), 653 resource.TestCheckResourceAttr( 654 "aws_instance.foo", "volume_tags.Name", "acceptance-test-volume-tag"), 655 ), 656 }, 657 { 658 Config: testAccCheckInstanceConfigWithVolumeTagsUpdate, 659 Check: resource.ComposeTestCheckFunc( 660 testAccCheckInstanceExists("aws_instance.foo", &v), 661 resource.TestCheckResourceAttr( 662 "aws_instance.foo", "volume_tags.%", "2"), 663 resource.TestCheckResourceAttr( 664 "aws_instance.foo", "volume_tags.Name", "acceptance-test-volume-tag"), 665 resource.TestCheckResourceAttr( 666 "aws_instance.foo", "volume_tags.Environment", "dev"), 667 ), 668 }, 669 { 670 Config: testAccCheckInstanceConfigNoVolumeTags, 671 Check: resource.ComposeTestCheckFunc( 672 testAccCheckInstanceExists("aws_instance.foo", &v), 673 resource.TestCheckNoResourceAttr( 674 "aws_instance.foo", "volume_tags"), 675 ), 676 }, 677 }, 678 }) 679 } 680 681 func TestAccAWSInstance_instanceProfileChange(t *testing.T) { 682 var v ec2.Instance 683 rName := acctest.RandString(5) 684 685 testCheckInstanceProfile := func() resource.TestCheckFunc { 686 return func(*terraform.State) error { 687 if v.IamInstanceProfile == nil { 688 return fmt.Errorf("Instance Profile is nil - we expected an InstanceProfile associated with the Instance") 689 } 690 691 return nil 692 } 693 } 694 695 resource.Test(t, resource.TestCase{ 696 PreCheck: func() { testAccPreCheck(t) }, 697 IDRefreshName: "aws_instance.foo", 698 Providers: testAccProviders, 699 CheckDestroy: testAccCheckInstanceDestroy, 700 Steps: []resource.TestStep{ 701 { 702 Config: testAccInstanceConfigWithoutInstanceProfile(rName), 703 Check: resource.ComposeTestCheckFunc( 704 testAccCheckInstanceExists("aws_instance.foo", &v), 705 ), 706 }, 707 { 708 Config: testAccInstanceConfigWithInstanceProfile(rName), 709 Check: resource.ComposeTestCheckFunc( 710 testAccCheckInstanceExists("aws_instance.foo", &v), 711 testCheckInstanceProfile(), 712 ), 713 }, 714 }, 715 }) 716 } 717 718 func TestAccAWSInstance_withIamInstanceProfile(t *testing.T) { 719 var v ec2.Instance 720 rName := acctest.RandString(5) 721 722 testCheckInstanceProfile := func() resource.TestCheckFunc { 723 return func(*terraform.State) error { 724 if v.IamInstanceProfile == nil { 725 return fmt.Errorf("Instance Profile is nil - we expected an InstanceProfile associated with the Instance") 726 } 727 728 return nil 729 } 730 } 731 732 resource.Test(t, resource.TestCase{ 733 PreCheck: func() { testAccPreCheck(t) }, 734 IDRefreshName: "aws_instance.foo", 735 Providers: testAccProviders, 736 CheckDestroy: testAccCheckInstanceDestroy, 737 Steps: []resource.TestStep{ 738 { 739 Config: testAccInstanceConfigWithInstanceProfile(rName), 740 Check: resource.ComposeTestCheckFunc( 741 testAccCheckInstanceExists("aws_instance.foo", &v), 742 testCheckInstanceProfile(), 743 ), 744 }, 745 }, 746 }) 747 } 748 749 func TestAccAWSInstance_privateIP(t *testing.T) { 750 var v ec2.Instance 751 752 testCheckPrivateIP := func() resource.TestCheckFunc { 753 return func(*terraform.State) error { 754 if *v.PrivateIpAddress != "10.1.1.42" { 755 return fmt.Errorf("bad private IP: %s", *v.PrivateIpAddress) 756 } 757 758 return nil 759 } 760 } 761 762 resource.Test(t, resource.TestCase{ 763 PreCheck: func() { testAccPreCheck(t) }, 764 IDRefreshName: "aws_instance.foo", 765 Providers: testAccProviders, 766 CheckDestroy: testAccCheckInstanceDestroy, 767 Steps: []resource.TestStep{ 768 { 769 Config: testAccInstanceConfigPrivateIP, 770 Check: resource.ComposeTestCheckFunc( 771 testAccCheckInstanceExists("aws_instance.foo", &v), 772 testCheckPrivateIP(), 773 ), 774 }, 775 }, 776 }) 777 } 778 779 func TestAccAWSInstance_associatePublicIPAndPrivateIP(t *testing.T) { 780 var v ec2.Instance 781 782 testCheckPrivateIP := func() resource.TestCheckFunc { 783 return func(*terraform.State) error { 784 if *v.PrivateIpAddress != "10.1.1.42" { 785 return fmt.Errorf("bad private IP: %s", *v.PrivateIpAddress) 786 } 787 788 return nil 789 } 790 } 791 792 resource.Test(t, resource.TestCase{ 793 PreCheck: func() { testAccPreCheck(t) }, 794 IDRefreshName: "aws_instance.foo", 795 IDRefreshIgnore: []string{"associate_public_ip_address"}, 796 Providers: testAccProviders, 797 CheckDestroy: testAccCheckInstanceDestroy, 798 Steps: []resource.TestStep{ 799 { 800 Config: testAccInstanceConfigAssociatePublicIPAndPrivateIP, 801 Check: resource.ComposeTestCheckFunc( 802 testAccCheckInstanceExists("aws_instance.foo", &v), 803 testCheckPrivateIP(), 804 ), 805 }, 806 }, 807 }) 808 } 809 810 // Guard against regression with KeyPairs 811 // https://github.com/hashicorp/terraform/issues/2302 812 func TestAccAWSInstance_keyPairCheck(t *testing.T) { 813 var v ec2.Instance 814 815 testCheckKeyPair := func(keyName string) resource.TestCheckFunc { 816 return func(*terraform.State) error { 817 if v.KeyName == nil { 818 return fmt.Errorf("No Key Pair found, expected(%s)", keyName) 819 } 820 if v.KeyName != nil && *v.KeyName != keyName { 821 return fmt.Errorf("Bad key name, expected (%s), got (%s)", keyName, *v.KeyName) 822 } 823 824 return nil 825 } 826 } 827 828 resource.Test(t, resource.TestCase{ 829 PreCheck: func() { testAccPreCheck(t) }, 830 IDRefreshName: "aws_instance.foo", 831 IDRefreshIgnore: []string{"source_dest_check"}, 832 Providers: testAccProviders, 833 CheckDestroy: testAccCheckInstanceDestroy, 834 Steps: []resource.TestStep{ 835 { 836 Config: testAccInstanceConfigKeyPair, 837 Check: resource.ComposeTestCheckFunc( 838 testAccCheckInstanceExists("aws_instance.foo", &v), 839 testCheckKeyPair("tmp-key"), 840 ), 841 }, 842 }, 843 }) 844 } 845 846 func TestAccAWSInstance_rootBlockDeviceMismatch(t *testing.T) { 847 var v ec2.Instance 848 849 resource.Test(t, resource.TestCase{ 850 PreCheck: func() { testAccPreCheck(t) }, 851 Providers: testAccProviders, 852 CheckDestroy: testAccCheckInstanceDestroy, 853 Steps: []resource.TestStep{ 854 { 855 Config: testAccInstanceConfigRootBlockDeviceMismatch, 856 Check: resource.ComposeTestCheckFunc( 857 testAccCheckInstanceExists("aws_instance.foo", &v), 858 resource.TestCheckResourceAttr( 859 "aws_instance.foo", "root_block_device.0.volume_size", "13"), 860 ), 861 }, 862 }, 863 }) 864 } 865 866 // This test reproduces the bug here: 867 // https://github.com/hashicorp/terraform/issues/1752 868 // 869 // I wish there were a way to exercise resources built with helper.Schema in a 870 // unit context, in which case this test could be moved there, but for now this 871 // will cover the bugfix. 872 // 873 // The following triggers "diffs didn't match during apply" without the fix in to 874 // set NewRemoved on the .# field when it changes to 0. 875 func TestAccAWSInstance_forceNewAndTagsDrift(t *testing.T) { 876 var v ec2.Instance 877 878 resource.Test(t, resource.TestCase{ 879 PreCheck: func() { testAccPreCheck(t) }, 880 IDRefreshName: "aws_instance.foo", 881 Providers: testAccProviders, 882 CheckDestroy: testAccCheckInstanceDestroy, 883 Steps: []resource.TestStep{ 884 { 885 Config: testAccInstanceConfigForceNewAndTagsDrift, 886 Check: resource.ComposeTestCheckFunc( 887 testAccCheckInstanceExists("aws_instance.foo", &v), 888 driftTags(&v), 889 ), 890 ExpectNonEmptyPlan: true, 891 }, 892 { 893 Config: testAccInstanceConfigForceNewAndTagsDrift_Update, 894 Check: resource.ComposeTestCheckFunc( 895 testAccCheckInstanceExists("aws_instance.foo", &v), 896 ), 897 }, 898 }, 899 }) 900 } 901 902 func TestAccAWSInstance_changeInstanceType(t *testing.T) { 903 var before ec2.Instance 904 var after ec2.Instance 905 906 resource.Test(t, resource.TestCase{ 907 PreCheck: func() { testAccPreCheck(t) }, 908 Providers: testAccProviders, 909 CheckDestroy: testAccCheckInstanceDestroy, 910 Steps: []resource.TestStep{ 911 { 912 Config: testAccInstanceConfigWithSmallInstanceType, 913 Check: resource.ComposeTestCheckFunc( 914 testAccCheckInstanceExists("aws_instance.foo", &before), 915 ), 916 }, 917 { 918 Config: testAccInstanceConfigUpdateInstanceType, 919 Check: resource.ComposeTestCheckFunc( 920 testAccCheckInstanceExists("aws_instance.foo", &after), 921 testAccCheckInstanceNotRecreated( 922 t, &before, &after), 923 ), 924 }, 925 }, 926 }) 927 } 928 929 func TestAccAWSInstance_primaryNetworkInterface(t *testing.T) { 930 var instance ec2.Instance 931 var ini ec2.NetworkInterface 932 933 resource.Test(t, resource.TestCase{ 934 PreCheck: func() { testAccPreCheck(t) }, 935 Providers: testAccProviders, 936 CheckDestroy: testAccCheckInstanceDestroy, 937 Steps: []resource.TestStep{ 938 { 939 Config: testAccInstanceConfigPrimaryNetworkInterface, 940 Check: resource.ComposeTestCheckFunc( 941 testAccCheckInstanceExists("aws_instance.foo", &instance), 942 testAccCheckAWSENIExists("aws_network_interface.bar", &ini), 943 resource.TestCheckResourceAttr("aws_instance.foo", "network_interface.#", "1"), 944 ), 945 }, 946 }, 947 }) 948 } 949 950 func TestAccAWSInstance_addSecondaryInterface(t *testing.T) { 951 var before ec2.Instance 952 var after ec2.Instance 953 var iniPrimary ec2.NetworkInterface 954 var iniSecondary ec2.NetworkInterface 955 956 resource.Test(t, resource.TestCase{ 957 PreCheck: func() { testAccPreCheck(t) }, 958 Providers: testAccProviders, 959 CheckDestroy: testAccCheckInstanceDestroy, 960 Steps: []resource.TestStep{ 961 { 962 Config: testAccInstanceConfigAddSecondaryNetworkInterfaceBefore, 963 Check: resource.ComposeTestCheckFunc( 964 testAccCheckInstanceExists("aws_instance.foo", &before), 965 testAccCheckAWSENIExists("aws_network_interface.primary", &iniPrimary), 966 resource.TestCheckResourceAttr("aws_instance.foo", "network_interface.#", "1"), 967 ), 968 }, 969 { 970 Config: testAccInstanceConfigAddSecondaryNetworkInterfaceAfter, 971 Check: resource.ComposeTestCheckFunc( 972 testAccCheckInstanceExists("aws_instance.foo", &after), 973 testAccCheckAWSENIExists("aws_network_interface.secondary", &iniSecondary), 974 resource.TestCheckResourceAttr("aws_instance.foo", "network_interface.#", "1"), 975 ), 976 }, 977 }, 978 }) 979 } 980 981 func testAccCheckInstanceNotRecreated(t *testing.T, 982 before, after *ec2.Instance) resource.TestCheckFunc { 983 return func(s *terraform.State) error { 984 if *before.InstanceId != *after.InstanceId { 985 t.Fatalf("AWS Instance IDs have changed. Before %s. After %s", *before.InstanceId, *after.InstanceId) 986 } 987 return nil 988 } 989 } 990 991 func testAccCheckInstanceDestroy(s *terraform.State) error { 992 return testAccCheckInstanceDestroyWithProvider(s, testAccProvider) 993 } 994 995 func testAccCheckInstanceDestroyWithProviders(providers *[]*schema.Provider) resource.TestCheckFunc { 996 return func(s *terraform.State) error { 997 for _, provider := range *providers { 998 if provider.Meta() == nil { 999 continue 1000 } 1001 if err := testAccCheckInstanceDestroyWithProvider(s, provider); err != nil { 1002 return err 1003 } 1004 } 1005 return nil 1006 } 1007 } 1008 1009 func testAccCheckInstanceDestroyWithProvider(s *terraform.State, provider *schema.Provider) error { 1010 conn := provider.Meta().(*AWSClient).ec2conn 1011 1012 for _, rs := range s.RootModule().Resources { 1013 if rs.Type != "aws_instance" { 1014 continue 1015 } 1016 1017 // Try to find the resource 1018 resp, err := conn.DescribeInstances(&ec2.DescribeInstancesInput{ 1019 InstanceIds: []*string{aws.String(rs.Primary.ID)}, 1020 }) 1021 if err == nil { 1022 for _, r := range resp.Reservations { 1023 for _, i := range r.Instances { 1024 if i.State != nil && *i.State.Name != "terminated" { 1025 return fmt.Errorf("Found unterminated instance: %s", i) 1026 } 1027 } 1028 } 1029 } 1030 1031 // Verify the error is what we want 1032 if ae, ok := err.(awserr.Error); ok && ae.Code() == "InvalidInstanceID.NotFound" { 1033 continue 1034 } 1035 1036 return err 1037 } 1038 1039 return nil 1040 } 1041 1042 func testAccCheckInstanceExists(n string, i *ec2.Instance) resource.TestCheckFunc { 1043 providers := []*schema.Provider{testAccProvider} 1044 return testAccCheckInstanceExistsWithProviders(n, i, &providers) 1045 } 1046 1047 func testAccCheckInstanceExistsWithProviders(n string, i *ec2.Instance, providers *[]*schema.Provider) resource.TestCheckFunc { 1048 return func(s *terraform.State) error { 1049 rs, ok := s.RootModule().Resources[n] 1050 if !ok { 1051 return fmt.Errorf("Not found: %s", n) 1052 } 1053 1054 if rs.Primary.ID == "" { 1055 return fmt.Errorf("No ID is set") 1056 } 1057 for _, provider := range *providers { 1058 // Ignore if Meta is empty, this can happen for validation providers 1059 if provider.Meta() == nil { 1060 continue 1061 } 1062 1063 conn := provider.Meta().(*AWSClient).ec2conn 1064 resp, err := conn.DescribeInstances(&ec2.DescribeInstancesInput{ 1065 InstanceIds: []*string{aws.String(rs.Primary.ID)}, 1066 }) 1067 if ec2err, ok := err.(awserr.Error); ok && ec2err.Code() == "InvalidInstanceID.NotFound" { 1068 continue 1069 } 1070 if err != nil { 1071 return err 1072 } 1073 1074 if len(resp.Reservations) > 0 { 1075 *i = *resp.Reservations[0].Instances[0] 1076 return nil 1077 } 1078 } 1079 1080 return fmt.Errorf("Instance not found") 1081 } 1082 } 1083 1084 func TestInstanceTenancySchema(t *testing.T) { 1085 actualSchema := resourceAwsInstance().Schema["tenancy"] 1086 expectedSchema := &schema.Schema{ 1087 Type: schema.TypeString, 1088 Optional: true, 1089 Computed: true, 1090 ForceNew: true, 1091 } 1092 if !reflect.DeepEqual(actualSchema, expectedSchema) { 1093 t.Fatalf( 1094 "Got:\n\n%#v\n\nExpected:\n\n%#v\n", 1095 actualSchema, 1096 expectedSchema) 1097 } 1098 } 1099 1100 func driftTags(instance *ec2.Instance) resource.TestCheckFunc { 1101 return func(s *terraform.State) error { 1102 conn := testAccProvider.Meta().(*AWSClient).ec2conn 1103 _, err := conn.CreateTags(&ec2.CreateTagsInput{ 1104 Resources: []*string{instance.InstanceId}, 1105 Tags: []*ec2.Tag{ 1106 { 1107 Key: aws.String("Drift"), 1108 Value: aws.String("Happens"), 1109 }, 1110 }, 1111 }) 1112 return err 1113 } 1114 } 1115 1116 const testAccInstanceConfig_pre = ` 1117 resource "aws_security_group" "tf_test_foo" { 1118 name = "tf_test_foo" 1119 description = "foo" 1120 1121 ingress { 1122 protocol = "icmp" 1123 from_port = -1 1124 to_port = -1 1125 cidr_blocks = ["0.0.0.0/0"] 1126 } 1127 } 1128 ` 1129 1130 const testAccInstanceConfig = ` 1131 resource "aws_security_group" "tf_test_foo" { 1132 name = "tf_test_foo" 1133 description = "foo" 1134 1135 ingress { 1136 protocol = "icmp" 1137 from_port = -1 1138 to_port = -1 1139 cidr_blocks = ["0.0.0.0/0"] 1140 } 1141 } 1142 1143 resource "aws_instance" "foo" { 1144 # us-west-2 1145 ami = "ami-4fccb37f" 1146 availability_zone = "us-west-2a" 1147 1148 instance_type = "m1.small" 1149 security_groups = ["${aws_security_group.tf_test_foo.name}"] 1150 user_data = "foo:-with-character's" 1151 } 1152 ` 1153 1154 const testAccInstanceConfigWithSmallInstanceType = ` 1155 resource "aws_instance" "foo" { 1156 # us-west-2 1157 ami = "ami-55a7ea65" 1158 availability_zone = "us-west-2a" 1159 1160 instance_type = "m3.medium" 1161 1162 tags { 1163 Name = "tf-acctest" 1164 } 1165 } 1166 ` 1167 1168 const testAccInstanceConfigUpdateInstanceType = ` 1169 resource "aws_instance" "foo" { 1170 # us-west-2 1171 ami = "ami-55a7ea65" 1172 availability_zone = "us-west-2a" 1173 1174 instance_type = "m3.large" 1175 1176 tags { 1177 Name = "tf-acctest" 1178 } 1179 } 1180 ` 1181 1182 const testAccInstanceGP2IopsDevice = ` 1183 resource "aws_instance" "foo" { 1184 # us-west-2 1185 ami = "ami-55a7ea65" 1186 1187 # In order to attach an encrypted volume to an instance you need to have an 1188 # m3.medium or larger. See "Supported Instance Types" in: 1189 # http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/EBSEncryption.html 1190 instance_type = "m3.medium" 1191 1192 root_block_device { 1193 volume_type = "gp2" 1194 volume_size = 11 1195 } 1196 } 1197 ` 1198 1199 const testAccInstanceConfigBlockDevices = ` 1200 resource "aws_instance" "foo" { 1201 # us-west-2 1202 ami = "ami-55a7ea65" 1203 1204 # In order to attach an encrypted volume to an instance you need to have an 1205 # m3.medium or larger. See "Supported Instance Types" in: 1206 # http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/EBSEncryption.html 1207 instance_type = "m3.medium" 1208 1209 root_block_device { 1210 volume_type = "gp2" 1211 volume_size = 11 1212 } 1213 ebs_block_device { 1214 device_name = "/dev/sdb" 1215 volume_size = 9 1216 } 1217 ebs_block_device { 1218 device_name = "/dev/sdc" 1219 volume_size = 10 1220 volume_type = "io1" 1221 iops = 100 1222 } 1223 1224 # Encrypted ebs block device 1225 ebs_block_device { 1226 device_name = "/dev/sdd" 1227 volume_size = 12 1228 encrypted = true 1229 } 1230 1231 ephemeral_block_device { 1232 device_name = "/dev/sde" 1233 virtual_name = "ephemeral0" 1234 } 1235 } 1236 ` 1237 1238 const testAccInstanceConfigSourceDestEnable = ` 1239 resource "aws_vpc" "foo" { 1240 cidr_block = "10.1.0.0/16" 1241 } 1242 1243 resource "aws_subnet" "foo" { 1244 cidr_block = "10.1.1.0/24" 1245 vpc_id = "${aws_vpc.foo.id}" 1246 } 1247 1248 resource "aws_instance" "foo" { 1249 # us-west-2 1250 ami = "ami-4fccb37f" 1251 instance_type = "m1.small" 1252 subnet_id = "${aws_subnet.foo.id}" 1253 } 1254 ` 1255 1256 const testAccInstanceConfigSourceDestDisable = ` 1257 resource "aws_vpc" "foo" { 1258 cidr_block = "10.1.0.0/16" 1259 } 1260 1261 resource "aws_subnet" "foo" { 1262 cidr_block = "10.1.1.0/24" 1263 vpc_id = "${aws_vpc.foo.id}" 1264 } 1265 1266 resource "aws_instance" "foo" { 1267 # us-west-2 1268 ami = "ami-4fccb37f" 1269 instance_type = "m1.small" 1270 subnet_id = "${aws_subnet.foo.id}" 1271 source_dest_check = false 1272 } 1273 ` 1274 1275 func testAccInstanceConfigDisableAPITermination(val bool) string { 1276 return fmt.Sprintf(` 1277 resource "aws_vpc" "foo" { 1278 cidr_block = "10.1.0.0/16" 1279 } 1280 1281 resource "aws_subnet" "foo" { 1282 cidr_block = "10.1.1.0/24" 1283 vpc_id = "${aws_vpc.foo.id}" 1284 } 1285 1286 resource "aws_instance" "foo" { 1287 # us-west-2 1288 ami = "ami-4fccb37f" 1289 instance_type = "m1.small" 1290 subnet_id = "${aws_subnet.foo.id}" 1291 disable_api_termination = %t 1292 } 1293 `, val) 1294 } 1295 1296 const testAccInstanceConfigVPC = ` 1297 resource "aws_vpc" "foo" { 1298 cidr_block = "10.1.0.0/16" 1299 } 1300 1301 resource "aws_subnet" "foo" { 1302 cidr_block = "10.1.1.0/24" 1303 vpc_id = "${aws_vpc.foo.id}" 1304 } 1305 1306 resource "aws_instance" "foo" { 1307 # us-west-2 1308 ami = "ami-4fccb37f" 1309 instance_type = "m1.small" 1310 subnet_id = "${aws_subnet.foo.id}" 1311 associate_public_ip_address = true 1312 tenancy = "dedicated" 1313 # pre-encoded base64 data 1314 user_data = "3dc39dda39be1205215e776bad998da361a5955d" 1315 } 1316 ` 1317 1318 const testAccInstanceConfigIpv6Support = ` 1319 resource "aws_vpc" "foo" { 1320 cidr_block = "10.1.0.0/16" 1321 assign_generated_ipv6_cidr_block = true 1322 tags { 1323 Name = "tf-ipv6-instance-acc-test" 1324 } 1325 } 1326 1327 resource "aws_subnet" "foo" { 1328 cidr_block = "10.1.1.0/24" 1329 vpc_id = "${aws_vpc.foo.id}" 1330 ipv6_cidr_block = "${cidrsubnet(aws_vpc.foo.ipv6_cidr_block, 8, 1)}" 1331 tags { 1332 Name = "tf-ipv6-instance-acc-test" 1333 } 1334 } 1335 1336 resource "aws_instance" "foo" { 1337 # us-west-2 1338 ami = "ami-c5eabbf5" 1339 instance_type = "t2.micro" 1340 subnet_id = "${aws_subnet.foo.id}" 1341 1342 ipv6_address_count = 1 1343 tags { 1344 Name = "tf-ipv6-instance-acc-test" 1345 } 1346 } 1347 ` 1348 1349 const testAccInstanceConfigMultipleRegions = ` 1350 provider "aws" { 1351 alias = "west" 1352 region = "us-west-2" 1353 } 1354 1355 provider "aws" { 1356 alias = "east" 1357 region = "us-east-1" 1358 } 1359 1360 resource "aws_instance" "foo" { 1361 # us-west-2 1362 provider = "aws.west" 1363 ami = "ami-4fccb37f" 1364 instance_type = "m1.small" 1365 } 1366 1367 resource "aws_instance" "bar" { 1368 # us-east-1 1369 provider = "aws.east" 1370 ami = "ami-8c6ea9e4" 1371 instance_type = "m1.small" 1372 } 1373 ` 1374 1375 const testAccCheckInstanceConfigTags = ` 1376 resource "aws_instance" "foo" { 1377 ami = "ami-4fccb37f" 1378 instance_type = "m1.small" 1379 tags { 1380 foo = "bar" 1381 } 1382 } 1383 ` 1384 1385 const testAccCheckInstanceConfigNoVolumeTags = ` 1386 resource "aws_instance" "foo" { 1387 ami = "ami-55a7ea65" 1388 1389 instance_type = "m3.medium" 1390 1391 root_block_device { 1392 volume_type = "gp2" 1393 volume_size = 11 1394 } 1395 ebs_block_device { 1396 device_name = "/dev/sdb" 1397 volume_size = 9 1398 } 1399 ebs_block_device { 1400 device_name = "/dev/sdc" 1401 volume_size = 10 1402 volume_type = "io1" 1403 iops = 100 1404 } 1405 1406 ebs_block_device { 1407 device_name = "/dev/sdd" 1408 volume_size = 12 1409 encrypted = true 1410 } 1411 1412 ephemeral_block_device { 1413 device_name = "/dev/sde" 1414 virtual_name = "ephemeral0" 1415 } 1416 } 1417 ` 1418 1419 const testAccCheckInstanceConfigWithVolumeTags = ` 1420 resource "aws_instance" "foo" { 1421 ami = "ami-55a7ea65" 1422 1423 instance_type = "m3.medium" 1424 1425 root_block_device { 1426 volume_type = "gp2" 1427 volume_size = 11 1428 } 1429 ebs_block_device { 1430 device_name = "/dev/sdb" 1431 volume_size = 9 1432 } 1433 ebs_block_device { 1434 device_name = "/dev/sdc" 1435 volume_size = 10 1436 volume_type = "io1" 1437 iops = 100 1438 } 1439 1440 ebs_block_device { 1441 device_name = "/dev/sdd" 1442 volume_size = 12 1443 encrypted = true 1444 } 1445 1446 ephemeral_block_device { 1447 device_name = "/dev/sde" 1448 virtual_name = "ephemeral0" 1449 } 1450 1451 volume_tags { 1452 Name = "acceptance-test-volume-tag" 1453 } 1454 } 1455 ` 1456 1457 const testAccCheckInstanceConfigWithVolumeTagsUpdate = ` 1458 resource "aws_instance" "foo" { 1459 ami = "ami-55a7ea65" 1460 1461 instance_type = "m3.medium" 1462 1463 root_block_device { 1464 volume_type = "gp2" 1465 volume_size = 11 1466 } 1467 ebs_block_device { 1468 device_name = "/dev/sdb" 1469 volume_size = 9 1470 } 1471 ebs_block_device { 1472 device_name = "/dev/sdc" 1473 volume_size = 10 1474 volume_type = "io1" 1475 iops = 100 1476 } 1477 1478 ebs_block_device { 1479 device_name = "/dev/sdd" 1480 volume_size = 12 1481 encrypted = true 1482 } 1483 1484 ephemeral_block_device { 1485 device_name = "/dev/sde" 1486 virtual_name = "ephemeral0" 1487 } 1488 1489 volume_tags { 1490 Name = "acceptance-test-volume-tag" 1491 Environment = "dev" 1492 } 1493 } 1494 ` 1495 1496 const testAccCheckInstanceConfigTagsUpdate = ` 1497 resource "aws_instance" "foo" { 1498 ami = "ami-4fccb37f" 1499 instance_type = "m1.small" 1500 tags { 1501 bar = "baz" 1502 } 1503 } 1504 ` 1505 1506 func testAccInstanceConfigWithoutInstanceProfile(rName string) string { 1507 return fmt.Sprintf(` 1508 resource "aws_iam_role" "test" { 1509 name = "test-%s" 1510 assume_role_policy = "{\"Version\":\"2012-10-17\",\"Statement\":[{\"Effect\":\"Allow\",\"Principal\":{\"Service\":[\"ec2.amazonaws.com\"]},\"Action\":[\"sts:AssumeRole\"]}]}" 1511 } 1512 1513 resource "aws_iam_instance_profile" "test" { 1514 name = "test-%s" 1515 roles = ["${aws_iam_role.test.name}"] 1516 } 1517 1518 resource "aws_instance" "foo" { 1519 ami = "ami-4fccb37f" 1520 instance_type = "m1.small" 1521 tags { 1522 bar = "baz" 1523 } 1524 }`, rName, rName) 1525 } 1526 1527 func testAccInstanceConfigWithInstanceProfile(rName string) string { 1528 return fmt.Sprintf(` 1529 resource "aws_iam_role" "test" { 1530 name = "test-%s" 1531 assume_role_policy = "{\"Version\":\"2012-10-17\",\"Statement\":[{\"Effect\":\"Allow\",\"Principal\":{\"Service\":[\"ec2.amazonaws.com\"]},\"Action\":[\"sts:AssumeRole\"]}]}" 1532 } 1533 1534 resource "aws_iam_instance_profile" "test" { 1535 name = "test-%s" 1536 roles = ["${aws_iam_role.test.name}"] 1537 } 1538 1539 resource "aws_instance" "foo" { 1540 ami = "ami-4fccb37f" 1541 instance_type = "m1.small" 1542 iam_instance_profile = "${aws_iam_instance_profile.test.name}" 1543 tags { 1544 bar = "baz" 1545 } 1546 }`, rName, rName) 1547 } 1548 1549 const testAccInstanceConfigPrivateIP = ` 1550 resource "aws_vpc" "foo" { 1551 cidr_block = "10.1.0.0/16" 1552 } 1553 1554 resource "aws_subnet" "foo" { 1555 cidr_block = "10.1.1.0/24" 1556 vpc_id = "${aws_vpc.foo.id}" 1557 } 1558 1559 resource "aws_instance" "foo" { 1560 ami = "ami-c5eabbf5" 1561 instance_type = "t2.micro" 1562 subnet_id = "${aws_subnet.foo.id}" 1563 private_ip = "10.1.1.42" 1564 } 1565 ` 1566 1567 const testAccInstanceConfigAssociatePublicIPAndPrivateIP = ` 1568 resource "aws_vpc" "foo" { 1569 cidr_block = "10.1.0.0/16" 1570 } 1571 1572 resource "aws_subnet" "foo" { 1573 cidr_block = "10.1.1.0/24" 1574 vpc_id = "${aws_vpc.foo.id}" 1575 } 1576 1577 resource "aws_instance" "foo" { 1578 ami = "ami-c5eabbf5" 1579 instance_type = "t2.micro" 1580 subnet_id = "${aws_subnet.foo.id}" 1581 associate_public_ip_address = true 1582 private_ip = "10.1.1.42" 1583 } 1584 ` 1585 1586 const testAccInstanceNetworkInstanceSecurityGroups = ` 1587 resource "aws_internet_gateway" "gw" { 1588 vpc_id = "${aws_vpc.foo.id}" 1589 } 1590 1591 resource "aws_vpc" "foo" { 1592 cidr_block = "10.1.0.0/16" 1593 tags { 1594 Name = "tf-network-test" 1595 } 1596 } 1597 1598 resource "aws_security_group" "tf_test_foo" { 1599 name = "tf_test_foo" 1600 description = "foo" 1601 vpc_id="${aws_vpc.foo.id}" 1602 1603 ingress { 1604 protocol = "icmp" 1605 from_port = -1 1606 to_port = -1 1607 cidr_blocks = ["0.0.0.0/0"] 1608 } 1609 } 1610 1611 resource "aws_subnet" "foo" { 1612 cidr_block = "10.1.1.0/24" 1613 vpc_id = "${aws_vpc.foo.id}" 1614 } 1615 1616 resource "aws_instance" "foo_instance" { 1617 ami = "ami-21f78e11" 1618 instance_type = "t1.micro" 1619 vpc_security_group_ids = ["${aws_security_group.tf_test_foo.id}"] 1620 subnet_id = "${aws_subnet.foo.id}" 1621 associate_public_ip_address = true 1622 depends_on = ["aws_internet_gateway.gw"] 1623 } 1624 1625 resource "aws_eip" "foo_eip" { 1626 instance = "${aws_instance.foo_instance.id}" 1627 vpc = true 1628 depends_on = ["aws_internet_gateway.gw"] 1629 } 1630 ` 1631 1632 const testAccInstanceNetworkInstanceVPCSecurityGroupIDs = ` 1633 resource "aws_internet_gateway" "gw" { 1634 vpc_id = "${aws_vpc.foo.id}" 1635 } 1636 1637 resource "aws_vpc" "foo" { 1638 cidr_block = "10.1.0.0/16" 1639 tags { 1640 Name = "tf-network-test" 1641 } 1642 } 1643 1644 resource "aws_security_group" "tf_test_foo" { 1645 name = "tf_test_foo" 1646 description = "foo" 1647 vpc_id="${aws_vpc.foo.id}" 1648 1649 ingress { 1650 protocol = "icmp" 1651 from_port = -1 1652 to_port = -1 1653 cidr_blocks = ["0.0.0.0/0"] 1654 } 1655 } 1656 1657 resource "aws_subnet" "foo" { 1658 cidr_block = "10.1.1.0/24" 1659 vpc_id = "${aws_vpc.foo.id}" 1660 } 1661 1662 resource "aws_instance" "foo_instance" { 1663 ami = "ami-21f78e11" 1664 instance_type = "t1.micro" 1665 vpc_security_group_ids = ["${aws_security_group.tf_test_foo.id}"] 1666 subnet_id = "${aws_subnet.foo.id}" 1667 depends_on = ["aws_internet_gateway.gw"] 1668 } 1669 1670 resource "aws_eip" "foo_eip" { 1671 instance = "${aws_instance.foo_instance.id}" 1672 vpc = true 1673 depends_on = ["aws_internet_gateway.gw"] 1674 } 1675 ` 1676 1677 const testAccInstanceConfigKeyPair = ` 1678 provider "aws" { 1679 region = "us-east-1" 1680 } 1681 1682 resource "aws_key_pair" "debugging" { 1683 key_name = "tmp-key" 1684 public_key = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQD3F6tyPEFEzV0LX3X8BsXdMsQz1x2cEikKDEY0aIj41qgxMCP/iteneqXSIFZBp5vizPvaoIR3Um9xK7PGoW8giupGn+EPuxIA4cDM4vzOqOkiMPhz5XK0whEjkVzTo4+S0puvDZuwIsdiW9mxhJc7tgBNL0cYlWSYVkz4G/fslNfRPW5mYAM49f4fhtxPb5ok4Q2Lg9dPKVHO/Bgeu5woMc7RY0p1ej6D4CKFE6lymSDJpW0YHX/wqE9+cfEauh7xZcG0q9t2ta6F6fmX0agvpFyZo8aFbXeUBr7osSCJNgvavWbM/06niWrOvYX2xwWdhXmXSrbX8ZbabVohBK41 phodgson@thoughtworks.com" 1685 } 1686 1687 resource "aws_instance" "foo" { 1688 ami = "ami-408c7f28" 1689 instance_type = "t1.micro" 1690 key_name = "${aws_key_pair.debugging.key_name}" 1691 tags { 1692 Name = "testAccInstanceConfigKeyPair_TestAMI" 1693 } 1694 } 1695 ` 1696 1697 const testAccInstanceConfigRootBlockDeviceMismatch = ` 1698 resource "aws_vpc" "foo" { 1699 cidr_block = "10.1.0.0/16" 1700 } 1701 1702 resource "aws_subnet" "foo" { 1703 cidr_block = "10.1.1.0/24" 1704 vpc_id = "${aws_vpc.foo.id}" 1705 } 1706 1707 resource "aws_instance" "foo" { 1708 // This is an AMI with RootDeviceName: "/dev/sda1"; actual root: "/dev/sda" 1709 ami = "ami-ef5b69df" 1710 instance_type = "t1.micro" 1711 subnet_id = "${aws_subnet.foo.id}" 1712 root_block_device { 1713 volume_size = 13 1714 } 1715 } 1716 ` 1717 1718 const testAccInstanceConfigForceNewAndTagsDrift = ` 1719 resource "aws_vpc" "foo" { 1720 cidr_block = "10.1.0.0/16" 1721 } 1722 1723 resource "aws_subnet" "foo" { 1724 cidr_block = "10.1.1.0/24" 1725 vpc_id = "${aws_vpc.foo.id}" 1726 } 1727 1728 resource "aws_instance" "foo" { 1729 ami = "ami-22b9a343" 1730 instance_type = "t2.nano" 1731 subnet_id = "${aws_subnet.foo.id}" 1732 } 1733 ` 1734 1735 const testAccInstanceConfigForceNewAndTagsDrift_Update = ` 1736 resource "aws_vpc" "foo" { 1737 cidr_block = "10.1.0.0/16" 1738 } 1739 1740 resource "aws_subnet" "foo" { 1741 cidr_block = "10.1.1.0/24" 1742 vpc_id = "${aws_vpc.foo.id}" 1743 } 1744 1745 resource "aws_instance" "foo" { 1746 ami = "ami-22b9a343" 1747 instance_type = "t2.micro" 1748 subnet_id = "${aws_subnet.foo.id}" 1749 } 1750 ` 1751 1752 const testAccInstanceConfigPrimaryNetworkInterface = ` 1753 resource "aws_vpc" "foo" { 1754 cidr_block = "172.16.0.0/16" 1755 tags { 1756 Name = "tf-instance-test" 1757 } 1758 } 1759 1760 resource "aws_subnet" "foo" { 1761 vpc_id = "${aws_vpc.foo.id}" 1762 cidr_block = "172.16.10.0/24" 1763 availability_zone = "us-west-2a" 1764 tags { 1765 Name = "tf-instance-test" 1766 } 1767 } 1768 1769 resource "aws_network_interface" "bar" { 1770 subnet_id = "${aws_subnet.foo.id}" 1771 private_ips = ["172.16.10.100"] 1772 tags { 1773 Name = "primary_network_interface" 1774 } 1775 } 1776 1777 resource "aws_instance" "foo" { 1778 ami = "ami-22b9a343" 1779 instance_type = "t2.micro" 1780 network_interface { 1781 network_interface_id = "${aws_network_interface.bar.id}" 1782 device_index = 0 1783 } 1784 } 1785 ` 1786 1787 const testAccInstanceConfigAddSecondaryNetworkInterfaceBefore = ` 1788 resource "aws_vpc" "foo" { 1789 cidr_block = "172.16.0.0/16" 1790 tags { 1791 Name = "tf-instance-test" 1792 } 1793 } 1794 1795 resource "aws_subnet" "foo" { 1796 vpc_id = "${aws_vpc.foo.id}" 1797 cidr_block = "172.16.10.0/24" 1798 availability_zone = "us-west-2a" 1799 tags { 1800 Name = "tf-instance-test" 1801 } 1802 } 1803 1804 resource "aws_network_interface" "primary" { 1805 subnet_id = "${aws_subnet.foo.id}" 1806 private_ips = ["172.16.10.100"] 1807 tags { 1808 Name = "primary_network_interface" 1809 } 1810 } 1811 1812 resource "aws_network_interface" "secondary" { 1813 subnet_id = "${aws_subnet.foo.id}" 1814 private_ips = ["172.16.10.101"] 1815 tags { 1816 Name = "secondary_network_interface" 1817 } 1818 } 1819 1820 resource "aws_instance" "foo" { 1821 ami = "ami-22b9a343" 1822 instance_type = "t2.micro" 1823 network_interface { 1824 network_interface_id = "${aws_network_interface.primary.id}" 1825 device_index = 0 1826 } 1827 } 1828 ` 1829 1830 const testAccInstanceConfigAddSecondaryNetworkInterfaceAfter = ` 1831 resource "aws_vpc" "foo" { 1832 cidr_block = "172.16.0.0/16" 1833 tags { 1834 Name = "tf-instance-test" 1835 } 1836 } 1837 1838 resource "aws_subnet" "foo" { 1839 vpc_id = "${aws_vpc.foo.id}" 1840 cidr_block = "172.16.10.0/24" 1841 availability_zone = "us-west-2a" 1842 tags { 1843 Name = "tf-instance-test" 1844 } 1845 } 1846 1847 resource "aws_network_interface" "primary" { 1848 subnet_id = "${aws_subnet.foo.id}" 1849 private_ips = ["172.16.10.100"] 1850 tags { 1851 Name = "primary_network_interface" 1852 } 1853 } 1854 1855 // Attach previously created network interface, observe no state diff on instance resource 1856 resource "aws_network_interface" "secondary" { 1857 subnet_id = "${aws_subnet.foo.id}" 1858 private_ips = ["172.16.10.101"] 1859 tags { 1860 Name = "secondary_network_interface" 1861 } 1862 attachment { 1863 instance = "${aws_instance.foo.id}" 1864 device_index = 1 1865 } 1866 } 1867 1868 resource "aws_instance" "foo" { 1869 ami = "ami-22b9a343" 1870 instance_type = "t2.micro" 1871 network_interface { 1872 network_interface_id = "${aws_network_interface.primary.id}" 1873 device_index = 0 1874 } 1875 } 1876 `