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_hosted_transit_virtual_interface and aws_dx_hosted_transit_virtual_interface_accepter #8523

Merged
Merged
2 changes: 2 additions & 0 deletions aws/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -445,6 +445,8 @@ func Provider() terraform.ResourceProvider {
"aws_dx_hosted_private_virtual_interface_accepter": resourceAwsDxHostedPrivateVirtualInterfaceAccepter(),
"aws_dx_hosted_public_virtual_interface": resourceAwsDxHostedPublicVirtualInterface(),
"aws_dx_hosted_public_virtual_interface_accepter": resourceAwsDxHostedPublicVirtualInterfaceAccepter(),
"aws_dx_hosted_transit_virtual_interface": resourceAwsDxHostedTransitVirtualInterface(),
"aws_dx_hosted_transit_virtual_interface_accepter": resourceAwsDxHostedTransitVirtualInterfaceAccepter(),
"aws_dx_lag": resourceAwsDxLag(),
"aws_dx_private_virtual_interface": resourceAwsDxPrivateVirtualInterface(),
"aws_dx_public_virtual_interface": resourceAwsDxPublicVirtualInterface(),
Expand Down
219 changes: 219 additions & 0 deletions aws/resource_aws_dx_hosted_transit_virtual_interface.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,219 @@
package aws

import (
"fmt"
"log"
"time"

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

func resourceAwsDxHostedTransitVirtualInterface() *schema.Resource {
return &schema.Resource{
Create: resourceAwsDxHostedTransitVirtualInterfaceCreate,
Read: resourceAwsDxHostedTransitVirtualInterfaceRead,
Delete: resourceAwsDxHostedTransitVirtualInterfaceDelete,
Importer: &schema.ResourceImporter{
State: resourceAwsDxHostedTransitVirtualInterfaceImport,
},

Schema: map[string]*schema.Schema{
"address_family": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
ValidateFunc: validation.StringInSlice([]string{
directconnect.AddressFamilyIpv4,
directconnect.AddressFamilyIpv6,
}, false),
},
"amazon_address": {
Type: schema.TypeString,
Optional: true,
Computed: true,
ForceNew: true,
},
"arn": {
Type: schema.TypeString,
Computed: true,
},
"aws_device": {
Type: schema.TypeString,
Computed: true,
},
"bgp_asn": {
Type: schema.TypeInt,
Required: true,
ForceNew: true,
},
"bgp_auth_key": {
Type: schema.TypeString,
Optional: true,
Computed: true,
ForceNew: true,
},
"connection_id": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
},
"customer_address": {
Type: schema.TypeString,
Optional: true,
Computed: true,
ForceNew: true,
},
"jumbo_frame_capable": {
Type: schema.TypeBool,
Computed: true,
},
"mtu": {
Type: schema.TypeInt,
Default: 1500,
Optional: true,
ForceNew: true,
ValidateFunc: validation.IntInSlice([]int{1500, 8500}),
},
"name": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
},
"owner_account_id": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
ValidateFunc: validateAwsAccountId,
},
"vlan": {
Type: schema.TypeInt,
Required: true,
ForceNew: true,
ValidateFunc: validation.IntBetween(1, 4094),
},
},

Timeouts: &schema.ResourceTimeout{
Create: schema.DefaultTimeout(10 * time.Minute),
Update: schema.DefaultTimeout(10 * time.Minute),
Delete: schema.DefaultTimeout(10 * time.Minute),
},
}
}

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

req := &directconnect.AllocateTransitVirtualInterfaceInput{
ConnectionId: aws.String(d.Get("connection_id").(string)),
OwnerAccount: aws.String(d.Get("owner_account_id").(string)),
NewTransitVirtualInterfaceAllocation: &directconnect.NewTransitVirtualInterfaceAllocation{
AddressFamily: aws.String(d.Get("address_family").(string)),
Asn: aws.Int64(int64(d.Get("bgp_asn").(int))),
Mtu: aws.Int64(int64(d.Get("mtu").(int))),
VirtualInterfaceName: aws.String(d.Get("name").(string)),
Vlan: aws.Int64(int64(d.Get("vlan").(int))),
},
}
if v, ok := d.GetOk("amazon_address"); ok && v.(string) != "" {
req.NewTransitVirtualInterfaceAllocation.AmazonAddress = aws.String(v.(string))
}
if v, ok := d.GetOk("bgp_auth_key"); ok && v.(string) != "" {
req.NewTransitVirtualInterfaceAllocation.AuthKey = aws.String(v.(string))
}
if v, ok := d.GetOk("customer_address"); ok && v.(string) != "" {
req.NewTransitVirtualInterfaceAllocation.CustomerAddress = aws.String(v.(string))
}

log.Printf("[DEBUG] Creating Direct Connect hosted transit virtual interface: %s", req)
resp, err := conn.AllocateTransitVirtualInterface(req)
if err != nil {
return fmt.Errorf("error creating Direct Connect hosted transit virtual interface: %s", err)
}

d.SetId(aws.StringValue(resp.VirtualInterface.VirtualInterfaceId))

if err := dxHostedTransitVirtualInterfaceWaitUntilAvailable(conn, d.Id(), d.Timeout(schema.TimeoutCreate)); err != nil {
return err
}

return resourceAwsDxHostedTransitVirtualInterfaceRead(d, meta)
}

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

vif, err := dxVirtualInterfaceRead(d.Id(), conn)
if err != nil {
return err
}
if vif == nil {
log.Printf("[WARN] Direct Connect hosted transit virtual interface (%s) not found, removing from state", d.Id())
d.SetId("")
return nil
}

d.Set("address_family", vif.AddressFamily)
d.Set("amazon_address", vif.AmazonAddress)
arn := arn.ARN{
Partition: meta.(*AWSClient).partition,
Region: meta.(*AWSClient).region,
Service: "directconnect",
AccountID: meta.(*AWSClient).accountid,
Resource: fmt.Sprintf("dxvif/%s", d.Id()),
}.String()
d.Set("arn", arn)
d.Set("aws_device", vif.AwsDeviceV2)
d.Set("bgp_asn", vif.Asn)
d.Set("bgp_auth_key", vif.AuthKey)
d.Set("connection_id", vif.ConnectionId)
d.Set("customer_address", vif.CustomerAddress)
d.Set("jumbo_frame_capable", vif.JumboFrameCapable)
d.Set("mtu", vif.Mtu)
d.Set("name", vif.VirtualInterfaceName)
d.Set("owner_account_id", vif.OwnerAccount)
d.Set("vlan", vif.Vlan)

return nil
}

func resourceAwsDxHostedTransitVirtualInterfaceDelete(d *schema.ResourceData, meta interface{}) error {
return dxVirtualInterfaceDelete(d, meta)
}

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

vif, err := dxVirtualInterfaceRead(d.Id(), conn)
if err != nil {
return nil, err
}
if vif == nil {
return nil, fmt.Errorf("virtual interface (%s) not found", d.Id())
}

if vifType := aws.StringValue(vif.VirtualInterfaceType); vifType != "transit" {
return nil, fmt.Errorf("virtual interface (%s) has incorrect type: %s", d.Id(), vifType)
}

return []*schema.ResourceData{d}, nil
}

func dxHostedTransitVirtualInterfaceWaitUntilAvailable(conn *directconnect.DirectConnect, vifId string, timeout time.Duration) error {
return dxVirtualInterfaceWaitUntilAvailable(
conn,
vifId,
timeout,
[]string{
directconnect.VirtualInterfaceStatePending,
},
[]string{
directconnect.VirtualInterfaceStateAvailable,
directconnect.VirtualInterfaceStateConfirming,
directconnect.VirtualInterfaceStateDown,
})
}
162 changes: 162 additions & 0 deletions aws/resource_aws_dx_hosted_transit_virtual_interface_accepter.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,162 @@
package aws

import (
"fmt"
"log"
"time"

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

func resourceAwsDxHostedTransitVirtualInterfaceAccepter() *schema.Resource {
return &schema.Resource{
Create: resourceAwsDxHostedTransitVirtualInterfaceAccepterCreate,
Read: resourceAwsDxHostedTransitVirtualInterfaceAccepterRead,
Update: resourceAwsDxHostedTransitVirtualInterfaceAccepterUpdate,
Delete: resourceAwsDxHostedTransitVirtualInterfaceAccepterDelete,
Importer: &schema.ResourceImporter{
State: resourceAwsDxHostedTransitVirtualInterfaceAccepterImport,
},

Schema: map[string]*schema.Schema{
"arn": {
Type: schema.TypeString,
Computed: true,
},
"dx_gateway_id": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
},
"tags": tagsSchema(),
"virtual_interface_id": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
},
},

Timeouts: &schema.ResourceTimeout{
Create: schema.DefaultTimeout(10 * time.Minute),
Delete: schema.DefaultTimeout(10 * time.Minute),
},
}
}

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

vifId := d.Get("virtual_interface_id").(string)
req := &directconnect.ConfirmTransitVirtualInterfaceInput{
DirectConnectGatewayId: aws.String(d.Get("dx_gateway_id").(string)),
VirtualInterfaceId: aws.String(vifId),
}

log.Printf("[DEBUG] Accepting Direct Connect hosted transit virtual interface: %s", req)
_, err := conn.ConfirmTransitVirtualInterface(req)
if err != nil {
return fmt.Errorf("error accepting Direct Connect hosted transit virtual interface (%s): %s", vifId, err)
}

d.SetId(vifId)
arn := arn.ARN{
Partition: meta.(*AWSClient).partition,
Region: meta.(*AWSClient).region,
Service: "directconnect",
AccountID: meta.(*AWSClient).accountid,
Resource: fmt.Sprintf("dxvif/%s", d.Id()),
}.String()
d.Set("arn", arn)

if err := dxHostedTransitVirtualInterfaceAccepterWaitUntilAvailable(conn, d.Id(), d.Timeout(schema.TimeoutCreate)); err != nil {
return err
}

return resourceAwsDxHostedTransitVirtualInterfaceAccepterUpdate(d, meta)
}

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

vif, err := dxVirtualInterfaceRead(d.Id(), conn)
if err != nil {
return err
}
if vif == nil {
log.Printf("[WARN] Direct Connect transit virtual interface (%s) not found, removing from state", d.Id())
d.SetId("")
return nil
}
vifState := aws.StringValue(vif.VirtualInterfaceState)
if vifState != directconnect.VirtualInterfaceStateAvailable && vifState != directconnect.VirtualInterfaceStateDown {
log.Printf("[WARN] Direct Connect virtual interface (%s) is '%s', removing from state", vifState, d.Id())
d.SetId("")
return nil
}

d.Set("dx_gateway_id", vif.DirectConnectGatewayId)
d.Set("virtual_interface_id", vif.VirtualInterfaceId)
if err := getTagsDX(conn, d, d.Get("arn").(string)); err != nil {
return fmt.Errorf("error getting Direct Connect transit virtual interface (%s) tags: %s", d.Id(), err)
}

return nil
}

func resourceAwsDxHostedTransitVirtualInterfaceAccepterUpdate(d *schema.ResourceData, meta interface{}) error {
if err := dxVirtualInterfaceUpdate(d, meta); err != nil {
return err
}

return resourceAwsDxHostedTransitVirtualInterfaceAccepterRead(d, meta)
}

func resourceAwsDxHostedTransitVirtualInterfaceAccepterDelete(d *schema.ResourceData, meta interface{}) error {
log.Printf("[WARN] Will not delete Direct Connect virtual interface. Terraform will remove this resource from the state file, however resources may remain.")
return nil
}

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

vif, err := dxVirtualInterfaceRead(d.Id(), conn)
if err != nil {
return nil, err
}
if vif == nil {
return nil, fmt.Errorf("virtual interface (%s) not found", d.Id())
}

if vifType := aws.StringValue(vif.VirtualInterfaceType); vifType != "transit" {
return nil, fmt.Errorf("virtual interface (%s) has incorrect type: %s", d.Id(), vifType)
}

arn := arn.ARN{
Partition: meta.(*AWSClient).partition,
Region: meta.(*AWSClient).region,
Service: "directconnect",
AccountID: meta.(*AWSClient).accountid,
Resource: fmt.Sprintf("dxvif/%s", d.Id()),
}.String()
d.Set("arn", arn)

return []*schema.ResourceData{d}, nil
}

func dxHostedTransitVirtualInterfaceAccepterWaitUntilAvailable(conn *directconnect.DirectConnect, vifId string, timeout time.Duration) error {
return dxVirtualInterfaceWaitUntilAvailable(
conn,
vifId,
timeout,
[]string{
directconnect.VirtualInterfaceStateConfirming,
directconnect.VirtualInterfaceStatePending,
},
[]string{
directconnect.VirtualInterfaceStateAvailable,
directconnect.VirtualInterfaceStateDown,
})
}
Loading