github.com/danp/terraform@v0.9.5-0.20170426144147-39d740081351/builtin/providers/aws/resource_aws_vpn_gateway_test.go (about) 1 package aws 2 3 import ( 4 "fmt" 5 "testing" 6 "time" 7 8 "github.com/aws/aws-sdk-go/aws" 9 "github.com/aws/aws-sdk-go/aws/awserr" 10 "github.com/aws/aws-sdk-go/service/ec2" 11 "github.com/hashicorp/terraform/helper/resource" 12 "github.com/hashicorp/terraform/terraform" 13 ) 14 15 func TestAccAWSVpnGateway_basic(t *testing.T) { 16 var v, v2 ec2.VpnGateway 17 18 testNotEqual := func(*terraform.State) error { 19 if len(v.VpcAttachments) == 0 { 20 return fmt.Errorf("VPN Gateway A is not attached") 21 } 22 if len(v2.VpcAttachments) == 0 { 23 return fmt.Errorf("VPN Gateway B is not attached") 24 } 25 26 id1 := v.VpcAttachments[0].VpcId 27 id2 := v2.VpcAttachments[0].VpcId 28 if id1 == id2 { 29 return fmt.Errorf("Both attachment IDs are the same") 30 } 31 32 return nil 33 } 34 35 resource.Test(t, resource.TestCase{ 36 PreCheck: func() { testAccPreCheck(t) }, 37 IDRefreshName: "aws_vpn_gateway.foo", 38 Providers: testAccProviders, 39 CheckDestroy: testAccCheckVpnGatewayDestroy, 40 Steps: []resource.TestStep{ 41 resource.TestStep{ 42 Config: testAccVpnGatewayConfig, 43 Check: resource.ComposeTestCheckFunc( 44 testAccCheckVpnGatewayExists( 45 "aws_vpn_gateway.foo", &v), 46 ), 47 }, 48 49 resource.TestStep{ 50 Config: testAccVpnGatewayConfigChangeVPC, 51 Check: resource.ComposeTestCheckFunc( 52 testAccCheckVpnGatewayExists( 53 "aws_vpn_gateway.foo", &v2), 54 testNotEqual, 55 ), 56 }, 57 }, 58 }) 59 } 60 61 func TestAccAWSVpnGateway_withAvailabilityZoneSetToState(t *testing.T) { 62 var v ec2.VpnGateway 63 64 resource.Test(t, resource.TestCase{ 65 PreCheck: func() { testAccPreCheck(t) }, 66 Providers: testAccProviders, 67 CheckDestroy: testAccCheckVpnGatewayDestroy, 68 Steps: []resource.TestStep{ 69 resource.TestStep{ 70 Config: testAccVpnGatewayConfigWithAZ, 71 Check: resource.ComposeTestCheckFunc( 72 testAccCheckVpnGatewayExists("aws_vpn_gateway.foo", &v), 73 resource.TestCheckResourceAttr( 74 "aws_vpn_gateway.foo", "availability_zone", "us-west-2a"), 75 ), 76 }, 77 }, 78 }) 79 } 80 81 func TestAccAWSVpnGateway_disappears(t *testing.T) { 82 var v ec2.VpnGateway 83 84 resource.Test(t, resource.TestCase{ 85 PreCheck: func() { testAccPreCheck(t) }, 86 Providers: testAccProviders, 87 CheckDestroy: testAccCheckVpnGatewayDestroy, 88 Steps: []resource.TestStep{ 89 resource.TestStep{ 90 Config: testAccVpnGatewayConfig, 91 Check: resource.ComposeTestCheckFunc( 92 testAccCheckVpnGatewayExists("aws_vpn_gateway.foo", &v), 93 testAccAWSVpnGatewayDisappears(&v), 94 ), 95 ExpectNonEmptyPlan: true, 96 }, 97 }, 98 }) 99 } 100 101 func TestAccAWSVpnGateway_reattach(t *testing.T) { 102 var vpc1, vpc2 ec2.Vpc 103 var vgw1, vgw2 ec2.VpnGateway 104 105 testAttachmentFunc := func(vgw *ec2.VpnGateway, vpc *ec2.Vpc) func(*terraform.State) error { 106 return func(*terraform.State) error { 107 if len(vgw.VpcAttachments) == 0 { 108 return fmt.Errorf("VPN Gateway %q has no VPC attachments.", 109 *vgw.VpnGatewayId) 110 } 111 112 if len(vgw.VpcAttachments) > 1 { 113 count := 0 114 for _, v := range vgw.VpcAttachments { 115 if *v.State == "attached" { 116 count += 1 117 } 118 } 119 if count > 1 { 120 return fmt.Errorf( 121 "VPN Gateway %q has an unexpected number of VPC attachments (more than 1): %#v", 122 *vgw.VpnGatewayId, vgw.VpcAttachments) 123 } 124 } 125 126 if *vgw.VpcAttachments[0].State != "attached" { 127 return fmt.Errorf("Expected VPN Gateway %q to be attached.", 128 *vgw.VpnGatewayId) 129 } 130 131 if *vgw.VpcAttachments[0].VpcId != *vpc.VpcId { 132 return fmt.Errorf("Expected VPN Gateway %q to be attached to VPC %q, but got: %q", 133 *vgw.VpnGatewayId, *vpc.VpcId, *vgw.VpcAttachments[0].VpcId) 134 } 135 return nil 136 } 137 } 138 139 resource.Test(t, resource.TestCase{ 140 PreCheck: func() { testAccPreCheck(t) }, 141 IDRefreshName: "aws_vpn_gateway.foo", 142 Providers: testAccProviders, 143 CheckDestroy: testAccCheckVpnGatewayDestroy, 144 Steps: []resource.TestStep{ 145 resource.TestStep{ 146 Config: testAccCheckVpnGatewayConfigReattach, 147 Check: resource.ComposeTestCheckFunc( 148 testAccCheckVpcExists("aws_vpc.foo", &vpc1), 149 testAccCheckVpcExists("aws_vpc.bar", &vpc2), 150 testAccCheckVpnGatewayExists( 151 "aws_vpn_gateway.foo", &vgw1), 152 testAccCheckVpnGatewayExists( 153 "aws_vpn_gateway.bar", &vgw2), 154 testAttachmentFunc(&vgw1, &vpc1), 155 testAttachmentFunc(&vgw2, &vpc2), 156 ), 157 }, 158 resource.TestStep{ 159 Config: testAccCheckVpnGatewayConfigReattachChange, 160 Check: resource.ComposeTestCheckFunc( 161 testAccCheckVpnGatewayExists( 162 "aws_vpn_gateway.foo", &vgw1), 163 testAccCheckVpnGatewayExists( 164 "aws_vpn_gateway.bar", &vgw2), 165 testAttachmentFunc(&vgw2, &vpc1), 166 testAttachmentFunc(&vgw1, &vpc2), 167 ), 168 }, 169 resource.TestStep{ 170 Config: testAccCheckVpnGatewayConfigReattach, 171 Check: resource.ComposeTestCheckFunc( 172 testAccCheckVpnGatewayExists( 173 "aws_vpn_gateway.foo", &vgw1), 174 testAccCheckVpnGatewayExists( 175 "aws_vpn_gateway.bar", &vgw2), 176 testAttachmentFunc(&vgw1, &vpc1), 177 testAttachmentFunc(&vgw2, &vpc2), 178 ), 179 }, 180 }, 181 }) 182 } 183 184 func TestAccAWSVpnGateway_delete(t *testing.T) { 185 var vpnGateway ec2.VpnGateway 186 187 testDeleted := func(r string) resource.TestCheckFunc { 188 return func(s *terraform.State) error { 189 _, ok := s.RootModule().Resources[r] 190 if ok { 191 return fmt.Errorf("VPN Gateway %q should have been deleted.", r) 192 } 193 return nil 194 } 195 } 196 197 resource.Test(t, resource.TestCase{ 198 PreCheck: func() { testAccPreCheck(t) }, 199 IDRefreshName: "aws_vpn_gateway.foo", 200 Providers: testAccProviders, 201 CheckDestroy: testAccCheckVpnGatewayDestroy, 202 Steps: []resource.TestStep{ 203 resource.TestStep{ 204 Config: testAccVpnGatewayConfig, 205 Check: resource.ComposeTestCheckFunc( 206 testAccCheckVpnGatewayExists("aws_vpn_gateway.foo", &vpnGateway)), 207 }, 208 resource.TestStep{ 209 Config: testAccNoVpnGatewayConfig, 210 Check: resource.ComposeTestCheckFunc(testDeleted("aws_vpn_gateway.foo")), 211 }, 212 }, 213 }) 214 } 215 216 func TestAccAWSVpnGateway_tags(t *testing.T) { 217 var v ec2.VpnGateway 218 219 resource.Test(t, resource.TestCase{ 220 PreCheck: func() { testAccPreCheck(t) }, 221 IDRefreshName: "aws_vpn_gateway.foo", 222 Providers: testAccProviders, 223 CheckDestroy: testAccCheckVpnGatewayDestroy, 224 Steps: []resource.TestStep{ 225 resource.TestStep{ 226 Config: testAccCheckVpnGatewayConfigTags, 227 Check: resource.ComposeTestCheckFunc( 228 testAccCheckVpnGatewayExists("aws_vpn_gateway.foo", &v), 229 testAccCheckTags(&v.Tags, "foo", "bar"), 230 ), 231 }, 232 resource.TestStep{ 233 Config: testAccCheckVpnGatewayConfigTagsUpdate, 234 Check: resource.ComposeTestCheckFunc( 235 testAccCheckVpnGatewayExists("aws_vpn_gateway.foo", &v), 236 testAccCheckTags(&v.Tags, "foo", ""), 237 testAccCheckTags(&v.Tags, "bar", "baz"), 238 ), 239 }, 240 }, 241 }) 242 } 243 244 func testAccAWSVpnGatewayDisappears(gateway *ec2.VpnGateway) resource.TestCheckFunc { 245 return func(s *terraform.State) error { 246 conn := testAccProvider.Meta().(*AWSClient).ec2conn 247 248 _, err := conn.DetachVpnGateway(&ec2.DetachVpnGatewayInput{ 249 VpnGatewayId: gateway.VpnGatewayId, 250 VpcId: gateway.VpcAttachments[0].VpcId, 251 }) 252 if err != nil { 253 ec2err, ok := err.(awserr.Error) 254 if ok { 255 if ec2err.Code() == "InvalidVpnGatewayID.NotFound" { 256 return nil 257 } else if ec2err.Code() == "InvalidVpnGatewayAttachment.NotFound" { 258 return nil 259 } 260 } 261 262 if err != nil { 263 return err 264 } 265 } 266 267 opts := &ec2.DeleteVpnGatewayInput{ 268 VpnGatewayId: gateway.VpnGatewayId, 269 } 270 if _, err := conn.DeleteVpnGateway(opts); err != nil { 271 return err 272 } 273 return resource.Retry(40*time.Minute, func() *resource.RetryError { 274 opts := &ec2.DescribeVpnGatewaysInput{ 275 VpnGatewayIds: []*string{gateway.VpnGatewayId}, 276 } 277 resp, err := conn.DescribeVpnGateways(opts) 278 if err != nil { 279 cgw, ok := err.(awserr.Error) 280 if ok && cgw.Code() == "InvalidVpnGatewayID.NotFound" { 281 return nil 282 } 283 if ok && cgw.Code() == "IncorrectState" { 284 return resource.RetryableError(fmt.Errorf( 285 "Waiting for VPN Gateway to be in the correct state: %v", gateway.VpnGatewayId)) 286 } 287 return resource.NonRetryableError( 288 fmt.Errorf("Error retrieving VPN Gateway: %s", err)) 289 } 290 if *resp.VpnGateways[0].State == "deleted" { 291 return nil 292 } 293 return resource.RetryableError(fmt.Errorf( 294 "Waiting for VPN Gateway: %v", gateway.VpnGatewayId)) 295 }) 296 } 297 } 298 299 func testAccCheckVpnGatewayDestroy(s *terraform.State) error { 300 ec2conn := testAccProvider.Meta().(*AWSClient).ec2conn 301 302 for _, rs := range s.RootModule().Resources { 303 if rs.Type != "aws_vpn_gateway" { 304 continue 305 } 306 307 // Try to find the resource 308 resp, err := ec2conn.DescribeVpnGateways(&ec2.DescribeVpnGatewaysInput{ 309 VpnGatewayIds: []*string{aws.String(rs.Primary.ID)}, 310 }) 311 if err == nil { 312 var v *ec2.VpnGateway 313 for _, g := range resp.VpnGateways { 314 if *g.VpnGatewayId == rs.Primary.ID { 315 v = g 316 } 317 } 318 319 if v == nil { 320 // wasn't found 321 return nil 322 } 323 324 if *v.State != "deleted" { 325 return fmt.Errorf("Expected VPN Gateway to be in deleted state, but was not: %s", v) 326 } 327 return nil 328 } 329 330 // Verify the error is what we want 331 ec2err, ok := err.(awserr.Error) 332 if !ok { 333 return err 334 } 335 if ec2err.Code() != "InvalidVpnGatewayID.NotFound" { 336 return err 337 } 338 } 339 340 return nil 341 } 342 343 func testAccCheckVpnGatewayExists(n string, ig *ec2.VpnGateway) resource.TestCheckFunc { 344 return func(s *terraform.State) error { 345 rs, ok := s.RootModule().Resources[n] 346 if !ok { 347 return fmt.Errorf("Not found: %s", n) 348 } 349 350 if rs.Primary.ID == "" { 351 return fmt.Errorf("No ID is set") 352 } 353 354 ec2conn := testAccProvider.Meta().(*AWSClient).ec2conn 355 resp, err := ec2conn.DescribeVpnGateways(&ec2.DescribeVpnGatewaysInput{ 356 VpnGatewayIds: []*string{aws.String(rs.Primary.ID)}, 357 }) 358 if err != nil { 359 return err 360 } 361 if len(resp.VpnGateways) == 0 { 362 return fmt.Errorf("VPN Gateway not found") 363 } 364 365 *ig = *resp.VpnGateways[0] 366 367 return nil 368 } 369 } 370 371 const testAccNoVpnGatewayConfig = ` 372 resource "aws_vpc" "foo" { 373 cidr_block = "10.1.0.0/16" 374 } 375 ` 376 377 const testAccVpnGatewayConfig = ` 378 resource "aws_vpc" "foo" { 379 cidr_block = "10.1.0.0/16" 380 } 381 382 resource "aws_vpn_gateway" "foo" { 383 vpc_id = "${aws_vpc.foo.id}" 384 } 385 ` 386 387 const testAccVpnGatewayConfigChangeVPC = ` 388 resource "aws_vpc" "bar" { 389 cidr_block = "10.2.0.0/16" 390 } 391 392 resource "aws_vpn_gateway" "foo" { 393 vpc_id = "${aws_vpc.bar.id}" 394 } 395 ` 396 397 const testAccCheckVpnGatewayConfigTags = ` 398 resource "aws_vpc" "foo" { 399 cidr_block = "10.1.0.0/16" 400 } 401 402 resource "aws_vpn_gateway" "foo" { 403 vpc_id = "${aws_vpc.foo.id}" 404 tags { 405 foo = "bar" 406 } 407 } 408 ` 409 410 const testAccCheckVpnGatewayConfigTagsUpdate = ` 411 resource "aws_vpc" "foo" { 412 cidr_block = "10.1.0.0/16" 413 } 414 415 resource "aws_vpn_gateway" "foo" { 416 vpc_id = "${aws_vpc.foo.id}" 417 tags { 418 bar = "baz" 419 } 420 } 421 ` 422 423 const testAccCheckVpnGatewayConfigReattach = ` 424 resource "aws_vpc" "foo" { 425 cidr_block = "10.1.0.0/16" 426 } 427 428 resource "aws_vpc" "bar" { 429 cidr_block = "10.2.0.0/16" 430 } 431 432 resource "aws_vpn_gateway" "foo" { 433 vpc_id = "${aws_vpc.foo.id}" 434 } 435 436 resource "aws_vpn_gateway" "bar" { 437 vpc_id = "${aws_vpc.bar.id}" 438 } 439 ` 440 441 const testAccCheckVpnGatewayConfigReattachChange = ` 442 resource "aws_vpc" "foo" { 443 cidr_block = "10.1.0.0/16" 444 } 445 446 resource "aws_vpc" "bar" { 447 cidr_block = "10.2.0.0/16" 448 } 449 450 resource "aws_vpn_gateway" "foo" { 451 vpc_id = "${aws_vpc.bar.id}" 452 } 453 454 resource "aws_vpn_gateway" "bar" { 455 vpc_id = "${aws_vpc.foo.id}" 456 } 457 ` 458 459 const testAccVpnGatewayConfigWithAZ = ` 460 resource "aws_vpc" "foo" { 461 cidr_block = "10.1.0.0/16" 462 } 463 464 resource "aws_vpn_gateway" "foo" { 465 vpc_id = "${aws_vpc.foo.id}" 466 availability_zone = "us-west-2a" 467 } 468 `