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 `