github.com/leeprovoost/terraform@v0.6.10-0.20160119085442-96f3f76118e7/builtin/providers/google/resource_compute_instance_test.go (about) 1 package google 2 3 import ( 4 "fmt" 5 "strings" 6 "testing" 7 8 "github.com/hashicorp/terraform/helper/acctest" 9 "github.com/hashicorp/terraform/helper/resource" 10 "github.com/hashicorp/terraform/terraform" 11 "google.golang.org/api/compute/v1" 12 ) 13 14 func TestAccComputeInstance_basic_deprecated_network(t *testing.T) { 15 var instance compute.Instance 16 var instanceName = fmt.Sprintf("instance-test-%s", acctest.RandString(10)) 17 18 resource.Test(t, resource.TestCase{ 19 PreCheck: func() { testAccPreCheck(t) }, 20 Providers: testAccProviders, 21 CheckDestroy: testAccCheckComputeInstanceDestroy, 22 Steps: []resource.TestStep{ 23 resource.TestStep{ 24 Config: testAccComputeInstance_basic_deprecated_network(instanceName), 25 Check: resource.ComposeTestCheckFunc( 26 testAccCheckComputeInstanceExists( 27 "google_compute_instance.foobar", &instance), 28 testAccCheckComputeInstanceTag(&instance, "foo"), 29 testAccCheckComputeInstanceMetadata(&instance, "foo", "bar"), 30 testAccCheckComputeInstanceDisk(&instance, instanceName, true, true), 31 ), 32 }, 33 }, 34 }) 35 } 36 37 func TestAccComputeInstance_basic1(t *testing.T) { 38 var instance compute.Instance 39 var instanceName = fmt.Sprintf("instance-test-%s", acctest.RandString(10)) 40 41 resource.Test(t, resource.TestCase{ 42 PreCheck: func() { testAccPreCheck(t) }, 43 Providers: testAccProviders, 44 CheckDestroy: testAccCheckComputeInstanceDestroy, 45 Steps: []resource.TestStep{ 46 resource.TestStep{ 47 Config: testAccComputeInstance_basic(instanceName), 48 Check: resource.ComposeTestCheckFunc( 49 testAccCheckComputeInstanceExists( 50 "google_compute_instance.foobar", &instance), 51 testAccCheckComputeInstanceTag(&instance, "foo"), 52 testAccCheckComputeInstanceMetadata(&instance, "foo", "bar"), 53 testAccCheckComputeInstanceMetadata(&instance, "baz", "qux"), 54 testAccCheckComputeInstanceDisk(&instance, instanceName, true, true), 55 ), 56 }, 57 }, 58 }) 59 } 60 61 func TestAccComputeInstance_basic2(t *testing.T) { 62 var instance compute.Instance 63 var instanceName = fmt.Sprintf("instance-test-%s", acctest.RandString(10)) 64 65 resource.Test(t, resource.TestCase{ 66 PreCheck: func() { testAccPreCheck(t) }, 67 Providers: testAccProviders, 68 CheckDestroy: testAccCheckComputeInstanceDestroy, 69 Steps: []resource.TestStep{ 70 resource.TestStep{ 71 Config: testAccComputeInstance_basic2(instanceName), 72 Check: resource.ComposeTestCheckFunc( 73 testAccCheckComputeInstanceExists( 74 "google_compute_instance.foobar", &instance), 75 testAccCheckComputeInstanceTag(&instance, "foo"), 76 testAccCheckComputeInstanceMetadata(&instance, "foo", "bar"), 77 testAccCheckComputeInstanceDisk(&instance, instanceName, true, true), 78 ), 79 }, 80 }, 81 }) 82 } 83 84 func TestAccComputeInstance_basic3(t *testing.T) { 85 var instance compute.Instance 86 var instanceName = fmt.Sprintf("instance-test-%s", acctest.RandString(10)) 87 88 resource.Test(t, resource.TestCase{ 89 PreCheck: func() { testAccPreCheck(t) }, 90 Providers: testAccProviders, 91 CheckDestroy: testAccCheckComputeInstanceDestroy, 92 Steps: []resource.TestStep{ 93 resource.TestStep{ 94 Config: testAccComputeInstance_basic3(instanceName), 95 Check: resource.ComposeTestCheckFunc( 96 testAccCheckComputeInstanceExists( 97 "google_compute_instance.foobar", &instance), 98 testAccCheckComputeInstanceTag(&instance, "foo"), 99 testAccCheckComputeInstanceMetadata(&instance, "foo", "bar"), 100 testAccCheckComputeInstanceDisk(&instance, instanceName, true, true), 101 ), 102 }, 103 }, 104 }) 105 } 106 107 func TestAccComputeInstance_IP(t *testing.T) { 108 var instance compute.Instance 109 var ipName = fmt.Sprintf("instance-test-%s", acctest.RandString(10)) 110 var instanceName = fmt.Sprintf("instance-test-%s", acctest.RandString(10)) 111 112 resource.Test(t, resource.TestCase{ 113 PreCheck: func() { testAccPreCheck(t) }, 114 Providers: testAccProviders, 115 CheckDestroy: testAccCheckComputeInstanceDestroy, 116 Steps: []resource.TestStep{ 117 resource.TestStep{ 118 Config: testAccComputeInstance_ip(ipName, instanceName), 119 Check: resource.ComposeTestCheckFunc( 120 testAccCheckComputeInstanceExists( 121 "google_compute_instance.foobar", &instance), 122 testAccCheckComputeInstanceAccessConfigHasIP(&instance), 123 ), 124 }, 125 }, 126 }) 127 } 128 129 func TestAccComputeInstance_disks(t *testing.T) { 130 var instance compute.Instance 131 var instanceName = fmt.Sprintf("instance-test-%s", acctest.RandString(10)) 132 var diskName = fmt.Sprintf("instance-testd-%s", acctest.RandString(10)) 133 134 resource.Test(t, resource.TestCase{ 135 PreCheck: func() { testAccPreCheck(t) }, 136 Providers: testAccProviders, 137 CheckDestroy: testAccCheckComputeInstanceDestroy, 138 Steps: []resource.TestStep{ 139 resource.TestStep{ 140 Config: testAccComputeInstance_disks(diskName, instanceName), 141 Check: resource.ComposeTestCheckFunc( 142 testAccCheckComputeInstanceExists( 143 "google_compute_instance.foobar", &instance), 144 testAccCheckComputeInstanceDisk(&instance, instanceName, true, true), 145 testAccCheckComputeInstanceDisk(&instance, diskName, false, false), 146 ), 147 }, 148 }, 149 }) 150 } 151 152 func TestAccComputeInstance_local_ssd(t *testing.T) { 153 var instance compute.Instance 154 var instanceName = fmt.Sprintf("instance-test-%s", acctest.RandString(10)) 155 156 resource.Test(t, resource.TestCase{ 157 PreCheck: func() { testAccPreCheck(t) }, 158 Providers: testAccProviders, 159 CheckDestroy: testAccCheckComputeInstanceDestroy, 160 Steps: []resource.TestStep{ 161 resource.TestStep{ 162 Config: testAccComputeInstance_local_ssd(instanceName), 163 Check: resource.ComposeTestCheckFunc( 164 testAccCheckComputeInstanceExists( 165 "google_compute_instance.local-ssd", &instance), 166 testAccCheckComputeInstanceDisk(&instance, instanceName, true, true), 167 ), 168 }, 169 }, 170 }) 171 } 172 173 func TestAccComputeInstance_update_deprecated_network(t *testing.T) { 174 var instance compute.Instance 175 var instanceName = fmt.Sprintf("instance-test-%s", acctest.RandString(10)) 176 177 resource.Test(t, resource.TestCase{ 178 PreCheck: func() { testAccPreCheck(t) }, 179 Providers: testAccProviders, 180 CheckDestroy: testAccCheckComputeInstanceDestroy, 181 Steps: []resource.TestStep{ 182 resource.TestStep{ 183 Config: testAccComputeInstance_basic_deprecated_network(instanceName), 184 Check: resource.ComposeTestCheckFunc( 185 testAccCheckComputeInstanceExists( 186 "google_compute_instance.foobar", &instance), 187 ), 188 }, 189 resource.TestStep{ 190 Config: testAccComputeInstance_update_deprecated_network(instanceName), 191 Check: resource.ComposeTestCheckFunc( 192 testAccCheckComputeInstanceExists( 193 "google_compute_instance.foobar", &instance), 194 testAccCheckComputeInstanceMetadata( 195 &instance, "bar", "baz"), 196 testAccCheckComputeInstanceTag(&instance, "baz"), 197 ), 198 }, 199 }, 200 }) 201 } 202 203 func TestAccComputeInstance_forceNewAndChangeMetadata(t *testing.T) { 204 var instance compute.Instance 205 var instanceName = fmt.Sprintf("instance-test-%s", acctest.RandString(10)) 206 207 resource.Test(t, resource.TestCase{ 208 PreCheck: func() { testAccPreCheck(t) }, 209 Providers: testAccProviders, 210 CheckDestroy: testAccCheckComputeInstanceDestroy, 211 Steps: []resource.TestStep{ 212 resource.TestStep{ 213 Config: testAccComputeInstance_basic(instanceName), 214 Check: resource.ComposeTestCheckFunc( 215 testAccCheckComputeInstanceExists( 216 "google_compute_instance.foobar", &instance), 217 ), 218 }, 219 resource.TestStep{ 220 Config: testAccComputeInstance_forceNewAndChangeMetadata(instanceName), 221 Check: resource.ComposeTestCheckFunc( 222 testAccCheckComputeInstanceExists( 223 "google_compute_instance.foobar", &instance), 224 testAccCheckComputeInstanceMetadata( 225 &instance, "qux", "true"), 226 ), 227 }, 228 }, 229 }) 230 } 231 232 func TestAccComputeInstance_update(t *testing.T) { 233 var instance compute.Instance 234 var instanceName = fmt.Sprintf("instance-test-%s", acctest.RandString(10)) 235 236 resource.Test(t, resource.TestCase{ 237 PreCheck: func() { testAccPreCheck(t) }, 238 Providers: testAccProviders, 239 CheckDestroy: testAccCheckComputeInstanceDestroy, 240 Steps: []resource.TestStep{ 241 resource.TestStep{ 242 Config: testAccComputeInstance_basic(instanceName), 243 Check: resource.ComposeTestCheckFunc( 244 testAccCheckComputeInstanceExists( 245 "google_compute_instance.foobar", &instance), 246 ), 247 }, 248 resource.TestStep{ 249 Config: testAccComputeInstance_update(instanceName), 250 Check: resource.ComposeTestCheckFunc( 251 testAccCheckComputeInstanceExists( 252 "google_compute_instance.foobar", &instance), 253 testAccCheckComputeInstanceMetadata( 254 &instance, "bar", "baz"), 255 testAccCheckComputeInstanceTag(&instance, "baz"), 256 testAccCheckComputeInstanceAccessConfig(&instance), 257 ), 258 }, 259 }, 260 }) 261 } 262 263 func TestAccComputeInstance_service_account(t *testing.T) { 264 var instance compute.Instance 265 var instanceName = fmt.Sprintf("instance-test-%s", acctest.RandString(10)) 266 267 resource.Test(t, resource.TestCase{ 268 PreCheck: func() { testAccPreCheck(t) }, 269 Providers: testAccProviders, 270 CheckDestroy: testAccCheckComputeInstanceDestroy, 271 Steps: []resource.TestStep{ 272 resource.TestStep{ 273 Config: testAccComputeInstance_service_account(instanceName), 274 Check: resource.ComposeTestCheckFunc( 275 testAccCheckComputeInstanceExists( 276 "google_compute_instance.foobar", &instance), 277 testAccCheckComputeInstanceServiceAccount(&instance, 278 "https://www.googleapis.com/auth/compute.readonly"), 279 testAccCheckComputeInstanceServiceAccount(&instance, 280 "https://www.googleapis.com/auth/devstorage.read_only"), 281 testAccCheckComputeInstanceServiceAccount(&instance, 282 "https://www.googleapis.com/auth/userinfo.email"), 283 ), 284 }, 285 }, 286 }) 287 } 288 289 func TestAccComputeInstance_scheduling(t *testing.T) { 290 var instance compute.Instance 291 var instanceName = fmt.Sprintf("instance-test-%s", acctest.RandString(10)) 292 293 resource.Test(t, resource.TestCase{ 294 PreCheck: func() { testAccPreCheck(t) }, 295 Providers: testAccProviders, 296 CheckDestroy: testAccCheckComputeInstanceDestroy, 297 Steps: []resource.TestStep{ 298 resource.TestStep{ 299 Config: testAccComputeInstance_scheduling(instanceName), 300 Check: resource.ComposeTestCheckFunc( 301 testAccCheckComputeInstanceExists( 302 "google_compute_instance.foobar", &instance), 303 ), 304 }, 305 }, 306 }) 307 } 308 309 func testAccCheckComputeInstanceDestroy(s *terraform.State) error { 310 config := testAccProvider.Meta().(*Config) 311 312 for _, rs := range s.RootModule().Resources { 313 if rs.Type != "google_compute_instance" { 314 continue 315 } 316 317 _, err := config.clientCompute.Instances.Get( 318 config.Project, rs.Primary.Attributes["zone"], rs.Primary.ID).Do() 319 if err == nil { 320 return fmt.Errorf("Instance still exists") 321 } 322 } 323 324 return nil 325 } 326 327 func testAccCheckComputeInstanceExists(n string, instance *compute.Instance) resource.TestCheckFunc { 328 return func(s *terraform.State) error { 329 rs, ok := s.RootModule().Resources[n] 330 if !ok { 331 return fmt.Errorf("Not found: %s", n) 332 } 333 334 if rs.Primary.ID == "" { 335 return fmt.Errorf("No ID is set") 336 } 337 338 config := testAccProvider.Meta().(*Config) 339 340 found, err := config.clientCompute.Instances.Get( 341 config.Project, rs.Primary.Attributes["zone"], rs.Primary.ID).Do() 342 if err != nil { 343 return err 344 } 345 346 if found.Name != rs.Primary.ID { 347 return fmt.Errorf("Instance not found") 348 } 349 350 *instance = *found 351 352 return nil 353 } 354 } 355 356 func testAccCheckComputeInstanceMetadata( 357 instance *compute.Instance, 358 k string, v string) resource.TestCheckFunc { 359 return func(s *terraform.State) error { 360 if instance.Metadata == nil { 361 return fmt.Errorf("no metadata") 362 } 363 364 for _, item := range instance.Metadata.Items { 365 if k != item.Key { 366 continue 367 } 368 369 if item.Value != nil && v == *item.Value { 370 return nil 371 } 372 373 return fmt.Errorf("bad value for %s: %s", k, *item.Value) 374 } 375 376 return fmt.Errorf("metadata not found: %s", k) 377 } 378 } 379 380 func testAccCheckComputeInstanceAccessConfig(instance *compute.Instance) resource.TestCheckFunc { 381 return func(s *terraform.State) error { 382 for _, i := range instance.NetworkInterfaces { 383 if len(i.AccessConfigs) == 0 { 384 return fmt.Errorf("no access_config") 385 } 386 } 387 388 return nil 389 } 390 } 391 392 func testAccCheckComputeInstanceAccessConfigHasIP(instance *compute.Instance) resource.TestCheckFunc { 393 return func(s *terraform.State) error { 394 for _, i := range instance.NetworkInterfaces { 395 for _, c := range i.AccessConfigs { 396 if c.NatIP == "" { 397 return fmt.Errorf("no NAT IP") 398 } 399 } 400 } 401 402 return nil 403 } 404 } 405 406 func testAccCheckComputeInstanceDisk(instance *compute.Instance, source string, delete bool, boot bool) resource.TestCheckFunc { 407 return func(s *terraform.State) error { 408 if instance.Disks == nil { 409 return fmt.Errorf("no disks") 410 } 411 412 for _, disk := range instance.Disks { 413 if strings.LastIndex(disk.Source, "/"+source) == len(disk.Source)-len(source)-1 && disk.AutoDelete == delete && disk.Boot == boot { 414 return nil 415 } 416 } 417 418 return fmt.Errorf("Disk not found: %s", source) 419 } 420 } 421 422 func testAccCheckComputeInstanceTag(instance *compute.Instance, n string) resource.TestCheckFunc { 423 return func(s *terraform.State) error { 424 if instance.Tags == nil { 425 return fmt.Errorf("no tags") 426 } 427 428 for _, k := range instance.Tags.Items { 429 if k == n { 430 return nil 431 } 432 } 433 434 return fmt.Errorf("tag not found: %s", n) 435 } 436 } 437 438 func testAccCheckComputeInstanceServiceAccount(instance *compute.Instance, scope string) resource.TestCheckFunc { 439 return func(s *terraform.State) error { 440 if count := len(instance.ServiceAccounts); count != 1 { 441 return fmt.Errorf("Wrong number of ServiceAccounts: expected 1, got %d", count) 442 } 443 444 for _, val := range instance.ServiceAccounts[0].Scopes { 445 if val == scope { 446 return nil 447 } 448 } 449 450 return fmt.Errorf("Scope not found: %s", scope) 451 } 452 } 453 454 func testAccComputeInstance_basic_deprecated_network(instance string) string { 455 return fmt.Sprintf(` 456 resource "google_compute_instance" "foobar" { 457 name = "%s" 458 machine_type = "n1-standard-1" 459 zone = "us-central1-a" 460 can_ip_forward = false 461 tags = ["foo", "bar"] 462 463 disk { 464 image = "debian-7-wheezy-v20140814" 465 } 466 467 network { 468 source = "default" 469 } 470 471 metadata { 472 foo = "bar" 473 } 474 }`, instance) 475 } 476 477 func testAccComputeInstance_update_deprecated_network(instance string) string { 478 return fmt.Sprintf(` 479 resource "google_compute_instance" "foobar" { 480 name = "%s" 481 machine_type = "n1-standard-1" 482 zone = "us-central1-a" 483 tags = ["baz"] 484 485 disk { 486 image = "debian-7-wheezy-v20140814" 487 } 488 489 network { 490 source = "default" 491 } 492 493 metadata { 494 bar = "baz" 495 } 496 }`, instance) 497 } 498 499 func testAccComputeInstance_basic(instance string) string { 500 return fmt.Sprintf(` 501 resource "google_compute_instance" "foobar" { 502 name = "%s" 503 machine_type = "n1-standard-1" 504 zone = "us-central1-a" 505 can_ip_forward = false 506 tags = ["foo", "bar"] 507 508 disk { 509 image = "debian-7-wheezy-v20140814" 510 } 511 512 network_interface { 513 network = "default" 514 } 515 516 metadata { 517 foo = "bar" 518 baz = "qux" 519 } 520 521 metadata_startup_script = "echo Hello" 522 }`, instance) 523 } 524 525 func testAccComputeInstance_basic2(instance string) string { 526 return fmt.Sprintf(` 527 resource "google_compute_instance" "foobar" { 528 name = "%s" 529 machine_type = "n1-standard-1" 530 zone = "us-central1-a" 531 can_ip_forward = false 532 tags = ["foo", "bar"] 533 534 disk { 535 image = "debian-cloud/debian-7-wheezy-v20140814" 536 } 537 538 network_interface { 539 network = "default" 540 } 541 542 543 metadata { 544 foo = "bar" 545 } 546 }`, instance) 547 } 548 549 func testAccComputeInstance_basic3(instance string) string { 550 return fmt.Sprintf(` 551 resource "google_compute_instance" "foobar" { 552 name = "%s" 553 machine_type = "n1-standard-1" 554 zone = "us-central1-a" 555 can_ip_forward = false 556 tags = ["foo", "bar"] 557 558 disk { 559 image = "https://www.googleapis.com/compute/v1/projects/debian-cloud/global/images/debian-7-wheezy-v20140814" 560 } 561 562 network_interface { 563 network = "default" 564 } 565 566 metadata { 567 foo = "bar" 568 } 569 }`, instance) 570 } 571 572 // Update zone to ForceNew, and change metadata k/v entirely 573 // Generates diff mismatch 574 func testAccComputeInstance_forceNewAndChangeMetadata(instance string) string { 575 return fmt.Sprintf(` 576 resource "google_compute_instance" "foobar" { 577 name = "%s" 578 machine_type = "n1-standard-1" 579 zone = "us-central1-a" 580 zone = "us-central1-b" 581 tags = ["baz"] 582 583 disk { 584 image = "debian-7-wheezy-v20140814" 585 } 586 587 network_interface { 588 network = "default" 589 access_config { } 590 } 591 592 metadata { 593 qux = "true" 594 } 595 }`, instance) 596 } 597 598 // Update metadata, tags, and network_interface 599 func testAccComputeInstance_update(instance string) string { 600 return fmt.Sprintf(` 601 resource "google_compute_instance" "foobar" { 602 name = "%s" 603 machine_type = "n1-standard-1" 604 zone = "us-central1-a" 605 tags = ["baz"] 606 607 disk { 608 image = "debian-7-wheezy-v20140814" 609 } 610 611 network_interface { 612 network = "default" 613 access_config { } 614 } 615 616 metadata { 617 bar = "baz" 618 } 619 }`, instance) 620 } 621 622 func testAccComputeInstance_ip(ip, instance string) string { 623 return fmt.Sprintf(` 624 resource "google_compute_address" "foo" { 625 name = "%s" 626 } 627 628 resource "google_compute_instance" "foobar" { 629 name = "%s" 630 machine_type = "n1-standard-1" 631 zone = "us-central1-a" 632 tags = ["foo", "bar"] 633 634 disk { 635 image = "debian-7-wheezy-v20140814" 636 } 637 638 network_interface { 639 network = "default" 640 access_config { 641 nat_ip = "${google_compute_address.foo.address}" 642 } 643 } 644 645 metadata { 646 foo = "bar" 647 } 648 }`, ip, instance) 649 } 650 651 func testAccComputeInstance_disks(disk, instance string) string { 652 return fmt.Sprintf(` 653 resource "google_compute_disk" "foobar" { 654 name = "%s" 655 size = 10 656 type = "pd-ssd" 657 zone = "us-central1-a" 658 } 659 660 resource "google_compute_instance" "foobar" { 661 name = "%s" 662 machine_type = "n1-standard-1" 663 zone = "us-central1-a" 664 665 disk { 666 image = "debian-7-wheezy-v20140814" 667 } 668 669 disk { 670 disk = "${google_compute_disk.foobar.name}" 671 auto_delete = false 672 } 673 674 network_interface { 675 network = "default" 676 } 677 678 metadata { 679 foo = "bar" 680 } 681 }`, disk, instance) 682 } 683 684 func testAccComputeInstance_local_ssd(instance string) string { 685 return fmt.Sprintf(` 686 resource "google_compute_instance" "local-ssd" { 687 name = "%s" 688 machine_type = "n1-standard-1" 689 zone = "us-central1-a" 690 691 disk { 692 image = "debian-7-wheezy-v20140814" 693 } 694 695 disk { 696 type = "local-ssd" 697 scratch = true 698 } 699 700 network_interface { 701 network = "default" 702 } 703 704 }`, instance) 705 } 706 707 func testAccComputeInstance_service_account(instance string) string { 708 return fmt.Sprintf(` 709 resource "google_compute_instance" "foobar" { 710 name = "%s" 711 machine_type = "n1-standard-1" 712 zone = "us-central1-a" 713 714 disk { 715 image = "debian-7-wheezy-v20140814" 716 } 717 718 network_interface { 719 network = "default" 720 } 721 722 service_account { 723 scopes = [ 724 "userinfo-email", 725 "compute-ro", 726 "storage-ro", 727 ] 728 } 729 }`, instance) 730 } 731 732 func testAccComputeInstance_scheduling(instance string) string { 733 return fmt.Sprintf(` 734 resource "google_compute_instance" "foobar" { 735 name = "%s" 736 machine_type = "n1-standard-1" 737 zone = "us-central1-a" 738 739 disk { 740 image = "debian-7-wheezy-v20140814" 741 } 742 743 network_interface { 744 network = "default" 745 } 746 747 scheduling { 748 } 749 }`, instance) 750 }