Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New resources: aws_dx_gateway, aws_dx_gateway_assocation #2861

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 48 additions & 0 deletions aws/import_aws_dx_gateway.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package aws

import (
"fmt"

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

// Direct Connect Gateway import also imports all assocations
func resourceAwsDxGatewayImportState(d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) {
conn := meta.(*AWSClient).dxconn

id := d.Id()
resp, err := conn.DescribeDirectConnectGateways(&directconnect.DescribeDirectConnectGatewaysInput{
DirectConnectGatewayId: aws.String(id),
})
if err != nil {
return nil, err
}
if len(resp.DirectConnectGateways) < 1 || resp.DirectConnectGateways[0] == nil {
return nil, fmt.Errorf("Direct Connect Gateway %s was not found", id)
}
results := make([]*schema.ResourceData, 1)
results[0] = d

{
subResource := resourceAwsDxGatewayAssociation()
resp, err := conn.DescribeDirectConnectGatewayAssociations(&directconnect.DescribeDirectConnectGatewayAssociationsInput{
DirectConnectGatewayId: aws.String(id),
})
if err != nil {
return nil, err
}

for _, assoc := range resp.DirectConnectGatewayAssociations {
d := subResource.Data(nil)
d.SetType("aws_dx_gateway_association")
d.Set("dx_gateway_id", assoc.DirectConnectGatewayId)
d.Set("virtual_gateway_id", assoc.VirtualGatewayId)
d.SetId(dxGatewayIdVgwIdHash(*assoc.DirectConnectGatewayId, *assoc.VirtualGatewayId))
results = append(results, d)
}
}

return results, nil
}
93 changes: 93 additions & 0 deletions aws/import_aws_dx_gateway_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
package aws

import (
"fmt"
"testing"

"github.com/hashicorp/terraform/helper/acctest"
"github.com/hashicorp/terraform/helper/resource"
"github.com/hashicorp/terraform/terraform"
)

func TestAccAwsDxGateway_importBasic(t *testing.T) {
resourceName := "aws_dx_gateway.test"

resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckAwsDxGatewayDestroy,
Steps: []resource.TestStep{
resource.TestStep{
Config: testAccDxGatewayConfig(acctest.RandString(5), acctest.RandIntRange(64512, 65534)),
},

resource.TestStep{
ResourceName: resourceName,
ImportState: true,
ImportStateVerify: true,
},
},
})
}

func TestAccAwsDxGateway_importComplex(t *testing.T) {
checkFn := func(s []*terraform.InstanceState) error {
if len(s) != 3 {
return fmt.Errorf("Got %d resources, expected 3. State: %#v", len(s), s)
}
return nil
}

resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckAwsDxGatewayDestroy,
Steps: []resource.TestStep{
resource.TestStep{
Config: testAccDxGatewayConfig_complexImport(acctest.RandString(5), acctest.RandIntRange(64512, 65534)),
},

resource.TestStep{
ResourceName: "aws_dx_gateway.test",
ImportState: true,
ImportStateCheck: checkFn,
ImportStateVerify: true,
},
},
})
}

func testAccDxGatewayConfig_complexImport(rName string, rBgpAsn int) string {
return fmt.Sprintf(`
resource "aws_dx_gateway" "test" {
name = "tf-dxg-%s"
amazon_side_asn = "%d"
}

resource "aws_vpc" "test1" {
cidr_block = "10.255.255.16/28"
}

resource "aws_vpc" "test2" {
cidr_block = "10.255.255.32/28"
}

resource "aws_vpn_gateway" "test1" {
vpc_id = "${aws_vpc.test1.id}"
}

resource "aws_vpn_gateway" "test2" {
vpc_id = "${aws_vpc.test2.id}"
}

resource "aws_dx_gateway_association" "test1" {
dx_gateway_id = "${aws_dx_gateway.test.id}"
virtual_gateway_id = "${aws_vpn_gateway.test1.id}"
}

resource "aws_dx_gateway_association" "test2" {
dx_gateway_id = "${aws_dx_gateway.test.id}"
virtual_gateway_id = "${aws_vpn_gateway.test2.id}"
}
`, rName, rBgpAsn)
}
2 changes: 2 additions & 0 deletions aws/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -336,6 +336,8 @@ func Provider() terraform.ResourceProvider {
"aws_dx_lag": resourceAwsDxLag(),
"aws_dx_connection": resourceAwsDxConnection(),
"aws_dx_connection_association": resourceAwsDxConnectionAssociation(),
"aws_dx_gateway": resourceAwsDxGateway(),
"aws_dx_gateway_association": resourceAwsDxGatewayAssociation(),
"aws_dynamodb_table": resourceAwsDynamoDbTable(),
"aws_dynamodb_table_item": resourceAwsDynamoDbTableItem(),
"aws_dynamodb_global_table": resourceAwsDynamoDbGlobalTable(),
Expand Down
141 changes: 141 additions & 0 deletions aws/resource_aws_dx_gateway.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
package aws

import (
"fmt"
"strconv"
"time"

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

func resourceAwsDxGateway() *schema.Resource {
return &schema.Resource{
Create: resourceAwsDxGatewayCreate,
Read: resourceAwsDxGatewayRead,
Delete: resourceAwsDxGatewayDelete,
Importer: &schema.ResourceImporter{
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If terraform import is supported please note in the documentation and add an import acceptance test.
I did that for the existing Direct Connect resources in #2992.

State: resourceAwsDxGatewayImportState,
},

Schema: map[string]*schema.Schema{
"name": &schema.Schema{
Type: schema.TypeString,
Required: true,
ForceNew: true,
},
"amazon_side_asn": &schema.Schema{
Type: schema.TypeString,
Required: true,
ForceNew: true,
ValidateFunc: validateAmazonSideAsn,
},
},
}
}

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

input := &directconnect.CreateDirectConnectGatewayInput{
DirectConnectGatewayName: aws.String(d.Get("name").(string)),
}

if asn, ok := d.GetOk("amazon_side_asn"); ok {
i, err := strconv.ParseInt(asn.(string), 10, 64)
if err != nil {
return err
}
input.AmazonSideAsn = aws.Int64(i)
}

resp, err := conn.CreateDirectConnectGateway(input)
if err != nil {
return err
}
gatewayId := aws.StringValue(resp.DirectConnectGateway.DirectConnectGatewayId)

stateConf := &resource.StateChangeConf{
Pending: []string{directconnect.GatewayStatePending},
Target: []string{directconnect.GatewayStateAvailable},
Refresh: dxGatewayRefreshStateFunc(conn, gatewayId),
Timeout: 10 * time.Minute,
Delay: 10 * time.Second,
MinTimeout: 3 * time.Second,
}
_, err = stateConf.WaitForState()
if err != nil {
return fmt.Errorf("Error waiting for Direct Connect Gateway (%s) to become available: %s", gatewayId, err)
}

d.SetId(gatewayId)
return resourceAwsDxGatewayRead(d, meta)
}

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

resp, err := conn.DescribeDirectConnectGateways(&directconnect.DescribeDirectConnectGatewaysInput{
DirectConnectGatewayId: aws.String(d.Id()),
})
if err != nil {
return err
}

if len(resp.DirectConnectGateways) < 1 {
d.SetId("")
return nil
}
if len(resp.DirectConnectGateways) != 1 {
return fmt.Errorf("[ERROR] Number of Direct Connect Gateways (%s) isn't one, got %d", d.Id(), len(resp.DirectConnectGateways))
}
gateway := resp.DirectConnectGateways[0]

if d.Id() != aws.StringValue(gateway.DirectConnectGatewayId) {
return fmt.Errorf("[ERROR] Direct Connect Gateway (%s) not found", d.Id())
}

d.Set("name", aws.StringValue(gateway.DirectConnectGatewayName))
d.Set("amazon_side_asn", strconv.FormatInt(aws.Int64Value(gateway.AmazonSideAsn), 10))

return nil
}

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

_, err := conn.DeleteDirectConnectGateway(&directconnect.DeleteDirectConnectGatewayInput{
DirectConnectGatewayId: aws.String(d.Id()),
})
if err != nil {
return err
}
stateConf := &resource.StateChangeConf{
Pending: []string{directconnect.GatewayStatePending, directconnect.GatewayStateAvailable, directconnect.GatewayStateDeleting},
Target: []string{directconnect.GatewayStateDeleted},
Refresh: dxGatewayRefreshStateFunc(conn, d.Id()),
Timeout: 10 * time.Minute,
Delay: 10 * time.Second,
MinTimeout: 3 * time.Second,
}
_, err = stateConf.WaitForState()
if err != nil {
return fmt.Errorf("Error waiting for Direct Connect Gateway (%s) to be deleted: %s", d.Id(), err)
}
d.SetId("")
return nil
}

func dxGatewayRefreshStateFunc(conn *directconnect.DirectConnect, gatewayId string) resource.StateRefreshFunc {
return func() (interface{}, string, error) {
resp, err := conn.DescribeDirectConnectGateways(&directconnect.DescribeDirectConnectGatewaysInput{
DirectConnectGatewayId: aws.String(gatewayId),
})
if err != nil {
return nil, "failed", err
}
return resp, *resp.DirectConnectGateways[0].DirectConnectGatewayState, nil
}
}
102 changes: 102 additions & 0 deletions aws/resource_aws_dx_gateway_association.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
package aws

import (
"fmt"
"log"

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

func resourceAwsDxGatewayAssociation() *schema.Resource {
return &schema.Resource{
Create: resourceAwsDxGatewayAssociationCreate,
Read: resourceAwsDxGatewayAssociationRead,
Delete: resourceAwsDxGatewayAssociationDelete,

Schema: map[string]*schema.Schema{
"dx_gateway_id": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
},
"virtual_gateway_id": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
},
},
}
}

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

dxGatewayId := d.Get("dx_gateway_id").(string)
vgwId := d.Get("virtual_gateway_id").(string)

_, err := conn.CreateDirectConnectGatewayAssociation(&directconnect.CreateDirectConnectGatewayAssociationInput{
DirectConnectGatewayId: aws.String(dxGatewayId),
VirtualGatewayId: aws.String(vgwId),
})
if err != nil {
return err
}

d.SetId(dxGatewayIdVgwIdHash(dxGatewayId, vgwId))
return nil
}

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

dxGatewayId := d.Get("dx_gateway_id").(string)
vgwId := d.Get("virtual_gateway_id").(string)

resp, err := conn.DescribeDirectConnectGatewayAssociations(&directconnect.DescribeDirectConnectGatewayAssociationsInput{
DirectConnectGatewayId: aws.String(dxGatewayId),
VirtualGatewayId: aws.String(vgwId),
})

if err != nil {
return err
}
if len(resp.DirectConnectGatewayAssociations) < 1 {
d.SetId("")
return nil
}
if len(resp.DirectConnectGatewayAssociations) != 1 {
return fmt.Errorf("Found %d Direct Connect Gateway associations for %s, expected 1", len(resp.DirectConnectGatewayAssociations), d.Id())
}
if *resp.DirectConnectGatewayAssociations[0].VirtualGatewayId != d.Get("virtual_gateway_id").(string) {
log.Printf("[WARN] Direct Connect Gateway Association %s not found, removing from state", d.Id())
d.SetId("")
return nil
}

return nil
}

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

dxGatewayId := d.Get("dx_gateway_id").(string)
vgwId := d.Get("virtual_gateway_id").(string)

_, err := conn.DeleteDirectConnectGatewayAssociation(&directconnect.DeleteDirectConnectGatewayAssociationInput{
DirectConnectGatewayId: aws.String(dxGatewayId),
VirtualGatewayId: aws.String(vgwId),
})

if err != nil {
return err
}

d.SetId("")
return nil
}

func dxGatewayIdVgwIdHash(gatewayId, vgwId string) string {
return fmt.Sprintf("ga-%s%s", gatewayId, vgwId)
}
Loading