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 `