github.com/nathanielks/terraform@v0.6.1-0.20170509030759-13e1a62319dc/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_volumeTagsComputed(t *testing.T) { 682 var v ec2.Instance 683 684 resource.Test(t, resource.TestCase{ 685 PreCheck: func() { testAccPreCheck(t) }, 686 Providers: testAccProviders, 687 CheckDestroy: testAccCheckInstanceDestroy, 688 Steps: []resource.TestStep{ 689 { 690 Config: testAccCheckInstanceConfigWithAttachedVolume, 691 Check: resource.ComposeTestCheckFunc( 692 testAccCheckInstanceExists("aws_instance.foo", &v), 693 ), 694 ExpectNonEmptyPlan: false, 695 }, 696 }, 697 }) 698 } 699 700 func TestAccAWSInstance_instanceProfileChange(t *testing.T) { 701 var v ec2.Instance 702 rName := acctest.RandString(5) 703 704 testCheckInstanceProfile := func() resource.TestCheckFunc { 705 return func(*terraform.State) error { 706 if v.IamInstanceProfile == nil { 707 return fmt.Errorf("Instance Profile is nil - we expected an InstanceProfile associated with the Instance") 708 } 709 710 return nil 711 } 712 } 713 714 resource.Test(t, resource.TestCase{ 715 PreCheck: func() { testAccPreCheck(t) }, 716 IDRefreshName: "aws_instance.foo", 717 Providers: testAccProviders, 718 CheckDestroy: testAccCheckInstanceDestroy, 719 Steps: []resource.TestStep{ 720 { 721 Config: testAccInstanceConfigWithoutInstanceProfile(rName), 722 Check: resource.ComposeTestCheckFunc( 723 testAccCheckInstanceExists("aws_instance.foo", &v), 724 ), 725 }, 726 { 727 Config: testAccInstanceConfigWithInstanceProfile(rName), 728 Check: resource.ComposeTestCheckFunc( 729 testAccCheckInstanceExists("aws_instance.foo", &v), 730 testCheckInstanceProfile(), 731 ), 732 }, 733 }, 734 }) 735 } 736 737 func TestAccAWSInstance_withIamInstanceProfile(t *testing.T) { 738 var v ec2.Instance 739 rName := acctest.RandString(5) 740 741 testCheckInstanceProfile := func() resource.TestCheckFunc { 742 return func(*terraform.State) error { 743 if v.IamInstanceProfile == nil { 744 return fmt.Errorf("Instance Profile is nil - we expected an InstanceProfile associated with the Instance") 745 } 746 747 return nil 748 } 749 } 750 751 resource.Test(t, resource.TestCase{ 752 PreCheck: func() { testAccPreCheck(t) }, 753 IDRefreshName: "aws_instance.foo", 754 Providers: testAccProviders, 755 CheckDestroy: testAccCheckInstanceDestroy, 756 Steps: []resource.TestStep{ 757 { 758 Config: testAccInstanceConfigWithInstanceProfile(rName), 759 Check: resource.ComposeTestCheckFunc( 760 testAccCheckInstanceExists("aws_instance.foo", &v), 761 testCheckInstanceProfile(), 762 ), 763 }, 764 }, 765 }) 766 } 767 768 func TestAccAWSInstance_privateIP(t *testing.T) { 769 var v ec2.Instance 770 771 testCheckPrivateIP := func() resource.TestCheckFunc { 772 return func(*terraform.State) error { 773 if *v.PrivateIpAddress != "10.1.1.42" { 774 return fmt.Errorf("bad private IP: %s", *v.PrivateIpAddress) 775 } 776 777 return nil 778 } 779 } 780 781 resource.Test(t, resource.TestCase{ 782 PreCheck: func() { testAccPreCheck(t) }, 783 IDRefreshName: "aws_instance.foo", 784 Providers: testAccProviders, 785 CheckDestroy: testAccCheckInstanceDestroy, 786 Steps: []resource.TestStep{ 787 { 788 Config: testAccInstanceConfigPrivateIP, 789 Check: resource.ComposeTestCheckFunc( 790 testAccCheckInstanceExists("aws_instance.foo", &v), 791 testCheckPrivateIP(), 792 ), 793 }, 794 }, 795 }) 796 } 797 798 func TestAccAWSInstance_associatePublicIPAndPrivateIP(t *testing.T) { 799 var v ec2.Instance 800 801 testCheckPrivateIP := func() resource.TestCheckFunc { 802 return func(*terraform.State) error { 803 if *v.PrivateIpAddress != "10.1.1.42" { 804 return fmt.Errorf("bad private IP: %s", *v.PrivateIpAddress) 805 } 806 807 return nil 808 } 809 } 810 811 resource.Test(t, resource.TestCase{ 812 PreCheck: func() { testAccPreCheck(t) }, 813 IDRefreshName: "aws_instance.foo", 814 IDRefreshIgnore: []string{"associate_public_ip_address"}, 815 Providers: testAccProviders, 816 CheckDestroy: testAccCheckInstanceDestroy, 817 Steps: []resource.TestStep{ 818 { 819 Config: testAccInstanceConfigAssociatePublicIPAndPrivateIP, 820 Check: resource.ComposeTestCheckFunc( 821 testAccCheckInstanceExists("aws_instance.foo", &v), 822 testCheckPrivateIP(), 823 ), 824 }, 825 }, 826 }) 827 } 828 829 // Guard against regression with KeyPairs 830 // https://github.com/hashicorp/terraform/issues/2302 831 func TestAccAWSInstance_keyPairCheck(t *testing.T) { 832 var v ec2.Instance 833 834 testCheckKeyPair := func(keyName string) resource.TestCheckFunc { 835 return func(*terraform.State) error { 836 if v.KeyName == nil { 837 return fmt.Errorf("No Key Pair found, expected(%s)", keyName) 838 } 839 if v.KeyName != nil && *v.KeyName != keyName { 840 return fmt.Errorf("Bad key name, expected (%s), got (%s)", keyName, *v.KeyName) 841 } 842 843 return nil 844 } 845 } 846 847 resource.Test(t, resource.TestCase{ 848 PreCheck: func() { testAccPreCheck(t) }, 849 IDRefreshName: "aws_instance.foo", 850 IDRefreshIgnore: []string{"source_dest_check"}, 851 Providers: testAccProviders, 852 CheckDestroy: testAccCheckInstanceDestroy, 853 Steps: []resource.TestStep{ 854 { 855 Config: testAccInstanceConfigKeyPair, 856 Check: resource.ComposeTestCheckFunc( 857 testAccCheckInstanceExists("aws_instance.foo", &v), 858 testCheckKeyPair("tmp-key"), 859 ), 860 }, 861 }, 862 }) 863 } 864 865 func TestAccAWSInstance_rootBlockDeviceMismatch(t *testing.T) { 866 var v ec2.Instance 867 868 resource.Test(t, resource.TestCase{ 869 PreCheck: func() { testAccPreCheck(t) }, 870 Providers: testAccProviders, 871 CheckDestroy: testAccCheckInstanceDestroy, 872 Steps: []resource.TestStep{ 873 { 874 Config: testAccInstanceConfigRootBlockDeviceMismatch, 875 Check: resource.ComposeTestCheckFunc( 876 testAccCheckInstanceExists("aws_instance.foo", &v), 877 resource.TestCheckResourceAttr( 878 "aws_instance.foo", "root_block_device.0.volume_size", "13"), 879 ), 880 }, 881 }, 882 }) 883 } 884 885 // This test reproduces the bug here: 886 // https://github.com/hashicorp/terraform/issues/1752 887 // 888 // I wish there were a way to exercise resources built with helper.Schema in a 889 // unit context, in which case this test could be moved there, but for now this 890 // will cover the bugfix. 891 // 892 // The following triggers "diffs didn't match during apply" without the fix in to 893 // set NewRemoved on the .# field when it changes to 0. 894 func TestAccAWSInstance_forceNewAndTagsDrift(t *testing.T) { 895 var v ec2.Instance 896 897 resource.Test(t, resource.TestCase{ 898 PreCheck: func() { testAccPreCheck(t) }, 899 IDRefreshName: "aws_instance.foo", 900 Providers: testAccProviders, 901 CheckDestroy: testAccCheckInstanceDestroy, 902 Steps: []resource.TestStep{ 903 { 904 Config: testAccInstanceConfigForceNewAndTagsDrift, 905 Check: resource.ComposeTestCheckFunc( 906 testAccCheckInstanceExists("aws_instance.foo", &v), 907 driftTags(&v), 908 ), 909 ExpectNonEmptyPlan: true, 910 }, 911 { 912 Config: testAccInstanceConfigForceNewAndTagsDrift_Update, 913 Check: resource.ComposeTestCheckFunc( 914 testAccCheckInstanceExists("aws_instance.foo", &v), 915 ), 916 }, 917 }, 918 }) 919 } 920 921 func TestAccAWSInstance_changeInstanceType(t *testing.T) { 922 var before ec2.Instance 923 var after ec2.Instance 924 925 resource.Test(t, resource.TestCase{ 926 PreCheck: func() { testAccPreCheck(t) }, 927 Providers: testAccProviders, 928 CheckDestroy: testAccCheckInstanceDestroy, 929 Steps: []resource.TestStep{ 930 { 931 Config: testAccInstanceConfigWithSmallInstanceType, 932 Check: resource.ComposeTestCheckFunc( 933 testAccCheckInstanceExists("aws_instance.foo", &before), 934 ), 935 }, 936 { 937 Config: testAccInstanceConfigUpdateInstanceType, 938 Check: resource.ComposeTestCheckFunc( 939 testAccCheckInstanceExists("aws_instance.foo", &after), 940 testAccCheckInstanceNotRecreated( 941 t, &before, &after), 942 ), 943 }, 944 }, 945 }) 946 } 947 948 func TestAccAWSInstance_primaryNetworkInterface(t *testing.T) { 949 var instance ec2.Instance 950 var ini ec2.NetworkInterface 951 952 resource.Test(t, resource.TestCase{ 953 PreCheck: func() { testAccPreCheck(t) }, 954 Providers: testAccProviders, 955 CheckDestroy: testAccCheckInstanceDestroy, 956 Steps: []resource.TestStep{ 957 { 958 Config: testAccInstanceConfigPrimaryNetworkInterface, 959 Check: resource.ComposeTestCheckFunc( 960 testAccCheckInstanceExists("aws_instance.foo", &instance), 961 testAccCheckAWSENIExists("aws_network_interface.bar", &ini), 962 resource.TestCheckResourceAttr("aws_instance.foo", "network_interface.#", "1"), 963 ), 964 }, 965 }, 966 }) 967 } 968 969 func TestAccAWSInstance_primaryNetworkInterfaceSourceDestCheck(t *testing.T) { 970 var instance ec2.Instance 971 var ini ec2.NetworkInterface 972 973 resource.Test(t, resource.TestCase{ 974 PreCheck: func() { testAccPreCheck(t) }, 975 Providers: testAccProviders, 976 CheckDestroy: testAccCheckInstanceDestroy, 977 Steps: []resource.TestStep{ 978 { 979 Config: testAccInstanceConfigPrimaryNetworkInterfaceSourceDestCheck, 980 Check: resource.ComposeTestCheckFunc( 981 testAccCheckInstanceExists("aws_instance.foo", &instance), 982 testAccCheckAWSENIExists("aws_network_interface.bar", &ini), 983 resource.TestCheckResourceAttr("aws_instance.foo", "source_dest_check", "false"), 984 ), 985 }, 986 }, 987 }) 988 } 989 990 func TestAccAWSInstance_addSecondaryInterface(t *testing.T) { 991 var before ec2.Instance 992 var after ec2.Instance 993 var iniPrimary ec2.NetworkInterface 994 var iniSecondary ec2.NetworkInterface 995 996 resource.Test(t, resource.TestCase{ 997 PreCheck: func() { testAccPreCheck(t) }, 998 Providers: testAccProviders, 999 CheckDestroy: testAccCheckInstanceDestroy, 1000 Steps: []resource.TestStep{ 1001 { 1002 Config: testAccInstanceConfigAddSecondaryNetworkInterfaceBefore, 1003 Check: resource.ComposeTestCheckFunc( 1004 testAccCheckInstanceExists("aws_instance.foo", &before), 1005 testAccCheckAWSENIExists("aws_network_interface.primary", &iniPrimary), 1006 resource.TestCheckResourceAttr("aws_instance.foo", "network_interface.#", "1"), 1007 ), 1008 }, 1009 { 1010 Config: testAccInstanceConfigAddSecondaryNetworkInterfaceAfter, 1011 Check: resource.ComposeTestCheckFunc( 1012 testAccCheckInstanceExists("aws_instance.foo", &after), 1013 testAccCheckAWSENIExists("aws_network_interface.secondary", &iniSecondary), 1014 resource.TestCheckResourceAttr("aws_instance.foo", "network_interface.#", "1"), 1015 ), 1016 }, 1017 }, 1018 }) 1019 } 1020 1021 func testAccCheckInstanceNotRecreated(t *testing.T, 1022 before, after *ec2.Instance) resource.TestCheckFunc { 1023 return func(s *terraform.State) error { 1024 if *before.InstanceId != *after.InstanceId { 1025 t.Fatalf("AWS Instance IDs have changed. Before %s. After %s", *before.InstanceId, *after.InstanceId) 1026 } 1027 return nil 1028 } 1029 } 1030 1031 func testAccCheckInstanceDestroy(s *terraform.State) error { 1032 return testAccCheckInstanceDestroyWithProvider(s, testAccProvider) 1033 } 1034 1035 func testAccCheckInstanceDestroyWithProviders(providers *[]*schema.Provider) resource.TestCheckFunc { 1036 return func(s *terraform.State) error { 1037 for _, provider := range *providers { 1038 if provider.Meta() == nil { 1039 continue 1040 } 1041 if err := testAccCheckInstanceDestroyWithProvider(s, provider); err != nil { 1042 return err 1043 } 1044 } 1045 return nil 1046 } 1047 } 1048 1049 func testAccCheckInstanceDestroyWithProvider(s *terraform.State, provider *schema.Provider) error { 1050 conn := provider.Meta().(*AWSClient).ec2conn 1051 1052 for _, rs := range s.RootModule().Resources { 1053 if rs.Type != "aws_instance" { 1054 continue 1055 } 1056 1057 // Try to find the resource 1058 resp, err := conn.DescribeInstances(&ec2.DescribeInstancesInput{ 1059 InstanceIds: []*string{aws.String(rs.Primary.ID)}, 1060 }) 1061 if err == nil { 1062 for _, r := range resp.Reservations { 1063 for _, i := range r.Instances { 1064 if i.State != nil && *i.State.Name != "terminated" { 1065 return fmt.Errorf("Found unterminated instance: %s", i) 1066 } 1067 } 1068 } 1069 } 1070 1071 // Verify the error is what we want 1072 if ae, ok := err.(awserr.Error); ok && ae.Code() == "InvalidInstanceID.NotFound" { 1073 continue 1074 } 1075 1076 return err 1077 } 1078 1079 return nil 1080 } 1081 1082 func testAccCheckInstanceExists(n string, i *ec2.Instance) resource.TestCheckFunc { 1083 providers := []*schema.Provider{testAccProvider} 1084 return testAccCheckInstanceExistsWithProviders(n, i, &providers) 1085 } 1086 1087 func testAccCheckInstanceExistsWithProviders(n string, i *ec2.Instance, providers *[]*schema.Provider) resource.TestCheckFunc { 1088 return func(s *terraform.State) error { 1089 rs, ok := s.RootModule().Resources[n] 1090 if !ok { 1091 return fmt.Errorf("Not found: %s", n) 1092 } 1093 1094 if rs.Primary.ID == "" { 1095 return fmt.Errorf("No ID is set") 1096 } 1097 for _, provider := range *providers { 1098 // Ignore if Meta is empty, this can happen for validation providers 1099 if provider.Meta() == nil { 1100 continue 1101 } 1102 1103 conn := provider.Meta().(*AWSClient).ec2conn 1104 resp, err := conn.DescribeInstances(&ec2.DescribeInstancesInput{ 1105 InstanceIds: []*string{aws.String(rs.Primary.ID)}, 1106 }) 1107 if ec2err, ok := err.(awserr.Error); ok && ec2err.Code() == "InvalidInstanceID.NotFound" { 1108 continue 1109 } 1110 if err != nil { 1111 return err 1112 } 1113 1114 if len(resp.Reservations) > 0 { 1115 *i = *resp.Reservations[0].Instances[0] 1116 return nil 1117 } 1118 } 1119 1120 return fmt.Errorf("Instance not found") 1121 } 1122 } 1123 1124 func TestInstanceTenancySchema(t *testing.T) { 1125 actualSchema := resourceAwsInstance().Schema["tenancy"] 1126 expectedSchema := &schema.Schema{ 1127 Type: schema.TypeString, 1128 Optional: true, 1129 Computed: true, 1130 ForceNew: true, 1131 } 1132 if !reflect.DeepEqual(actualSchema, expectedSchema) { 1133 t.Fatalf( 1134 "Got:\n\n%#v\n\nExpected:\n\n%#v\n", 1135 actualSchema, 1136 expectedSchema) 1137 } 1138 } 1139 1140 func driftTags(instance *ec2.Instance) resource.TestCheckFunc { 1141 return func(s *terraform.State) error { 1142 conn := testAccProvider.Meta().(*AWSClient).ec2conn 1143 _, err := conn.CreateTags(&ec2.CreateTagsInput{ 1144 Resources: []*string{instance.InstanceId}, 1145 Tags: []*ec2.Tag{ 1146 { 1147 Key: aws.String("Drift"), 1148 Value: aws.String("Happens"), 1149 }, 1150 }, 1151 }) 1152 return err 1153 } 1154 } 1155 1156 const testAccInstanceConfig_pre = ` 1157 resource "aws_security_group" "tf_test_foo" { 1158 name = "tf_test_foo" 1159 description = "foo" 1160 1161 ingress { 1162 protocol = "icmp" 1163 from_port = -1 1164 to_port = -1 1165 cidr_blocks = ["0.0.0.0/0"] 1166 } 1167 } 1168 ` 1169 1170 const testAccInstanceConfig = ` 1171 resource "aws_security_group" "tf_test_foo" { 1172 name = "tf_test_foo" 1173 description = "foo" 1174 1175 ingress { 1176 protocol = "icmp" 1177 from_port = -1 1178 to_port = -1 1179 cidr_blocks = ["0.0.0.0/0"] 1180 } 1181 } 1182 1183 resource "aws_instance" "foo" { 1184 # us-west-2 1185 ami = "ami-4fccb37f" 1186 availability_zone = "us-west-2a" 1187 1188 instance_type = "m1.small" 1189 security_groups = ["${aws_security_group.tf_test_foo.name}"] 1190 user_data = "foo:-with-character's" 1191 } 1192 ` 1193 1194 const testAccInstanceConfigWithSmallInstanceType = ` 1195 resource "aws_instance" "foo" { 1196 # us-west-2 1197 ami = "ami-55a7ea65" 1198 availability_zone = "us-west-2a" 1199 1200 instance_type = "m3.medium" 1201 1202 tags { 1203 Name = "tf-acctest" 1204 } 1205 } 1206 ` 1207 1208 const testAccInstanceConfigUpdateInstanceType = ` 1209 resource "aws_instance" "foo" { 1210 # us-west-2 1211 ami = "ami-55a7ea65" 1212 availability_zone = "us-west-2a" 1213 1214 instance_type = "m3.large" 1215 1216 tags { 1217 Name = "tf-acctest" 1218 } 1219 } 1220 ` 1221 1222 const testAccInstanceGP2IopsDevice = ` 1223 resource "aws_instance" "foo" { 1224 # us-west-2 1225 ami = "ami-55a7ea65" 1226 1227 # In order to attach an encrypted volume to an instance you need to have an 1228 # m3.medium or larger. See "Supported Instance Types" in: 1229 # http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/EBSEncryption.html 1230 instance_type = "m3.medium" 1231 1232 root_block_device { 1233 volume_type = "gp2" 1234 volume_size = 11 1235 } 1236 } 1237 ` 1238 1239 const testAccInstanceConfigBlockDevices = ` 1240 resource "aws_instance" "foo" { 1241 # us-west-2 1242 ami = "ami-55a7ea65" 1243 1244 # In order to attach an encrypted volume to an instance you need to have an 1245 # m3.medium or larger. See "Supported Instance Types" in: 1246 # http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/EBSEncryption.html 1247 instance_type = "m3.medium" 1248 1249 root_block_device { 1250 volume_type = "gp2" 1251 volume_size = 11 1252 } 1253 ebs_block_device { 1254 device_name = "/dev/sdb" 1255 volume_size = 9 1256 } 1257 ebs_block_device { 1258 device_name = "/dev/sdc" 1259 volume_size = 10 1260 volume_type = "io1" 1261 iops = 100 1262 } 1263 1264 # Encrypted ebs block device 1265 ebs_block_device { 1266 device_name = "/dev/sdd" 1267 volume_size = 12 1268 encrypted = true 1269 } 1270 1271 ephemeral_block_device { 1272 device_name = "/dev/sde" 1273 virtual_name = "ephemeral0" 1274 } 1275 } 1276 ` 1277 1278 const testAccInstanceConfigSourceDestEnable = ` 1279 resource "aws_vpc" "foo" { 1280 cidr_block = "10.1.0.0/16" 1281 } 1282 1283 resource "aws_subnet" "foo" { 1284 cidr_block = "10.1.1.0/24" 1285 vpc_id = "${aws_vpc.foo.id}" 1286 } 1287 1288 resource "aws_instance" "foo" { 1289 # us-west-2 1290 ami = "ami-4fccb37f" 1291 instance_type = "m1.small" 1292 subnet_id = "${aws_subnet.foo.id}" 1293 } 1294 ` 1295 1296 const testAccInstanceConfigSourceDestDisable = ` 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 source_dest_check = false 1312 } 1313 ` 1314 1315 func testAccInstanceConfigDisableAPITermination(val bool) string { 1316 return fmt.Sprintf(` 1317 resource "aws_vpc" "foo" { 1318 cidr_block = "10.1.0.0/16" 1319 } 1320 1321 resource "aws_subnet" "foo" { 1322 cidr_block = "10.1.1.0/24" 1323 vpc_id = "${aws_vpc.foo.id}" 1324 } 1325 1326 resource "aws_instance" "foo" { 1327 # us-west-2 1328 ami = "ami-4fccb37f" 1329 instance_type = "m1.small" 1330 subnet_id = "${aws_subnet.foo.id}" 1331 disable_api_termination = %t 1332 } 1333 `, val) 1334 } 1335 1336 const testAccInstanceConfigVPC = ` 1337 resource "aws_vpc" "foo" { 1338 cidr_block = "10.1.0.0/16" 1339 } 1340 1341 resource "aws_subnet" "foo" { 1342 cidr_block = "10.1.1.0/24" 1343 vpc_id = "${aws_vpc.foo.id}" 1344 } 1345 1346 resource "aws_instance" "foo" { 1347 # us-west-2 1348 ami = "ami-4fccb37f" 1349 instance_type = "m1.small" 1350 subnet_id = "${aws_subnet.foo.id}" 1351 associate_public_ip_address = true 1352 tenancy = "dedicated" 1353 # pre-encoded base64 data 1354 user_data = "3dc39dda39be1205215e776bad998da361a5955d" 1355 } 1356 ` 1357 1358 const testAccInstanceConfigIpv6Support = ` 1359 resource "aws_vpc" "foo" { 1360 cidr_block = "10.1.0.0/16" 1361 assign_generated_ipv6_cidr_block = true 1362 tags { 1363 Name = "tf-ipv6-instance-acc-test" 1364 } 1365 } 1366 1367 resource "aws_subnet" "foo" { 1368 cidr_block = "10.1.1.0/24" 1369 vpc_id = "${aws_vpc.foo.id}" 1370 ipv6_cidr_block = "${cidrsubnet(aws_vpc.foo.ipv6_cidr_block, 8, 1)}" 1371 tags { 1372 Name = "tf-ipv6-instance-acc-test" 1373 } 1374 } 1375 1376 resource "aws_instance" "foo" { 1377 # us-west-2 1378 ami = "ami-c5eabbf5" 1379 instance_type = "t2.micro" 1380 subnet_id = "${aws_subnet.foo.id}" 1381 1382 ipv6_address_count = 1 1383 tags { 1384 Name = "tf-ipv6-instance-acc-test" 1385 } 1386 } 1387 ` 1388 1389 const testAccInstanceConfigMultipleRegions = ` 1390 provider "aws" { 1391 alias = "west" 1392 region = "us-west-2" 1393 } 1394 1395 provider "aws" { 1396 alias = "east" 1397 region = "us-east-1" 1398 } 1399 1400 resource "aws_instance" "foo" { 1401 # us-west-2 1402 provider = "aws.west" 1403 ami = "ami-4fccb37f" 1404 instance_type = "m1.small" 1405 } 1406 1407 resource "aws_instance" "bar" { 1408 # us-east-1 1409 provider = "aws.east" 1410 ami = "ami-8c6ea9e4" 1411 instance_type = "m1.small" 1412 } 1413 ` 1414 1415 const testAccCheckInstanceConfigTags = ` 1416 resource "aws_instance" "foo" { 1417 ami = "ami-4fccb37f" 1418 instance_type = "m1.small" 1419 tags { 1420 foo = "bar" 1421 } 1422 } 1423 ` 1424 1425 const testAccCheckInstanceConfigWithAttachedVolume = ` 1426 data "aws_ami" "debian_jessie_latest" { 1427 most_recent = true 1428 1429 filter { 1430 name = "name" 1431 values = ["debian-jessie-*"] 1432 } 1433 1434 filter { 1435 name = "virtualization-type" 1436 values = ["hvm"] 1437 } 1438 1439 filter { 1440 name = "architecture" 1441 values = ["x86_64"] 1442 } 1443 1444 filter { 1445 name = "root-device-type" 1446 values = ["ebs"] 1447 } 1448 1449 owners = ["379101102735"] # Debian 1450 } 1451 1452 resource "aws_instance" "foo" { 1453 ami = "${data.aws_ami.debian_jessie_latest.id}" 1454 associate_public_ip_address = true 1455 count = 1 1456 instance_type = "t2.medium" 1457 1458 root_block_device { 1459 volume_size = "10" 1460 volume_type = "standard" 1461 delete_on_termination = true 1462 } 1463 1464 tags { 1465 Name = "test-terraform" 1466 } 1467 } 1468 1469 resource "aws_ebs_volume" "test" { 1470 depends_on = ["aws_instance.foo"] 1471 availability_zone = "${aws_instance.foo.availability_zone}" 1472 type = "gp2" 1473 size = "10" 1474 1475 tags { 1476 Name = "test-terraform" 1477 } 1478 } 1479 1480 resource "aws_volume_attachment" "test" { 1481 depends_on = ["aws_ebs_volume.test"] 1482 device_name = "/dev/xvdg" 1483 volume_id = "${aws_ebs_volume.test.id}" 1484 instance_id = "${aws_instance.foo.id}" 1485 } 1486 ` 1487 1488 const testAccCheckInstanceConfigNoVolumeTags = ` 1489 resource "aws_instance" "foo" { 1490 ami = "ami-55a7ea65" 1491 1492 instance_type = "m3.medium" 1493 1494 root_block_device { 1495 volume_type = "gp2" 1496 volume_size = 11 1497 } 1498 ebs_block_device { 1499 device_name = "/dev/sdb" 1500 volume_size = 9 1501 } 1502 ebs_block_device { 1503 device_name = "/dev/sdc" 1504 volume_size = 10 1505 volume_type = "io1" 1506 iops = 100 1507 } 1508 1509 ebs_block_device { 1510 device_name = "/dev/sdd" 1511 volume_size = 12 1512 encrypted = true 1513 } 1514 1515 ephemeral_block_device { 1516 device_name = "/dev/sde" 1517 virtual_name = "ephemeral0" 1518 } 1519 } 1520 ` 1521 1522 const testAccCheckInstanceConfigWithVolumeTags = ` 1523 resource "aws_instance" "foo" { 1524 ami = "ami-55a7ea65" 1525 1526 instance_type = "m3.medium" 1527 1528 root_block_device { 1529 volume_type = "gp2" 1530 volume_size = 11 1531 } 1532 ebs_block_device { 1533 device_name = "/dev/sdb" 1534 volume_size = 9 1535 } 1536 ebs_block_device { 1537 device_name = "/dev/sdc" 1538 volume_size = 10 1539 volume_type = "io1" 1540 iops = 100 1541 } 1542 1543 ebs_block_device { 1544 device_name = "/dev/sdd" 1545 volume_size = 12 1546 encrypted = true 1547 } 1548 1549 ephemeral_block_device { 1550 device_name = "/dev/sde" 1551 virtual_name = "ephemeral0" 1552 } 1553 1554 volume_tags { 1555 Name = "acceptance-test-volume-tag" 1556 } 1557 } 1558 ` 1559 1560 const testAccCheckInstanceConfigWithVolumeTagsUpdate = ` 1561 resource "aws_instance" "foo" { 1562 ami = "ami-55a7ea65" 1563 1564 instance_type = "m3.medium" 1565 1566 root_block_device { 1567 volume_type = "gp2" 1568 volume_size = 11 1569 } 1570 ebs_block_device { 1571 device_name = "/dev/sdb" 1572 volume_size = 9 1573 } 1574 ebs_block_device { 1575 device_name = "/dev/sdc" 1576 volume_size = 10 1577 volume_type = "io1" 1578 iops = 100 1579 } 1580 1581 ebs_block_device { 1582 device_name = "/dev/sdd" 1583 volume_size = 12 1584 encrypted = true 1585 } 1586 1587 ephemeral_block_device { 1588 device_name = "/dev/sde" 1589 virtual_name = "ephemeral0" 1590 } 1591 1592 volume_tags { 1593 Name = "acceptance-test-volume-tag" 1594 Environment = "dev" 1595 } 1596 } 1597 ` 1598 1599 const testAccCheckInstanceConfigTagsUpdate = ` 1600 resource "aws_instance" "foo" { 1601 ami = "ami-4fccb37f" 1602 instance_type = "m1.small" 1603 tags { 1604 bar = "baz" 1605 } 1606 } 1607 ` 1608 1609 func testAccInstanceConfigWithoutInstanceProfile(rName string) string { 1610 return fmt.Sprintf(` 1611 resource "aws_iam_role" "test" { 1612 name = "test-%s" 1613 assume_role_policy = "{\"Version\":\"2012-10-17\",\"Statement\":[{\"Effect\":\"Allow\",\"Principal\":{\"Service\":[\"ec2.amazonaws.com\"]},\"Action\":[\"sts:AssumeRole\"]}]}" 1614 } 1615 1616 resource "aws_iam_instance_profile" "test" { 1617 name = "test-%s" 1618 roles = ["${aws_iam_role.test.name}"] 1619 } 1620 1621 resource "aws_instance" "foo" { 1622 ami = "ami-4fccb37f" 1623 instance_type = "m1.small" 1624 tags { 1625 bar = "baz" 1626 } 1627 }`, rName, rName) 1628 } 1629 1630 func testAccInstanceConfigWithInstanceProfile(rName string) string { 1631 return fmt.Sprintf(` 1632 resource "aws_iam_role" "test" { 1633 name = "test-%s" 1634 assume_role_policy = "{\"Version\":\"2012-10-17\",\"Statement\":[{\"Effect\":\"Allow\",\"Principal\":{\"Service\":[\"ec2.amazonaws.com\"]},\"Action\":[\"sts:AssumeRole\"]}]}" 1635 } 1636 1637 resource "aws_iam_instance_profile" "test" { 1638 name = "test-%s" 1639 roles = ["${aws_iam_role.test.name}"] 1640 } 1641 1642 resource "aws_instance" "foo" { 1643 ami = "ami-4fccb37f" 1644 instance_type = "m1.small" 1645 iam_instance_profile = "${aws_iam_instance_profile.test.name}" 1646 tags { 1647 bar = "baz" 1648 } 1649 }`, rName, rName) 1650 } 1651 1652 const testAccInstanceConfigPrivateIP = ` 1653 resource "aws_vpc" "foo" { 1654 cidr_block = "10.1.0.0/16" 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" { 1663 ami = "ami-c5eabbf5" 1664 instance_type = "t2.micro" 1665 subnet_id = "${aws_subnet.foo.id}" 1666 private_ip = "10.1.1.42" 1667 } 1668 ` 1669 1670 const testAccInstanceConfigAssociatePublicIPAndPrivateIP = ` 1671 resource "aws_vpc" "foo" { 1672 cidr_block = "10.1.0.0/16" 1673 } 1674 1675 resource "aws_subnet" "foo" { 1676 cidr_block = "10.1.1.0/24" 1677 vpc_id = "${aws_vpc.foo.id}" 1678 } 1679 1680 resource "aws_instance" "foo" { 1681 ami = "ami-c5eabbf5" 1682 instance_type = "t2.micro" 1683 subnet_id = "${aws_subnet.foo.id}" 1684 associate_public_ip_address = true 1685 private_ip = "10.1.1.42" 1686 } 1687 ` 1688 1689 const testAccInstanceNetworkInstanceSecurityGroups = ` 1690 resource "aws_internet_gateway" "gw" { 1691 vpc_id = "${aws_vpc.foo.id}" 1692 } 1693 1694 resource "aws_vpc" "foo" { 1695 cidr_block = "10.1.0.0/16" 1696 tags { 1697 Name = "tf-network-test" 1698 } 1699 } 1700 1701 resource "aws_security_group" "tf_test_foo" { 1702 name = "tf_test_foo" 1703 description = "foo" 1704 vpc_id="${aws_vpc.foo.id}" 1705 1706 ingress { 1707 protocol = "icmp" 1708 from_port = -1 1709 to_port = -1 1710 cidr_blocks = ["0.0.0.0/0"] 1711 } 1712 } 1713 1714 resource "aws_subnet" "foo" { 1715 cidr_block = "10.1.1.0/24" 1716 vpc_id = "${aws_vpc.foo.id}" 1717 } 1718 1719 resource "aws_instance" "foo_instance" { 1720 ami = "ami-21f78e11" 1721 instance_type = "t1.micro" 1722 vpc_security_group_ids = ["${aws_security_group.tf_test_foo.id}"] 1723 subnet_id = "${aws_subnet.foo.id}" 1724 associate_public_ip_address = true 1725 depends_on = ["aws_internet_gateway.gw"] 1726 } 1727 1728 resource "aws_eip" "foo_eip" { 1729 instance = "${aws_instance.foo_instance.id}" 1730 vpc = true 1731 depends_on = ["aws_internet_gateway.gw"] 1732 } 1733 ` 1734 1735 const testAccInstanceNetworkInstanceVPCSecurityGroupIDs = ` 1736 resource "aws_internet_gateway" "gw" { 1737 vpc_id = "${aws_vpc.foo.id}" 1738 } 1739 1740 resource "aws_vpc" "foo" { 1741 cidr_block = "10.1.0.0/16" 1742 tags { 1743 Name = "tf-network-test" 1744 } 1745 } 1746 1747 resource "aws_security_group" "tf_test_foo" { 1748 name = "tf_test_foo" 1749 description = "foo" 1750 vpc_id="${aws_vpc.foo.id}" 1751 1752 ingress { 1753 protocol = "icmp" 1754 from_port = -1 1755 to_port = -1 1756 cidr_blocks = ["0.0.0.0/0"] 1757 } 1758 } 1759 1760 resource "aws_subnet" "foo" { 1761 cidr_block = "10.1.1.0/24" 1762 vpc_id = "${aws_vpc.foo.id}" 1763 } 1764 1765 resource "aws_instance" "foo_instance" { 1766 ami = "ami-21f78e11" 1767 instance_type = "t1.micro" 1768 vpc_security_group_ids = ["${aws_security_group.tf_test_foo.id}"] 1769 subnet_id = "${aws_subnet.foo.id}" 1770 depends_on = ["aws_internet_gateway.gw"] 1771 } 1772 1773 resource "aws_eip" "foo_eip" { 1774 instance = "${aws_instance.foo_instance.id}" 1775 vpc = true 1776 depends_on = ["aws_internet_gateway.gw"] 1777 } 1778 ` 1779 1780 const testAccInstanceConfigKeyPair = ` 1781 provider "aws" { 1782 region = "us-east-1" 1783 } 1784 1785 resource "aws_key_pair" "debugging" { 1786 key_name = "tmp-key" 1787 public_key = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQD3F6tyPEFEzV0LX3X8BsXdMsQz1x2cEikKDEY0aIj41qgxMCP/iteneqXSIFZBp5vizPvaoIR3Um9xK7PGoW8giupGn+EPuxIA4cDM4vzOqOkiMPhz5XK0whEjkVzTo4+S0puvDZuwIsdiW9mxhJc7tgBNL0cYlWSYVkz4G/fslNfRPW5mYAM49f4fhtxPb5ok4Q2Lg9dPKVHO/Bgeu5woMc7RY0p1ej6D4CKFE6lymSDJpW0YHX/wqE9+cfEauh7xZcG0q9t2ta6F6fmX0agvpFyZo8aFbXeUBr7osSCJNgvavWbM/06niWrOvYX2xwWdhXmXSrbX8ZbabVohBK41 phodgson@thoughtworks.com" 1788 } 1789 1790 resource "aws_instance" "foo" { 1791 ami = "ami-408c7f28" 1792 instance_type = "t1.micro" 1793 key_name = "${aws_key_pair.debugging.key_name}" 1794 tags { 1795 Name = "testAccInstanceConfigKeyPair_TestAMI" 1796 } 1797 } 1798 ` 1799 1800 const testAccInstanceConfigRootBlockDeviceMismatch = ` 1801 resource "aws_vpc" "foo" { 1802 cidr_block = "10.1.0.0/16" 1803 } 1804 1805 resource "aws_subnet" "foo" { 1806 cidr_block = "10.1.1.0/24" 1807 vpc_id = "${aws_vpc.foo.id}" 1808 } 1809 1810 resource "aws_instance" "foo" { 1811 // This is an AMI with RootDeviceName: "/dev/sda1"; actual root: "/dev/sda" 1812 ami = "ami-ef5b69df" 1813 instance_type = "t1.micro" 1814 subnet_id = "${aws_subnet.foo.id}" 1815 root_block_device { 1816 volume_size = 13 1817 } 1818 } 1819 ` 1820 1821 const testAccInstanceConfigForceNewAndTagsDrift = ` 1822 resource "aws_vpc" "foo" { 1823 cidr_block = "10.1.0.0/16" 1824 } 1825 1826 resource "aws_subnet" "foo" { 1827 cidr_block = "10.1.1.0/24" 1828 vpc_id = "${aws_vpc.foo.id}" 1829 } 1830 1831 resource "aws_instance" "foo" { 1832 ami = "ami-22b9a343" 1833 instance_type = "t2.nano" 1834 subnet_id = "${aws_subnet.foo.id}" 1835 } 1836 ` 1837 1838 const testAccInstanceConfigForceNewAndTagsDrift_Update = ` 1839 resource "aws_vpc" "foo" { 1840 cidr_block = "10.1.0.0/16" 1841 } 1842 1843 resource "aws_subnet" "foo" { 1844 cidr_block = "10.1.1.0/24" 1845 vpc_id = "${aws_vpc.foo.id}" 1846 } 1847 1848 resource "aws_instance" "foo" { 1849 ami = "ami-22b9a343" 1850 instance_type = "t2.micro" 1851 subnet_id = "${aws_subnet.foo.id}" 1852 } 1853 ` 1854 1855 const testAccInstanceConfigPrimaryNetworkInterface = ` 1856 resource "aws_vpc" "foo" { 1857 cidr_block = "172.16.0.0/16" 1858 tags { 1859 Name = "tf-instance-test" 1860 } 1861 } 1862 1863 resource "aws_subnet" "foo" { 1864 vpc_id = "${aws_vpc.foo.id}" 1865 cidr_block = "172.16.10.0/24" 1866 availability_zone = "us-west-2a" 1867 tags { 1868 Name = "tf-instance-test" 1869 } 1870 } 1871 1872 resource "aws_network_interface" "bar" { 1873 subnet_id = "${aws_subnet.foo.id}" 1874 private_ips = ["172.16.10.100"] 1875 tags { 1876 Name = "primary_network_interface" 1877 } 1878 } 1879 1880 resource "aws_instance" "foo" { 1881 ami = "ami-22b9a343" 1882 instance_type = "t2.micro" 1883 network_interface { 1884 network_interface_id = "${aws_network_interface.bar.id}" 1885 device_index = 0 1886 } 1887 } 1888 ` 1889 1890 const testAccInstanceConfigPrimaryNetworkInterfaceSourceDestCheck = ` 1891 resource "aws_vpc" "foo" { 1892 cidr_block = "172.16.0.0/16" 1893 tags { 1894 Name = "tf-instance-test" 1895 } 1896 } 1897 1898 resource "aws_subnet" "foo" { 1899 vpc_id = "${aws_vpc.foo.id}" 1900 cidr_block = "172.16.10.0/24" 1901 availability_zone = "us-west-2a" 1902 tags { 1903 Name = "tf-instance-test" 1904 } 1905 } 1906 1907 resource "aws_network_interface" "bar" { 1908 subnet_id = "${aws_subnet.foo.id}" 1909 private_ips = ["172.16.10.100"] 1910 source_dest_check = false 1911 tags { 1912 Name = "primary_network_interface" 1913 } 1914 } 1915 1916 resource "aws_instance" "foo" { 1917 ami = "ami-22b9a343" 1918 instance_type = "t2.micro" 1919 network_interface { 1920 network_interface_id = "${aws_network_interface.bar.id}" 1921 device_index = 0 1922 } 1923 } 1924 ` 1925 1926 const testAccInstanceConfigAddSecondaryNetworkInterfaceBefore = ` 1927 resource "aws_vpc" "foo" { 1928 cidr_block = "172.16.0.0/16" 1929 tags { 1930 Name = "tf-instance-test" 1931 } 1932 } 1933 1934 resource "aws_subnet" "foo" { 1935 vpc_id = "${aws_vpc.foo.id}" 1936 cidr_block = "172.16.10.0/24" 1937 availability_zone = "us-west-2a" 1938 tags { 1939 Name = "tf-instance-test" 1940 } 1941 } 1942 1943 resource "aws_network_interface" "primary" { 1944 subnet_id = "${aws_subnet.foo.id}" 1945 private_ips = ["172.16.10.100"] 1946 tags { 1947 Name = "primary_network_interface" 1948 } 1949 } 1950 1951 resource "aws_network_interface" "secondary" { 1952 subnet_id = "${aws_subnet.foo.id}" 1953 private_ips = ["172.16.10.101"] 1954 tags { 1955 Name = "secondary_network_interface" 1956 } 1957 } 1958 1959 resource "aws_instance" "foo" { 1960 ami = "ami-22b9a343" 1961 instance_type = "t2.micro" 1962 network_interface { 1963 network_interface_id = "${aws_network_interface.primary.id}" 1964 device_index = 0 1965 } 1966 } 1967 ` 1968 1969 const testAccInstanceConfigAddSecondaryNetworkInterfaceAfter = ` 1970 resource "aws_vpc" "foo" { 1971 cidr_block = "172.16.0.0/16" 1972 tags { 1973 Name = "tf-instance-test" 1974 } 1975 } 1976 1977 resource "aws_subnet" "foo" { 1978 vpc_id = "${aws_vpc.foo.id}" 1979 cidr_block = "172.16.10.0/24" 1980 availability_zone = "us-west-2a" 1981 tags { 1982 Name = "tf-instance-test" 1983 } 1984 } 1985 1986 resource "aws_network_interface" "primary" { 1987 subnet_id = "${aws_subnet.foo.id}" 1988 private_ips = ["172.16.10.100"] 1989 tags { 1990 Name = "primary_network_interface" 1991 } 1992 } 1993 1994 // Attach previously created network interface, observe no state diff on instance resource 1995 resource "aws_network_interface" "secondary" { 1996 subnet_id = "${aws_subnet.foo.id}" 1997 private_ips = ["172.16.10.101"] 1998 tags { 1999 Name = "secondary_network_interface" 2000 } 2001 attachment { 2002 instance = "${aws_instance.foo.id}" 2003 device_index = 1 2004 } 2005 } 2006 2007 resource "aws_instance" "foo" { 2008 ami = "ami-22b9a343" 2009 instance_type = "t2.micro" 2010 network_interface { 2011 network_interface_id = "${aws_network_interface.primary.id}" 2012 device_index = 0 2013 } 2014 } 2015 `