github.com/arvindram03/terraform@v0.3.7-0.20150212015210-408f838db36d/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  					// though two block devices exist in EC2, terraform state should only
   101  					// have the one block device we created, as terraform does not manage
   102  					// the root device
   103  					resource.TestCheckResourceAttr(
   104  						"aws_instance.foo", "block_device.#", "1"),
   105  					testCheck(),
   106  				),
   107  			},
   108  		},
   109  	})
   110  }
   111  
   112  func TestAccAWSInstance_sourceDestCheck(t *testing.T) {
   113  	var v ec2.Instance
   114  
   115  	testCheck := func(enabled bool) resource.TestCheckFunc {
   116  		return func(*terraform.State) error {
   117  			if v.SourceDestCheck != enabled {
   118  				return fmt.Errorf("bad source_dest_check: %#v", v.SourceDestCheck)
   119  			}
   120  
   121  			return nil
   122  		}
   123  	}
   124  
   125  	resource.Test(t, resource.TestCase{
   126  		PreCheck:     func() { testAccPreCheck(t) },
   127  		Providers:    testAccProviders,
   128  		CheckDestroy: testAccCheckInstanceDestroy,
   129  		Steps: []resource.TestStep{
   130  			resource.TestStep{
   131  				Config: testAccInstanceConfigSourceDest,
   132  				Check: resource.ComposeTestCheckFunc(
   133  					testAccCheckInstanceExists(
   134  						"aws_instance.foo", &v),
   135  					testCheck(true),
   136  				),
   137  			},
   138  
   139  			resource.TestStep{
   140  				Config: testAccInstanceConfigSourceDestDisable,
   141  				Check: resource.ComposeTestCheckFunc(
   142  					testAccCheckInstanceExists(
   143  						"aws_instance.foo", &v),
   144  					testCheck(false),
   145  				),
   146  			},
   147  		},
   148  	})
   149  }
   150  
   151  func TestAccAWSInstance_vpc(t *testing.T) {
   152  	var v ec2.Instance
   153  
   154  	resource.Test(t, resource.TestCase{
   155  		PreCheck:     func() { testAccPreCheck(t) },
   156  		Providers:    testAccProviders,
   157  		CheckDestroy: testAccCheckInstanceDestroy,
   158  		Steps: []resource.TestStep{
   159  			resource.TestStep{
   160  				Config: testAccInstanceConfigVPC,
   161  				Check: resource.ComposeTestCheckFunc(
   162  					testAccCheckInstanceExists(
   163  						"aws_instance.foo", &v),
   164  				),
   165  			},
   166  		},
   167  	})
   168  }
   169  
   170  func TestAccInstance_tags(t *testing.T) {
   171  	var v ec2.Instance
   172  
   173  	resource.Test(t, resource.TestCase{
   174  		PreCheck:     func() { testAccPreCheck(t) },
   175  		Providers:    testAccProviders,
   176  		CheckDestroy: testAccCheckInstanceDestroy,
   177  		Steps: []resource.TestStep{
   178  			resource.TestStep{
   179  				Config: testAccCheckInstanceConfigTags,
   180  				Check: resource.ComposeTestCheckFunc(
   181  					testAccCheckInstanceExists("aws_instance.foo", &v),
   182  					testAccCheckTags(&v.Tags, "foo", "bar"),
   183  					// Guard against regression of https://github.com/hashicorp/terraform/issues/914
   184  					testAccCheckTags(&v.Tags, "#", ""),
   185  				),
   186  			},
   187  
   188  			resource.TestStep{
   189  				Config: testAccCheckInstanceConfigTagsUpdate,
   190  				Check: resource.ComposeTestCheckFunc(
   191  					testAccCheckInstanceExists("aws_instance.foo", &v),
   192  					testAccCheckTags(&v.Tags, "foo", ""),
   193  					testAccCheckTags(&v.Tags, "bar", "baz"),
   194  				),
   195  			},
   196  		},
   197  	})
   198  }
   199  
   200  func TestAccInstance_privateIP(t *testing.T) {
   201  	var v ec2.Instance
   202  
   203  	testCheckPrivateIP := func() resource.TestCheckFunc {
   204  		return func(*terraform.State) error {
   205  			if v.PrivateIpAddress != "10.1.1.42" {
   206  				return fmt.Errorf("bad private IP: %s", v.PrivateIpAddress)
   207  			}
   208  
   209  			return nil
   210  		}
   211  	}
   212  
   213  	resource.Test(t, resource.TestCase{
   214  		PreCheck:     func() { testAccPreCheck(t) },
   215  		Providers:    testAccProviders,
   216  		CheckDestroy: testAccCheckInstanceDestroy,
   217  		Steps: []resource.TestStep{
   218  			resource.TestStep{
   219  				Config: testAccInstanceConfigPrivateIP,
   220  				Check: resource.ComposeTestCheckFunc(
   221  					testAccCheckInstanceExists("aws_instance.foo", &v),
   222  					testCheckPrivateIP(),
   223  				),
   224  			},
   225  		},
   226  	})
   227  }
   228  
   229  func TestAccInstance_associatePublicIPAndPrivateIP(t *testing.T) {
   230  	var v ec2.Instance
   231  
   232  	testCheckPrivateIP := func() resource.TestCheckFunc {
   233  		return func(*terraform.State) error {
   234  			if v.PrivateIpAddress != "10.1.1.42" {
   235  				return fmt.Errorf("bad private IP: %s", v.PrivateIpAddress)
   236  			}
   237  
   238  			return nil
   239  		}
   240  	}
   241  
   242  	resource.Test(t, resource.TestCase{
   243  		PreCheck:     func() { testAccPreCheck(t) },
   244  		Providers:    testAccProviders,
   245  		CheckDestroy: testAccCheckInstanceDestroy,
   246  		Steps: []resource.TestStep{
   247  			resource.TestStep{
   248  				Config: testAccInstanceConfigAssociatePublicIPAndPrivateIP,
   249  				Check: resource.ComposeTestCheckFunc(
   250  					testAccCheckInstanceExists("aws_instance.foo", &v),
   251  					testCheckPrivateIP(),
   252  				),
   253  			},
   254  		},
   255  	})
   256  }
   257  
   258  func testAccCheckInstanceDestroy(s *terraform.State) error {
   259  	conn := testAccProvider.Meta().(*AWSClient).ec2conn
   260  
   261  	for _, rs := range s.RootModule().Resources {
   262  		if rs.Type != "aws_instance" {
   263  			continue
   264  		}
   265  
   266  		// Try to find the resource
   267  		resp, err := conn.Instances(
   268  			[]string{rs.Primary.ID}, ec2.NewFilter())
   269  		if err == nil {
   270  			if len(resp.Reservations) > 0 {
   271  				return fmt.Errorf("still exist.")
   272  			}
   273  
   274  			return nil
   275  		}
   276  
   277  		// Verify the error is what we want
   278  		ec2err, ok := err.(*ec2.Error)
   279  		if !ok {
   280  			return err
   281  		}
   282  		if ec2err.Code != "InvalidInstanceID.NotFound" {
   283  			return err
   284  		}
   285  	}
   286  
   287  	return nil
   288  }
   289  
   290  func testAccCheckInstanceExists(n string, i *ec2.Instance) resource.TestCheckFunc {
   291  	return func(s *terraform.State) error {
   292  		rs, ok := s.RootModule().Resources[n]
   293  		if !ok {
   294  			return fmt.Errorf("Not found: %s", n)
   295  		}
   296  
   297  		if rs.Primary.ID == "" {
   298  			return fmt.Errorf("No ID is set")
   299  		}
   300  
   301  		conn := testAccProvider.Meta().(*AWSClient).ec2conn
   302  		resp, err := conn.Instances(
   303  			[]string{rs.Primary.ID}, ec2.NewFilter())
   304  		if err != nil {
   305  			return err
   306  		}
   307  		if len(resp.Reservations) == 0 {
   308  			return fmt.Errorf("Instance not found")
   309  		}
   310  
   311  		*i = resp.Reservations[0].Instances[0]
   312  
   313  		return nil
   314  	}
   315  }
   316  
   317  func TestInstanceTenancySchema(t *testing.T) {
   318  	actualSchema := resourceAwsInstance().Schema["tenancy"]
   319  	expectedSchema := &schema.Schema{
   320  		Type:     schema.TypeString,
   321  		Optional: true,
   322  		Computed: true,
   323  		ForceNew: true,
   324  	}
   325  	if !reflect.DeepEqual(actualSchema, expectedSchema) {
   326  		t.Fatalf(
   327  			"Got:\n\n%#v\n\nExpected:\n\n%#v\n",
   328  			actualSchema,
   329  			expectedSchema)
   330  	}
   331  }
   332  
   333  const testAccInstanceConfig = `
   334  resource "aws_security_group" "tf_test_foo" {
   335  	name = "tf_test_foo"
   336  	description = "foo"
   337  
   338  	ingress {
   339  		protocol = "icmp"
   340  		from_port = -1
   341  		to_port = -1
   342  		cidr_blocks = ["0.0.0.0/0"]
   343  	}
   344  }
   345  
   346  resource "aws_instance" "foo" {
   347  	# us-west-2
   348  	ami = "ami-4fccb37f"
   349  	availability_zone = "us-west-2a"
   350  
   351  	instance_type = "m1.small"
   352  	security_groups = ["${aws_security_group.tf_test_foo.name}"]
   353  	user_data = "foo"
   354  }
   355  `
   356  
   357  const testAccInstanceConfigBlockDevices = `
   358  resource "aws_instance" "foo" {
   359  	# us-west-2
   360  	ami = "ami-55a7ea65"
   361  	instance_type = "m1.small"
   362  	block_device {
   363  		device_name = "/dev/sdb"
   364  		volume_type = "gp2"
   365  		volume_size = 10
   366  	}
   367  }
   368  `
   369  
   370  const testAccInstanceConfigSourceDest = `
   371  resource "aws_vpc" "foo" {
   372  	cidr_block = "10.1.0.0/16"
   373  }
   374  
   375  resource "aws_subnet" "foo" {
   376  	cidr_block = "10.1.1.0/24"
   377  	vpc_id = "${aws_vpc.foo.id}"
   378  }
   379  
   380  resource "aws_instance" "foo" {
   381  	# us-west-2
   382  	ami = "ami-4fccb37f"
   383  	instance_type = "m1.small"
   384  	subnet_id = "${aws_subnet.foo.id}"
   385  	source_dest_check = true
   386  }
   387  `
   388  
   389  const testAccInstanceConfigSourceDestDisable = `
   390  resource "aws_vpc" "foo" {
   391  	cidr_block = "10.1.0.0/16"
   392  }
   393  
   394  resource "aws_subnet" "foo" {
   395  	cidr_block = "10.1.1.0/24"
   396  	vpc_id = "${aws_vpc.foo.id}"
   397  }
   398  
   399  resource "aws_instance" "foo" {
   400  	# us-west-2
   401  	ami = "ami-4fccb37f"
   402  	instance_type = "m1.small"
   403  	subnet_id = "${aws_subnet.foo.id}"
   404  	source_dest_check = false
   405  }
   406  `
   407  
   408  const testAccInstanceConfigVPC = `
   409  resource "aws_vpc" "foo" {
   410  	cidr_block = "10.1.0.0/16"
   411  }
   412  
   413  resource "aws_subnet" "foo" {
   414  	cidr_block = "10.1.1.0/24"
   415  	vpc_id = "${aws_vpc.foo.id}"
   416  }
   417  
   418  resource "aws_instance" "foo" {
   419  	# us-west-2
   420  	ami = "ami-4fccb37f"
   421  	instance_type = "m1.small"
   422  	subnet_id = "${aws_subnet.foo.id}"
   423  	associate_public_ip_address = true
   424  	tenancy = "dedicated"
   425  }
   426  `
   427  
   428  const testAccCheckInstanceConfigTags = `
   429  resource "aws_instance" "foo" {
   430  	ami = "ami-4fccb37f"
   431  	instance_type = "m1.small"
   432  	tags {
   433  		foo = "bar"
   434  	}
   435  }
   436  `
   437  
   438  const testAccCheckInstanceConfigTagsUpdate = `
   439  resource "aws_instance" "foo" {
   440  	ami = "ami-4fccb37f"
   441  	instance_type = "m1.small"
   442  	tags {
   443  		bar = "baz"
   444  	}
   445  }
   446  `
   447  
   448  const testAccInstanceConfigPrivateIP = `
   449  resource "aws_vpc" "foo" {
   450  	cidr_block = "10.1.0.0/16"
   451  }
   452  
   453  resource "aws_subnet" "foo" {
   454  	cidr_block = "10.1.1.0/24"
   455  	vpc_id = "${aws_vpc.foo.id}"
   456  }
   457  
   458  resource "aws_instance" "foo" {
   459  	ami = "ami-c5eabbf5"
   460  	instance_type = "t2.micro"
   461  	subnet_id = "${aws_subnet.foo.id}"
   462  	private_ip = "10.1.1.42"
   463  }
   464  `
   465  
   466  const testAccInstanceConfigAssociatePublicIPAndPrivateIP = `
   467  resource "aws_vpc" "foo" {
   468  	cidr_block = "10.1.0.0/16"
   469  }
   470  
   471  resource "aws_subnet" "foo" {
   472  	cidr_block = "10.1.1.0/24"
   473  	vpc_id = "${aws_vpc.foo.id}"
   474  }
   475  
   476  resource "aws_instance" "foo" {
   477  	ami = "ami-c5eabbf5"
   478  	instance_type = "t2.micro"
   479  	subnet_id = "${aws_subnet.foo.id}"
   480  	associate_public_ip_address = true
   481  	private_ip = "10.1.1.42"
   482  }
   483  `