provider/aws: Error on trying to recreate an existing customer gateway (#12501)
Fixes: #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 ```
This commit is contained in:
parent
0b0a76a3d5
commit
b5b53bc56a
|
@ -25,19 +25,19 @@ func resourceAwsCustomerGateway() *schema.Resource {
|
||||||
},
|
},
|
||||||
|
|
||||||
Schema: map[string]*schema.Schema{
|
Schema: map[string]*schema.Schema{
|
||||||
"bgp_asn": &schema.Schema{
|
"bgp_asn": {
|
||||||
Type: schema.TypeInt,
|
Type: schema.TypeInt,
|
||||||
Required: true,
|
Required: true,
|
||||||
ForceNew: true,
|
ForceNew: true,
|
||||||
},
|
},
|
||||||
|
|
||||||
"ip_address": &schema.Schema{
|
"ip_address": {
|
||||||
Type: schema.TypeString,
|
Type: schema.TypeString,
|
||||||
Required: true,
|
Required: true,
|
||||||
ForceNew: true,
|
ForceNew: true,
|
||||||
},
|
},
|
||||||
|
|
||||||
"type": &schema.Schema{
|
"type": {
|
||||||
Type: schema.TypeString,
|
Type: schema.TypeString,
|
||||||
Required: true,
|
Required: true,
|
||||||
ForceNew: true,
|
ForceNew: true,
|
||||||
|
@ -51,10 +51,23 @@ func resourceAwsCustomerGateway() *schema.Resource {
|
||||||
func resourceAwsCustomerGatewayCreate(d *schema.ResourceData, meta interface{}) error {
|
func resourceAwsCustomerGatewayCreate(d *schema.ResourceData, meta interface{}) error {
|
||||||
conn := meta.(*AWSClient).ec2conn
|
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{
|
createOpts := &ec2.CreateCustomerGatewayInput{
|
||||||
BgpAsn: aws.Int64(int64(d.Get("bgp_asn").(int))),
|
BgpAsn: aws.Int64(int64(bgpAsn)),
|
||||||
PublicIp: aws.String(d.Get("ip_address").(string)),
|
PublicIp: aws.String(ipAddress),
|
||||||
Type: aws.String(d.Get("type").(string)),
|
Type: aws.String(vpnType),
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create the Customer Gateway.
|
// Create the Customer Gateway.
|
||||||
|
@ -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 {
|
func resourceAwsCustomerGatewayRead(d *schema.ResourceData, meta interface{}) error {
|
||||||
conn := meta.(*AWSClient).ec2conn
|
conn := meta.(*AWSClient).ec2conn
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,7 @@ package aws
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"regexp"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
@ -21,19 +22,19 @@ func TestAccAWSCustomerGateway_basic(t *testing.T) {
|
||||||
Providers: testAccProviders,
|
Providers: testAccProviders,
|
||||||
CheckDestroy: testAccCheckCustomerGatewayDestroy,
|
CheckDestroy: testAccCheckCustomerGatewayDestroy,
|
||||||
Steps: []resource.TestStep{
|
Steps: []resource.TestStep{
|
||||||
resource.TestStep{
|
{
|
||||||
Config: testAccCustomerGatewayConfig,
|
Config: testAccCustomerGatewayConfig,
|
||||||
Check: resource.ComposeTestCheckFunc(
|
Check: resource.ComposeTestCheckFunc(
|
||||||
testAccCheckCustomerGateway("aws_customer_gateway.foo", &gateway),
|
testAccCheckCustomerGateway("aws_customer_gateway.foo", &gateway),
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
resource.TestStep{
|
{
|
||||||
Config: testAccCustomerGatewayConfigUpdateTags,
|
Config: testAccCustomerGatewayConfigUpdateTags,
|
||||||
Check: resource.ComposeTestCheckFunc(
|
Check: resource.ComposeTestCheckFunc(
|
||||||
testAccCheckCustomerGateway("aws_customer_gateway.foo", &gateway),
|
testAccCheckCustomerGateway("aws_customer_gateway.foo", &gateway),
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
resource.TestStep{
|
{
|
||||||
Config: testAccCustomerGatewayConfigForceReplace,
|
Config: testAccCustomerGatewayConfigForceReplace,
|
||||||
Check: resource.ComposeTestCheckFunc(
|
Check: resource.ComposeTestCheckFunc(
|
||||||
testAccCheckCustomerGateway("aws_customer_gateway.foo", &gateway),
|
testAccCheckCustomerGateway("aws_customer_gateway.foo", &gateway),
|
||||||
|
@ -43,6 +44,28 @@ 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) {
|
func TestAccAWSCustomerGateway_disappears(t *testing.T) {
|
||||||
var gateway ec2.CustomerGateway
|
var gateway ec2.CustomerGateway
|
||||||
resource.Test(t, resource.TestCase{
|
resource.Test(t, resource.TestCase{
|
||||||
|
@ -50,7 +73,7 @@ func TestAccAWSCustomerGateway_disappears(t *testing.T) {
|
||||||
Providers: testAccProviders,
|
Providers: testAccProviders,
|
||||||
CheckDestroy: testAccCheckCustomerGatewayDestroy,
|
CheckDestroy: testAccCheckCustomerGatewayDestroy,
|
||||||
Steps: []resource.TestStep{
|
Steps: []resource.TestStep{
|
||||||
resource.TestStep{
|
{
|
||||||
Config: testAccCustomerGatewayConfig,
|
Config: testAccCustomerGatewayConfig,
|
||||||
Check: resource.ComposeTestCheckFunc(
|
Check: resource.ComposeTestCheckFunc(
|
||||||
testAccCheckCustomerGateway("aws_customer_gateway.foo", &gateway),
|
testAccCheckCustomerGateway("aws_customer_gateway.foo", &gateway),
|
||||||
|
@ -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.
|
// Add the Another: "tag" tag.
|
||||||
const testAccCustomerGatewayConfigUpdateTags = `
|
const testAccCustomerGatewayConfigUpdateTags = `
|
||||||
resource "aws_customer_gateway" "foo" {
|
resource "aws_customer_gateway" "foo" {
|
||||||
|
|
Loading…
Reference in New Issue