github.com/chalford/terraform@v0.3.7-0.20150113080010-a78c69a8c81f/builtin/providers/aws/resource_aws_instance_test.go (about)

     1  package aws
     2  
     3  import (
     4  	"fmt"
     5  	"reflect"
     6  	"testing"
     7  
     8  	"github.com/hashicorp/terraform/helper/resource"
     9  	"github.com/hashicorp/terraform/helper/schema"
    10  	"github.com/hashicorp/terraform/terraform"
    11  	"github.com/mitchellh/goamz/ec2"
    12  )
    13  
    14  func TestAccAWSInstance_normal(t *testing.T) {
    15  	var v ec2.Instance
    16  
    17  	testCheck := func(*terraform.State) error {
    18  		if v.AvailZone != "us-west-2a" {
    19  			return fmt.Errorf("bad availability zone: %#v", v.AvailZone)
    20  		}
    21  
    22  		if len(v.SecurityGroups) == 0 {
    23  			return fmt.Errorf("no security groups: %#v", v.SecurityGroups)
    24  		}
    25  		if v.SecurityGroups[0].Name != "tf_test_foo" {
    26  			return fmt.Errorf("no security groups: %#v", v.SecurityGroups)
    27  		}
    28  
    29  		return nil
    30  	}
    31  
    32  	resource.Test(t, resource.TestCase{
    33  		PreCheck:     func() { testAccPreCheck(t) },
    34  		Providers:    testAccProviders,
    35  		CheckDestroy: testAccCheckInstanceDestroy,
    36  		Steps: []resource.TestStep{
    37  			resource.TestStep{
    38  				Config: testAccInstanceConfig,
    39  				Check: resource.ComposeTestCheckFunc(
    40  					testAccCheckInstanceExists(
    41  						"aws_instance.foo", &v),
    42  					testCheck,
    43  					resource.TestCheckResourceAttr(
    44  						"aws_instance.foo",
    45  						"user_data",
    46  						"0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33"),
    47  				),
    48  			},
    49  
    50  			// We repeat the exact same test so that we can be sure
    51  			// that the user data hash stuff is working without generating
    52  			// an incorrect diff.
    53  			resource.TestStep{
    54  				Config: testAccInstanceConfig,
    55  				Check: resource.ComposeTestCheckFunc(
    56  					testAccCheckInstanceExists(
    57  						"aws_instance.foo", &v),
    58  					testCheck,
    59  					resource.TestCheckResourceAttr(
    60  						"aws_instance.foo",
    61  						"user_data",
    62  						"0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33"),
    63  				),
    64  			},
    65  		},
    66  	})
    67  }
    68  
    69  func TestAccAWSInstance_blockDevicesCheck(t *testing.T) {
    70  	var v ec2.Instance
    71  
    72  	testCheck := func() resource.TestCheckFunc {
    73  		return func(*terraform.State) error {
    74  
    75  			// Map out the block devices by name, which should be unique.
    76  			blockDevices := make(map[string]ec2.BlockDevice)
    77  			for _, blockDevice := range v.BlockDevices {
    78  				blockDevices[blockDevice.DeviceName] = blockDevice
    79  			}
    80  
    81  			// Check if the secondary block device exists.
    82  			if _, ok := blockDevices["/dev/sdb"]; !ok {
    83  				fmt.Errorf("block device doesn't exist: /dev/sdb")
    84  			}
    85  
    86  			return nil
    87  		}
    88  	}
    89  
    90  	resource.Test(t, resource.TestCase{
    91  		PreCheck:     func() { testAccPreCheck(t) },
    92  		Providers:    testAccProviders,
    93  		CheckDestroy: testAccCheckInstanceDestroy,
    94  		Steps: []resource.TestStep{
    95  			resource.TestStep{
    96  				Config: testAccInstanceConfigBlockDevices,
    97  				Check: resource.ComposeTestCheckFunc(
    98  					testAccCheckInstanceExists(
    99  						"aws_instance.foo", &v),
   100  					testCheck(),
   101  				),
   102  			},
   103  		},
   104  	})
   105  }
   106  
   107  func TestAccAWSInstance_sourceDestCheck(t *testing.T) {
   108  	var v ec2.Instance
   109  
   110  	testCheck := func(enabled bool) resource.TestCheckFunc {
   111  		return func(*terraform.State) error {
   112  			if v.SourceDestCheck != enabled {
   113  				return fmt.Errorf("bad source_dest_check: %#v", v.SourceDestCheck)
   114  			}
   115  
   116  			return nil
   117  		}
   118  	}
   119  
   120  	resource.Test(t, resource.TestCase{
   121  		PreCheck:     func() { testAccPreCheck(t) },
   122  		Providers:    testAccProviders,
   123  		CheckDestroy: testAccCheckInstanceDestroy,
   124  		Steps: []resource.TestStep{
   125  			resource.TestStep{
   126  				Config: testAccInstanceConfigSourceDest,
   127  				Check: resource.ComposeTestCheckFunc(
   128  					testAccCheckInstanceExists(
   129  						"aws_instance.foo", &v),
   130  					testCheck(true),
   131  				),
   132  			},
   133  
   134  			resource.TestStep{
   135  				Config: testAccInstanceConfigSourceDestDisable,
   136  				Check: resource.ComposeTestCheckFunc(
   137  					testAccCheckInstanceExists(
   138  						"aws_instance.foo", &v),
   139  					testCheck(false),
   140  				),
   141  			},
   142  		},
   143  	})
   144  }
   145  
   146  func TestAccAWSInstance_vpc(t *testing.T) {
   147  	var v ec2.Instance
   148  
   149  	resource.Test(t, resource.TestCase{
   150  		PreCheck:     func() { testAccPreCheck(t) },
   151  		Providers:    testAccProviders,
   152  		CheckDestroy: testAccCheckInstanceDestroy,
   153  		Steps: []resource.TestStep{
   154  			resource.TestStep{
   155  				Config: testAccInstanceConfigVPC,
   156  				Check: resource.ComposeTestCheckFunc(
   157  					testAccCheckInstanceExists(
   158  						"aws_instance.foo", &v),
   159  				),
   160  			},
   161  		},
   162  	})
   163  }
   164  
   165  func TestAccInstance_tags(t *testing.T) {
   166  	var v ec2.Instance
   167  
   168  	resource.Test(t, resource.TestCase{
   169  		PreCheck:     func() { testAccPreCheck(t) },
   170  		Providers:    testAccProviders,
   171  		CheckDestroy: testAccCheckInstanceDestroy,
   172  		Steps: []resource.TestStep{
   173  			resource.TestStep{
   174  				Config: testAccCheckInstanceConfigTags,
   175  				Check: resource.ComposeTestCheckFunc(
   176  					testAccCheckInstanceExists("aws_instance.foo", &v),
   177  					testAccCheckTags(&v.Tags, "foo", "bar"),
   178  				),
   179  			},
   180  
   181  			resource.TestStep{
   182  				Config: testAccCheckInstanceConfigTagsUpdate,
   183  				Check: resource.ComposeTestCheckFunc(
   184  					testAccCheckInstanceExists("aws_instance.foo", &v),
   185  					testAccCheckTags(&v.Tags, "foo", ""),
   186  					testAccCheckTags(&v.Tags, "bar", "baz"),
   187  				),
   188  			},
   189  		},
   190  	})
   191  }
   192  
   193  func TestAccInstance_privateIP(t *testing.T) {
   194  	var v ec2.Instance
   195  
   196  	testCheckPrivateIP := func() resource.TestCheckFunc {
   197  		return func(*terraform.State) error {
   198  			if v.PrivateIpAddress != "10.1.1.42" {
   199  				return fmt.Errorf("bad private IP: %s", v.PrivateIpAddress)
   200  			}
   201  
   202  			return nil
   203  		}
   204  	}
   205  
   206  	resource.Test(t, resource.TestCase{
   207  		PreCheck:     func() { testAccPreCheck(t) },
   208  		Providers:    testAccProviders,
   209  		CheckDestroy: testAccCheckInstanceDestroy,
   210  		Steps: []resource.TestStep{
   211  			resource.TestStep{
   212  				Config: testAccInstanceConfigPrivateIP,
   213  				Check: resource.ComposeTestCheckFunc(
   214  					testAccCheckInstanceExists("aws_instance.foo", &v),
   215  					testCheckPrivateIP(),
   216  				),
   217  			},
   218  		},
   219  	})
   220  }
   221  
   222  func TestAccInstance_associatePublicIPAndPrivateIP(t *testing.T) {
   223  	var v ec2.Instance
   224  
   225  	testCheckPrivateIP := func() resource.TestCheckFunc {
   226  		return func(*terraform.State) error {
   227  			if v.PrivateIpAddress != "10.1.1.42" {
   228  				return fmt.Errorf("bad private IP: %s", v.PrivateIpAddress)
   229  			}
   230  
   231  			return nil
   232  		}
   233  	}
   234  
   235  	resource.Test(t, resource.TestCase{
   236  		PreCheck:     func() { testAccPreCheck(t) },
   237  		Providers:    testAccProviders,
   238  		CheckDestroy: testAccCheckInstanceDestroy,
   239  		Steps: []resource.TestStep{
   240  			resource.TestStep{
   241  				Config: testAccInstanceConfigAssociatePublicIPAndPrivateIP,
   242  				Check: resource.ComposeTestCheckFunc(
   243  					testAccCheckInstanceExists("aws_instance.foo", &v),
   244  					testCheckPrivateIP(),
   245  				),
   246  			},
   247  		},
   248  	})
   249  }
   250  
   251  func testAccCheckInstanceDestroy(s *terraform.State) error {
   252  	conn := testAccProvider.Meta().(*AWSClient).ec2conn
   253  
   254  	for _, rs := range s.RootModule().Resources {
   255  		if rs.Type != "aws_instance" {
   256  			continue
   257  		}
   258  
   259  		// Try to find the resource
   260  		resp, err := conn.Instances(
   261  			[]string{rs.Primary.ID}, ec2.NewFilter())
   262  		if err == nil {
   263  			if len(resp.Reservations) > 0 {
   264  				return fmt.Errorf("still exist.")
   265  			}
   266  
   267  			return nil
   268  		}
   269  
   270  		// Verify the error is what we want
   271  		ec2err, ok := err.(*ec2.Error)
   272  		if !ok {
   273  			return err
   274  		}
   275  		if ec2err.Code != "InvalidInstanceID.NotFound" {
   276  			return err
   277  		}
   278  	}
   279  
   280  	return nil
   281  }
   282  
   283  func testAccCheckInstanceExists(n string, i *ec2.Instance) resource.TestCheckFunc {
   284  	return func(s *terraform.State) error {
   285  		rs, ok := s.RootModule().Resources[n]
   286  		if !ok {
   287  			return fmt.Errorf("Not found: %s", n)
   288  		}
   289  
   290  		if rs.Primary.ID == "" {
   291  			return fmt.Errorf("No ID is set")
   292  		}
   293  
   294  		conn := testAccProvider.Meta().(*AWSClient).ec2conn
   295  		resp, err := conn.Instances(
   296  			[]string{rs.Primary.ID}, ec2.NewFilter())
   297  		if err != nil {
   298  			return err
   299  		}
   300  		if len(resp.Reservations) == 0 {
   301  			return fmt.Errorf("Instance not found")
   302  		}
   303  
   304  		*i = resp.Reservations[0].Instances[0]
   305  
   306  		return nil
   307  	}
   308  }
   309  
   310  func TestInstanceTenancySchema(t *testing.T) {
   311  	actualSchema := resourceAwsInstance().Schema["tenancy"]
   312  	expectedSchema := &schema.Schema{
   313  		Type:     schema.TypeString,
   314  		Optional: true,
   315  		Computed: true,
   316  		ForceNew: true,
   317  	}
   318  	if !reflect.DeepEqual(actualSchema, expectedSchema) {
   319  		t.Fatalf(
   320  			"Got:\n\n%#v\n\nExpected:\n\n%#v\n",
   321  			actualSchema,
   322  			expectedSchema)
   323  	}
   324  }
   325  
   326  const testAccInstanceConfig = `
   327  resource "aws_security_group" "tf_test_foo" {
   328  	name = "tf_test_foo"
   329  	description = "foo"
   330  
   331  	ingress {
   332  		protocol = "icmp"
   333  		from_port = -1
   334  		to_port = -1
   335  		cidr_blocks = ["0.0.0.0/0"]
   336  	}
   337  }
   338  
   339  resource "aws_instance" "foo" {
   340  	# us-west-2
   341  	ami = "ami-4fccb37f"
   342  	availability_zone = "us-west-2a"
   343  
   344  	instance_type = "m1.small"
   345  	security_groups = ["${aws_security_group.tf_test_foo.name}"]
   346  	user_data = "foo"
   347  }
   348  `
   349  
   350  const testAccInstanceConfigBlockDevices = `
   351  resource "aws_instance" "foo" {
   352  	# us-west-2
   353  	ami = "ami-55a7ea65"
   354  	instance_type = "m1.small"
   355  	block_device {
   356  	  device_name = "/dev/sdb"
   357  	  volume_type = "gp2"
   358  	  volume_size = 10
   359  	}
   360  }
   361  `
   362  
   363  const testAccInstanceConfigSourceDest = `
   364  resource "aws_vpc" "foo" {
   365  	cidr_block = "10.1.0.0/16"
   366  }
   367  
   368  resource "aws_subnet" "foo" {
   369  	cidr_block = "10.1.1.0/24"
   370  	vpc_id = "${aws_vpc.foo.id}"
   371  }
   372  
   373  resource "aws_instance" "foo" {
   374  	# us-west-2
   375  	ami = "ami-4fccb37f"
   376  	instance_type = "m1.small"
   377  	subnet_id = "${aws_subnet.foo.id}"
   378  	source_dest_check = true
   379  }
   380  `
   381  
   382  const testAccInstanceConfigSourceDestDisable = `
   383  resource "aws_vpc" "foo" {
   384  	cidr_block = "10.1.0.0/16"
   385  }
   386  
   387  resource "aws_subnet" "foo" {
   388  	cidr_block = "10.1.1.0/24"
   389  	vpc_id = "${aws_vpc.foo.id}"
   390  }
   391  
   392  resource "aws_instance" "foo" {
   393  	# us-west-2
   394  	ami = "ami-4fccb37f"
   395  	instance_type = "m1.small"
   396  	subnet_id = "${aws_subnet.foo.id}"
   397  	source_dest_check = false
   398  }
   399  `
   400  
   401  const testAccInstanceConfigVPC = `
   402  resource "aws_vpc" "foo" {
   403  	cidr_block = "10.1.0.0/16"
   404  }
   405  
   406  resource "aws_subnet" "foo" {
   407  	cidr_block = "10.1.1.0/24"
   408  	vpc_id = "${aws_vpc.foo.id}"
   409  }
   410  
   411  resource "aws_instance" "foo" {
   412  	# us-west-2
   413  	ami = "ami-4fccb37f"
   414  	instance_type = "m1.small"
   415  	subnet_id = "${aws_subnet.foo.id}"
   416  	associate_public_ip_address = true
   417  	tenancy = "dedicated"
   418  }
   419  `
   420  
   421  const testAccCheckInstanceConfigTags = `
   422  resource "aws_instance" "foo" {
   423  	ami = "ami-4fccb37f"
   424  	instance_type = "m1.small"
   425  	tags {
   426  		foo = "bar"
   427  	}
   428  }
   429  `
   430  
   431  const testAccCheckInstanceConfigTagsUpdate = `
   432  resource "aws_instance" "foo" {
   433  	ami = "ami-4fccb37f"
   434  	instance_type = "m1.small"
   435  	tags {
   436  		bar = "baz"
   437  	}
   438  }
   439  `
   440  
   441  const testAccInstanceConfigPrivateIP = `
   442  resource "aws_vpc" "foo" {
   443  	cidr_block = "10.1.0.0/16"
   444  }
   445  
   446  resource "aws_subnet" "foo" {
   447  	cidr_block = "10.1.1.0/24"
   448  	vpc_id = "${aws_vpc.foo.id}"
   449  }
   450  
   451  resource "aws_instance" "foo" {
   452  	ami = "ami-c5eabbf5"
   453  	instance_type = "t2.micro"
   454  	subnet_id = "${aws_subnet.foo.id}"
   455  	private_ip = "10.1.1.42"
   456  }
   457  `
   458  
   459  const testAccInstanceConfigAssociatePublicIPAndPrivateIP = `
   460  resource "aws_vpc" "foo" {
   461  	cidr_block = "10.1.0.0/16"
   462  }
   463  
   464  resource "aws_subnet" "foo" {
   465  	cidr_block = "10.1.1.0/24"
   466  	vpc_id = "${aws_vpc.foo.id}"
   467  }
   468  
   469  resource "aws_instance" "foo" {
   470  	ami = "ami-c5eabbf5"
   471  	instance_type = "t2.micro"
   472  	subnet_id = "${aws_subnet.foo.id}"
   473  	associate_public_ip_address = true
   474  	private_ip = "10.1.1.42"
   475  }
   476  `