diff --git a/aws/provider.go b/aws/provider.go index 0655be2d4c6..53cd84c4412 100644 --- a/aws/provider.go +++ b/aws/provider.go @@ -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(), diff --git a/aws/resource_aws_dx_hosted_transit_virtual_interface.go b/aws/resource_aws_dx_hosted_transit_virtual_interface.go new file mode 100644 index 00000000000..194eac432cc --- /dev/null +++ b/aws/resource_aws_dx_hosted_transit_virtual_interface.go @@ -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, + }) +} diff --git a/aws/resource_aws_dx_hosted_transit_virtual_interface_accepter.go b/aws/resource_aws_dx_hosted_transit_virtual_interface_accepter.go new file mode 100644 index 00000000000..ba69cd5dd7e --- /dev/null +++ b/aws/resource_aws_dx_hosted_transit_virtual_interface_accepter.go @@ -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, + }) +} diff --git a/aws/resource_aws_dx_hosted_transit_virtual_interface_test.go b/aws/resource_aws_dx_hosted_transit_virtual_interface_test.go new file mode 100644 index 00000000000..dd2a51b2989 --- /dev/null +++ b/aws/resource_aws_dx_hosted_transit_virtual_interface_test.go @@ -0,0 +1,250 @@ +package aws + +import ( + "fmt" + "os" + "regexp" + "strconv" + "testing" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/service/directconnect" + "github.com/hashicorp/terraform-plugin-sdk/helper/acctest" + "github.com/hashicorp/terraform-plugin-sdk/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/helper/schema" + "github.com/hashicorp/terraform-plugin-sdk/terraform" +) + +func TestAccAwsDxHostedTransitVirtualInterface(t *testing.T) { + testCases := map[string]func(t *testing.T){ + "basic": testAccAwsDxHostedTransitVirtualInterface_basic, + "accepterTags": testAccAwsDxHostedTransitVirtualInterface_accepterTags, + } + + for name, tc := range testCases { + tc := tc + t.Run(name, func(t *testing.T) { + tc(t) + }) + } +} + +func testAccAwsDxHostedTransitVirtualInterface_basic(t *testing.T) { + key := "DX_CONNECTION_ID" + connectionId := os.Getenv(key) + if connectionId == "" { + t.Skipf("Environment variable %s is not set", key) + } + + var providers []*schema.Provider + var vif directconnect.VirtualInterface + resourceName := "aws_dx_hosted_transit_virtual_interface.test" + accepterResourceName := "aws_dx_hosted_transit_virtual_interface_accepter.test" + dxGatewayResourceName := "aws_dx_gateway.test" + rName := fmt.Sprintf("tf-testacc-transit-vif-%s", acctest.RandString(9)) + amzAsn := randIntRange(64512, 65534) + bgpAsn := randIntRange(64512, 65534) + vlan := randIntRange(2049, 4094) + + resource.Test(t, resource.TestCase{ + PreCheck: func() { + testAccPreCheck(t) + testAccAlternateAccountPreCheck(t) + }, + ProviderFactories: testAccProviderFactories(&providers), + CheckDestroy: testAccCheckAwsDxHostedTransitVirtualInterfaceDestroy, + Steps: []resource.TestStep{ + { + Config: testAccDxHostedTransitVirtualInterfaceConfig_basic(connectionId, rName, amzAsn, bgpAsn, vlan), + Check: resource.ComposeTestCheckFunc( + testAccCheckAwsDxHostedTransitVirtualInterfaceExists(resourceName, &vif), + resource.TestCheckResourceAttr(resourceName, "address_family", "ipv4"), + testAccMatchResourceAttrRegionalARN(resourceName, "arn", "directconnect", regexp.MustCompile(fmt.Sprintf("dxvif/%s", aws.StringValue(vif.VirtualInterfaceId)))), + resource.TestCheckResourceAttrSet(resourceName, "aws_device"), + resource.TestCheckResourceAttr(resourceName, "bgp_asn", strconv.Itoa(bgpAsn)), + resource.TestCheckResourceAttrSet(resourceName, "bgp_auth_key"), + resource.TestCheckResourceAttr(resourceName, "connection_id", connectionId), + resource.TestCheckResourceAttr(resourceName, "jumbo_frame_capable", "true"), + resource.TestCheckResourceAttr(resourceName, "mtu", "1500"), + resource.TestCheckResourceAttr(resourceName, "name", rName), + resource.TestCheckResourceAttrSet(resourceName, "owner_account_id"), + resource.TestCheckResourceAttr(resourceName, "vlan", strconv.Itoa(vlan)), + // Accepter's attributes: + resource.TestCheckResourceAttrSet(accepterResourceName, "arn"), + resource.TestCheckResourceAttrPair(accepterResourceName, "dx_gateway_id", dxGatewayResourceName, "id"), + resource.TestCheckResourceAttr(accepterResourceName, "tags.%", "0"), + resource.TestCheckResourceAttrPair(accepterResourceName, "virtual_interface_id", resourceName, "id"), + ), + }, + // Test import. + { + Config: testAccDxHostedTransitVirtualInterfaceConfig_basic(connectionId, rName, amzAsn, bgpAsn, vlan), + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func testAccAwsDxHostedTransitVirtualInterface_accepterTags(t *testing.T) { + key := "DX_CONNECTION_ID" + connectionId := os.Getenv(key) + if connectionId == "" { + t.Skipf("Environment variable %s is not set", key) + } + + var providers []*schema.Provider + var vif directconnect.VirtualInterface + resourceName := "aws_dx_hosted_transit_virtual_interface.test" + accepterResourceName := "aws_dx_hosted_transit_virtual_interface_accepter.test" + dxGatewayResourceName := "aws_dx_gateway.test" + rName := fmt.Sprintf("tf-testacc-transit-vif-%s", acctest.RandString(9)) + amzAsn := randIntRange(64512, 65534) + bgpAsn := randIntRange(64512, 65534) + vlan := randIntRange(2049, 4094) + + resource.Test(t, resource.TestCase{ + PreCheck: func() { + testAccPreCheck(t) + testAccAlternateAccountPreCheck(t) + }, + ProviderFactories: testAccProviderFactories(&providers), + CheckDestroy: testAccCheckAwsDxHostedTransitVirtualInterfaceDestroy, + Steps: []resource.TestStep{ + { + Config: testAccDxHostedTransitVirtualInterfaceConfig_accepterTags(connectionId, rName, amzAsn, bgpAsn, vlan), + Check: resource.ComposeTestCheckFunc( + testAccCheckAwsDxHostedTransitVirtualInterfaceExists(resourceName, &vif), + resource.TestCheckResourceAttr(resourceName, "address_family", "ipv4"), + testAccMatchResourceAttrRegionalARN(resourceName, "arn", "directconnect", regexp.MustCompile(fmt.Sprintf("dxvif/%s", aws.StringValue(vif.VirtualInterfaceId)))), + resource.TestCheckResourceAttrSet(resourceName, "aws_device"), + resource.TestCheckResourceAttr(resourceName, "bgp_asn", strconv.Itoa(bgpAsn)), + resource.TestCheckResourceAttrSet(resourceName, "bgp_auth_key"), + resource.TestCheckResourceAttr(resourceName, "connection_id", connectionId), + resource.TestCheckResourceAttr(resourceName, "jumbo_frame_capable", "true"), + resource.TestCheckResourceAttr(resourceName, "mtu", "1500"), + resource.TestCheckResourceAttr(resourceName, "name", rName), + resource.TestCheckResourceAttrSet(resourceName, "owner_account_id"), + resource.TestCheckResourceAttr(resourceName, "vlan", strconv.Itoa(vlan)), + // Accepter's attributes: + resource.TestCheckResourceAttrSet(accepterResourceName, "arn"), + resource.TestCheckResourceAttrPair(accepterResourceName, "dx_gateway_id", dxGatewayResourceName, "id"), + resource.TestCheckResourceAttr(accepterResourceName, "tags.%", "3"), + resource.TestCheckResourceAttr(accepterResourceName, "tags.Name", rName), + resource.TestCheckResourceAttr(accepterResourceName, "tags.Key1", "Value1"), + resource.TestCheckResourceAttr(accepterResourceName, "tags.Key2", "Value2a"), + resource.TestCheckResourceAttrPair(accepterResourceName, "virtual_interface_id", resourceName, "id"), + ), + }, + { + Config: testAccDxHostedTransitVirtualInterfaceConfig_accepterTagsUpdated(connectionId, rName, amzAsn, bgpAsn, vlan), + Check: resource.ComposeTestCheckFunc( + testAccCheckAwsDxHostedTransitVirtualInterfaceExists(resourceName, &vif), + resource.TestCheckResourceAttr(resourceName, "address_family", "ipv4"), + testAccMatchResourceAttrRegionalARN(resourceName, "arn", "directconnect", regexp.MustCompile(fmt.Sprintf("dxvif/%s", aws.StringValue(vif.VirtualInterfaceId)))), + resource.TestCheckResourceAttrSet(resourceName, "aws_device"), + resource.TestCheckResourceAttr(resourceName, "bgp_asn", strconv.Itoa(bgpAsn)), + resource.TestCheckResourceAttrSet(resourceName, "bgp_auth_key"), + resource.TestCheckResourceAttr(resourceName, "connection_id", connectionId), + resource.TestCheckResourceAttr(resourceName, "jumbo_frame_capable", "true"), + resource.TestCheckResourceAttr(resourceName, "mtu", "1500"), + resource.TestCheckResourceAttr(resourceName, "name", rName), + resource.TestCheckResourceAttrSet(resourceName, "owner_account_id"), + resource.TestCheckResourceAttr(resourceName, "vlan", strconv.Itoa(vlan)), + // Accepter's attributes: + resource.TestCheckResourceAttrSet(accepterResourceName, "arn"), + resource.TestCheckResourceAttrPair(accepterResourceName, "dx_gateway_id", dxGatewayResourceName, "id"), + resource.TestCheckResourceAttr(accepterResourceName, "tags.%", "3"), + resource.TestCheckResourceAttr(accepterResourceName, "tags.Name", rName), + resource.TestCheckResourceAttr(accepterResourceName, "tags.Key2", "Value2b"), + resource.TestCheckResourceAttr(accepterResourceName, "tags.Key3", "Value3"), + resource.TestCheckResourceAttrPair(accepterResourceName, "virtual_interface_id", resourceName, "id"), + ), + }, + }, + }) +} + +func testAccCheckAwsDxHostedTransitVirtualInterfaceExists(name string, vif *directconnect.VirtualInterface) resource.TestCheckFunc { + return testAccCheckDxVirtualInterfaceExists(name, vif) +} + +func testAccCheckAwsDxHostedTransitVirtualInterfaceDestroy(s *terraform.State) error { + return testAccCheckDxVirtualInterfaceDestroy(s, "aws_dx_hosted_transit_virtual_interface") +} + +func testAccDxHostedTransitVirtualInterfaceConfig_base(cid, rName string, amzAsn, bgpAsn, vlan int) string { + return testAccAlternateAccountProviderConfig() + fmt.Sprintf(` +# Creator +resource "aws_dx_hosted_transit_virtual_interface" "test" { + address_family = "ipv4" + bgp_asn = %[4]d + connection_id = %[1]q + name = %[2]q + owner_account_id = "${data.aws_caller_identity.accepter.account_id}" + vlan = %[5]d + + # The aws_dx_hosted_transit_virtual_interface + # must be destroyed before the aws_dx_gateway. + depends_on = ["aws_dx_gateway.test"] +} + +# Accepter +data "aws_caller_identity" "accepter" { + provider = "aws.alternate" +} + +resource "aws_dx_gateway" "test" { + provider = "aws.alternate" + + amazon_side_asn = %[3]d + name = %[2]q +} +`, cid, rName, amzAsn, bgpAsn, vlan) +} + +func testAccDxHostedTransitVirtualInterfaceConfig_basic(cid, rName string, amzAsn, bgpAsn, vlan int) string { + return testAccDxHostedTransitVirtualInterfaceConfig_base(cid, rName, amzAsn, bgpAsn, vlan) + fmt.Sprintf(` +resource "aws_dx_hosted_transit_virtual_interface_accepter" "test" { + provider = "aws.alternate" + + dx_gateway_id = "${aws_dx_gateway.test.id}" + virtual_interface_id = "${aws_dx_hosted_transit_virtual_interface.test.id}" +} +`) +} + +func testAccDxHostedTransitVirtualInterfaceConfig_accepterTags(cid, rName string, amzAsn, bgpAsn, vlan int) string { + return testAccDxHostedTransitVirtualInterfaceConfig_base(cid, rName, amzAsn, bgpAsn, vlan) + fmt.Sprintf(` +resource "aws_dx_hosted_transit_virtual_interface_accepter" "test" { + provider = "aws.alternate" + + dx_gateway_id = "${aws_dx_gateway.test.id}" + virtual_interface_id = "${aws_dx_hosted_transit_virtual_interface.test.id}" + + tags = { + Name = %[1]q + Key1 = "Value1" + Key2 = "Value2a" + } +} +`, rName) +} + +func testAccDxHostedTransitVirtualInterfaceConfig_accepterTagsUpdated(cid, rName string, amzAsn, bgpAsn, vlan int) string { + return testAccDxHostedTransitVirtualInterfaceConfig_base(cid, rName, amzAsn, bgpAsn, vlan) + fmt.Sprintf(` +resource "aws_dx_hosted_transit_virtual_interface_accepter" "test" { + provider = "aws.alternate" + + dx_gateway_id = "${aws_dx_gateway.test.id}" + virtual_interface_id = "${aws_dx_hosted_transit_virtual_interface.test.id}" + + tags = { + Name = %[1]q + Key2 = "Value2b" + Key3 = "Value3" + } +} +`, rName) +} diff --git a/website/aws.erb b/website/aws.erb index 8b880c6a1b0..13d868ca19c 100644 --- a/website/aws.erb +++ b/website/aws.erb @@ -877,13 +877,13 @@ aws_dx_hosted_public_virtual_interface_accepter