github.com/recobe182/terraform@v0.8.5-0.20170117231232-49ab22a935b7/builtin/providers/google/resource_compute_instance_test.go (about)

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