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

HCPE-830 - Add TGW attachment resource #58

Merged
merged 17 commits into from
Feb 11, 2021
Merged
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
52 changes: 52 additions & 0 deletions docs/data-sources/aws_transit_gateway_attachment.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
---
Copy link
Contributor Author

Choose a reason for hiding this comment

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

The docs/* files included here were generated with go generate, which pulls in the examples and resource/field descriptions.

page_title: "hcp_aws_transit_gateway_attachment Data Source - terraform-provider-hcp"
subcategory: ""
description: |-
The AWS Transit Gateway Attachment data source provides information about an existing transit gateway attachment.
---

# Data Source `hcp_aws_transit_gateway_attachment`

The AWS Transit Gateway Attachment data source provides information about an existing transit gateway attachment.

## Example Usage

```terraform
data "hcp_aws_transit_gateway_attachment" "test" {
hvn_id = var.hvn_id
transit_gateway_attachment_id = var.transit_gateway_attachment_id
}
```

## Schema

### Required

- **hvn_id** (String) The ID of the HashiCorp Virtual Network (HVN).
- **transit_gateway_attachment_id** (String) The user-settable name of the transit gateway attachment in HCP.

### Optional

- **id** (String) The ID of this resource.
roaks3 marked this conversation as resolved.
Show resolved Hide resolved
- **timeouts** (Block, Optional) (see [below for nested schema](#nestedblock--timeouts))
- **wait_for_active_state** (Boolean) If `true`, Terraform will wait for the transit gateway attachment to reach an `ACTIVE` state before continuing. Default `false`.

### Read-only

- **created_at** (String) The time that the transit gateway attachment was created.
- **destination_cidrs** (List of String) The list of associated CIDR ranges. Traffic from these CIDRs will be allowed for all resources in the HVN. Traffic to these CIDRs will be routed into this transit gateway attachment.
- **expires_at** (String) The time after which the transit gateway attachment will be considered expired if it hasn't transitioned into `ACCEPTED` or `ACTIVE` state.
- **organization_id** (String) The ID of the HCP organization where the transit gateway attachment is located. Always matches the HVN's organization.
- **project_id** (String) The ID of the HCP project where the transit gateway attachment is located. Always matches the HVN's project.
- **provider_transit_gateway_attachment_id** (String) The transit gateway attachment ID used by AWS.
- **state** (String) The state of the transit gateway attachment.
- **transit_gateway_id** (String) The ID of the user-owned transit gateway in AWS.

roaks3 marked this conversation as resolved.
Show resolved Hide resolved
<a id="nestedblock--timeouts"></a>
### Nested Schema for `timeouts`

Optional:

- **default** (String)
roaks3 marked this conversation as resolved.
Show resolved Hide resolved


1 change: 1 addition & 0 deletions docs/data-sources/hvn.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ data "hcp_hvn" "example" {
- **created_at** (String) The time that the HVN was created.
- **organization_id** (String) The ID of the HCP organization where the HVN is located.
- **project_id** (String) The ID of the HCP project where the HVN is located.
- **provider_account_id** (String) The provider account ID where the HVN is located.
- **region** (String) The region where the HVN is located.

<a id="nestedblock--timeouts"></a>
Expand Down
102 changes: 102 additions & 0 deletions docs/resources/aws_transit_gateway_attachment.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
---
page_title: "hcp_aws_transit_gateway_attachment Resource - terraform-provider-hcp"
subcategory: ""
description: |-
The AWS Transit Gateway Attachment resource allows you to manage a transit gateway attachment. The transit gateway attachment attaches an HVN to a user-owned transit gateway in AWS. Note that the HVN and transit gateway must be located in the same AWS region.
---

# Resource `hcp_aws_transit_gateway_attachment`

The AWS Transit Gateway Attachment resource allows you to manage a transit gateway attachment. The transit gateway attachment attaches an HVN to a user-owned transit gateway in AWS. Note that the HVN and transit gateway must be located in the same AWS region.

## Example Usage

```terraform
provider "aws" {
region = "us-west-2"
}

resource "hcp_hvn" "main" {
hvn_id = "main-hvn"
cloud_provider = "aws"
region = "us-west-2"
cidr_block = "172.25.16.0/20"
}

resource "aws_vpc" "example" {
cidr_block = "172.31.0.0/16"
}

resource "aws_ec2_transit_gateway" "example" {
tags = {
Name = "example-tgw"
}
}

resource "aws_ram_resource_share" "example" {
name = "example-resource-share"
allow_external_principals = true
}

resource "aws_ram_principal_association" "example" {
resource_share_arn = aws_ram_resource_share.example.arn
principal = hcp_hvn.main.provider_account_id
}

resource "aws_ram_resource_association" "example" {
resource_share_arn = aws_ram_resource_share.example.arn
resource_arn = aws_ec2_transit_gateway.example.arn
}

resource "hcp_aws_transit_gateway_attachment" "example" {
depends_on = [
aws_ram_principal_association.example,
aws_ram_resource_association.example,
]

hvn_id = hcp_hvn.main.hvn_id
transit_gateway_attachment_id = "example-tgw-attachment"
transit_gateway_id = aws_ec2_transit_gateway.example.id
resource_share_arn = aws_ram_resource_share.example.arn
destination_cidrs = [aws_vpc.example.cidr_block]
}

resource "aws_ec2_transit_gateway_vpc_attachment_accepter" "example" {
transit_gateway_attachment_id = hcp_aws_transit_gateway_attachment.example.provider_transit_gateway_attachment_id
}
```

## Schema

### Required

- **destination_cidrs** (List of String) The list of associated CIDR ranges. Traffic from these CIDRs will be allowed for all resources in the HVN. Traffic to these CIDRs will be routed into this transit gateway attachment.
- **hvn_id** (String) The ID of the HashiCorp Virtual Network (HVN).
- **resource_share_arn** (String, Sensitive) The Amazon Resource Name (ARN) of the Resource Share that is needed to grant HCP access to the transit gateway in AWS. The Resource Share should be associated with the HCP AWS account principal (see [aws_ram_principal_association](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/ram_principal_association)) and the transit gateway resource (see [aws_ram_resource_association](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/ram_resource_association))
- **transit_gateway_attachment_id** (String) The user-settable name of the transit gateway attachment in HCP.
- **transit_gateway_id** (String) The ID of the user-owned transit gateway in AWS. The AWS region of the transit gateway must match the HVN.

### Optional

- **id** (String) The ID of this resource.
- **timeouts** (Block, Optional) (see [below for nested schema](#nestedblock--timeouts))
roaks3 marked this conversation as resolved.
Show resolved Hide resolved

### Read-only

- **created_at** (String) The time that the transit gateway attachment was created.
- **expires_at** (String) The time after which the transit gateway attachment will be considered expired if it hasn't transitioned into `ACCEPTED` or `ACTIVE` state.
- **organization_id** (String) The ID of the HCP organization where the transit gateway attachment is located. Always matches the HVN's organization.
- **project_id** (String) The ID of the HCP project where the transit gateway attachment is located. Always matches the HVN's project.
- **provider_transit_gateway_attachment_id** (String) The transit gateway attachment ID used by AWS.
- **state** (String) The state of the transit gateway attachment.

<a id="nestedblock--timeouts"></a>
### Nested Schema for `timeouts`

Optional:

- **create** (String)
smaant marked this conversation as resolved.
Show resolved Hide resolved
- **default** (String)
- **delete** (String)


1 change: 1 addition & 0 deletions docs/resources/hvn.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ resource "hcp_hvn" "example" {
- **created_at** (String) The time that the HVN was created.
- **organization_id** (String) The ID of the HCP organization where the HVN is located.
- **project_id** (String) The ID of the HCP project where the HVN is located.
- **provider_account_id** (String) The provider account ID where the HVN is located.

<a id="nestedblock--timeouts"></a>
### Nested Schema for `timeouts`
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
data "hcp_aws_transit_gateway_attachment" "test" {
hvn_id = var.hvn_id
transit_gateway_attachment_id = var.transit_gateway_attachment_id
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
variable "hvn_id" {
description = "The ID of the HashiCorp Virtual Network (HVN)."
type = string
}

variable "transit_gateway_attachment_id" {
description = "The user-settable name of the transit gateway attachment in HCP."
type = string
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
provider "aws" {
region = "us-west-2"
}

resource "hcp_hvn" "main" {
hvn_id = "main-hvn"
cloud_provider = "aws"
region = "us-west-2"
cidr_block = "172.25.16.0/20"
}

resource "aws_vpc" "example" {
cidr_block = "172.31.0.0/16"
}

resource "aws_ec2_transit_gateway" "example" {
tags = {
Name = "example-tgw"
}
}

resource "aws_ram_resource_share" "example" {
name = "example-resource-share"
allow_external_principals = true
}

resource "aws_ram_principal_association" "example" {
resource_share_arn = aws_ram_resource_share.example.arn
principal = hcp_hvn.main.provider_account_id
}

resource "aws_ram_resource_association" "example" {
resource_share_arn = aws_ram_resource_share.example.arn
resource_arn = aws_ec2_transit_gateway.example.arn
}

resource "hcp_aws_transit_gateway_attachment" "example" {
depends_on = [
aws_ram_principal_association.example,
aws_ram_resource_association.example,
]

hvn_id = hcp_hvn.main.hvn_id
transit_gateway_attachment_id = "example-tgw-attachment"
transit_gateway_id = aws_ec2_transit_gateway.example.id
resource_share_arn = aws_ram_resource_share.example.arn
destination_cidrs = [aws_vpc.example.cidr_block]
}

resource "aws_ec2_transit_gateway_vpc_attachment_accepter" "example" {
transit_gateway_attachment_id = hcp_aws_transit_gateway_attachment.example.provider_transit_gateway_attachment_id
}
1 change: 1 addition & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -298,6 +298,7 @@ github.com/hashicorp/hcl/v2 v2.3.0 h1:iRly8YaMwTBAKhn1Ybk7VSdzbnopghktCD031P8ggU
github.com/hashicorp/hcl/v2 v2.3.0/go.mod h1:d+FwDBbOLvpAM3Z6J7gPj/VoAGkNe/gm352ZhjJ/Zv8=
github.com/hashicorp/hcp-sdk-go v0.1.0 h1:3UQRLDsgXHnK6++hQ9uFKwLbsQ8lLXm+nGO/ZbUtlg0=
github.com/hashicorp/hcp-sdk-go v0.1.0/go.mod h1:vpV5eSGZVmfCFcksi4AH8d/QSybuyLSH5UQcwmnRUQk=
github.com/hashicorp/logutils v1.0.0 h1:dLEQVugN8vlakKOUE3ihGLTZJRB4j+M2cdTm/ORI65Y=
github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64=
github.com/hashicorp/terraform-exec v0.9.0/go.mod h1:tOT8j1J8rP05bZBGWXfMyU3HkLi1LWyqL3Bzsc3CJjo=
github.com/hashicorp/terraform-exec v0.12.0 h1:Tb1VC2gqArl9EJziJjoazep2MyxMk00tnNKV/rgMba0=
Expand Down
103 changes: 103 additions & 0 deletions internal/clients/tgw.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
package clients

import (
"context"
"fmt"
"time"

"github.com/hashicorp/hcp-sdk-go/clients/cloud-network/preview/2020-09-07/client/network_service"
networkmodels "github.com/hashicorp/hcp-sdk-go/clients/cloud-network/preview/2020-09-07/models"
sharedmodels "github.com/hashicorp/hcp-sdk-go/clients/cloud-shared/v1/models"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
)

// GetTGWAttachmentByID gets a TGW attachment by its ID, hvnID, and location
func GetTGWAttachmentByID(ctx context.Context, client *Client, tgwAttachmentID string, hvnID string, loc *sharedmodels.HashicorpCloudLocationLocation) (*networkmodels.HashicorpCloudNetwork20200907TGWAttachment, error) {
getTGWAttachmentParams := network_service.NewGetTGWAttachmentParams()
getTGWAttachmentParams.ID = tgwAttachmentID
getTGWAttachmentParams.HvnID = hvnID
getTGWAttachmentParams.HvnLocationOrganizationID = loc.OrganizationID
getTGWAttachmentParams.HvnLocationProjectID = loc.ProjectID
getTGWAttachmentResponse, err := client.Network.GetTGWAttachment(getTGWAttachmentParams, nil)
if err != nil {
return nil, err
}

return getTGWAttachmentResponse.Payload.TgwAttachment, nil
}

const (
// TgwAttachmentStateCreating is the CREATING state of a TGW attachment
TgwAttachmentStateCreating = string(networkmodels.HashicorpCloudNetwork20200907TGWAttachmentStateCREATING)

// TgwAttachmentStatePendingAcceptance is the PENDING_ACCEPTANCE state of a TGW attachment
TgwAttachmentStatePendingAcceptance = string(networkmodels.HashicorpCloudNetwork20200907TGWAttachmentStatePENDINGACCEPTANCE)

// TgwAttachmentStateAccepted is the ACCEPTED state of a TGW attachment
TgwAttachmentStateAccepted = string(networkmodels.HashicorpCloudNetwork20200907TGWAttachmentStateACCEPTED)

// TgwAttachmentStateActive is the ACTIVE state of a TGW attachment
TgwAttachmentStateActive = string(networkmodels.HashicorpCloudNetwork20200907TGWAttachmentStateACTIVE)
)

// tgwAttachmentRefreshState refreshes the state of the TGW attachment by
// calling the GET endpoint
func tgwAttachmentRefreshState(ctx context.Context, client *Client, tgwAttachmentID string, hvnID string, loc *sharedmodels.HashicorpCloudLocationLocation) resource.StateRefreshFunc {
return func() (interface{}, string, error) {
tgwAtt, err := GetTGWAttachmentByID(ctx, client, tgwAttachmentID, hvnID, loc)
if err != nil {
return nil, "", err
}

return tgwAtt, string(tgwAtt.State), nil
}
}

// WaitForTGWAttachmentToBeActive will poll the GET TGW attachment endpoint
// until the state is ACTIVE, ctx is canceled, or an error occurs.
func WaitForTGWAttachmentToBeActive(ctx context.Context, client *Client, tgwAttachmentID string, hvnID string, loc *sharedmodels.HashicorpCloudLocationLocation, timeout time.Duration) (*networkmodels.HashicorpCloudNetwork20200907TGWAttachment, error) {
stateChangeConf := resource.StateChangeConf{
Pending: []string{
TgwAttachmentStateCreating,
TgwAttachmentStatePendingAcceptance,
TgwAttachmentStateAccepted,
},
Target: []string{
TgwAttachmentStateActive,
},
Refresh: tgwAttachmentRefreshState(ctx, client, tgwAttachmentID, hvnID, loc),
Timeout: timeout,
PollInterval: 5 * time.Second,
}

result, err := stateChangeConf.WaitForStateContext(ctx)
if err != nil {
return nil, fmt.Errorf("Error waiting for transit gateway attachment (%s) to become 'ACTIVE': %s", tgwAttachmentID, err)
}

return result.(*networkmodels.HashicorpCloudNetwork20200907TGWAttachment), nil
}

// WaitForTGWAttachmentToBePendingAcceptance will poll the GET TGW attachment
// endpoint until the state is PENDING_ACCEPTANCE, ctx is canceled, or an error
// occurs.
func WaitForTGWAttachmentToBePendingAcceptance(ctx context.Context, client *Client, tgwAttachmentID string, hvnID string, loc *sharedmodels.HashicorpCloudLocationLocation, timeout time.Duration) (*networkmodels.HashicorpCloudNetwork20200907TGWAttachment, error) {
stateChangeConf := resource.StateChangeConf{
Pending: []string{
TgwAttachmentStateCreating,
},
Target: []string{
TgwAttachmentStatePendingAcceptance,
},
Refresh: tgwAttachmentRefreshState(ctx, client, tgwAttachmentID, hvnID, loc),
Timeout: timeout,
PollInterval: 5 * time.Second,
}

result, err := stateChangeConf.WaitForStateContext(ctx)
if err != nil {
return nil, fmt.Errorf("Error waiting for transit gateway attachment (%s) to become 'PENDING_ACCEPTANCE': %s", tgwAttachmentID, err)
}

return result.(*networkmodels.HashicorpCloudNetwork20200907TGWAttachment), nil
}
Loading