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