github.com/koding/terraform@v0.6.4-0.20170608090606-5d7e0339779d/builtin/providers/aws/resource_aws_vpn_connection_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 12 "github.com/hashicorp/terraform/helper/acctest" 13 "github.com/hashicorp/terraform/helper/resource" 14 "github.com/hashicorp/terraform/terraform" 15 ) 16 17 func TestAccAWSVpnConnection_basic(t *testing.T) { 18 rInt := acctest.RandInt() 19 rBgpAsn := acctest.RandIntRange(64512, 65534) 20 var vpn ec2.VpnConnection 21 22 resource.Test(t, resource.TestCase{ 23 PreCheck: func() { testAccPreCheck(t) }, 24 IDRefreshName: "aws_vpn_connection.foo", 25 Providers: testAccProviders, 26 CheckDestroy: testAccAwsVpnConnectionDestroy, 27 Steps: []resource.TestStep{ 28 { 29 Config: testAccAwsVpnConnectionConfig(rBgpAsn), 30 Check: resource.ComposeTestCheckFunc( 31 testAccAwsVpnConnection( 32 "aws_vpc.vpc", 33 "aws_vpn_gateway.vpn_gateway", 34 "aws_customer_gateway.customer_gateway", 35 "aws_vpn_connection.foo", 36 &vpn, 37 ), 38 ), 39 }, 40 { 41 Config: testAccAwsVpnConnectionConfigUpdate(rInt, rBgpAsn), 42 Check: resource.ComposeTestCheckFunc( 43 testAccAwsVpnConnection( 44 "aws_vpc.vpc", 45 "aws_vpn_gateway.vpn_gateway", 46 "aws_customer_gateway.customer_gateway", 47 "aws_vpn_connection.foo", 48 &vpn, 49 ), 50 ), 51 }, 52 }, 53 }) 54 } 55 56 func TestAccAWSVpnConnection_withoutStaticRoutes(t *testing.T) { 57 rInt := acctest.RandInt() 58 rBgpAsn := acctest.RandIntRange(64512, 65534) 59 var vpn ec2.VpnConnection 60 resource.Test(t, resource.TestCase{ 61 PreCheck: func() { testAccPreCheck(t) }, 62 IDRefreshName: "aws_vpn_connection.foo", 63 Providers: testAccProviders, 64 CheckDestroy: testAccAwsVpnConnectionDestroy, 65 Steps: []resource.TestStep{ 66 { 67 Config: testAccAwsVpnConnectionConfigUpdate(rInt, rBgpAsn), 68 Check: resource.ComposeTestCheckFunc( 69 testAccAwsVpnConnection( 70 "aws_vpc.vpc", 71 "aws_vpn_gateway.vpn_gateway", 72 "aws_customer_gateway.customer_gateway", 73 "aws_vpn_connection.foo", 74 &vpn, 75 ), 76 resource.TestCheckResourceAttr("aws_vpn_connection.foo", "static_routes_only", "false"), 77 ), 78 }, 79 }, 80 }) 81 } 82 83 func TestAccAWSVpnConnection_disappears(t *testing.T) { 84 rBgpAsn := acctest.RandIntRange(64512, 65534) 85 var vpn ec2.VpnConnection 86 87 resource.Test(t, resource.TestCase{ 88 PreCheck: func() { testAccPreCheck(t) }, 89 Providers: testAccProviders, 90 CheckDestroy: testAccAwsVpnConnectionDestroy, 91 Steps: []resource.TestStep{ 92 { 93 Config: testAccAwsVpnConnectionConfig(rBgpAsn), 94 Check: resource.ComposeTestCheckFunc( 95 testAccAwsVpnConnection( 96 "aws_vpc.vpc", 97 "aws_vpn_gateway.vpn_gateway", 98 "aws_customer_gateway.customer_gateway", 99 "aws_vpn_connection.foo", 100 &vpn, 101 ), 102 testAccAWSVpnConnectionDisappears(&vpn), 103 ), 104 ExpectNonEmptyPlan: true, 105 }, 106 }, 107 }) 108 } 109 110 func testAccAWSVpnConnectionDisappears(connection *ec2.VpnConnection) resource.TestCheckFunc { 111 return func(s *terraform.State) error { 112 conn := testAccProvider.Meta().(*AWSClient).ec2conn 113 114 _, err := conn.DeleteVpnConnection(&ec2.DeleteVpnConnectionInput{ 115 VpnConnectionId: connection.VpnConnectionId, 116 }) 117 if err != nil { 118 if ec2err, ok := err.(awserr.Error); ok && ec2err.Code() == "InvalidVpnConnectionID.NotFound" { 119 return nil 120 } 121 if err != nil { 122 return err 123 } 124 } 125 126 return resource.Retry(40*time.Minute, func() *resource.RetryError { 127 opts := &ec2.DescribeVpnConnectionsInput{ 128 VpnConnectionIds: []*string{connection.VpnConnectionId}, 129 } 130 resp, err := conn.DescribeVpnConnections(opts) 131 if err != nil { 132 cgw, ok := err.(awserr.Error) 133 if ok && cgw.Code() == "InvalidVpnConnectionID.NotFound" { 134 return nil 135 } 136 if ok && cgw.Code() == "IncorrectState" { 137 return resource.RetryableError(fmt.Errorf( 138 "Waiting for VPN Connection to be in the correct state: %v", connection.VpnConnectionId)) 139 } 140 return resource.NonRetryableError( 141 fmt.Errorf("Error retrieving VPN Connection: %s", err)) 142 } 143 if *resp.VpnConnections[0].State == "deleted" { 144 return nil 145 } 146 return resource.RetryableError(fmt.Errorf( 147 "Waiting for VPN Connection: %v", connection.VpnConnectionId)) 148 }) 149 } 150 } 151 152 func testAccAwsVpnConnectionDestroy(s *terraform.State) error { 153 conn := testAccProvider.Meta().(*AWSClient).ec2conn 154 for _, rs := range s.RootModule().Resources { 155 if rs.Type != "aws_vpn_connection" { 156 continue 157 } 158 159 resp, err := conn.DescribeVpnConnections(&ec2.DescribeVpnConnectionsInput{ 160 VpnConnectionIds: []*string{aws.String(rs.Primary.ID)}, 161 }) 162 163 if err != nil { 164 if ec2err, ok := err.(awserr.Error); ok && ec2err.Code() == "InvalidVpnConnectionID.NotFound" { 165 // not found 166 return nil 167 } 168 return err 169 } 170 171 var vpn *ec2.VpnConnection 172 for _, v := range resp.VpnConnections { 173 if v.VpnConnectionId != nil && *v.VpnConnectionId == rs.Primary.ID { 174 vpn = v 175 } 176 } 177 178 if vpn == nil { 179 // vpn connection not found 180 return nil 181 } 182 183 if vpn.State != nil && *vpn.State == "deleted" { 184 return nil 185 } 186 187 } 188 189 return nil 190 } 191 192 func testAccAwsVpnConnection( 193 vpcResource string, 194 vpnGatewayResource string, 195 customerGatewayResource string, 196 vpnConnectionResource string, 197 vpnConnection *ec2.VpnConnection) resource.TestCheckFunc { 198 return func(s *terraform.State) error { 199 rs, ok := s.RootModule().Resources[vpnConnectionResource] 200 if !ok { 201 return fmt.Errorf("Not found: %s", vpnConnectionResource) 202 } 203 204 if rs.Primary.ID == "" { 205 return fmt.Errorf("No ID is set") 206 } 207 connection, ok := s.RootModule().Resources[vpnConnectionResource] 208 if !ok { 209 return fmt.Errorf("Not found: %s", vpnConnectionResource) 210 } 211 212 ec2conn := testAccProvider.Meta().(*AWSClient).ec2conn 213 214 resp, err := ec2conn.DescribeVpnConnections(&ec2.DescribeVpnConnectionsInput{ 215 VpnConnectionIds: []*string{aws.String(connection.Primary.ID)}, 216 }) 217 218 if err != nil { 219 return err 220 } 221 222 *vpnConnection = *resp.VpnConnections[0] 223 224 return nil 225 } 226 } 227 228 func TestAWSVpnConnection_xmlconfig(t *testing.T) { 229 tunnelInfo, err := xmlConfigToTunnelInfo(testAccAwsVpnTunnelInfoXML) 230 if err != nil { 231 t.Fatalf("Error unmarshalling XML: %s", err) 232 } 233 if tunnelInfo.Tunnel1Address != "FIRST_ADDRESS" { 234 t.Fatalf("First address from tunnel XML was incorrect.") 235 } 236 if tunnelInfo.Tunnel1CgwInsideAddress != "FIRST_CGW_INSIDE_ADDRESS" { 237 t.Fatalf("First Customer Gateway inside address from tunnel" + 238 " XML was incorrect.") 239 } 240 if tunnelInfo.Tunnel1VgwInsideAddress != "FIRST_VGW_INSIDE_ADDRESS" { 241 t.Fatalf("First VPN Gateway inside address from tunnel " + 242 " XML was incorrect.") 243 } 244 if tunnelInfo.Tunnel1PreSharedKey != "FIRST_KEY" { 245 t.Fatalf("First key from tunnel XML was incorrect.") 246 } 247 if tunnelInfo.Tunnel2Address != "SECOND_ADDRESS" { 248 t.Fatalf("Second address from tunnel XML was incorrect.") 249 } 250 if tunnelInfo.Tunnel2CgwInsideAddress != "SECOND_CGW_INSIDE_ADDRESS" { 251 t.Fatalf("Second Customer Gateway inside address from tunnel" + 252 " XML was incorrect.") 253 } 254 if tunnelInfo.Tunnel2VgwInsideAddress != "SECOND_VGW_INSIDE_ADDRESS" { 255 t.Fatalf("Second VPN Gateway inside address from tunnel " + 256 " XML was incorrect.") 257 } 258 if tunnelInfo.Tunnel2PreSharedKey != "SECOND_KEY" { 259 t.Fatalf("Second key from tunnel XML was incorrect.") 260 } 261 } 262 263 func testAccAwsVpnConnectionConfig(rBgpAsn int) string { 264 return fmt.Sprintf(` 265 resource "aws_vpn_gateway" "vpn_gateway" { 266 tags { 267 Name = "vpn_gateway" 268 } 269 } 270 271 resource "aws_customer_gateway" "customer_gateway" { 272 bgp_asn = %d 273 ip_address = "178.0.0.1" 274 type = "ipsec.1" 275 tags { 276 Name = "main-customer-gateway" 277 } 278 } 279 280 resource "aws_vpn_connection" "foo" { 281 vpn_gateway_id = "${aws_vpn_gateway.vpn_gateway.id}" 282 customer_gateway_id = "${aws_customer_gateway.customer_gateway.id}" 283 type = "ipsec.1" 284 static_routes_only = true 285 } 286 `, rBgpAsn) 287 } 288 289 // Change static_routes_only to be false, forcing a refresh. 290 func testAccAwsVpnConnectionConfigUpdate(rInt, rBgpAsn int) string { 291 return fmt.Sprintf(` 292 resource "aws_vpn_gateway" "vpn_gateway" { 293 tags { 294 Name = "vpn_gateway" 295 } 296 } 297 298 resource "aws_customer_gateway" "customer_gateway" { 299 bgp_asn = %d 300 ip_address = "178.0.0.1" 301 type = "ipsec.1" 302 tags { 303 Name = "main-customer-gateway-%d" 304 } 305 } 306 307 resource "aws_vpn_connection" "foo" { 308 vpn_gateway_id = "${aws_vpn_gateway.vpn_gateway.id}" 309 customer_gateway_id = "${aws_customer_gateway.customer_gateway.id}" 310 type = "ipsec.1" 311 static_routes_only = false 312 } 313 `, rBgpAsn, rInt) 314 } 315 316 // Test our VPN tunnel config XML parsing 317 const testAccAwsVpnTunnelInfoXML = ` 318 <vpn_connection id="vpn-abc123"> 319 <ipsec_tunnel> 320 <customer_gateway> 321 <tunnel_outside_address> 322 <ip_address>123.123.123.123</ip_address> 323 </tunnel_outside_address> 324 <tunnel_inside_address> 325 <ip_address>SECOND_CGW_INSIDE_ADDRESS</ip_address> 326 <network_mask>255.255.255.252</network_mask> 327 <network_cidr>30</network_cidr> 328 </tunnel_inside_address> 329 </customer_gateway> 330 <vpn_gateway> 331 <tunnel_outside_address> 332 <ip_address>SECOND_ADDRESS</ip_address> 333 </tunnel_outside_address> 334 <tunnel_inside_address> 335 <ip_address>SECOND_VGW_INSIDE_ADDRESS</ip_address> 336 <network_mask>255.255.255.252</network_mask> 337 <network_cidr>30</network_cidr> 338 </tunnel_inside_address> 339 </vpn_gateway> 340 <ike> 341 <pre_shared_key>SECOND_KEY</pre_shared_key> 342 </ike> 343 </ipsec_tunnel> 344 <ipsec_tunnel> 345 <customer_gateway> 346 <tunnel_outside_address> 347 <ip_address>123.123.123.123</ip_address> 348 </tunnel_outside_address> 349 <tunnel_inside_address> 350 <ip_address>FIRST_CGW_INSIDE_ADDRESS</ip_address> 351 <network_mask>255.255.255.252</network_mask> 352 <network_cidr>30</network_cidr> 353 </tunnel_inside_address> 354 </customer_gateway> 355 <vpn_gateway> 356 <tunnel_outside_address> 357 <ip_address>FIRST_ADDRESS</ip_address> 358 </tunnel_outside_address> 359 <tunnel_inside_address> 360 <ip_address>FIRST_VGW_INSIDE_ADDRESS</ip_address> 361 <network_mask>255.255.255.252</network_mask> 362 <network_cidr>30</network_cidr> 363 </tunnel_inside_address> 364 </vpn_gateway> 365 <ike> 366 <pre_shared_key>FIRST_KEY</pre_shared_key> 367 </ike> 368 </ipsec_tunnel> 369 </vpn_connection> 370 `