Skip to content

Commit

Permalink
provider/aws: Error on trying to recreate an existing customer gateway (
Browse files Browse the repository at this point in the history
hashicorp#12501)

Fixes: hashicorp#7492

When we use the same IP Address, BGP ASN and VPN Type as an existing
aws_customer_gateway, terraform will take control of that gateway (not
import it!) and try and modify it. This could be very bad

There is a warning on the AWS documentation that one gateway of the same
parameters can be created, Terraform is now going to error if a gateway
of the same parameters is attempted to be created

```
% make testacc TEST=./builtin/providers/aws TESTARGS='-run=TestAccAWSCustomerGateway_'
==> Checking that code complies with gofmt requirements...
go generate $(go list ./... | grep -v /terraform/vendor/)
2017/03/07 18:40:39 Generated command/internal_plugin_list.go
TF_ACC=1 go test ./builtin/providers/aws -v -run=TestAccAWSCustomerGateway_ -timeout 120m
=== RUN   TestAccAWSCustomerGateway_importBasic
--- PASS: TestAccAWSCustomerGateway_importBasic (31.11s)
=== RUN   TestAccAWSCustomerGateway_basic
--- PASS: TestAccAWSCustomerGateway_basic (68.72s)
=== RUN   TestAccAWSCustomerGateway_similarAlreadyExists
--- PASS: TestAccAWSCustomerGateway_similarAlreadyExists (35.18s)
=== RUN   TestAccAWSCustomerGateway_disappears
--- PASS: TestAccAWSCustomerGateway_disappears (25.13s)
PASS
ok  	github.com/hashicorp/terraform/builtin/providers/aws	160.172s
```
  • Loading branch information
stack72 authored and Yann DEGAT committed Mar 13, 2017
1 parent 87406ac commit 9d23aec
Show file tree
Hide file tree
Showing 2 changed files with 97 additions and 10 deletions.
56 changes: 50 additions & 6 deletions builtin/providers/aws/resource_aws_customer_gateway.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,19 +25,19 @@ func resourceAwsCustomerGateway() *schema.Resource {
},

Schema: map[string]*schema.Schema{
"bgp_asn": &schema.Schema{
"bgp_asn": {
Type: schema.TypeInt,
Required: true,
ForceNew: true,
},

"ip_address": &schema.Schema{
"ip_address": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
},

"type": &schema.Schema{
"type": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
Expand All @@ -51,10 +51,23 @@ func resourceAwsCustomerGateway() *schema.Resource {
func resourceAwsCustomerGatewayCreate(d *schema.ResourceData, meta interface{}) error {
conn := meta.(*AWSClient).ec2conn

ipAddress := d.Get("ip_address").(string)
vpnType := d.Get("type").(string)
bgpAsn := d.Get("bgp_asn").(int)

alreadyExists, err := resourceAwsCustomerGatewayExists(vpnType, ipAddress, bgpAsn, conn)
if err != nil {
return err
}

if alreadyExists {
return fmt.Errorf("An existing customer gateway for IpAddress: %s, VpnType: %s, BGP ASN: %d has been found", ipAddress, vpnType, bgpAsn)
}

createOpts := &ec2.CreateCustomerGatewayInput{
BgpAsn: aws.Int64(int64(d.Get("bgp_asn").(int))),
PublicIp: aws.String(d.Get("ip_address").(string)),
Type: aws.String(d.Get("type").(string)),
BgpAsn: aws.Int64(int64(bgpAsn)),
PublicIp: aws.String(ipAddress),
Type: aws.String(vpnType),
}

// Create the Customer Gateway.
Expand Down Expand Up @@ -123,6 +136,37 @@ func customerGatewayRefreshFunc(conn *ec2.EC2, gatewayId string) resource.StateR
}
}

func resourceAwsCustomerGatewayExists(vpnType, ipAddress string, bgpAsn int, conn *ec2.EC2) (bool, error) {
ipAddressFilter := &ec2.Filter{
Name: aws.String("ip-address"),
Values: []*string{aws.String(ipAddress)},
}

typeFilter := &ec2.Filter{
Name: aws.String("type"),
Values: []*string{aws.String(vpnType)},
}

bgp := strconv.Itoa(bgpAsn)
bgpAsnFilter := &ec2.Filter{
Name: aws.String("bgp-asn"),
Values: []*string{aws.String(bgp)},
}

resp, err := conn.DescribeCustomerGateways(&ec2.DescribeCustomerGatewaysInput{
Filters: []*ec2.Filter{ipAddressFilter, typeFilter, bgpAsnFilter},
})
if err != nil {
return false, err
}

if len(resp.CustomerGateways) > 0 && *resp.CustomerGateways[0].State != "deleted" {
return true, nil
}

return false, nil
}

func resourceAwsCustomerGatewayRead(d *schema.ResourceData, meta interface{}) error {
conn := meta.(*AWSClient).ec2conn

Expand Down
51 changes: 47 additions & 4 deletions builtin/providers/aws/resource_aws_customer_gateway_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package aws

import (
"fmt"
"regexp"
"testing"
"time"

Expand All @@ -21,19 +22,19 @@ func TestAccAWSCustomerGateway_basic(t *testing.T) {
Providers: testAccProviders,
CheckDestroy: testAccCheckCustomerGatewayDestroy,
Steps: []resource.TestStep{
resource.TestStep{
{
Config: testAccCustomerGatewayConfig,
Check: resource.ComposeTestCheckFunc(
testAccCheckCustomerGateway("aws_customer_gateway.foo", &gateway),
),
},
resource.TestStep{
{
Config: testAccCustomerGatewayConfigUpdateTags,
Check: resource.ComposeTestCheckFunc(
testAccCheckCustomerGateway("aws_customer_gateway.foo", &gateway),
),
},
resource.TestStep{
{
Config: testAccCustomerGatewayConfigForceReplace,
Check: resource.ComposeTestCheckFunc(
testAccCheckCustomerGateway("aws_customer_gateway.foo", &gateway),
Expand All @@ -43,14 +44,36 @@ func TestAccAWSCustomerGateway_basic(t *testing.T) {
})
}

func TestAccAWSCustomerGateway_similarAlreadyExists(t *testing.T) {
var gateway ec2.CustomerGateway
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
IDRefreshName: "aws_customer_gateway.foo",
Providers: testAccProviders,
CheckDestroy: testAccCheckCustomerGatewayDestroy,
Steps: []resource.TestStep{
{
Config: testAccCustomerGatewayConfig,
Check: resource.ComposeTestCheckFunc(
testAccCheckCustomerGateway("aws_customer_gateway.foo", &gateway),
),
},
{
Config: testAccCustomerGatewayConfigIdentical,
ExpectError: regexp.MustCompile("An existing customer gateway"),
},
},
})
}

func TestAccAWSCustomerGateway_disappears(t *testing.T) {
var gateway ec2.CustomerGateway
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckCustomerGatewayDestroy,
Steps: []resource.TestStep{
resource.TestStep{
{
Config: testAccCustomerGatewayConfig,
Check: resource.ComposeTestCheckFunc(
testAccCheckCustomerGateway("aws_customer_gateway.foo", &gateway),
Expand Down Expand Up @@ -178,6 +201,26 @@ resource "aws_customer_gateway" "foo" {
}
`

const testAccCustomerGatewayConfigIdentical = `
resource "aws_customer_gateway" "foo" {
bgp_asn = 65000
ip_address = "172.0.0.1"
type = "ipsec.1"
tags {
Name = "foo-gateway"
}
}
resource "aws_customer_gateway" "identical" {
bgp_asn = 65000
ip_address = "172.0.0.1"
type = "ipsec.1"
tags {
Name = "foo-gateway-identical"
}
}
`

// Add the Another: "tag" tag.
const testAccCustomerGatewayConfigUpdateTags = `
resource "aws_customer_gateway" "foo" {
Expand Down

0 comments on commit 9d23aec

Please sign in to comment.