github.com/ndarilek/terraform@v0.3.8-0.20150320140257-d3135c1b2bac/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/hashicorp/aws-sdk-go/aws" 9 "github.com/hashicorp/aws-sdk-go/gen/ec2" 10 "github.com/hashicorp/terraform/helper/resource" 11 "github.com/hashicorp/terraform/helper/schema" 12 "github.com/hashicorp/terraform/terraform" 13 ) 14 15 func TestAccAWSInstance_normal(t *testing.T) { 16 var v ec2.Instance 17 var vol *ec2.Volume 18 19 testCheck := func(*terraform.State) error { 20 if *v.Placement.AvailabilityZone != "us-west-2a" { 21 return fmt.Errorf("bad availability zone: %#v", *v.Placement.AvailabilityZone) 22 } 23 24 if len(v.SecurityGroups) == 0 { 25 return fmt.Errorf("no security groups: %#v", v.SecurityGroups) 26 } 27 if *v.SecurityGroups[0].GroupName != "tf_test_foo" { 28 return fmt.Errorf("no security groups: %#v", v.SecurityGroups) 29 } 30 31 return nil 32 } 33 34 resource.Test(t, resource.TestCase{ 35 PreCheck: func() { testAccPreCheck(t) }, 36 Providers: testAccProviders, 37 CheckDestroy: testAccCheckInstanceDestroy, 38 Steps: []resource.TestStep{ 39 // Create a volume to cover #1249 40 resource.TestStep{ 41 // Need a resource in this config so the provisioner will be available 42 Config: testAccInstanceConfig_pre, 43 Check: func(*terraform.State) error { 44 conn := testAccProvider.Meta().(*AWSClient).ec2conn 45 var err error 46 vol, err = conn.CreateVolume(&ec2.CreateVolumeRequest{ 47 AvailabilityZone: aws.String("us-west-2a"), 48 Size: aws.Integer(5), 49 }) 50 return err 51 }, 52 }, 53 54 resource.TestStep{ 55 Config: testAccInstanceConfig, 56 Check: resource.ComposeTestCheckFunc( 57 testAccCheckInstanceExists( 58 "aws_instance.foo", &v), 59 testCheck, 60 resource.TestCheckResourceAttr( 61 "aws_instance.foo", 62 "user_data", 63 "3dc39dda39be1205215e776bad998da361a5955d"), 64 resource.TestCheckResourceAttr( 65 "aws_instance.foo", "ebs_block_device.#", "0"), 66 ), 67 }, 68 69 // We repeat the exact same test so that we can be sure 70 // that the user data hash stuff is working without generating 71 // an incorrect diff. 72 resource.TestStep{ 73 Config: testAccInstanceConfig, 74 Check: resource.ComposeTestCheckFunc( 75 testAccCheckInstanceExists( 76 "aws_instance.foo", &v), 77 testCheck, 78 resource.TestCheckResourceAttr( 79 "aws_instance.foo", 80 "user_data", 81 "3dc39dda39be1205215e776bad998da361a5955d"), 82 resource.TestCheckResourceAttr( 83 "aws_instance.foo", "ebs_block_device.#", "0"), 84 ), 85 }, 86 87 // Clean up volume created above 88 resource.TestStep{ 89 Config: testAccInstanceConfig, 90 Check: func(*terraform.State) error { 91 conn := testAccProvider.Meta().(*AWSClient).ec2conn 92 return conn.DeleteVolume(&ec2.DeleteVolumeRequest{VolumeID: vol.VolumeID}) 93 }, 94 }, 95 }, 96 }) 97 } 98 99 func TestAccAWSInstance_blockDevices(t *testing.T) { 100 var v ec2.Instance 101 102 testCheck := func() resource.TestCheckFunc { 103 return func(*terraform.State) error { 104 105 // Map out the block devices by name, which should be unique. 106 blockDevices := make(map[string]ec2.InstanceBlockDeviceMapping) 107 for _, blockDevice := range v.BlockDeviceMappings { 108 blockDevices[*blockDevice.DeviceName] = blockDevice 109 } 110 111 // Check if the root block device exists. 112 if _, ok := blockDevices["/dev/sda1"]; !ok { 113 fmt.Errorf("block device doesn't exist: /dev/sda1") 114 } 115 116 // Check if the secondary block device exists. 117 if _, ok := blockDevices["/dev/sdb"]; !ok { 118 fmt.Errorf("block device doesn't exist: /dev/sdb") 119 } 120 121 // Check if the third block device exists. 122 if _, ok := blockDevices["/dev/sdc"]; !ok { 123 fmt.Errorf("block device doesn't exist: /dev/sdc") 124 } 125 126 return nil 127 } 128 } 129 130 resource.Test(t, resource.TestCase{ 131 PreCheck: func() { testAccPreCheck(t) }, 132 Providers: testAccProviders, 133 CheckDestroy: testAccCheckInstanceDestroy, 134 Steps: []resource.TestStep{ 135 resource.TestStep{ 136 Config: testAccInstanceConfigBlockDevices, 137 Check: resource.ComposeTestCheckFunc( 138 testAccCheckInstanceExists( 139 "aws_instance.foo", &v), 140 resource.TestCheckResourceAttr( 141 "aws_instance.foo", "root_block_device.#", "1"), 142 resource.TestCheckResourceAttr( 143 "aws_instance.foo", "root_block_device.1246122048.device_name", "/dev/sda1"), 144 resource.TestCheckResourceAttr( 145 "aws_instance.foo", "root_block_device.1246122048.volume_size", "11"), 146 resource.TestCheckResourceAttr( 147 "aws_instance.foo", "root_block_device.1246122048.volume_type", "gp2"), 148 resource.TestCheckResourceAttr( 149 "aws_instance.foo", "ebs_block_device.#", "2"), 150 resource.TestCheckResourceAttr( 151 "aws_instance.foo", "ebs_block_device.2225977507.device_name", "/dev/sdb"), 152 resource.TestCheckResourceAttr( 153 "aws_instance.foo", "ebs_block_device.2225977507.volume_size", "9"), 154 resource.TestCheckResourceAttr( 155 "aws_instance.foo", "ebs_block_device.2225977507.volume_type", "standard"), 156 resource.TestCheckResourceAttr( 157 "aws_instance.foo", "ebs_block_device.1977224956.device_name", "/dev/sdc"), 158 resource.TestCheckResourceAttr( 159 "aws_instance.foo", "ebs_block_device.1977224956.volume_size", "10"), 160 resource.TestCheckResourceAttr( 161 "aws_instance.foo", "ebs_block_device.1977224956.volume_type", "io1"), 162 resource.TestCheckResourceAttr( 163 "aws_instance.foo", "ebs_block_device.1977224956.iops", "100"), 164 resource.TestCheckResourceAttr( 165 "aws_instance.foo", "ephemeral_block_device.#", "1"), 166 resource.TestCheckResourceAttr( 167 "aws_instance.foo", "ephemeral_block_device.1692014856.device_name", "/dev/sde"), 168 resource.TestCheckResourceAttr( 169 "aws_instance.foo", "ephemeral_block_device.1692014856.virtual_name", "ephemeral0"), 170 testCheck(), 171 ), 172 }, 173 }, 174 }) 175 } 176 177 func TestAccAWSInstance_sourceDestCheck(t *testing.T) { 178 var v ec2.Instance 179 180 testCheck := func(enabled bool) resource.TestCheckFunc { 181 return func(*terraform.State) error { 182 if *v.SourceDestCheck != enabled { 183 return fmt.Errorf("bad source_dest_check: %#v", *v.SourceDestCheck) 184 } 185 186 return nil 187 } 188 } 189 190 resource.Test(t, resource.TestCase{ 191 PreCheck: func() { testAccPreCheck(t) }, 192 Providers: testAccProviders, 193 CheckDestroy: testAccCheckInstanceDestroy, 194 Steps: []resource.TestStep{ 195 resource.TestStep{ 196 Config: testAccInstanceConfigSourceDestDisable, 197 Check: resource.ComposeTestCheckFunc( 198 testAccCheckInstanceExists("aws_instance.foo", &v), 199 testCheck(false), 200 ), 201 }, 202 203 resource.TestStep{ 204 Config: testAccInstanceConfigSourceDestEnable, 205 Check: resource.ComposeTestCheckFunc( 206 testAccCheckInstanceExists("aws_instance.foo", &v), 207 testCheck(true), 208 ), 209 }, 210 211 resource.TestStep{ 212 Config: testAccInstanceConfigSourceDestDisable, 213 Check: resource.ComposeTestCheckFunc( 214 testAccCheckInstanceExists("aws_instance.foo", &v), 215 testCheck(false), 216 ), 217 }, 218 }, 219 }) 220 } 221 222 func TestAccAWSInstance_vpc(t *testing.T) { 223 var v ec2.Instance 224 225 resource.Test(t, resource.TestCase{ 226 PreCheck: func() { testAccPreCheck(t) }, 227 Providers: testAccProviders, 228 CheckDestroy: testAccCheckInstanceDestroy, 229 Steps: []resource.TestStep{ 230 resource.TestStep{ 231 Config: testAccInstanceConfigVPC, 232 Check: resource.ComposeTestCheckFunc( 233 testAccCheckInstanceExists( 234 "aws_instance.foo", &v), 235 ), 236 }, 237 }, 238 }) 239 } 240 241 func TestAccInstance_NetworkInstanceSecurityGroups(t *testing.T) { 242 var v ec2.Instance 243 244 resource.Test(t, resource.TestCase{ 245 PreCheck: func() { testAccPreCheck(t) }, 246 Providers: testAccProviders, 247 CheckDestroy: testAccCheckInstanceDestroy, 248 Steps: []resource.TestStep{ 249 resource.TestStep{ 250 Config: testAccInstanceNetworkInstanceSecurityGroups, 251 Check: resource.ComposeTestCheckFunc( 252 testAccCheckInstanceExists( 253 "aws_instance.foo_instance", &v), 254 ), 255 }, 256 }, 257 }) 258 } 259 260 func TestAccAWSInstance_tags(t *testing.T) { 261 var v ec2.Instance 262 263 resource.Test(t, resource.TestCase{ 264 PreCheck: func() { testAccPreCheck(t) }, 265 Providers: testAccProviders, 266 CheckDestroy: testAccCheckInstanceDestroy, 267 Steps: []resource.TestStep{ 268 resource.TestStep{ 269 Config: testAccCheckInstanceConfigTags, 270 Check: resource.ComposeTestCheckFunc( 271 testAccCheckInstanceExists("aws_instance.foo", &v), 272 testAccCheckTags(&v.Tags, "foo", "bar"), 273 // Guard against regression of https://github.com/hashicorp/terraform/issues/914 274 testAccCheckTags(&v.Tags, "#", ""), 275 ), 276 }, 277 278 resource.TestStep{ 279 Config: testAccCheckInstanceConfigTagsUpdate, 280 Check: resource.ComposeTestCheckFunc( 281 testAccCheckInstanceExists("aws_instance.foo", &v), 282 testAccCheckTags(&v.Tags, "foo", ""), 283 testAccCheckTags(&v.Tags, "bar", "baz"), 284 ), 285 }, 286 }, 287 }) 288 } 289 290 func TestAccAWSInstance_privateIP(t *testing.T) { 291 var v ec2.Instance 292 293 testCheckPrivateIP := func() resource.TestCheckFunc { 294 return func(*terraform.State) error { 295 if *v.PrivateIPAddress != "10.1.1.42" { 296 return fmt.Errorf("bad private IP: %s", *v.PrivateIPAddress) 297 } 298 299 return nil 300 } 301 } 302 303 resource.Test(t, resource.TestCase{ 304 PreCheck: func() { testAccPreCheck(t) }, 305 Providers: testAccProviders, 306 CheckDestroy: testAccCheckInstanceDestroy, 307 Steps: []resource.TestStep{ 308 resource.TestStep{ 309 Config: testAccInstanceConfigPrivateIP, 310 Check: resource.ComposeTestCheckFunc( 311 testAccCheckInstanceExists("aws_instance.foo", &v), 312 testCheckPrivateIP(), 313 ), 314 }, 315 }, 316 }) 317 } 318 319 func TestAccAWSInstance_associatePublicIPAndPrivateIP(t *testing.T) { 320 var v ec2.Instance 321 322 testCheckPrivateIP := func() resource.TestCheckFunc { 323 return func(*terraform.State) error { 324 if *v.PrivateIPAddress != "10.1.1.42" { 325 return fmt.Errorf("bad private IP: %s", *v.PrivateIPAddress) 326 } 327 328 return nil 329 } 330 } 331 332 resource.Test(t, resource.TestCase{ 333 PreCheck: func() { testAccPreCheck(t) }, 334 Providers: testAccProviders, 335 CheckDestroy: testAccCheckInstanceDestroy, 336 Steps: []resource.TestStep{ 337 resource.TestStep{ 338 Config: testAccInstanceConfigAssociatePublicIPAndPrivateIP, 339 Check: resource.ComposeTestCheckFunc( 340 testAccCheckInstanceExists("aws_instance.foo", &v), 341 testCheckPrivateIP(), 342 ), 343 }, 344 }, 345 }) 346 } 347 348 func testAccCheckInstanceDestroy(s *terraform.State) error { 349 conn := testAccProvider.Meta().(*AWSClient).ec2conn 350 351 for _, rs := range s.RootModule().Resources { 352 if rs.Type != "aws_instance" { 353 continue 354 } 355 356 // Try to find the resource 357 resp, err := conn.DescribeInstances(&ec2.DescribeInstancesRequest{ 358 InstanceIDs: []string{rs.Primary.ID}, 359 }) 360 if err == nil { 361 if len(resp.Reservations) > 0 { 362 return fmt.Errorf("still exist.") 363 } 364 365 return nil 366 } 367 368 // Verify the error is what we want 369 ec2err, ok := err.(aws.APIError) 370 if !ok { 371 return err 372 } 373 if ec2err.Code != "InvalidInstanceID.NotFound" { 374 return err 375 } 376 } 377 378 return nil 379 } 380 381 func testAccCheckInstanceExists(n string, i *ec2.Instance) resource.TestCheckFunc { 382 return func(s *terraform.State) error { 383 rs, ok := s.RootModule().Resources[n] 384 if !ok { 385 return fmt.Errorf("Not found: %s", n) 386 } 387 388 if rs.Primary.ID == "" { 389 return fmt.Errorf("No ID is set") 390 } 391 392 conn := testAccProvider.Meta().(*AWSClient).ec2conn 393 resp, err := conn.DescribeInstances(&ec2.DescribeInstancesRequest{ 394 InstanceIDs: []string{rs.Primary.ID}, 395 }) 396 if err != nil { 397 return err 398 } 399 if len(resp.Reservations) == 0 { 400 return fmt.Errorf("Instance not found") 401 } 402 403 *i = resp.Reservations[0].Instances[0] 404 405 return nil 406 } 407 } 408 409 func TestInstanceTenancySchema(t *testing.T) { 410 actualSchema := resourceAwsInstance().Schema["tenancy"] 411 expectedSchema := &schema.Schema{ 412 Type: schema.TypeString, 413 Optional: true, 414 Computed: true, 415 ForceNew: true, 416 } 417 if !reflect.DeepEqual(actualSchema, expectedSchema) { 418 t.Fatalf( 419 "Got:\n\n%#v\n\nExpected:\n\n%#v\n", 420 actualSchema, 421 expectedSchema) 422 } 423 } 424 425 const testAccInstanceConfig_pre = ` 426 resource "aws_security_group" "tf_test_foo" { 427 name = "tf_test_foo" 428 description = "foo" 429 430 ingress { 431 protocol = "icmp" 432 from_port = -1 433 to_port = -1 434 cidr_blocks = ["0.0.0.0/0"] 435 } 436 } 437 ` 438 439 const testAccInstanceConfig = ` 440 resource "aws_security_group" "tf_test_foo" { 441 name = "tf_test_foo" 442 description = "foo" 443 444 ingress { 445 protocol = "icmp" 446 from_port = -1 447 to_port = -1 448 cidr_blocks = ["0.0.0.0/0"] 449 } 450 } 451 452 resource "aws_instance" "foo" { 453 # us-west-2 454 ami = "ami-4fccb37f" 455 availability_zone = "us-west-2a" 456 457 instance_type = "m1.small" 458 security_groups = ["${aws_security_group.tf_test_foo.name}"] 459 user_data = "foo:-with-character's" 460 } 461 ` 462 463 const testAccInstanceConfigBlockDevices = ` 464 resource "aws_instance" "foo" { 465 # us-west-2 466 ami = "ami-55a7ea65" 467 instance_type = "m1.small" 468 469 root_block_device { 470 device_name = "/dev/sda1" 471 volume_type = "gp2" 472 volume_size = 11 473 } 474 ebs_block_device { 475 device_name = "/dev/sdb" 476 volume_size = 9 477 } 478 ebs_block_device { 479 device_name = "/dev/sdc" 480 volume_size = 10 481 volume_type = "io1" 482 iops = 100 483 } 484 ephemeral_block_device { 485 device_name = "/dev/sde" 486 virtual_name = "ephemeral0" 487 } 488 } 489 ` 490 491 const testAccInstanceConfigSourceDestEnable = ` 492 resource "aws_vpc" "foo" { 493 cidr_block = "10.1.0.0/16" 494 } 495 496 resource "aws_subnet" "foo" { 497 cidr_block = "10.1.1.0/24" 498 vpc_id = "${aws_vpc.foo.id}" 499 } 500 501 resource "aws_instance" "foo" { 502 # us-west-2 503 ami = "ami-4fccb37f" 504 instance_type = "m1.small" 505 subnet_id = "${aws_subnet.foo.id}" 506 source_dest_check = true 507 } 508 ` 509 510 const testAccInstanceConfigSourceDestDisable = ` 511 resource "aws_vpc" "foo" { 512 cidr_block = "10.1.0.0/16" 513 } 514 515 resource "aws_subnet" "foo" { 516 cidr_block = "10.1.1.0/24" 517 vpc_id = "${aws_vpc.foo.id}" 518 } 519 520 resource "aws_instance" "foo" { 521 # us-west-2 522 ami = "ami-4fccb37f" 523 instance_type = "m1.small" 524 subnet_id = "${aws_subnet.foo.id}" 525 source_dest_check = false 526 } 527 ` 528 529 const testAccInstanceConfigVPC = ` 530 resource "aws_vpc" "foo" { 531 cidr_block = "10.1.0.0/16" 532 } 533 534 resource "aws_subnet" "foo" { 535 cidr_block = "10.1.1.0/24" 536 vpc_id = "${aws_vpc.foo.id}" 537 } 538 539 resource "aws_instance" "foo" { 540 # us-west-2 541 ami = "ami-4fccb37f" 542 instance_type = "m1.small" 543 subnet_id = "${aws_subnet.foo.id}" 544 associate_public_ip_address = true 545 tenancy = "dedicated" 546 } 547 ` 548 549 const testAccCheckInstanceConfigTags = ` 550 resource "aws_instance" "foo" { 551 ami = "ami-4fccb37f" 552 instance_type = "m1.small" 553 tags { 554 foo = "bar" 555 } 556 } 557 ` 558 559 const testAccCheckInstanceConfigTagsUpdate = ` 560 resource "aws_instance" "foo" { 561 ami = "ami-4fccb37f" 562 instance_type = "m1.small" 563 tags { 564 bar = "baz" 565 } 566 } 567 ` 568 569 const testAccInstanceConfigPrivateIP = ` 570 resource "aws_vpc" "foo" { 571 cidr_block = "10.1.0.0/16" 572 } 573 574 resource "aws_subnet" "foo" { 575 cidr_block = "10.1.1.0/24" 576 vpc_id = "${aws_vpc.foo.id}" 577 } 578 579 resource "aws_instance" "foo" { 580 ami = "ami-c5eabbf5" 581 instance_type = "t2.micro" 582 subnet_id = "${aws_subnet.foo.id}" 583 private_ip = "10.1.1.42" 584 } 585 ` 586 587 const testAccInstanceConfigAssociatePublicIPAndPrivateIP = ` 588 resource "aws_vpc" "foo" { 589 cidr_block = "10.1.0.0/16" 590 } 591 592 resource "aws_subnet" "foo" { 593 cidr_block = "10.1.1.0/24" 594 vpc_id = "${aws_vpc.foo.id}" 595 } 596 597 resource "aws_instance" "foo" { 598 ami = "ami-c5eabbf5" 599 instance_type = "t2.micro" 600 subnet_id = "${aws_subnet.foo.id}" 601 associate_public_ip_address = true 602 private_ip = "10.1.1.42" 603 } 604 ` 605 606 const testAccInstanceNetworkInstanceSecurityGroups = ` 607 resource "aws_internet_gateway" "gw" { 608 vpc_id = "${aws_vpc.foo.id}" 609 } 610 611 resource "aws_vpc" "foo" { 612 cidr_block = "10.1.0.0/16" 613 tags { 614 Name = "tf-network-test" 615 } 616 } 617 618 resource "aws_security_group" "tf_test_foo" { 619 name = "tf_test_foo" 620 description = "foo" 621 vpc_id="${aws_vpc.foo.id}" 622 623 ingress { 624 protocol = "icmp" 625 from_port = -1 626 to_port = -1 627 cidr_blocks = ["0.0.0.0/0"] 628 } 629 } 630 631 resource "aws_subnet" "foo" { 632 cidr_block = "10.1.1.0/24" 633 vpc_id = "${aws_vpc.foo.id}" 634 } 635 636 resource "aws_instance" "foo_instance" { 637 ami = "ami-21f78e11" 638 instance_type = "t1.micro" 639 security_groups = ["${aws_security_group.tf_test_foo.id}"] 640 subnet_id = "${aws_subnet.foo.id}" 641 associate_public_ip_address = true 642 depends_on = ["aws_internet_gateway.gw"] 643 } 644 645 resource "aws_eip" "foo_eip" { 646 instance = "${aws_instance.foo_instance.id}" 647 vpc = true 648 depends_on = ["aws_internet_gateway.gw"] 649 } 650 `