github.com/rhenning/terraform@v0.8.0-beta2/builtin/providers/google/resource_compute_instance_test.go (about)

     1  package google
     2  
     3  import (
     4  	"fmt"
     5  	"regexp"
     6  	"strings"
     7  	"testing"
     8  
     9  	"github.com/hashicorp/terraform/helper/acctest"
    10  	"github.com/hashicorp/terraform/helper/resource"
    11  	"github.com/hashicorp/terraform/terraform"
    12  	"google.golang.org/api/compute/v1"
    13  )
    14  
    15  func TestAccComputeInstance_basic_deprecated_network(t *testing.T) {
    16  	var instance compute.Instance
    17  	var instanceName = fmt.Sprintf("instance-test-%s", acctest.RandString(10))
    18  
    19  	resource.Test(t, resource.TestCase{
    20  		PreCheck:     func() { testAccPreCheck(t) },
    21  		Providers:    testAccProviders,
    22  		CheckDestroy: testAccCheckComputeInstanceDestroy,
    23  		Steps: []resource.TestStep{
    24  			resource.TestStep{
    25  				Config: testAccComputeInstance_basic_deprecated_network(instanceName),
    26  				Check: resource.ComposeTestCheckFunc(
    27  					testAccCheckComputeInstanceExists(
    28  						"google_compute_instance.foobar", &instance),
    29  					testAccCheckComputeInstanceTag(&instance, "foo"),
    30  					testAccCheckComputeInstanceMetadata(&instance, "foo", "bar"),
    31  					testAccCheckComputeInstanceDisk(&instance, instanceName, true, true),
    32  				),
    33  			},
    34  		},
    35  	})
    36  }
    37  
    38  func TestAccComputeInstance_basic1(t *testing.T) {
    39  	var instance compute.Instance
    40  	var instanceName = fmt.Sprintf("instance-test-%s", acctest.RandString(10))
    41  
    42  	resource.Test(t, resource.TestCase{
    43  		PreCheck:     func() { testAccPreCheck(t) },
    44  		Providers:    testAccProviders,
    45  		CheckDestroy: testAccCheckComputeInstanceDestroy,
    46  		Steps: []resource.TestStep{
    47  			resource.TestStep{
    48  				Config: testAccComputeInstance_basic(instanceName),
    49  				Check: resource.ComposeTestCheckFunc(
    50  					testAccCheckComputeInstanceExists(
    51  						"google_compute_instance.foobar", &instance),
    52  					testAccCheckComputeInstanceTag(&instance, "foo"),
    53  					testAccCheckComputeInstanceMetadata(&instance, "foo", "bar"),
    54  					testAccCheckComputeInstanceMetadata(&instance, "baz", "qux"),
    55  					testAccCheckComputeInstanceDisk(&instance, instanceName, true, true),
    56  				),
    57  			},
    58  		},
    59  	})
    60  }
    61  
    62  func TestAccComputeInstance_basic2(t *testing.T) {
    63  	var instance compute.Instance
    64  	var instanceName = fmt.Sprintf("instance-test-%s", acctest.RandString(10))
    65  
    66  	resource.Test(t, resource.TestCase{
    67  		PreCheck:     func() { testAccPreCheck(t) },
    68  		Providers:    testAccProviders,
    69  		CheckDestroy: testAccCheckComputeInstanceDestroy,
    70  		Steps: []resource.TestStep{
    71  			resource.TestStep{
    72  				Config: testAccComputeInstance_basic2(instanceName),
    73  				Check: resource.ComposeTestCheckFunc(
    74  					testAccCheckComputeInstanceExists(
    75  						"google_compute_instance.foobar", &instance),
    76  					testAccCheckComputeInstanceTag(&instance, "foo"),
    77  					testAccCheckComputeInstanceMetadata(&instance, "foo", "bar"),
    78  					testAccCheckComputeInstanceDisk(&instance, instanceName, true, true),
    79  				),
    80  			},
    81  		},
    82  	})
    83  }
    84  
    85  func TestAccComputeInstance_basic3(t *testing.T) {
    86  	var instance compute.Instance
    87  	var instanceName = fmt.Sprintf("instance-test-%s", acctest.RandString(10))
    88  
    89  	resource.Test(t, resource.TestCase{
    90  		PreCheck:     func() { testAccPreCheck(t) },
    91  		Providers:    testAccProviders,
    92  		CheckDestroy: testAccCheckComputeInstanceDestroy,
    93  		Steps: []resource.TestStep{
    94  			resource.TestStep{
    95  				Config: testAccComputeInstance_basic3(instanceName),
    96  				Check: resource.ComposeTestCheckFunc(
    97  					testAccCheckComputeInstanceExists(
    98  						"google_compute_instance.foobar", &instance),
    99  					testAccCheckComputeInstanceTag(&instance, "foo"),
   100  					testAccCheckComputeInstanceMetadata(&instance, "foo", "bar"),
   101  					testAccCheckComputeInstanceDisk(&instance, instanceName, true, true),
   102  				),
   103  			},
   104  		},
   105  	})
   106  }
   107  
   108  func TestAccComputeInstance_basic4(t *testing.T) {
   109  	var instance compute.Instance
   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_basic4(instanceName),
   119  				Check: resource.ComposeTestCheckFunc(
   120  					testAccCheckComputeInstanceExists(
   121  						"google_compute_instance.foobar", &instance),
   122  					testAccCheckComputeInstanceTag(&instance, "foo"),
   123  					testAccCheckComputeInstanceMetadata(&instance, "foo", "bar"),
   124  					testAccCheckComputeInstanceDisk(&instance, instanceName, true, true),
   125  				),
   126  			},
   127  		},
   128  	})
   129  }
   130  
   131  func TestAccComputeInstance_basic5(t *testing.T) {
   132  	var instance compute.Instance
   133  	var instanceName = fmt.Sprintf("instance-test-%s", acctest.RandString(10))
   134  
   135  	resource.Test(t, resource.TestCase{
   136  		PreCheck:     func() { testAccPreCheck(t) },
   137  		Providers:    testAccProviders,
   138  		CheckDestroy: testAccCheckComputeInstanceDestroy,
   139  		Steps: []resource.TestStep{
   140  			resource.TestStep{
   141  				Config: testAccComputeInstance_basic5(instanceName),
   142  				Check: resource.ComposeTestCheckFunc(
   143  					testAccCheckComputeInstanceExists(
   144  						"google_compute_instance.foobar", &instance),
   145  					testAccCheckComputeInstanceTag(&instance, "foo"),
   146  					testAccCheckComputeInstanceMetadata(&instance, "foo", "bar"),
   147  					testAccCheckComputeInstanceDisk(&instance, instanceName, true, true),
   148  				),
   149  			},
   150  		},
   151  	})
   152  }
   153  
   154  func TestAccComputeInstance_IP(t *testing.T) {
   155  	var instance compute.Instance
   156  	var ipName = fmt.Sprintf("instance-test-%s", acctest.RandString(10))
   157  	var instanceName = fmt.Sprintf("instance-test-%s", acctest.RandString(10))
   158  
   159  	resource.Test(t, resource.TestCase{
   160  		PreCheck:     func() { testAccPreCheck(t) },
   161  		Providers:    testAccProviders,
   162  		CheckDestroy: testAccCheckComputeInstanceDestroy,
   163  		Steps: []resource.TestStep{
   164  			resource.TestStep{
   165  				Config: testAccComputeInstance_ip(ipName, instanceName),
   166  				Check: resource.ComposeTestCheckFunc(
   167  					testAccCheckComputeInstanceExists(
   168  						"google_compute_instance.foobar", &instance),
   169  					testAccCheckComputeInstanceAccessConfigHasIP(&instance),
   170  				),
   171  			},
   172  		},
   173  	})
   174  }
   175  
   176  func TestAccComputeInstance_disksWithoutAutodelete(t *testing.T) {
   177  	var instance compute.Instance
   178  	var instanceName = fmt.Sprintf("instance-test-%s", acctest.RandString(10))
   179  	var diskName = fmt.Sprintf("instance-testd-%s", acctest.RandString(10))
   180  
   181  	resource.Test(t, resource.TestCase{
   182  		PreCheck:     func() { testAccPreCheck(t) },
   183  		Providers:    testAccProviders,
   184  		CheckDestroy: testAccCheckComputeInstanceDestroy,
   185  		Steps: []resource.TestStep{
   186  			resource.TestStep{
   187  				Config: testAccComputeInstance_disks(diskName, instanceName, false),
   188  				Check: resource.ComposeTestCheckFunc(
   189  					testAccCheckComputeInstanceExists(
   190  						"google_compute_instance.foobar", &instance),
   191  					testAccCheckComputeInstanceDisk(&instance, instanceName, true, true),
   192  					testAccCheckComputeInstanceDisk(&instance, diskName, false, false),
   193  				),
   194  			},
   195  		},
   196  	})
   197  }
   198  
   199  func TestAccComputeInstance_disksWithAutodelete(t *testing.T) {
   200  	var instance compute.Instance
   201  	var instanceName = fmt.Sprintf("instance-test-%s", acctest.RandString(10))
   202  	var diskName = fmt.Sprintf("instance-testd-%s", acctest.RandString(10))
   203  
   204  	resource.Test(t, resource.TestCase{
   205  		PreCheck:     func() { testAccPreCheck(t) },
   206  		Providers:    testAccProviders,
   207  		CheckDestroy: testAccCheckComputeInstanceDestroy,
   208  		Steps: []resource.TestStep{
   209  			resource.TestStep{
   210  				Config: testAccComputeInstance_disks(diskName, instanceName, true),
   211  				Check: resource.ComposeTestCheckFunc(
   212  					testAccCheckComputeInstanceExists(
   213  						"google_compute_instance.foobar", &instance),
   214  					testAccCheckComputeInstanceDisk(&instance, instanceName, true, true),
   215  					testAccCheckComputeInstanceDisk(&instance, diskName, true, false),
   216  				),
   217  			},
   218  		},
   219  	})
   220  }
   221  
   222  func TestAccComputeInstance_local_ssd(t *testing.T) {
   223  	var instance compute.Instance
   224  	var instanceName = fmt.Sprintf("instance-test-%s", acctest.RandString(10))
   225  
   226  	resource.Test(t, resource.TestCase{
   227  		PreCheck:     func() { testAccPreCheck(t) },
   228  		Providers:    testAccProviders,
   229  		CheckDestroy: testAccCheckComputeInstanceDestroy,
   230  		Steps: []resource.TestStep{
   231  			resource.TestStep{
   232  				Config: testAccComputeInstance_local_ssd(instanceName),
   233  				Check: resource.ComposeTestCheckFunc(
   234  					testAccCheckComputeInstanceExists(
   235  						"google_compute_instance.local-ssd", &instance),
   236  					testAccCheckComputeInstanceDisk(&instance, instanceName, true, true),
   237  				),
   238  			},
   239  		},
   240  	})
   241  }
   242  
   243  func TestAccComputeInstance_update_deprecated_network(t *testing.T) {
   244  	var instance compute.Instance
   245  	var instanceName = fmt.Sprintf("instance-test-%s", acctest.RandString(10))
   246  
   247  	resource.Test(t, resource.TestCase{
   248  		PreCheck:     func() { testAccPreCheck(t) },
   249  		Providers:    testAccProviders,
   250  		CheckDestroy: testAccCheckComputeInstanceDestroy,
   251  		Steps: []resource.TestStep{
   252  			resource.TestStep{
   253  				Config: testAccComputeInstance_basic_deprecated_network(instanceName),
   254  				Check: resource.ComposeTestCheckFunc(
   255  					testAccCheckComputeInstanceExists(
   256  						"google_compute_instance.foobar", &instance),
   257  				),
   258  			},
   259  			resource.TestStep{
   260  				Config: testAccComputeInstance_update_deprecated_network(instanceName),
   261  				Check: resource.ComposeTestCheckFunc(
   262  					testAccCheckComputeInstanceExists(
   263  						"google_compute_instance.foobar", &instance),
   264  					testAccCheckComputeInstanceMetadata(
   265  						&instance, "bar", "baz"),
   266  					testAccCheckComputeInstanceTag(&instance, "baz"),
   267  				),
   268  			},
   269  		},
   270  	})
   271  }
   272  
   273  func TestAccComputeInstance_forceNewAndChangeMetadata(t *testing.T) {
   274  	var instance compute.Instance
   275  	var instanceName = fmt.Sprintf("instance-test-%s", acctest.RandString(10))
   276  
   277  	resource.Test(t, resource.TestCase{
   278  		PreCheck:     func() { testAccPreCheck(t) },
   279  		Providers:    testAccProviders,
   280  		CheckDestroy: testAccCheckComputeInstanceDestroy,
   281  		Steps: []resource.TestStep{
   282  			resource.TestStep{
   283  				Config: testAccComputeInstance_basic(instanceName),
   284  				Check: resource.ComposeTestCheckFunc(
   285  					testAccCheckComputeInstanceExists(
   286  						"google_compute_instance.foobar", &instance),
   287  				),
   288  			},
   289  			resource.TestStep{
   290  				Config: testAccComputeInstance_forceNewAndChangeMetadata(instanceName),
   291  				Check: resource.ComposeTestCheckFunc(
   292  					testAccCheckComputeInstanceExists(
   293  						"google_compute_instance.foobar", &instance),
   294  					testAccCheckComputeInstanceMetadata(
   295  						&instance, "qux", "true"),
   296  				),
   297  			},
   298  		},
   299  	})
   300  }
   301  
   302  func TestAccComputeInstance_update(t *testing.T) {
   303  	var instance compute.Instance
   304  	var instanceName = fmt.Sprintf("instance-test-%s", acctest.RandString(10))
   305  
   306  	resource.Test(t, resource.TestCase{
   307  		PreCheck:     func() { testAccPreCheck(t) },
   308  		Providers:    testAccProviders,
   309  		CheckDestroy: testAccCheckComputeInstanceDestroy,
   310  		Steps: []resource.TestStep{
   311  			resource.TestStep{
   312  				Config: testAccComputeInstance_basic(instanceName),
   313  				Check: resource.ComposeTestCheckFunc(
   314  					testAccCheckComputeInstanceExists(
   315  						"google_compute_instance.foobar", &instance),
   316  				),
   317  			},
   318  			resource.TestStep{
   319  				Config: testAccComputeInstance_update(instanceName),
   320  				Check: resource.ComposeTestCheckFunc(
   321  					testAccCheckComputeInstanceExists(
   322  						"google_compute_instance.foobar", &instance),
   323  					testAccCheckComputeInstanceMetadata(
   324  						&instance, "bar", "baz"),
   325  					testAccCheckComputeInstanceTag(&instance, "baz"),
   326  					testAccCheckComputeInstanceAccessConfig(&instance),
   327  				),
   328  			},
   329  		},
   330  	})
   331  }
   332  
   333  func TestAccComputeInstance_service_account(t *testing.T) {
   334  	var instance compute.Instance
   335  	var instanceName = fmt.Sprintf("instance-test-%s", acctest.RandString(10))
   336  
   337  	resource.Test(t, resource.TestCase{
   338  		PreCheck:     func() { testAccPreCheck(t) },
   339  		Providers:    testAccProviders,
   340  		CheckDestroy: testAccCheckComputeInstanceDestroy,
   341  		Steps: []resource.TestStep{
   342  			resource.TestStep{
   343  				Config: testAccComputeInstance_service_account(instanceName),
   344  				Check: resource.ComposeTestCheckFunc(
   345  					testAccCheckComputeInstanceExists(
   346  						"google_compute_instance.foobar", &instance),
   347  					testAccCheckComputeInstanceServiceAccount(&instance,
   348  						"https://www.googleapis.com/auth/compute.readonly"),
   349  					testAccCheckComputeInstanceServiceAccount(&instance,
   350  						"https://www.googleapis.com/auth/devstorage.read_only"),
   351  					testAccCheckComputeInstanceServiceAccount(&instance,
   352  						"https://www.googleapis.com/auth/userinfo.email"),
   353  				),
   354  			},
   355  		},
   356  	})
   357  }
   358  
   359  func TestAccComputeInstance_scheduling(t *testing.T) {
   360  	var instance compute.Instance
   361  	var instanceName = fmt.Sprintf("instance-test-%s", acctest.RandString(10))
   362  
   363  	resource.Test(t, resource.TestCase{
   364  		PreCheck:     func() { testAccPreCheck(t) },
   365  		Providers:    testAccProviders,
   366  		CheckDestroy: testAccCheckComputeInstanceDestroy,
   367  		Steps: []resource.TestStep{
   368  			resource.TestStep{
   369  				Config: testAccComputeInstance_scheduling(instanceName),
   370  				Check: resource.ComposeTestCheckFunc(
   371  					testAccCheckComputeInstanceExists(
   372  						"google_compute_instance.foobar", &instance),
   373  				),
   374  			},
   375  		},
   376  	})
   377  }
   378  
   379  func TestAccComputeInstance_subnet_auto(t *testing.T) {
   380  	var instance compute.Instance
   381  	var instanceName = fmt.Sprintf("instance-test-%s", acctest.RandString(10))
   382  
   383  	resource.Test(t, resource.TestCase{
   384  		PreCheck:     func() { testAccPreCheck(t) },
   385  		Providers:    testAccProviders,
   386  		CheckDestroy: testAccCheckComputeInstanceDestroy,
   387  		Steps: []resource.TestStep{
   388  			resource.TestStep{
   389  				Config: testAccComputeInstance_subnet_auto(instanceName),
   390  				Check: resource.ComposeTestCheckFunc(
   391  					testAccCheckComputeInstanceExists(
   392  						"google_compute_instance.foobar", &instance),
   393  					testAccCheckComputeInstanceHasSubnet(&instance),
   394  				),
   395  			},
   396  		},
   397  	})
   398  }
   399  
   400  func TestAccComputeInstance_subnet_custom(t *testing.T) {
   401  	var instance compute.Instance
   402  	var instanceName = fmt.Sprintf("instance-test-%s", acctest.RandString(10))
   403  
   404  	resource.Test(t, resource.TestCase{
   405  		PreCheck:     func() { testAccPreCheck(t) },
   406  		Providers:    testAccProviders,
   407  		CheckDestroy: testAccCheckComputeInstanceDestroy,
   408  		Steps: []resource.TestStep{
   409  			resource.TestStep{
   410  				Config: testAccComputeInstance_subnet_custom(instanceName),
   411  				Check: resource.ComposeTestCheckFunc(
   412  					testAccCheckComputeInstanceExists(
   413  						"google_compute_instance.foobar", &instance),
   414  					testAccCheckComputeInstanceHasSubnet(&instance),
   415  				),
   416  			},
   417  		},
   418  	})
   419  }
   420  
   421  func TestAccComputeInstance_address_auto(t *testing.T) {
   422  	var instance compute.Instance
   423  	var instanceName = fmt.Sprintf("instance-test-%s", acctest.RandString(10))
   424  
   425  	resource.Test(t, resource.TestCase{
   426  		PreCheck:     func() { testAccPreCheck(t) },
   427  		Providers:    testAccProviders,
   428  		CheckDestroy: testAccCheckComputeInstanceDestroy,
   429  		Steps: []resource.TestStep{
   430  			resource.TestStep{
   431  				Config: testAccComputeInstance_address_auto(instanceName),
   432  				Check: resource.ComposeTestCheckFunc(
   433  					testAccCheckComputeInstanceExists(
   434  						"google_compute_instance.foobar", &instance),
   435  					testAccCheckComputeInstanceHasAnyAddress(&instance),
   436  				),
   437  			},
   438  		},
   439  	})
   440  }
   441  
   442  func TestAccComputeInstance_address_custom(t *testing.T) {
   443  	var instance compute.Instance
   444  	var instanceName = fmt.Sprintf("instance-test-%s", acctest.RandString(10))
   445  	var address = "10.0.200.200"
   446  	resource.Test(t, resource.TestCase{
   447  		PreCheck:     func() { testAccPreCheck(t) },
   448  		Providers:    testAccProviders,
   449  		CheckDestroy: testAccCheckComputeInstanceDestroy,
   450  		Steps: []resource.TestStep{
   451  			resource.TestStep{
   452  				Config: testAccComputeInstance_address_custom(instanceName, address),
   453  				Check: resource.ComposeTestCheckFunc(
   454  					testAccCheckComputeInstanceExists(
   455  						"google_compute_instance.foobar", &instance),
   456  					testAccCheckComputeInstanceHasAddress(&instance, address),
   457  				),
   458  			},
   459  		},
   460  	})
   461  }
   462  
   463  func TestAccComputeInstance_private_image_family(t *testing.T) {
   464  	var instance compute.Instance
   465  	var instanceName = fmt.Sprintf("instance-test-%s", acctest.RandString(10))
   466  	var diskName = fmt.Sprintf("instance-testd-%s", acctest.RandString(10))
   467  	var imageName = fmt.Sprintf("instance-testi-%s", acctest.RandString(10))
   468  	var familyName = fmt.Sprintf("instance-testf-%s", acctest.RandString(10))
   469  
   470  	resource.Test(t, resource.TestCase{
   471  		PreCheck:     func() { testAccPreCheck(t) },
   472  		Providers:    testAccProviders,
   473  		CheckDestroy: testAccCheckComputeInstanceDestroy,
   474  		Steps: []resource.TestStep{
   475  			resource.TestStep{
   476  				Config: testAccComputeInstance_private_image_family(diskName, imageName, familyName, instanceName),
   477  				Check: resource.ComposeTestCheckFunc(
   478  					testAccCheckComputeInstanceExists(
   479  						"google_compute_instance.foobar", &instance),
   480  				),
   481  			},
   482  		},
   483  	})
   484  }
   485  
   486  func TestAccComputeInstance_invalid_disk(t *testing.T) {
   487  	var instanceName = fmt.Sprintf("instance-test-%s", acctest.RandString(10))
   488  	var diskName = fmt.Sprintf("instance-testd-%s", acctest.RandString(10))
   489  
   490  	resource.Test(t, resource.TestCase{
   491  		PreCheck:     func() { testAccPreCheck(t) },
   492  		Providers:    testAccProviders,
   493  		CheckDestroy: testAccCheckComputeInstanceDestroy,
   494  		Steps: []resource.TestStep{
   495  			resource.TestStep{
   496  				Config:      testAccComputeInstance_invalid_disk(diskName, instanceName),
   497  				ExpectError: regexp.MustCompile("Error: cannot define both disk and type."),
   498  			},
   499  		},
   500  	})
   501  }
   502  
   503  func testAccCheckComputeInstanceDestroy(s *terraform.State) error {
   504  	config := testAccProvider.Meta().(*Config)
   505  
   506  	for _, rs := range s.RootModule().Resources {
   507  		if rs.Type != "google_compute_instance" {
   508  			continue
   509  		}
   510  
   511  		_, err := config.clientCompute.Instances.Get(
   512  			config.Project, rs.Primary.Attributes["zone"], rs.Primary.ID).Do()
   513  		if err == nil {
   514  			return fmt.Errorf("Instance still exists")
   515  		}
   516  	}
   517  
   518  	return nil
   519  }
   520  
   521  func testAccCheckComputeInstanceExists(n string, instance *compute.Instance) resource.TestCheckFunc {
   522  	return func(s *terraform.State) error {
   523  		rs, ok := s.RootModule().Resources[n]
   524  		if !ok {
   525  			return fmt.Errorf("Not found: %s", n)
   526  		}
   527  
   528  		if rs.Primary.ID == "" {
   529  			return fmt.Errorf("No ID is set")
   530  		}
   531  
   532  		config := testAccProvider.Meta().(*Config)
   533  
   534  		found, err := config.clientCompute.Instances.Get(
   535  			config.Project, rs.Primary.Attributes["zone"], rs.Primary.ID).Do()
   536  		if err != nil {
   537  			return err
   538  		}
   539  
   540  		if found.Name != rs.Primary.ID {
   541  			return fmt.Errorf("Instance not found")
   542  		}
   543  
   544  		*instance = *found
   545  
   546  		return nil
   547  	}
   548  }
   549  
   550  func testAccCheckComputeInstanceMetadata(
   551  	instance *compute.Instance,
   552  	k string, v string) resource.TestCheckFunc {
   553  	return func(s *terraform.State) error {
   554  		if instance.Metadata == nil {
   555  			return fmt.Errorf("no metadata")
   556  		}
   557  
   558  		for _, item := range instance.Metadata.Items {
   559  			if k != item.Key {
   560  				continue
   561  			}
   562  
   563  			if item.Value != nil && v == *item.Value {
   564  				return nil
   565  			}
   566  
   567  			return fmt.Errorf("bad value for %s: %s", k, *item.Value)
   568  		}
   569  
   570  		return fmt.Errorf("metadata not found: %s", k)
   571  	}
   572  }
   573  
   574  func testAccCheckComputeInstanceAccessConfig(instance *compute.Instance) resource.TestCheckFunc {
   575  	return func(s *terraform.State) error {
   576  		for _, i := range instance.NetworkInterfaces {
   577  			if len(i.AccessConfigs) == 0 {
   578  				return fmt.Errorf("no access_config")
   579  			}
   580  		}
   581  
   582  		return nil
   583  	}
   584  }
   585  
   586  func testAccCheckComputeInstanceAccessConfigHasIP(instance *compute.Instance) resource.TestCheckFunc {
   587  	return func(s *terraform.State) error {
   588  		for _, i := range instance.NetworkInterfaces {
   589  			for _, c := range i.AccessConfigs {
   590  				if c.NatIP == "" {
   591  					return fmt.Errorf("no NAT IP")
   592  				}
   593  			}
   594  		}
   595  
   596  		return nil
   597  	}
   598  }
   599  
   600  func testAccCheckComputeInstanceDisk(instance *compute.Instance, source string, delete bool, boot bool) resource.TestCheckFunc {
   601  	return func(s *terraform.State) error {
   602  		if instance.Disks == nil {
   603  			return fmt.Errorf("no disks")
   604  		}
   605  
   606  		for _, disk := range instance.Disks {
   607  			if strings.LastIndex(disk.Source, "/"+source) == len(disk.Source)-len(source)-1 && disk.AutoDelete == delete && disk.Boot == boot {
   608  				return nil
   609  			}
   610  		}
   611  
   612  		return fmt.Errorf("Disk not found: %s", source)
   613  	}
   614  }
   615  
   616  func testAccCheckComputeInstanceTag(instance *compute.Instance, n string) resource.TestCheckFunc {
   617  	return func(s *terraform.State) error {
   618  		if instance.Tags == nil {
   619  			return fmt.Errorf("no tags")
   620  		}
   621  
   622  		for _, k := range instance.Tags.Items {
   623  			if k == n {
   624  				return nil
   625  			}
   626  		}
   627  
   628  		return fmt.Errorf("tag not found: %s", n)
   629  	}
   630  }
   631  
   632  func testAccCheckComputeInstanceServiceAccount(instance *compute.Instance, scope string) resource.TestCheckFunc {
   633  	return func(s *terraform.State) error {
   634  		if count := len(instance.ServiceAccounts); count != 1 {
   635  			return fmt.Errorf("Wrong number of ServiceAccounts: expected 1, got %d", count)
   636  		}
   637  
   638  		for _, val := range instance.ServiceAccounts[0].Scopes {
   639  			if val == scope {
   640  				return nil
   641  			}
   642  		}
   643  
   644  		return fmt.Errorf("Scope not found: %s", scope)
   645  	}
   646  }
   647  
   648  func testAccCheckComputeInstanceHasSubnet(instance *compute.Instance) resource.TestCheckFunc {
   649  	return func(s *terraform.State) error {
   650  		for _, i := range instance.NetworkInterfaces {
   651  			if i.Subnetwork == "" {
   652  				return fmt.Errorf("no subnet")
   653  			}
   654  		}
   655  
   656  		return nil
   657  	}
   658  }
   659  
   660  func testAccCheckComputeInstanceHasAnyAddress(instance *compute.Instance) resource.TestCheckFunc {
   661  	return func(s *terraform.State) error {
   662  		for _, i := range instance.NetworkInterfaces {
   663  			if i.NetworkIP == "" {
   664  				return fmt.Errorf("no address")
   665  			}
   666  		}
   667  
   668  		return nil
   669  	}
   670  }
   671  
   672  func testAccCheckComputeInstanceHasAddress(instance *compute.Instance, address string) resource.TestCheckFunc {
   673  	return func(s *terraform.State) error {
   674  		for _, i := range instance.NetworkInterfaces {
   675  			if i.NetworkIP != address {
   676  				return fmt.Errorf("Wrong address found: expected %v, got %v", address, i.NetworkIP)
   677  			}
   678  		}
   679  
   680  		return nil
   681  	}
   682  }
   683  
   684  func testAccComputeInstance_basic_deprecated_network(instance string) string {
   685  	return fmt.Sprintf(`
   686  	resource "google_compute_instance" "foobar" {
   687  		name = "%s"
   688  		machine_type = "n1-standard-1"
   689  		zone = "us-central1-a"
   690  		can_ip_forward = false
   691  		tags = ["foo", "bar"]
   692  
   693  		disk {
   694  			image = "debian-8-jessie-v20160803"
   695  		}
   696  
   697  		network {
   698  			source = "default"
   699  		}
   700  
   701  		metadata {
   702  			foo = "bar"
   703  		}
   704  	}`, instance)
   705  }
   706  
   707  func testAccComputeInstance_update_deprecated_network(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  		tags = ["baz"]
   714  
   715  		disk {
   716  			image = "debian-8-jessie-v20160803"
   717  		}
   718  
   719  		network {
   720  			source = "default"
   721  		}
   722  
   723  		metadata {
   724  			bar = "baz"
   725  		}
   726  	}`, instance)
   727  }
   728  
   729  func testAccComputeInstance_basic(instance string) string {
   730  	return fmt.Sprintf(`
   731  	resource "google_compute_instance" "foobar" {
   732  		name = "%s"
   733  		machine_type = "n1-standard-1"
   734  		zone = "us-central1-a"
   735  		can_ip_forward = false
   736  		tags = ["foo", "bar"]
   737  
   738  		disk {
   739  			image = "debian-8-jessie-v20160803"
   740  		}
   741  
   742  		network_interface {
   743  			network = "default"
   744  		}
   745  
   746  		metadata {
   747  			foo = "bar"
   748  			baz = "qux"
   749  		}
   750  
   751  		metadata_startup_script = "echo Hello"
   752  	}`, instance)
   753  }
   754  
   755  func testAccComputeInstance_basic2(instance string) string {
   756  	return fmt.Sprintf(`
   757  	resource "google_compute_instance" "foobar" {
   758  		name = "%s"
   759  		machine_type = "n1-standard-1"
   760  		zone = "us-central1-a"
   761  		can_ip_forward = false
   762  		tags = ["foo", "bar"]
   763  
   764  		disk {
   765  			image = "debian-8"
   766  		}
   767  
   768  		network_interface {
   769  			network = "default"
   770  		}
   771  
   772  		metadata {
   773  			foo = "bar"
   774  		}
   775  	}`, instance)
   776  }
   777  
   778  func testAccComputeInstance_basic3(instance string) string {
   779  	return fmt.Sprintf(`
   780  	resource "google_compute_instance" "foobar" {
   781  		name = "%s"
   782  		machine_type = "n1-standard-1"
   783  		zone = "us-central1-a"
   784  		can_ip_forward = false
   785  		tags = ["foo", "bar"]
   786  
   787  		disk {
   788  			image = "debian-cloud/debian-8-jessie-v20160803"
   789  		}
   790  
   791  		network_interface {
   792  			network = "default"
   793  		}
   794  
   795  
   796  		metadata {
   797  			foo = "bar"
   798  		}
   799  	}`, instance)
   800  }
   801  
   802  func testAccComputeInstance_basic4(instance string) string {
   803  	return fmt.Sprintf(`
   804  	resource "google_compute_instance" "foobar" {
   805  		name = "%s"
   806  		machine_type = "n1-standard-1"
   807  		zone = "us-central1-a"
   808  		can_ip_forward = false
   809  		tags = ["foo", "bar"]
   810  
   811  		disk {
   812  			image = "debian-cloud/debian-8"
   813  		}
   814  
   815  		network_interface {
   816  			network = "default"
   817  		}
   818  
   819  
   820  		metadata {
   821  			foo = "bar"
   822  		}
   823  	}`, instance)
   824  }
   825  
   826  func testAccComputeInstance_basic5(instance string) string {
   827  	return fmt.Sprintf(`
   828  	resource "google_compute_instance" "foobar" {
   829  		name = "%s"
   830  		machine_type = "n1-standard-1"
   831  		zone = "us-central1-a"
   832  		can_ip_forward = false
   833  		tags = ["foo", "bar"]
   834  
   835  		disk {
   836  			image = "https://www.googleapis.com/compute/v1/projects/debian-cloud/global/images/debian-8-jessie-v20160803"
   837  		}
   838  
   839  		network_interface {
   840  			network = "default"
   841  		}
   842  
   843  		metadata {
   844  			foo = "bar"
   845  		}
   846  	}`, instance)
   847  }
   848  
   849  // Update zone to ForceNew, and change metadata k/v entirely
   850  // Generates diff mismatch
   851  func testAccComputeInstance_forceNewAndChangeMetadata(instance string) string {
   852  	return fmt.Sprintf(`
   853  	resource "google_compute_instance" "foobar" {
   854  		name = "%s"
   855  		machine_type = "n1-standard-1"
   856  		zone = "us-central1-a"
   857  		zone = "us-central1-b"
   858  		tags = ["baz"]
   859  
   860  		disk {
   861  			image = "debian-8-jessie-v20160803"
   862  		}
   863  
   864  		network_interface {
   865  			network = "default"
   866  			access_config { }
   867  		}
   868  
   869  		metadata {
   870  			qux = "true"
   871  		}
   872  	}`, instance)
   873  }
   874  
   875  // Update metadata, tags, and network_interface
   876  func testAccComputeInstance_update(instance string) string {
   877  	return fmt.Sprintf(`
   878  	resource "google_compute_instance" "foobar" {
   879  		name = "%s"
   880  		machine_type = "n1-standard-1"
   881  		zone = "us-central1-a"
   882  		tags = ["baz"]
   883  
   884  		disk {
   885  			image = "debian-8-jessie-v20160803"
   886  		}
   887  
   888  		network_interface {
   889  			network = "default"
   890  			access_config { }
   891  		}
   892  
   893  		metadata {
   894  			bar = "baz"
   895  		}
   896  	}`, instance)
   897  }
   898  
   899  func testAccComputeInstance_ip(ip, instance string) string {
   900  	return fmt.Sprintf(`
   901  	resource "google_compute_address" "foo" {
   902  		name = "%s"
   903  	}
   904  
   905  	resource "google_compute_instance" "foobar" {
   906  		name = "%s"
   907  		machine_type = "n1-standard-1"
   908  		zone = "us-central1-a"
   909  		tags = ["foo", "bar"]
   910  
   911  		disk {
   912  			image = "debian-8-jessie-v20160803"
   913  		}
   914  
   915  		network_interface {
   916  			network = "default"
   917  			access_config {
   918  				nat_ip = "${google_compute_address.foo.address}"
   919  			}
   920  		}
   921  
   922  		metadata {
   923  			foo = "bar"
   924  		}
   925  	}`, ip, instance)
   926  }
   927  
   928  func testAccComputeInstance_disks(disk, instance string, autodelete bool) string {
   929  	return fmt.Sprintf(`
   930  	resource "google_compute_disk" "foobar" {
   931  		name = "%s"
   932  		size = 10
   933  		type = "pd-ssd"
   934  		zone = "us-central1-a"
   935  	}
   936  
   937  	resource "google_compute_instance" "foobar" {
   938  		name = "%s"
   939  		machine_type = "n1-standard-1"
   940  		zone = "us-central1-a"
   941  
   942  		disk {
   943  			image = "debian-8-jessie-v20160803"
   944  		}
   945  
   946  		disk {
   947  			disk = "${google_compute_disk.foobar.name}"
   948  			auto_delete = %v
   949  		}
   950  
   951  		network_interface {
   952  			network = "default"
   953  		}
   954  
   955  		metadata {
   956  			foo = "bar"
   957  		}
   958  	}`, disk, instance, autodelete)
   959  }
   960  
   961  func testAccComputeInstance_local_ssd(instance string) string {
   962  	return fmt.Sprintf(`
   963  	resource "google_compute_instance" "local-ssd" {
   964  		name = "%s"
   965  		machine_type = "n1-standard-1"
   966  		zone = "us-central1-a"
   967  
   968  		disk {
   969  			image = "debian-8-jessie-v20160803"
   970  		}
   971  
   972  		disk {
   973  			type = "local-ssd"
   974  			scratch = true
   975  		}
   976  
   977  		network_interface {
   978  			network = "default"
   979  		}
   980  
   981  	}`, instance)
   982  }
   983  
   984  func testAccComputeInstance_service_account(instance string) string {
   985  	return fmt.Sprintf(`
   986  	resource "google_compute_instance" "foobar" {
   987  		name = "%s"
   988  		machine_type = "n1-standard-1"
   989  		zone = "us-central1-a"
   990  
   991  		disk {
   992  			image = "debian-8-jessie-v20160803"
   993  		}
   994  
   995  		network_interface {
   996  			network = "default"
   997  		}
   998  
   999  		service_account {
  1000  			scopes = [
  1001  				"userinfo-email",
  1002  				"compute-ro",
  1003  				"storage-ro",
  1004  			]
  1005  		}
  1006  	}`, instance)
  1007  }
  1008  
  1009  func testAccComputeInstance_scheduling(instance string) string {
  1010  	return fmt.Sprintf(`
  1011  	resource "google_compute_instance" "foobar" {
  1012  		name = "%s"
  1013  		machine_type = "n1-standard-1"
  1014  		zone = "us-central1-a"
  1015  
  1016  		disk {
  1017  			image = "debian-8-jessie-v20160803"
  1018  		}
  1019  
  1020  		network_interface {
  1021  			network = "default"
  1022  		}
  1023  
  1024  		scheduling {
  1025  		}
  1026  	}`, instance)
  1027  }
  1028  
  1029  func testAccComputeInstance_subnet_auto(instance string) string {
  1030  	return fmt.Sprintf(`
  1031  	resource "google_compute_network" "inst-test-network" {
  1032  		name = "inst-test-network-%s"
  1033  		auto_create_subnetworks = true
  1034  	}
  1035  
  1036  	resource "google_compute_instance" "foobar" {
  1037  		name = "%s"
  1038  		machine_type = "n1-standard-1"
  1039  		zone = "us-central1-a"
  1040  
  1041  		disk {
  1042  			image = "debian-8-jessie-v20160803"
  1043  		}
  1044  
  1045  		network_interface {
  1046  			network = "${google_compute_network.inst-test-network.name}"
  1047  			access_config {	}
  1048  		}
  1049  
  1050  	}`, acctest.RandString(10), instance)
  1051  }
  1052  
  1053  func testAccComputeInstance_subnet_custom(instance string) string {
  1054  	return fmt.Sprintf(`
  1055  	resource "google_compute_network" "inst-test-network" {
  1056  		name = "inst-test-network-%s"
  1057  		auto_create_subnetworks = false
  1058  	}
  1059  
  1060  	resource "google_compute_subnetwork" "inst-test-subnetwork" {
  1061  		name = "inst-test-subnetwork-%s"
  1062  		ip_cidr_range = "10.0.0.0/16"
  1063  		region = "us-central1"
  1064  		network = "${google_compute_network.inst-test-network.self_link}"
  1065  	}
  1066  
  1067  	resource "google_compute_instance" "foobar" {
  1068  		name = "%s"
  1069  		machine_type = "n1-standard-1"
  1070  		zone = "us-central1-a"
  1071  
  1072  		disk {
  1073  			image = "debian-8-jessie-v20160803"
  1074  		}
  1075  
  1076  		network_interface {
  1077  			subnetwork = "${google_compute_subnetwork.inst-test-subnetwork.name}"
  1078  			access_config {	}
  1079  		}
  1080  
  1081  	}`, acctest.RandString(10), acctest.RandString(10), instance)
  1082  }
  1083  
  1084  func testAccComputeInstance_address_auto(instance string) string {
  1085  	return fmt.Sprintf(`
  1086  	resource "google_compute_network" "inst-test-network" {
  1087  		name = "inst-test-network-%s"
  1088  	}
  1089  	resource "google_compute_subnetwork" "inst-test-subnetwork" {
  1090  		name = "inst-test-subnetwork-%s"
  1091  		ip_cidr_range = "10.0.0.0/16"
  1092  		region = "us-central1"
  1093  		network = "${google_compute_network.inst-test-network.self_link}"
  1094  	}
  1095  	resource "google_compute_instance" "foobar" {
  1096  		name = "%s"
  1097  		machine_type = "n1-standard-1"
  1098  		zone = "us-central1-a"
  1099  
  1100  		disk {
  1101  			image = "debian-8-jessie-v20160803"
  1102  		}
  1103  
  1104  		network_interface {
  1105  			subnetwork = "${google_compute_subnetwork.inst-test-subnetwork.name}"
  1106  			access_config {	}
  1107  		}
  1108  
  1109  	}`, acctest.RandString(10), acctest.RandString(10), instance)
  1110  }
  1111  
  1112  func testAccComputeInstance_address_custom(instance, address string) string {
  1113  	return fmt.Sprintf(`
  1114  	resource "google_compute_network" "inst-test-network" {
  1115  		name = "inst-test-network-%s"
  1116  	}
  1117  	resource "google_compute_subnetwork" "inst-test-subnetwork" {
  1118  		name = "inst-test-subnetwork-%s"
  1119  		ip_cidr_range = "10.0.0.0/16"
  1120  		region = "us-central1"
  1121  		network = "${google_compute_network.inst-test-network.self_link}"
  1122  	}
  1123  	resource "google_compute_instance" "foobar" {
  1124  		name = "%s"
  1125  		machine_type = "n1-standard-1"
  1126  		zone = "us-central1-a"
  1127  
  1128  		disk {
  1129  			image = "debian-8-jessie-v20160803"
  1130  		}
  1131  
  1132  		network_interface {
  1133  			subnetwork = "${google_compute_subnetwork.inst-test-subnetwork.name}"
  1134  		    address = "%s"
  1135  			access_config {	}
  1136  		}
  1137  
  1138  	}`, acctest.RandString(10), acctest.RandString(10), instance, address)
  1139  }
  1140  
  1141  func testAccComputeInstance_private_image_family(disk, image, family, instance string) string {
  1142  	return fmt.Sprintf(`
  1143  		resource "google_compute_disk" "foobar" {
  1144  			name = "%s"
  1145  			zone = "us-central1-a"
  1146  			image = "debian-8-jessie-v20160803"
  1147  		}
  1148  
  1149  		resource "google_compute_image" "foobar" {
  1150  			name = "%s"
  1151  			source_disk = "${google_compute_disk.foobar.self_link}"
  1152  			family = "%s"
  1153  		}
  1154  
  1155  		resource "google_compute_instance" "foobar" {
  1156  			name = "%s"
  1157  			machine_type = "n1-standard-1"
  1158  			zone = "us-central1-a"
  1159  
  1160  			disk {
  1161  				image = "${google_compute_image.foobar.family}"
  1162  			}
  1163  
  1164  			network_interface {
  1165  				network = "default"
  1166  			}
  1167  
  1168  			metadata {
  1169  				foo = "bar"
  1170  			}
  1171  		}`, disk, image, family, instance)
  1172  }
  1173  
  1174  func testAccComputeInstance_invalid_disk(disk, instance string) string {
  1175  	return fmt.Sprintf(`
  1176  		resource "google_compute_instance" "foobar" {
  1177  		  name         = "%s"
  1178  		  machine_type = "f1-micro"
  1179  		  zone         = "us-central1-a"
  1180  
  1181  		  disk {
  1182  		    image = "ubuntu-os-cloud/ubuntu-1604-lts"
  1183  		    type  = "pd-standard"
  1184  		  }
  1185  
  1186  		  disk {
  1187  		    disk        = "${google_compute_disk.foobar.name}"
  1188  		    type        = "pd-standard"
  1189  		    device_name = "xvdb"
  1190  		  }
  1191  
  1192  		  network_interface {
  1193  		    network = "default"
  1194  		  }
  1195  		}
  1196  
  1197  		resource "google_compute_disk" "foobar" {
  1198  		  name = "%s"
  1199  		  zone = "us-central1-a"
  1200  		  type = "pd-standard"
  1201  		  size = "1"
  1202  		}`, instance, disk)
  1203  }