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

service/ec2: Support Private NAT Gateways #19758

Merged
merged 3 commits into from
Jun 10, 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
7 changes: 7 additions & 0 deletions .changelog/19758.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
```release-note:enhancement
data-source/aws_nat_gateway: Add `connectivity_type` attribute
```

```release-note:enhancement
resource/aws_nat_gateway: Add `connectivity_type` argument
```
5 changes: 5 additions & 0 deletions aws/data_source_aws_nat_gateway.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,10 @@ func dataSourceAwsNatGateway() *schema.Resource {
Type: schema.TypeString,
Computed: true,
},
"connectivity_type": {
Type: schema.TypeString,
Computed: true,
},
"network_interface_id": {
Type: schema.TypeString,
Computed: true,
Expand Down Expand Up @@ -121,6 +125,7 @@ func dataSourceAwsNatGatewayRead(d *schema.ResourceData, meta interface{}) error
log.Printf("[DEBUG] NAT Gateway response: %s", ngw)

d.SetId(aws.StringValue(ngw.NatGatewayId))
d.Set("connectivity_type", ngw.ConnectivityType)
d.Set("state", ngw.State)
d.Set("subnet_id", ngw.SubnetId)
d.Set("vpc_id", ngw.VpcId)
Expand Down
1 change: 1 addition & 0 deletions aws/data_source_aws_nat_gateway_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ func TestAccDataSourceAwsNatGateway_basic(t *testing.T) {
{
Config: testAccDataSourceAwsNatGatewayConfig(rInt),
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttrPair("data.aws_nat_gateway.test_by_id", "connectivity_type", "aws_nat_gateway.test", "connectivity_type"),
resource.TestCheckResourceAttrPair(
"data.aws_nat_gateway.test_by_id", "id",
"aws_nat_gateway.test", "id"),
Expand Down
26 changes: 23 additions & 3 deletions aws/resource_aws_nat_gateway.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
"github.com/aws/aws-sdk-go/service/ec2"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation"
"github.com/terraform-providers/terraform-provider-aws/aws/internal/keyvaluetags"
)

Expand All @@ -27,7 +28,7 @@ func resourceAwsNatGateway() *schema.Resource {
Schema: map[string]*schema.Schema{
"allocation_id": {
Type: schema.TypeString,
Required: true,
Optional: true,
anGie44 marked this conversation as resolved.
Show resolved Hide resolved
ForceNew: true,
},

Expand All @@ -37,6 +38,14 @@ func resourceAwsNatGateway() *schema.Resource {
ForceNew: true,
},

"connectivity_type": {
Type: schema.TypeString,
Optional: true,
ForceNew: true,
Default: ec2.ConnectivityTypePublic,
ValidateFunc: validation.StringInSlice(ec2.ConnectivityType_Values(), false),
},

"network_interface_id": {
Type: schema.TypeString,
Computed: true,
Expand Down Expand Up @@ -67,11 +76,21 @@ func resourceAwsNatGatewayCreate(d *schema.ResourceData, meta interface{}) error

// Create the NAT Gateway
createOpts := &ec2.CreateNatGatewayInput{
AllocationId: aws.String(d.Get("allocation_id").(string)),
SubnetId: aws.String(d.Get("subnet_id").(string)),
TagSpecifications: ec2TagSpecificationsFromKeyValueTags(tags, ec2.ResourceTypeNatgateway),
}

if v, ok := d.GetOk("allocation_id"); ok {
createOpts.AllocationId = aws.String(v.(string))
}

if v, ok := d.GetOk("connectivity_type"); ok {
createOpts.ConnectivityType = aws.String(v.(string))
}

if v, ok := d.GetOk("subnet_id"); ok {
createOpts.SubnetId = aws.String(v.(string))
}

log.Printf("[DEBUG] Create NAT Gateway: %s", *createOpts)
natResp, err := conn.CreateNatGateway(createOpts)
if err != nil {
Expand Down Expand Up @@ -124,6 +143,7 @@ func resourceAwsNatGatewayRead(d *schema.ResourceData, meta interface{}) error {

// Set NAT Gateway attributes
ng := ngRaw.(*ec2.NatGateway)
d.Set("connectivity_type", ng.ConnectivityType)
d.Set("subnet_id", ng.SubnetId)

// Address
Expand Down
45 changes: 45 additions & 0 deletions aws/resource_aws_nat_gateway_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ func TestAccAWSNatGateway_basic(t *testing.T) {
Config: testAccNatGatewayConfig,
Check: resource.ComposeTestCheckFunc(
testAccCheckNatGatewayExists(resourceName, &natGateway),
resource.TestCheckResourceAttr(resourceName, "connectivity_type", "public"),
resource.TestCheckResourceAttr(resourceName, "tags.#", "0"),
),
},
Expand All @@ -82,6 +83,32 @@ func TestAccAWSNatGateway_basic(t *testing.T) {
})
}

func TestAccAWSNatGateway_ConnectivityType_Private(t *testing.T) {
var natGateway ec2.NatGateway
resourceName := "aws_nat_gateway.test"

resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
ErrorCheck: testAccErrorCheck(t, ec2.EndpointsID),
Providers: testAccProviders,
CheckDestroy: testAccCheckNatGatewayDestroy,
Steps: []resource.TestStep{
{
Config: testAccNatGatewayConfigConnectivityType("private"),
Check: resource.ComposeTestCheckFunc(
testAccCheckNatGatewayExists(resourceName, &natGateway),
resource.TestCheckResourceAttr(resourceName, "connectivity_type", "private"),
),
},
{
ResourceName: resourceName,
ImportState: true,
ImportStateVerify: true,
},
},
})
}

func TestAccAWSNatGateway_tags(t *testing.T) {
var natGateway ec2.NatGateway
resourceName := "aws_nat_gateway.test"
Expand Down Expand Up @@ -239,6 +266,24 @@ resource "aws_nat_gateway" "test" {
}
`

func testAccNatGatewayConfigConnectivityType(connectivityType string) string {
return fmt.Sprintf(`
resource "aws_vpc" "test" {
cidr_block = "10.0.0.0/16"
}

resource "aws_subnet" "test" {
cidr_block = cidrsubnet(aws_vpc.test.cidr_block, 8, 0)
vpc_id = aws_vpc.test.id
}

resource "aws_nat_gateway" "test" {
connectivity_type = %[1]q
subnet_id = aws_subnet.test.id
}
`, connectivityType)
}

func testAccNatGatewayConfigTags1(tagKey1, tagValue1 string) string {
return testAccNatGatewayConfigBase + fmt.Sprintf(`
resource "aws_nat_gateway" "test" {
Expand Down
1 change: 1 addition & 0 deletions website/docs/d/nat_gateway.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ the selected Nat Gateway.
Each attachment supports the following:

* `allocation_id` - The Id of the EIP allocated to the selected Nat Gateway.
* `connectivity_type` - The connectivity type of the NAT Gateway.
* `network_interface_id` - The Id of the ENI allocated to the selected Nat Gateway.
* `private_ip` - The private Ip address of the selected Nat Gateway.
* `public_ip` - The public Ip (EIP) address of the selected Nat Gateway.
43 changes: 18 additions & 25 deletions website/docs/r/nat_gateway.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -12,48 +12,41 @@ Provides a resource to create a VPC NAT Gateway.

## Example Usage

```terraform
resource "aws_nat_gateway" "gw" {
allocation_id = aws_eip.nat.id
subnet_id = aws_subnet.example.id
}
```

Usage with tags:
### Public NAT

```terraform
resource "aws_nat_gateway" "gw" {
allocation_id = aws_eip.nat.id
resource "aws_nat_gateway" "example" {
allocation_id = aws_eip.example.id
subnet_id = aws_subnet.example.id

tags = {
Name = "gw NAT"
}

# To ensure proper ordering, it is recommended to add an explicit dependency
# on the Internet Gateway for the VPC.
depends_on = [aws_internet_gateway.example]
}
```

### Private NAT

```terraform
resource "aws_nat_gateway" "example" {
connectivity_type = "private"
subnet_id = aws_subnet.example.id
}
```

## Argument Reference

The following arguments are supported:

* `allocation_id` - (Required) The Allocation ID of the Elastic IP address for the gateway.
* `allocation_id` - (Optional) The Allocation ID of the Elastic IP address for the gateway. Required for `connectivity_type` of `public`.
* `connectivity_type` - (Optional) Connectivity type for the gateway. Valid values are `private` and `public`. Defaults to `public`.
* `subnet_id` - (Required) The Subnet ID of the subnet in which to place the gateway.
* `tags` - (Optional) A map of tags to assign to the resource. If configured with a provider [`default_tags` configuration block](/docs/providers/aws/index.html#default_tags-configuration-block) present, tags with matching keys will overwrite those defined at the provider-level.

-> **Note:** It's recommended to denote that the NAT Gateway depends on the Internet Gateway for the VPC in which the NAT Gateway's subnet is located. For example:

```terraform
resource "aws_internet_gateway" "gw" {
vpc_id = aws_vpc.main.id
}

resource "aws_nat_gateway" "gw" {
# ... other arguments ...

depends_on = [aws_internet_gateway.gw]
}
```

## Attributes Reference

In addition to all arguments above, the following attributes are exported:
Expand Down