github.com/nalum/terraform@v0.3.2-0.20141223102918-aa2c22ffeff6/builtin/providers/aws/resource_aws_instance_test.go (about) 1 package aws 2 3 import ( 4 "fmt" 5 "testing" 6 "reflect" 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 testAccCheckInstanceDestroy(s *terraform.State) error { 194 conn := testAccProvider.Meta().(*AWSClient).ec2conn 195 196 for _, rs := range s.RootModule().Resources { 197 if rs.Type != "aws_instance" { 198 continue 199 } 200 201 // Try to find the resource 202 resp, err := conn.Instances( 203 []string{rs.Primary.ID}, ec2.NewFilter()) 204 if err == nil { 205 if len(resp.Reservations) > 0 { 206 return fmt.Errorf("still exist.") 207 } 208 209 return nil 210 } 211 212 // Verify the error is what we want 213 ec2err, ok := err.(*ec2.Error) 214 if !ok { 215 return err 216 } 217 if ec2err.Code != "InvalidInstanceID.NotFound" { 218 return err 219 } 220 } 221 222 return nil 223 } 224 225 func testAccCheckInstanceExists(n string, i *ec2.Instance) resource.TestCheckFunc { 226 return func(s *terraform.State) error { 227 rs, ok := s.RootModule().Resources[n] 228 if !ok { 229 return fmt.Errorf("Not found: %s", n) 230 } 231 232 if rs.Primary.ID == "" { 233 return fmt.Errorf("No ID is set") 234 } 235 236 conn := testAccProvider.Meta().(*AWSClient).ec2conn 237 resp, err := conn.Instances( 238 []string{rs.Primary.ID}, ec2.NewFilter()) 239 if err != nil { 240 return err 241 } 242 if len(resp.Reservations) == 0 { 243 return fmt.Errorf("Instance not found") 244 } 245 246 *i = resp.Reservations[0].Instances[0] 247 248 return nil 249 } 250 } 251 252 func TestInstanceTenancySchema(t *testing.T) { 253 actualSchema := resourceAwsInstance().Schema["tenancy"] 254 expectedSchema := &schema.Schema{ 255 Type: schema.TypeString, 256 Optional: true, 257 Computed: true, 258 ForceNew: true, 259 } 260 if !reflect.DeepEqual(actualSchema, expectedSchema ) { 261 t.Fatalf( 262 "Got:\n\n%#v\n\nExpected:\n\n%#v\n", 263 actualSchema, 264 expectedSchema) 265 } 266 } 267 268 const testAccInstanceConfig = ` 269 resource "aws_security_group" "tf_test_foo" { 270 name = "tf_test_foo" 271 description = "foo" 272 273 ingress { 274 protocol = "icmp" 275 from_port = -1 276 to_port = -1 277 cidr_blocks = ["0.0.0.0/0"] 278 } 279 } 280 281 resource "aws_instance" "foo" { 282 # us-west-2 283 ami = "ami-4fccb37f" 284 availability_zone = "us-west-2a" 285 286 instance_type = "m1.small" 287 security_groups = ["${aws_security_group.tf_test_foo.name}"] 288 user_data = "foo" 289 } 290 ` 291 292 const testAccInstanceConfigBlockDevices = ` 293 resource "aws_instance" "foo" { 294 # us-west-2 295 ami = "ami-55a7ea65" 296 instance_type = "m1.small" 297 block_device { 298 device_name = "/dev/sdb" 299 volume_type = "gp2" 300 volume_size = 10 301 } 302 } 303 ` 304 305 const testAccInstanceConfigSourceDest = ` 306 resource "aws_vpc" "foo" { 307 cidr_block = "10.1.0.0/16" 308 } 309 310 resource "aws_subnet" "foo" { 311 cidr_block = "10.1.1.0/24" 312 vpc_id = "${aws_vpc.foo.id}" 313 } 314 315 resource "aws_instance" "foo" { 316 # us-west-2 317 ami = "ami-4fccb37f" 318 instance_type = "m1.small" 319 subnet_id = "${aws_subnet.foo.id}" 320 source_dest_check = true 321 } 322 ` 323 324 const testAccInstanceConfigSourceDestDisable = ` 325 resource "aws_vpc" "foo" { 326 cidr_block = "10.1.0.0/16" 327 } 328 329 resource "aws_subnet" "foo" { 330 cidr_block = "10.1.1.0/24" 331 vpc_id = "${aws_vpc.foo.id}" 332 } 333 334 resource "aws_instance" "foo" { 335 # us-west-2 336 ami = "ami-4fccb37f" 337 instance_type = "m1.small" 338 subnet_id = "${aws_subnet.foo.id}" 339 source_dest_check = false 340 } 341 ` 342 343 const testAccInstanceConfigVPC = ` 344 resource "aws_vpc" "foo" { 345 cidr_block = "10.1.0.0/16" 346 } 347 348 resource "aws_subnet" "foo" { 349 cidr_block = "10.1.1.0/24" 350 vpc_id = "${aws_vpc.foo.id}" 351 } 352 353 resource "aws_instance" "foo" { 354 # us-west-2 355 ami = "ami-4fccb37f" 356 instance_type = "m1.small" 357 subnet_id = "${aws_subnet.foo.id}" 358 associate_public_ip_address = true 359 tenancy = "dedicated" 360 } 361 ` 362 363 const testAccCheckInstanceConfigTags = ` 364 resource "aws_instance" "foo" { 365 ami = "ami-4fccb37f" 366 instance_type = "m1.small" 367 tags { 368 foo = "bar" 369 } 370 } 371 ` 372 373 const testAccCheckInstanceConfigTagsUpdate = ` 374 resource "aws_instance" "foo" { 375 ami = "ami-4fccb37f" 376 instance_type = "m1.small" 377 tags { 378 bar = "baz" 379 } 380 } 381 `