github.com/econnell/terraform@v0.5.4-0.20150722160631-78eb236786a4/builtin/providers/aws/resource_aws_instance_test.go (about)

     1  package aws
     2  
     3  import (
     4  	"fmt"
     5  	"reflect"
     6  	"testing"
     7  
     8  	"github.com/aws/aws-sdk-go/aws"
     9  	"github.com/aws/aws-sdk-go/aws/awserr"
    10  	"github.com/aws/aws-sdk-go/aws/awsutil"
    11  	"github.com/aws/aws-sdk-go/service/ec2"
    12  	"github.com/hashicorp/terraform/helper/resource"
    13  	"github.com/hashicorp/terraform/helper/schema"
    14  	"github.com/hashicorp/terraform/terraform"
    15  )
    16  
    17  func TestAccAWSInstance_basic(t *testing.T) {
    18  	var v ec2.Instance
    19  	var vol *ec2.Volume
    20  
    21  	testCheck := func(*terraform.State) error {
    22  		if *v.Placement.AvailabilityZone != "us-west-2a" {
    23  			return fmt.Errorf("bad availability zone: %#v", *v.Placement.AvailabilityZone)
    24  		}
    25  
    26  		if len(v.SecurityGroups) == 0 {
    27  			return fmt.Errorf("no security groups: %#v", v.SecurityGroups)
    28  		}
    29  		if *v.SecurityGroups[0].GroupName != "tf_test_foo" {
    30  			return fmt.Errorf("no security groups: %#v", v.SecurityGroups)
    31  		}
    32  
    33  		return nil
    34  	}
    35  
    36  	resource.Test(t, resource.TestCase{
    37  		PreCheck:     func() { testAccPreCheck(t) },
    38  		Providers:    testAccProviders,
    39  		CheckDestroy: testAccCheckInstanceDestroy,
    40  		Steps: []resource.TestStep{
    41  			// Create a volume to cover #1249
    42  			resource.TestStep{
    43  				// Need a resource in this config so the provisioner will be available
    44  				Config: testAccInstanceConfig_pre,
    45  				Check: func(*terraform.State) error {
    46  					conn := testAccProvider.Meta().(*AWSClient).ec2conn
    47  					var err error
    48  					vol, err = conn.CreateVolume(&ec2.CreateVolumeInput{
    49  						AvailabilityZone: aws.String("us-west-2a"),
    50  						Size:             aws.Long(int64(5)),
    51  					})
    52  					return err
    53  				},
    54  			},
    55  
    56  			resource.TestStep{
    57  				Config: testAccInstanceConfig,
    58  				Check: resource.ComposeTestCheckFunc(
    59  					testAccCheckInstanceExists(
    60  						"aws_instance.foo", &v),
    61  					testCheck,
    62  					resource.TestCheckResourceAttr(
    63  						"aws_instance.foo",
    64  						"user_data",
    65  						"3dc39dda39be1205215e776bad998da361a5955d"),
    66  					resource.TestCheckResourceAttr(
    67  						"aws_instance.foo", "ebs_block_device.#", "0"),
    68  				),
    69  			},
    70  
    71  			// We repeat the exact same test so that we can be sure
    72  			// that the user data hash stuff is working without generating
    73  			// an incorrect diff.
    74  			resource.TestStep{
    75  				Config: testAccInstanceConfig,
    76  				Check: resource.ComposeTestCheckFunc(
    77  					testAccCheckInstanceExists(
    78  						"aws_instance.foo", &v),
    79  					testCheck,
    80  					resource.TestCheckResourceAttr(
    81  						"aws_instance.foo",
    82  						"user_data",
    83  						"3dc39dda39be1205215e776bad998da361a5955d"),
    84  					resource.TestCheckResourceAttr(
    85  						"aws_instance.foo", "ebs_block_device.#", "0"),
    86  				),
    87  			},
    88  
    89  			// Clean up volume created above
    90  			resource.TestStep{
    91  				Config: testAccInstanceConfig,
    92  				Check: func(*terraform.State) error {
    93  					conn := testAccProvider.Meta().(*AWSClient).ec2conn
    94  					_, err := conn.DeleteVolume(&ec2.DeleteVolumeInput{VolumeID: vol.VolumeID})
    95  					return err
    96  				},
    97  			},
    98  		},
    99  	})
   100  }
   101  
   102  func TestAccAWSInstance_blockDevices(t *testing.T) {
   103  	var v ec2.Instance
   104  
   105  	testCheck := func() resource.TestCheckFunc {
   106  		return func(*terraform.State) error {
   107  
   108  			// Map out the block devices by name, which should be unique.
   109  			blockDevices := make(map[string]*ec2.InstanceBlockDeviceMapping)
   110  			for _, blockDevice := range v.BlockDeviceMappings {
   111  				blockDevices[*blockDevice.DeviceName] = blockDevice
   112  			}
   113  
   114  			// Check if the root block device exists.
   115  			if _, ok := blockDevices["/dev/sda1"]; !ok {
   116  				fmt.Errorf("block device doesn't exist: /dev/sda1")
   117  			}
   118  
   119  			// Check if the secondary block device exists.
   120  			if _, ok := blockDevices["/dev/sdb"]; !ok {
   121  				fmt.Errorf("block device doesn't exist: /dev/sdb")
   122  			}
   123  
   124  			// Check if the third block device exists.
   125  			if _, ok := blockDevices["/dev/sdc"]; !ok {
   126  				fmt.Errorf("block device doesn't exist: /dev/sdc")
   127  			}
   128  
   129  			// Check if the encrypted block device exists
   130  			if _, ok := blockDevices["/dev/sdd"]; !ok {
   131  				fmt.Errorf("block device doesn't exist: /dev/sdd")
   132  			}
   133  
   134  			return nil
   135  		}
   136  	}
   137  
   138  	resource.Test(t, resource.TestCase{
   139  		PreCheck:     func() { testAccPreCheck(t) },
   140  		Providers:    testAccProviders,
   141  		CheckDestroy: testAccCheckInstanceDestroy,
   142  		Steps: []resource.TestStep{
   143  			resource.TestStep{
   144  				Config: testAccInstanceConfigBlockDevices,
   145  				Check: resource.ComposeTestCheckFunc(
   146  					testAccCheckInstanceExists(
   147  						"aws_instance.foo", &v),
   148  					resource.TestCheckResourceAttr(
   149  						"aws_instance.foo", "root_block_device.#", "1"),
   150  					resource.TestCheckResourceAttr(
   151  						"aws_instance.foo", "root_block_device.0.volume_size", "11"),
   152  					resource.TestCheckResourceAttr(
   153  						"aws_instance.foo", "root_block_device.0.volume_type", "gp2"),
   154  					resource.TestCheckResourceAttr(
   155  						"aws_instance.foo", "ebs_block_device.#", "3"),
   156  					resource.TestCheckResourceAttr(
   157  						"aws_instance.foo", "ebs_block_device.2576023345.device_name", "/dev/sdb"),
   158  					resource.TestCheckResourceAttr(
   159  						"aws_instance.foo", "ebs_block_device.2576023345.volume_size", "9"),
   160  					resource.TestCheckResourceAttr(
   161  						"aws_instance.foo", "ebs_block_device.2576023345.volume_type", "standard"),
   162  					resource.TestCheckResourceAttr(
   163  						"aws_instance.foo", "ebs_block_device.2554893574.device_name", "/dev/sdc"),
   164  					resource.TestCheckResourceAttr(
   165  						"aws_instance.foo", "ebs_block_device.2554893574.volume_size", "10"),
   166  					resource.TestCheckResourceAttr(
   167  						"aws_instance.foo", "ebs_block_device.2554893574.volume_type", "io1"),
   168  					resource.TestCheckResourceAttr(
   169  						"aws_instance.foo", "ebs_block_device.2554893574.iops", "100"),
   170  					resource.TestCheckResourceAttr(
   171  						"aws_instance.foo", "ebs_block_device.2634515331.device_name", "/dev/sdd"),
   172  					resource.TestCheckResourceAttr(
   173  						"aws_instance.foo", "ebs_block_device.2634515331.encrypted", "true"),
   174  					resource.TestCheckResourceAttr(
   175  						"aws_instance.foo", "ebs_block_device.2634515331.volume_size", "12"),
   176  					resource.TestCheckResourceAttr(
   177  						"aws_instance.foo", "ephemeral_block_device.#", "1"),
   178  					resource.TestCheckResourceAttr(
   179  						"aws_instance.foo", "ephemeral_block_device.1692014856.device_name", "/dev/sde"),
   180  					resource.TestCheckResourceAttr(
   181  						"aws_instance.foo", "ephemeral_block_device.1692014856.virtual_name", "ephemeral0"),
   182  					testCheck(),
   183  				),
   184  			},
   185  		},
   186  	})
   187  }
   188  
   189  func TestAccAWSInstance_sourceDestCheck(t *testing.T) {
   190  	var v ec2.Instance
   191  
   192  	testCheck := func(enabled bool) resource.TestCheckFunc {
   193  		return func(*terraform.State) error {
   194  			if *v.SourceDestCheck != enabled {
   195  				return fmt.Errorf("bad source_dest_check: %#v", *v.SourceDestCheck)
   196  			}
   197  
   198  			return nil
   199  		}
   200  	}
   201  
   202  	resource.Test(t, resource.TestCase{
   203  		PreCheck:     func() { testAccPreCheck(t) },
   204  		Providers:    testAccProviders,
   205  		CheckDestroy: testAccCheckInstanceDestroy,
   206  		Steps: []resource.TestStep{
   207  			resource.TestStep{
   208  				Config: testAccInstanceConfigSourceDestDisable,
   209  				Check: resource.ComposeTestCheckFunc(
   210  					testAccCheckInstanceExists("aws_instance.foo", &v),
   211  					testCheck(false),
   212  				),
   213  			},
   214  
   215  			resource.TestStep{
   216  				Config: testAccInstanceConfigSourceDestEnable,
   217  				Check: resource.ComposeTestCheckFunc(
   218  					testAccCheckInstanceExists("aws_instance.foo", &v),
   219  					testCheck(true),
   220  				),
   221  			},
   222  
   223  			resource.TestStep{
   224  				Config: testAccInstanceConfigSourceDestDisable,
   225  				Check: resource.ComposeTestCheckFunc(
   226  					testAccCheckInstanceExists("aws_instance.foo", &v),
   227  					testCheck(false),
   228  				),
   229  			},
   230  		},
   231  	})
   232  }
   233  
   234  func TestAccAWSInstance_disableApiTermination(t *testing.T) {
   235  	var v ec2.Instance
   236  
   237  	checkDisableApiTermination := func(expected bool) resource.TestCheckFunc {
   238  		return func(*terraform.State) error {
   239  			conn := testAccProvider.Meta().(*AWSClient).ec2conn
   240  			r, err := conn.DescribeInstanceAttribute(&ec2.DescribeInstanceAttributeInput{
   241  				InstanceID: v.InstanceID,
   242  				Attribute:  aws.String("disableApiTermination"),
   243  			})
   244  			if err != nil {
   245  				return err
   246  			}
   247  			got := *r.DisableAPITermination.Value
   248  			if got != expected {
   249  				return fmt.Errorf("expected: %t, got: %t", expected, got)
   250  			}
   251  			return nil
   252  		}
   253  	}
   254  
   255  	resource.Test(t, resource.TestCase{
   256  		PreCheck:     func() { testAccPreCheck(t) },
   257  		Providers:    testAccProviders,
   258  		CheckDestroy: testAccCheckInstanceDestroy,
   259  		Steps: []resource.TestStep{
   260  			resource.TestStep{
   261  				Config: testAccInstanceConfigDisableAPITermination(true),
   262  				Check: resource.ComposeTestCheckFunc(
   263  					testAccCheckInstanceExists("aws_instance.foo", &v),
   264  					checkDisableApiTermination(true),
   265  				),
   266  			},
   267  
   268  			resource.TestStep{
   269  				Config: testAccInstanceConfigDisableAPITermination(false),
   270  				Check: resource.ComposeTestCheckFunc(
   271  					testAccCheckInstanceExists("aws_instance.foo", &v),
   272  					checkDisableApiTermination(false),
   273  				),
   274  			},
   275  		},
   276  	})
   277  }
   278  
   279  func TestAccAWSInstance_vpc(t *testing.T) {
   280  	var v ec2.Instance
   281  
   282  	resource.Test(t, resource.TestCase{
   283  		PreCheck:     func() { testAccPreCheck(t) },
   284  		Providers:    testAccProviders,
   285  		CheckDestroy: testAccCheckInstanceDestroy,
   286  		Steps: []resource.TestStep{
   287  			resource.TestStep{
   288  				Config: testAccInstanceConfigVPC,
   289  				Check: resource.ComposeTestCheckFunc(
   290  					testAccCheckInstanceExists(
   291  						"aws_instance.foo", &v),
   292  				),
   293  			},
   294  		},
   295  	})
   296  }
   297  
   298  func TestAccAWSInstance_multipleRegions(t *testing.T) {
   299  	var v ec2.Instance
   300  
   301  	// record the initialized providers so that we can use them to
   302  	// check for the instances in each region
   303  	var providers []*schema.Provider
   304  	providerFactories := map[string]terraform.ResourceProviderFactory{
   305  		"aws": func() (terraform.ResourceProvider, error) {
   306  			p := Provider()
   307  			providers = append(providers, p.(*schema.Provider))
   308  			return p, nil
   309  		},
   310  	}
   311  
   312  	resource.Test(t, resource.TestCase{
   313  		PreCheck:          func() { testAccPreCheck(t) },
   314  		ProviderFactories: providerFactories,
   315  		CheckDestroy:      testAccCheckInstanceDestroyWithProviders(&providers),
   316  		Steps: []resource.TestStep{
   317  			resource.TestStep{
   318  				Config: testAccInstanceConfigMultipleRegions,
   319  				Check: resource.ComposeTestCheckFunc(
   320  					testAccCheckInstanceExistsWithProviders(
   321  						"aws_instance.foo", &v, &providers),
   322  					testAccCheckInstanceExistsWithProviders(
   323  						"aws_instance.bar", &v, &providers),
   324  				),
   325  			},
   326  		},
   327  	})
   328  }
   329  
   330  func TestAccAWSInstance_NetworkInstanceSecurityGroups(t *testing.T) {
   331  	var v ec2.Instance
   332  
   333  	resource.Test(t, resource.TestCase{
   334  		PreCheck:     func() { testAccPreCheck(t) },
   335  		Providers:    testAccProviders,
   336  		CheckDestroy: testAccCheckInstanceDestroy,
   337  		Steps: []resource.TestStep{
   338  			resource.TestStep{
   339  				Config: testAccInstanceNetworkInstanceSecurityGroups,
   340  				Check: resource.ComposeTestCheckFunc(
   341  					testAccCheckInstanceExists(
   342  						"aws_instance.foo_instance", &v),
   343  				),
   344  			},
   345  		},
   346  	})
   347  }
   348  
   349  func TestAccAWSInstance_NetworkInstanceVPCSecurityGroupIDs(t *testing.T) {
   350  	var v ec2.Instance
   351  
   352  	resource.Test(t, resource.TestCase{
   353  		PreCheck:     func() { testAccPreCheck(t) },
   354  		Providers:    testAccProviders,
   355  		CheckDestroy: testAccCheckInstanceDestroy,
   356  		Steps: []resource.TestStep{
   357  			resource.TestStep{
   358  				Config: testAccInstanceNetworkInstanceVPCSecurityGroupIDs,
   359  				Check: resource.ComposeTestCheckFunc(
   360  					testAccCheckInstanceExists(
   361  						"aws_instance.foo_instance", &v),
   362  					resource.TestCheckResourceAttr(
   363  						"aws_instance.foo_instance", "security_groups.#", "0"),
   364  					resource.TestCheckResourceAttr(
   365  						"aws_instance.foo_instance", "vpc_security_group_ids.#", "1"),
   366  				),
   367  			},
   368  		},
   369  	})
   370  }
   371  
   372  func TestAccAWSInstance_tags(t *testing.T) {
   373  	var v ec2.Instance
   374  
   375  	resource.Test(t, resource.TestCase{
   376  		PreCheck:     func() { testAccPreCheck(t) },
   377  		Providers:    testAccProviders,
   378  		CheckDestroy: testAccCheckInstanceDestroy,
   379  		Steps: []resource.TestStep{
   380  			resource.TestStep{
   381  				Config: testAccCheckInstanceConfigTags,
   382  				Check: resource.ComposeTestCheckFunc(
   383  					testAccCheckInstanceExists("aws_instance.foo", &v),
   384  					testAccCheckTags(&v.Tags, "foo", "bar"),
   385  					// Guard against regression of https://github.com/hashicorp/terraform/issues/914
   386  					testAccCheckTags(&v.Tags, "#", ""),
   387  				),
   388  			},
   389  
   390  			resource.TestStep{
   391  				Config: testAccCheckInstanceConfigTagsUpdate,
   392  				Check: resource.ComposeTestCheckFunc(
   393  					testAccCheckInstanceExists("aws_instance.foo", &v),
   394  					testAccCheckTags(&v.Tags, "foo", ""),
   395  					testAccCheckTags(&v.Tags, "bar", "baz"),
   396  				),
   397  			},
   398  		},
   399  	})
   400  }
   401  
   402  func TestAccAWSInstance_privateIP(t *testing.T) {
   403  	var v ec2.Instance
   404  
   405  	testCheckPrivateIP := func() resource.TestCheckFunc {
   406  		return func(*terraform.State) error {
   407  			if *v.PrivateIPAddress != "10.1.1.42" {
   408  				return fmt.Errorf("bad private IP: %s", *v.PrivateIPAddress)
   409  			}
   410  
   411  			return nil
   412  		}
   413  	}
   414  
   415  	resource.Test(t, resource.TestCase{
   416  		PreCheck:     func() { testAccPreCheck(t) },
   417  		Providers:    testAccProviders,
   418  		CheckDestroy: testAccCheckInstanceDestroy,
   419  		Steps: []resource.TestStep{
   420  			resource.TestStep{
   421  				Config: testAccInstanceConfigPrivateIP,
   422  				Check: resource.ComposeTestCheckFunc(
   423  					testAccCheckInstanceExists("aws_instance.foo", &v),
   424  					testCheckPrivateIP(),
   425  				),
   426  			},
   427  		},
   428  	})
   429  }
   430  
   431  func TestAccAWSInstance_associatePublicIPAndPrivateIP(t *testing.T) {
   432  	var v ec2.Instance
   433  
   434  	testCheckPrivateIP := func() resource.TestCheckFunc {
   435  		return func(*terraform.State) error {
   436  			if *v.PrivateIPAddress != "10.1.1.42" {
   437  				return fmt.Errorf("bad private IP: %s", *v.PrivateIPAddress)
   438  			}
   439  
   440  			return nil
   441  		}
   442  	}
   443  
   444  	resource.Test(t, resource.TestCase{
   445  		PreCheck:     func() { testAccPreCheck(t) },
   446  		Providers:    testAccProviders,
   447  		CheckDestroy: testAccCheckInstanceDestroy,
   448  		Steps: []resource.TestStep{
   449  			resource.TestStep{
   450  				Config: testAccInstanceConfigAssociatePublicIPAndPrivateIP,
   451  				Check: resource.ComposeTestCheckFunc(
   452  					testAccCheckInstanceExists("aws_instance.foo", &v),
   453  					testCheckPrivateIP(),
   454  				),
   455  			},
   456  		},
   457  	})
   458  }
   459  
   460  // Guard against regression with KeyPairs
   461  // https://github.com/hashicorp/terraform/issues/2302
   462  func TestAccAWSInstance_keyPairCheck(t *testing.T) {
   463  	var v ec2.Instance
   464  
   465  	testCheckKeyPair := func(keyName string) resource.TestCheckFunc {
   466  		return func(*terraform.State) error {
   467  			if v.KeyName == nil {
   468  				return fmt.Errorf("No Key Pair found, expected(%s)", keyName)
   469  			}
   470  			if *v.KeyName != keyName {
   471  				return fmt.Errorf("Bad key name, expected (%s), got (%s)", keyName, awsutil.StringValue(v.KeyName))
   472  			}
   473  
   474  			return nil
   475  		}
   476  	}
   477  
   478  	resource.Test(t, resource.TestCase{
   479  		PreCheck:     func() { testAccPreCheck(t) },
   480  		Providers:    testAccProviders,
   481  		CheckDestroy: testAccCheckInstanceDestroy,
   482  		Steps: []resource.TestStep{
   483  			resource.TestStep{
   484  				Config: testAccInstanceConfigKeyPair,
   485  				Check: resource.ComposeTestCheckFunc(
   486  					testAccCheckInstanceExists("aws_instance.foo", &v),
   487  					testCheckKeyPair("tmp-key"),
   488  				),
   489  			},
   490  		},
   491  	})
   492  }
   493  
   494  func TestAccAWSInstance_rootBlockDeviceMismatch(t *testing.T) {
   495  	var v ec2.Instance
   496  
   497  	resource.Test(t, resource.TestCase{
   498  		PreCheck:     func() { testAccPreCheck(t) },
   499  		Providers:    testAccProviders,
   500  		CheckDestroy: testAccCheckInstanceDestroy,
   501  		Steps: []resource.TestStep{
   502  			resource.TestStep{
   503  				Config: testAccInstanceConfigRootBlockDeviceMismatch,
   504  				Check: resource.ComposeTestCheckFunc(
   505  					testAccCheckInstanceExists("aws_instance.foo", &v),
   506  					resource.TestCheckResourceAttr(
   507  						"aws_instance.foo", "root_block_device.0.volume_size", "13"),
   508  				),
   509  			},
   510  		},
   511  	})
   512  }
   513  
   514  func testAccCheckInstanceDestroy(s *terraform.State) error {
   515  	return testAccCheckInstanceDestroyWithProvider(s, testAccProvider)
   516  }
   517  
   518  func testAccCheckInstanceDestroyWithProviders(providers *[]*schema.Provider) resource.TestCheckFunc {
   519  	return func(s *terraform.State) error {
   520  		for _, provider := range *providers {
   521  			if provider.Meta() == nil {
   522  				continue
   523  			}
   524  			if err := testAccCheckInstanceDestroyWithProvider(s, provider); err != nil {
   525  				return err
   526  			}
   527  		}
   528  		return nil
   529  	}
   530  }
   531  
   532  func testAccCheckInstanceDestroyWithProvider(s *terraform.State, provider *schema.Provider) error {
   533  	conn := provider.Meta().(*AWSClient).ec2conn
   534  
   535  	for _, rs := range s.RootModule().Resources {
   536  		if rs.Type != "aws_instance" {
   537  			continue
   538  		}
   539  
   540  		// Try to find the resource
   541  		var err error
   542  		resp, err := conn.DescribeInstances(&ec2.DescribeInstancesInput{
   543  			InstanceIDs: []*string{aws.String(rs.Primary.ID)},
   544  		})
   545  		if err == nil {
   546  			if len(resp.Reservations) > 0 {
   547  				return fmt.Errorf("still exist.")
   548  			}
   549  
   550  			return nil
   551  		}
   552  
   553  		// Verify the error is what we want
   554  		ec2err, ok := err.(awserr.Error)
   555  		if !ok {
   556  			return err
   557  		}
   558  		if ec2err.Code() != "InvalidInstanceID.NotFound" {
   559  			return err
   560  		}
   561  	}
   562  
   563  	return nil
   564  }
   565  
   566  func testAccCheckInstanceExists(n string, i *ec2.Instance) resource.TestCheckFunc {
   567  	providers := []*schema.Provider{testAccProvider}
   568  	return testAccCheckInstanceExistsWithProviders(n, i, &providers)
   569  }
   570  
   571  func testAccCheckInstanceExistsWithProviders(n string, i *ec2.Instance, providers *[]*schema.Provider) resource.TestCheckFunc {
   572  	return func(s *terraform.State) error {
   573  		rs, ok := s.RootModule().Resources[n]
   574  		if !ok {
   575  			return fmt.Errorf("Not found: %s", n)
   576  		}
   577  
   578  		if rs.Primary.ID == "" {
   579  			return fmt.Errorf("No ID is set")
   580  		}
   581  		for _, provider := range *providers {
   582  			// Ignore if Meta is empty, this can happen for validation providers
   583  			if provider.Meta() == nil {
   584  				continue
   585  			}
   586  
   587  			conn := provider.Meta().(*AWSClient).ec2conn
   588  			resp, err := conn.DescribeInstances(&ec2.DescribeInstancesInput{
   589  				InstanceIDs: []*string{aws.String(rs.Primary.ID)},
   590  			})
   591  			if ec2err, ok := err.(awserr.Error); ok && ec2err.Code() == "InvalidInstanceID.NotFound" {
   592  				continue
   593  			}
   594  			if err != nil {
   595  				return err
   596  			}
   597  
   598  			if len(resp.Reservations) > 0 {
   599  				*i = *resp.Reservations[0].Instances[0]
   600  				return nil
   601  			}
   602  		}
   603  
   604  		return fmt.Errorf("Instance not found")
   605  	}
   606  }
   607  
   608  func TestInstanceTenancySchema(t *testing.T) {
   609  	actualSchema := resourceAwsInstance().Schema["tenancy"]
   610  	expectedSchema := &schema.Schema{
   611  		Type:     schema.TypeString,
   612  		Optional: true,
   613  		Computed: true,
   614  		ForceNew: true,
   615  	}
   616  	if !reflect.DeepEqual(actualSchema, expectedSchema) {
   617  		t.Fatalf(
   618  			"Got:\n\n%#v\n\nExpected:\n\n%#v\n",
   619  			actualSchema,
   620  			expectedSchema)
   621  	}
   622  }
   623  
   624  const testAccInstanceConfig_pre = `
   625  resource "aws_security_group" "tf_test_foo" {
   626  	name = "tf_test_foo"
   627  	description = "foo"
   628  
   629  	ingress {
   630  		protocol = "icmp"
   631  		from_port = -1
   632  		to_port = -1
   633  		cidr_blocks = ["0.0.0.0/0"]
   634  	}
   635  }
   636  `
   637  
   638  const testAccInstanceConfig = `
   639  resource "aws_security_group" "tf_test_foo" {
   640  	name = "tf_test_foo"
   641  	description = "foo"
   642  
   643  	ingress {
   644  		protocol = "icmp"
   645  		from_port = -1
   646  		to_port = -1
   647  		cidr_blocks = ["0.0.0.0/0"]
   648  	}
   649  }
   650  
   651  resource "aws_instance" "foo" {
   652  	# us-west-2
   653  	ami = "ami-4fccb37f"
   654  	availability_zone = "us-west-2a"
   655  
   656  	instance_type = "m1.small"
   657  	security_groups = ["${aws_security_group.tf_test_foo.name}"]
   658  	user_data = "foo:-with-character's"
   659  }
   660  `
   661  
   662  const testAccInstanceConfigBlockDevices = `
   663  resource "aws_instance" "foo" {
   664  	# us-west-2
   665  	ami = "ami-55a7ea65"
   666  
   667  	# In order to attach an encrypted volume to an instance you need to have an
   668  	# m3.medium or larger. See "Supported Instance Types" in:
   669  	# http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/EBSEncryption.html
   670  	instance_type = "m3.medium"
   671  
   672  	root_block_device {
   673  		volume_type = "gp2"
   674  		volume_size = 11
   675  	}
   676  	ebs_block_device {
   677  		device_name = "/dev/sdb"
   678  		volume_size = 9
   679  	}
   680  	ebs_block_device {
   681  		device_name = "/dev/sdc"
   682  		volume_size = 10
   683  		volume_type = "io1"
   684  		iops = 100
   685  	}
   686  
   687  	# Encrypted ebs block device
   688  	ebs_block_device {
   689  		device_name = "/dev/sdd"
   690  		volume_size = 12
   691  		encrypted = true
   692  	}
   693  
   694  	ephemeral_block_device {
   695  		device_name = "/dev/sde"
   696  		virtual_name = "ephemeral0"
   697  	}
   698  }
   699  `
   700  
   701  const testAccInstanceConfigSourceDestEnable = `
   702  resource "aws_vpc" "foo" {
   703  	cidr_block = "10.1.0.0/16"
   704  }
   705  
   706  resource "aws_subnet" "foo" {
   707  	cidr_block = "10.1.1.0/24"
   708  	vpc_id = "${aws_vpc.foo.id}"
   709  }
   710  
   711  resource "aws_instance" "foo" {
   712  	# us-west-2
   713  	ami = "ami-4fccb37f"
   714  	instance_type = "m1.small"
   715  	subnet_id = "${aws_subnet.foo.id}"
   716  }
   717  `
   718  
   719  const testAccInstanceConfigSourceDestDisable = `
   720  resource "aws_vpc" "foo" {
   721  	cidr_block = "10.1.0.0/16"
   722  }
   723  
   724  resource "aws_subnet" "foo" {
   725  	cidr_block = "10.1.1.0/24"
   726  	vpc_id = "${aws_vpc.foo.id}"
   727  }
   728  
   729  resource "aws_instance" "foo" {
   730  	# us-west-2
   731  	ami = "ami-4fccb37f"
   732  	instance_type = "m1.small"
   733  	subnet_id = "${aws_subnet.foo.id}"
   734  	source_dest_check = false
   735  }
   736  `
   737  
   738  func testAccInstanceConfigDisableAPITermination(val bool) string {
   739  	return fmt.Sprintf(`
   740  	resource "aws_vpc" "foo" {
   741  		cidr_block = "10.1.0.0/16"
   742  	}
   743  
   744  	resource "aws_subnet" "foo" {
   745  		cidr_block = "10.1.1.0/24"
   746  		vpc_id = "${aws_vpc.foo.id}"
   747  	}
   748  
   749  	resource "aws_instance" "foo" {
   750  		# us-west-2
   751  		ami = "ami-4fccb37f"
   752  		instance_type = "m1.small"
   753  		subnet_id = "${aws_subnet.foo.id}"
   754  		disable_api_termination = %t
   755  	}
   756  	`, val)
   757  }
   758  
   759  const testAccInstanceConfigVPC = `
   760  resource "aws_vpc" "foo" {
   761  	cidr_block = "10.1.0.0/16"
   762  }
   763  
   764  resource "aws_subnet" "foo" {
   765  	cidr_block = "10.1.1.0/24"
   766  	vpc_id = "${aws_vpc.foo.id}"
   767  }
   768  
   769  resource "aws_instance" "foo" {
   770  	# us-west-2
   771  	ami = "ami-4fccb37f"
   772  	instance_type = "m1.small"
   773  	subnet_id = "${aws_subnet.foo.id}"
   774  	associate_public_ip_address = true
   775  	tenancy = "dedicated"
   776  }
   777  `
   778  
   779  const testAccInstanceConfigMultipleRegions = `
   780  provider "aws" {
   781  	alias = "west"
   782  	region = "us-west-2"
   783  }
   784  
   785  provider "aws" {
   786  	alias = "east"
   787  	region = "us-east-1"
   788  }
   789  
   790  resource "aws_instance" "foo" {
   791  	# us-west-2
   792  	provider = "aws.west"
   793  	ami = "ami-4fccb37f"
   794  	instance_type = "m1.small"
   795  }
   796  
   797  resource "aws_instance" "bar" {
   798  	# us-east-1
   799  	provider = "aws.east"
   800  	ami = "ami-8c6ea9e4"
   801  	instance_type = "m1.small"
   802  }
   803  `
   804  
   805  const testAccCheckInstanceConfigTags = `
   806  resource "aws_instance" "foo" {
   807  	ami = "ami-4fccb37f"
   808  	instance_type = "m1.small"
   809  	tags {
   810  		foo = "bar"
   811  	}
   812  }
   813  `
   814  
   815  const testAccCheckInstanceConfigTagsUpdate = `
   816  resource "aws_instance" "foo" {
   817  	ami = "ami-4fccb37f"
   818  	instance_type = "m1.small"
   819  	tags {
   820  		bar = "baz"
   821  	}
   822  }
   823  `
   824  
   825  const testAccInstanceConfigPrivateIP = `
   826  resource "aws_vpc" "foo" {
   827  	cidr_block = "10.1.0.0/16"
   828  }
   829  
   830  resource "aws_subnet" "foo" {
   831  	cidr_block = "10.1.1.0/24"
   832  	vpc_id = "${aws_vpc.foo.id}"
   833  }
   834  
   835  resource "aws_instance" "foo" {
   836  	ami = "ami-c5eabbf5"
   837  	instance_type = "t2.micro"
   838  	subnet_id = "${aws_subnet.foo.id}"
   839  	private_ip = "10.1.1.42"
   840  }
   841  `
   842  
   843  const testAccInstanceConfigAssociatePublicIPAndPrivateIP = `
   844  resource "aws_vpc" "foo" {
   845  	cidr_block = "10.1.0.0/16"
   846  }
   847  
   848  resource "aws_subnet" "foo" {
   849  	cidr_block = "10.1.1.0/24"
   850  	vpc_id = "${aws_vpc.foo.id}"
   851  }
   852  
   853  resource "aws_instance" "foo" {
   854  	ami = "ami-c5eabbf5"
   855  	instance_type = "t2.micro"
   856  	subnet_id = "${aws_subnet.foo.id}"
   857  	associate_public_ip_address = true
   858  	private_ip = "10.1.1.42"
   859  }
   860  `
   861  
   862  const testAccInstanceNetworkInstanceSecurityGroups = `
   863  resource "aws_internet_gateway" "gw" {
   864    vpc_id = "${aws_vpc.foo.id}"
   865  }
   866  
   867  resource "aws_vpc" "foo" {
   868    cidr_block = "10.1.0.0/16"
   869  	tags {
   870  		Name = "tf-network-test"
   871  	}
   872  }
   873  
   874  resource "aws_security_group" "tf_test_foo" {
   875    name = "tf_test_foo"
   876    description = "foo"
   877    vpc_id="${aws_vpc.foo.id}"
   878  
   879    ingress {
   880      protocol = "icmp"
   881      from_port = -1
   882      to_port = -1
   883      cidr_blocks = ["0.0.0.0/0"]
   884    }
   885  }
   886  
   887  resource "aws_subnet" "foo" {
   888    cidr_block = "10.1.1.0/24"
   889    vpc_id = "${aws_vpc.foo.id}"
   890  }
   891  
   892  resource "aws_instance" "foo_instance" {
   893    ami = "ami-21f78e11"
   894    instance_type = "t1.micro"
   895    security_groups = ["${aws_security_group.tf_test_foo.id}"]
   896    subnet_id = "${aws_subnet.foo.id}"
   897    associate_public_ip_address = true
   898  	depends_on = ["aws_internet_gateway.gw"]
   899  }
   900  
   901  resource "aws_eip" "foo_eip" {
   902    instance = "${aws_instance.foo_instance.id}"
   903    vpc = true
   904  	depends_on = ["aws_internet_gateway.gw"]
   905  }
   906  `
   907  
   908  const testAccInstanceNetworkInstanceVPCSecurityGroupIDs = `
   909  resource "aws_internet_gateway" "gw" {
   910    vpc_id = "${aws_vpc.foo.id}"
   911  }
   912  
   913  resource "aws_vpc" "foo" {
   914    cidr_block = "10.1.0.0/16"
   915  	tags {
   916  		Name = "tf-network-test"
   917  	}
   918  }
   919  
   920  resource "aws_security_group" "tf_test_foo" {
   921    name = "tf_test_foo"
   922    description = "foo"
   923    vpc_id="${aws_vpc.foo.id}"
   924  
   925    ingress {
   926      protocol = "icmp"
   927      from_port = -1
   928      to_port = -1
   929      cidr_blocks = ["0.0.0.0/0"]
   930    }
   931  }
   932  
   933  resource "aws_subnet" "foo" {
   934    cidr_block = "10.1.1.0/24"
   935    vpc_id = "${aws_vpc.foo.id}"
   936  }
   937  
   938  resource "aws_instance" "foo_instance" {
   939    ami = "ami-21f78e11"
   940    instance_type = "t1.micro"
   941    vpc_security_group_ids = ["${aws_security_group.tf_test_foo.id}"]
   942    subnet_id = "${aws_subnet.foo.id}"
   943  	depends_on = ["aws_internet_gateway.gw"]
   944  }
   945  
   946  resource "aws_eip" "foo_eip" {
   947    instance = "${aws_instance.foo_instance.id}"
   948    vpc = true
   949  	depends_on = ["aws_internet_gateway.gw"]
   950  }
   951  `
   952  
   953  const testAccInstanceConfigKeyPair = `
   954  provider "aws" {
   955  	region = "us-east-1"
   956  }
   957  
   958  resource "aws_key_pair" "debugging" {
   959  	key_name = "tmp-key"
   960  	public_key = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQD3F6tyPEFEzV0LX3X8BsXdMsQz1x2cEikKDEY0aIj41qgxMCP/iteneqXSIFZBp5vizPvaoIR3Um9xK7PGoW8giupGn+EPuxIA4cDM4vzOqOkiMPhz5XK0whEjkVzTo4+S0puvDZuwIsdiW9mxhJc7tgBNL0cYlWSYVkz4G/fslNfRPW5mYAM49f4fhtxPb5ok4Q2Lg9dPKVHO/Bgeu5woMc7RY0p1ej6D4CKFE6lymSDJpW0YHX/wqE9+cfEauh7xZcG0q9t2ta6F6fmX0agvpFyZo8aFbXeUBr7osSCJNgvavWbM/06niWrOvYX2xwWdhXmXSrbX8ZbabVohBK41 phodgson@thoughtworks.com"
   961  }
   962  
   963  resource "aws_instance" "foo" {
   964    ami = "ami-408c7f28"
   965    instance_type = "t1.micro"
   966    key_name = "${aws_key_pair.debugging.key_name}"
   967  }
   968  `
   969  
   970  const testAccInstanceConfigRootBlockDeviceMismatch = `
   971  resource "aws_vpc" "foo" {
   972  	cidr_block = "10.1.0.0/16"
   973  }
   974  
   975  resource "aws_subnet" "foo" {
   976  	cidr_block = "10.1.1.0/24"
   977  	vpc_id = "${aws_vpc.foo.id}"
   978  }
   979  
   980  resource "aws_instance" "foo" {
   981  	// This is an AMI with RootDeviceName: "/dev/sda1"; actual root: "/dev/sda"
   982  	ami = "ami-ef5b69df"
   983  	instance_type = "t1.micro"
   984  	subnet_id = "${aws_subnet.foo.id}"
   985  	root_block_device {
   986  		volume_size = 13
   987  	}
   988  }
   989  `