Skip to content

Commit

Permalink
r/aws_dx_gateway_association: Update for transit gateway support plus…
Browse files Browse the repository at this point in the history
… the second half (cross-account proposal acceptance) of support for Gateway Association Proposals (#8528)

r/aws_dx_gateway_association: Update for transit gateway support plus the second half (cross-account proposal acceptance) of support for Gateway Association Proposals
  • Loading branch information
nywilken authored May 24, 2019
2 parents 7acc9ba + 93e2df2 commit 08f2a8f
Show file tree
Hide file tree
Showing 11 changed files with 968 additions and 193 deletions.
257 changes: 191 additions & 66 deletions aws/resource_aws_dx_gateway_association.go

Large diffs are not rendered by default.

64 changes: 57 additions & 7 deletions aws/resource_aws_dx_gateway_association_proposal.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (

"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/service/directconnect"
"github.com/hashicorp/terraform/helper/customdiff"
"github.com/hashicorp/terraform/helper/schema"
)

Expand All @@ -18,14 +19,43 @@ func resourceAwsDxGatewayAssociationProposal() *schema.Resource {
State: schema.ImportStatePassthrough,
},

CustomizeDiff: customdiff.Sequence(
// Accepting the proposal with overridden prefixes changes the returned RequestedAllowedPrefixesToDirectConnectGateway value (allowed_prefixes attribute).
// We only want to force a new resource if this value changes and the current proposal state is "requested".
customdiff.ForceNewIf("allowed_prefixes", func(d *schema.ResourceDiff, meta interface{}) bool {
conn := meta.(*AWSClient).dxconn

proposal, err := describeDirectConnectGatewayAssociationProposal(conn, d.Id())
if err != nil {
log.Printf("[ERROR] Error reading Direct Connect Gateway Association Proposal (%s): %s", d.Id(), err)
return false
}

return proposal != nil && aws.StringValue(proposal.ProposalState) == directconnect.GatewayAssociationProposalStateRequested
}),
),

Schema: map[string]*schema.Schema{
"allowed_prefixes": {
Type: schema.TypeSet,
Optional: true,
Computed: true,
ForceNew: true,
Elem: &schema.Schema{Type: schema.TypeString},
},
"associated_gateway_id": {
Type: schema.TypeString,
Optional: true,
ForceNew: true,
ConflictsWith: []string{"vpn_gateway_id"},
},
"associated_gateway_owner_account_id": {
Type: schema.TypeString,
Computed: true,
},
"associated_gateway_type": {
Type: schema.TypeString,
Computed: true,
},
"dx_gateway_id": {
Type: schema.TypeString,
Required: true,
Expand All @@ -38,9 +68,11 @@ func resourceAwsDxGatewayAssociationProposal() *schema.Resource {
ValidateFunc: validateAwsAccountId,
},
"vpn_gateway_id": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
Type: schema.TypeString,
Optional: true,
ForceNew: true,
ConflictsWith: []string{"associated_gateway_id"},
Deprecated: "use 'associated_gateway_id' argument instead",
},
},
}
Expand All @@ -49,13 +81,25 @@ func resourceAwsDxGatewayAssociationProposal() *schema.Resource {
func resourceAwsDxGatewayAssociationProposalCreate(d *schema.ResourceData, meta interface{}) error {
conn := meta.(*AWSClient).dxconn

allowedPrefixes := expandDirectConnectGatewayAssociationProposalAllowedPrefixes(d.Get("allowed_prefixes").(*schema.Set).List())
input := &directconnect.CreateDirectConnectGatewayAssociationProposalInput{
AddAllowedPrefixesToDirectConnectGateway: expandDirectConnectGatewayAssociationProposalAllowedPrefixes(d.Get("allowed_prefixes").(*schema.Set).List()),
AddAllowedPrefixesToDirectConnectGateway: allowedPrefixes,
DirectConnectGatewayId: aws.String(d.Get("dx_gateway_id").(string)),
DirectConnectGatewayOwnerAccount: aws.String(d.Get("dx_gateway_owner_account_id").(string)),
GatewayId: aws.String(d.Get("vpn_gateway_id").(string)),
}
var gwID string
if v, ok := d.GetOk("vpn_gateway_id"); ok {
gwID = v.(string)
} else if v, ok := d.GetOk("associated_gateway_id"); ok {
gwID = v.(string)
}

if gwID == "" {
return fmt.Errorf("gateway id not provided, one of associated_gateway_id or vpn_gateway_id must be configured")
}

input.GatewayId = aws.String(gwID)

log.Printf("[DEBUG] Creating Direct Connect Gateway Association Proposal: %s", input)
output, err := conn.CreateDirectConnectGatewayAssociationProposal(input)

Expand Down Expand Up @@ -97,9 +141,15 @@ func resourceAwsDxGatewayAssociationProposalRead(d *schema.ResourceData, meta in
return fmt.Errorf("error setting allowed_prefixes: %s", err)
}

if _, ok := d.GetOk("vpn_gateway_id"); ok {
d.Set("vpn_gateway_id", aws.StringValue(proposal.AssociatedGateway.Id))
} else {
d.Set("associated_gateway_id", aws.StringValue(proposal.AssociatedGateway.Id))
}
d.Set("associated_gateway_owner_account_id", proposal.AssociatedGateway.OwnerAccount)
d.Set("associated_gateway_type", proposal.AssociatedGateway.Type)
d.Set("dx_gateway_id", aws.StringValue(proposal.DirectConnectGatewayId))
d.Set("dx_gateway_owner_account_id", aws.StringValue(proposal.DirectConnectGatewayOwnerAccount))
d.Set("vpn_gateway_id", aws.StringValue(proposal.AssociatedGateway.Id))

return nil
}
Expand Down
145 changes: 132 additions & 13 deletions aws/resource_aws_dx_gateway_association_proposal_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,14 @@ import (
"github.com/hashicorp/terraform/terraform"
)

func TestAccAwsDxGatewayAssociationProposal_basic(t *testing.T) {
func TestAccAwsDxGatewayAssociationProposal_VpnGatewayId(t *testing.T) {
var proposal1 directconnect.GatewayAssociationProposal
var providers []*schema.Provider
rBgpAsn := randIntRange(64512, 65534)
rName := acctest.RandomWithPrefix("tf-acc-test")
resourceName := "aws_dx_gateway_association_proposal.test"
resourceNameDxGw := "aws_dx_gateway.test"
resourceNameVgw := "aws_vpn_gateway.test"

resource.ParallelTest(t, resource.TestCase{
PreCheck: func() {
Expand All @@ -28,14 +30,93 @@ func TestAccAwsDxGatewayAssociationProposal_basic(t *testing.T) {
CheckDestroy: testAccCheckAwsDxGatewayAssociationProposalDestroy,
Steps: []resource.TestStep{
{
Config: testAccDxGatewayAssociationProposalConfig(rName, rBgpAsn),
Config: testAccDxGatewayAssociationProposalConfig_vpnGatewayId(rName, rBgpAsn),
Check: resource.ComposeTestCheckFunc(
testAccCheckAwsDxGatewayAssociationProposalExists(resourceName, &proposal1),
resource.TestCheckResourceAttrPair(resourceName, "dx_gateway_id", resourceNameDxGw, "id"),
resource.TestCheckResourceAttrPair(resourceName, "vpn_gateway_id", resourceNameVgw, "id"),
resource.TestCheckNoResourceAttr(resourceName, "associated_gateway_id"),
testAccCheckResourceAttrAccountID(resourceName, "associated_gateway_owner_account_id"),
resource.TestCheckResourceAttr(resourceName, "associated_gateway_type", "virtualPrivateGateway"),
resource.TestCheckResourceAttr(resourceName, "allowed_prefixes.#", "1"),
),
},
},
})
}

func TestAccAwsDxGatewayAssociationProposal_basicVpnGateway(t *testing.T) {
var proposal1 directconnect.GatewayAssociationProposal
var providers []*schema.Provider
rBgpAsn := randIntRange(64512, 65534)
rName := acctest.RandomWithPrefix("tf-acc-test")
resourceName := "aws_dx_gateway_association_proposal.test"
resourceNameDxGw := "aws_dx_gateway.test"
resourceNameVgw := "aws_vpn_gateway.test"

resource.ParallelTest(t, resource.TestCase{
PreCheck: func() {
testAccPreCheck(t)
testAccAlternateAccountPreCheck(t)
},
ProviderFactories: testAccProviderFactories(&providers),
CheckDestroy: testAccCheckAwsDxGatewayAssociationProposalDestroy,
Steps: []resource.TestStep{
{
Config: testAccDxGatewayAssociationProposalConfig_basicVpnGateway(rName, rBgpAsn),
Check: resource.ComposeTestCheckFunc(
testAccCheckAwsDxGatewayAssociationProposalExists(resourceName, &proposal1),
resource.TestCheckResourceAttrPair(resourceName, "dx_gateway_id", resourceNameDxGw, "id"),
resource.TestCheckResourceAttrPair(resourceName, "associated_gateway_id", resourceNameVgw, "id"),
resource.TestCheckNoResourceAttr(resourceName, "vpn_gateway_id"),
testAccCheckResourceAttrAccountID(resourceName, "associated_gateway_owner_account_id"),
resource.TestCheckResourceAttr(resourceName, "associated_gateway_type", "virtualPrivateGateway"),
resource.TestCheckResourceAttr(resourceName, "allowed_prefixes.#", "1"),
),
},
{
Config: testAccDxGatewayAssociationProposalConfig_basicVpnGateway(rName, rBgpAsn),
ResourceName: resourceName,
ImportState: true,
ImportStateVerify: true,
},
},
})
}

func TestAccAwsDxGatewayAssociationProposal_basicTransitGateway(t *testing.T) {
var proposal1 directconnect.GatewayAssociationProposal
var providers []*schema.Provider
rBgpAsn := randIntRange(64512, 65534)
rName := acctest.RandomWithPrefix("tf-acc-test")
resourceName := "aws_dx_gateway_association_proposal.test"
resourceNameDxGw := "aws_dx_gateway.test"
resourceNameTgw := "aws_ec2_transit_gateway.test"

resource.ParallelTest(t, resource.TestCase{
PreCheck: func() {
testAccPreCheck(t)
testAccAlternateAccountPreCheck(t)
},
ProviderFactories: testAccProviderFactories(&providers),
CheckDestroy: testAccCheckAwsDxGatewayAssociationProposalDestroy,
Steps: []resource.TestStep{
{
Config: testAccDxGatewayAssociationProposalConfig(rName, rBgpAsn),
Config: testAccDxGatewayAssociationProposalConfig_basicTransitGateway(rName, rBgpAsn),
Check: resource.ComposeTestCheckFunc(
testAccCheckAwsDxGatewayAssociationProposalExists(resourceName, &proposal1),
resource.TestCheckResourceAttrPair(resourceName, "dx_gateway_id", resourceNameDxGw, "id"),
resource.TestCheckResourceAttrPair(resourceName, "associated_gateway_id", resourceNameTgw, "id"),
resource.TestCheckNoResourceAttr(resourceName, "vpn_gateway_id"),
testAccCheckResourceAttrAccountID(resourceName, "associated_gateway_owner_account_id"),
resource.TestCheckResourceAttr(resourceName, "associated_gateway_type", "transitGateway"),
resource.TestCheckResourceAttr(resourceName, "allowed_prefixes.#", "2"),
resource.TestCheckResourceAttr(resourceName, "allowed_prefixes.2173830893", "10.255.255.0/30"),
resource.TestCheckResourceAttr(resourceName, "allowed_prefixes.2984398124", "10.255.255.8/30"),
),
},
{
Config: testAccDxGatewayAssociationProposalConfig_basicVpnGateway(rName, rBgpAsn),
ResourceName: resourceName,
ImportState: true,
ImportStateVerify: true,
Expand All @@ -60,7 +141,7 @@ func TestAccAwsDxGatewayAssociationProposal_disappears(t *testing.T) {
CheckDestroy: testAccCheckAwsDxGatewayAssociationProposalDestroy,
Steps: []resource.TestStep{
{
Config: testAccDxGatewayAssociationProposalConfig(rName, rBgpAsn),
Config: testAccDxGatewayAssociationProposalConfig_basicVpnGateway(rName, rBgpAsn),
Check: resource.ComposeTestCheckFunc(
testAccCheckAwsDxGatewayAssociationProposalExists(resourceName, &proposal1),
testAccCheckAwsDxGatewayAssociationProposalDisappears(&proposal1),
Expand Down Expand Up @@ -184,7 +265,7 @@ func testAccCheckAwsDxGatewayAssociationProposalRecreated(i, j *directconnect.Ga
}
}

func testAccDxGatewayAssociationProposalConfigBase(rName string, rBgpAsn int) string {
func testAccDxGatewayAssociationProposalConfigBase_vpnGateway(rName string, rBgpAsn int) string {
return testAccAlternateAccountProviderConfig() + fmt.Sprintf(`
resource "aws_dx_gateway" "test" {
provider = "aws.alternate"
Expand All @@ -197,22 +278,22 @@ resource "aws_vpc" "test" {
cidr_block = "10.0.0.0/16"
tags = {
Name = "tf-acc-test-dx-gateway-association-proposal"
Name = %[1]q
}
}
resource "aws_vpn_gateway" "test" {
vpc_id = "${aws_vpc.test.id}"
tags = {
Name = "tf-acc-test-dx-gateway-association-proposal"
Name = %[1]q
}
}
`, rName, rBgpAsn)
}

func testAccDxGatewayAssociationProposalConfig(rName string, rBgpAsn int) string {
return testAccDxGatewayAssociationProposalConfigBase(rName, rBgpAsn) + fmt.Sprintf(`
func testAccDxGatewayAssociationProposalConfig_vpnGatewayId(rName string, rBgpAsn int) string {
return testAccDxGatewayAssociationProposalConfigBase_vpnGateway(rName, rBgpAsn) + fmt.Sprintf(`
resource "aws_dx_gateway_association_proposal" "test" {
dx_gateway_id = "${aws_dx_gateway.test.id}"
dx_gateway_owner_account_id = "${aws_dx_gateway.test.owner_account_id}"
Expand All @@ -221,24 +302,62 @@ resource "aws_dx_gateway_association_proposal" "test" {
`)
}

func testAccDxGatewayAssociationProposalConfig_basicVpnGateway(rName string, rBgpAsn int) string {
return testAccDxGatewayAssociationProposalConfigBase_vpnGateway(rName, rBgpAsn) + fmt.Sprintf(`
resource "aws_dx_gateway_association_proposal" "test" {
dx_gateway_id = "${aws_dx_gateway.test.id}"
dx_gateway_owner_account_id = "${aws_dx_gateway.test.owner_account_id}"
associated_gateway_id = "${aws_vpn_gateway.test.id}"
}
`)
}

func testAccDxGatewayAssociationProposalConfig_basicTransitGateway(rName string, rBgpAsn int) string {
return testAccAlternateAccountProviderConfig() + fmt.Sprintf(`
resource "aws_dx_gateway" "test" {
provider = "aws.alternate"
amazon_side_asn = %[2]d
name = %[1]q
}
resource "aws_ec2_transit_gateway" "test" {
tags = {
Name = %[1]q
}
}
resource "aws_dx_gateway_association_proposal" "test" {
dx_gateway_id = "${aws_dx_gateway.test.id}"
dx_gateway_owner_account_id = "${aws_dx_gateway.test.owner_account_id}"
associated_gateway_id = "${aws_ec2_transit_gateway.test.id}"
allowed_prefixes = [
"10.255.255.0/30",
"10.255.255.8/30",
]
}
`, rName, rBgpAsn)
}

func testAccDxGatewayAssociationProposalConfigAllowedPrefixes1(rName string, rBgpAsn int) string {
return testAccDxGatewayAssociationProposalConfigBase(rName, rBgpAsn) + fmt.Sprintf(`
return testAccDxGatewayAssociationProposalConfigBase_vpnGateway(rName, rBgpAsn) + fmt.Sprintf(`
resource "aws_dx_gateway_association_proposal" "test" {
allowed_prefixes = ["10.0.0.0/16"]
dx_gateway_id = "${aws_dx_gateway.test.id}"
dx_gateway_owner_account_id = "${aws_dx_gateway.test.owner_account_id}"
vpn_gateway_id = "${aws_vpn_gateway.test.id}"
associated_gateway_id = "${aws_vpn_gateway.test.id}"
}
`)
}

func testAccDxGatewayAssociationProposalConfigAllowedPrefixes2(rName string, rBgpAsn int) string {
return testAccDxGatewayAssociationProposalConfigBase(rName, rBgpAsn) + fmt.Sprintf(`
return testAccDxGatewayAssociationProposalConfigBase_vpnGateway(rName, rBgpAsn) + fmt.Sprintf(`
resource "aws_dx_gateway_association_proposal" "test" {
allowed_prefixes = ["10.0.0.0/24", "10.0.1.0/24"]
dx_gateway_id = "${aws_dx_gateway.test.id}"
dx_gateway_owner_account_id = "${aws_dx_gateway.test.owner_account_id}"
vpn_gateway_id = "${aws_vpn_gateway.test.id}"
associated_gateway_id = "${aws_vpn_gateway.test.id}"
}
`)
}
Loading

0 comments on commit 08f2a8f

Please sign in to comment.