diff --git a/.github/labeler.yaml b/.github/labeler.yaml
index bb352d2..bc6b780 100644
--- a/.github/labeler.yaml
+++ b/.github/labeler.yaml
@@ -11,5 +11,8 @@
":floppy_disk: security-group":
- modules/security-group/**/*
+":floppy_disk: subnet-group":
+- modules/subnet-group/**/*
+
":floppy_disk: vpc":
- modules/vpc/**/*
diff --git a/examples/vpc-full/nat-gateways.tf b/examples/vpc-full/nat-gateways.tf
new file mode 100644
index 0000000..3df103c
--- /dev/null
+++ b/examples/vpc-full/nat-gateways.tf
@@ -0,0 +1,67 @@
+###################################################
+# Elastic IP
+###################################################
+
+module "elastic_ip" {
+ source = "tedilabs/ipam/aws//modules/elastic-ip"
+ version = "~> 0.3.0"
+
+ name = "nat-gw-test-public/az2"
+ type = "AMAZON"
+
+ tags = {
+ "project" = "terraform-aws-network-examples"
+ }
+}
+
+
+###################################################
+# Public NAT Gateway
+###################################################
+
+module "public_nat_gateway" {
+ source = "../../modules/nat-gateway"
+ # source = "tedilabs/network/aws//modules/nat-gateway"
+ # version = "~> 0.2.0"
+
+ name = "test-public/az2"
+ is_private = false
+ subnet = module.public_subnet_group.subnets_by_az["use1-az2"][0].id
+
+
+ ## Primary IP Address
+ primary_ip_assignment = {
+ elastic_ip = module.elastic_ip.id
+ }
+
+
+ tags = {
+ "project" = "terraform-aws-network-examples"
+ }
+}
+
+
+###################################################
+# Private NAT Gateway
+###################################################
+
+module "private_nat_gateway" {
+ source = "../../modules/nat-gateway"
+ # source = "tedilabs/network/aws//modules/nat-gateway"
+ # version = "~> 0.2.0"
+
+ name = "test-private/az2"
+ is_private = true
+ subnet = module.private_subnet_group.subnets_by_az["use1-az2"][0].id
+
+
+ ## Primary IP Address
+ primary_ip_assignment = {
+ private_ip = "10.0.200.7"
+ }
+
+
+ tags = {
+ "project" = "terraform-aws-network-examples"
+ }
+}
diff --git a/examples/vpc-full/outputs.tf b/examples/vpc-full/outputs.tf
index cc46043..6bd50a8 100644
--- a/examples/vpc-full/outputs.tf
+++ b/examples/vpc-full/outputs.tf
@@ -2,3 +2,21 @@ output "vpc" {
description = "The VPC."
value = module.vpc
}
+
+output "subnet_groups" {
+ description = "The Subnet Groups for the VPC."
+ value = {
+ private = module.private_subnet_group
+ public = module.public_subnet_group
+ }
+}
+
+output "public_nat_gateways" {
+ description = "The NAT Gateways in public."
+ value = module.public_nat_gateway
+}
+
+output "private_nat_gateways" {
+ description = "The NAT Gateways in private."
+ value = module.private_nat_gateway
+}
diff --git a/examples/vpc-full/subnet-groups.tf b/examples/vpc-full/subnet-groups.tf
new file mode 100644
index 0000000..868f46a
--- /dev/null
+++ b/examples/vpc-full/subnet-groups.tf
@@ -0,0 +1,138 @@
+###################################################
+# Subnet Groups
+###################################################
+
+module "private_subnet_group" {
+ source = "../../modules/subnet-group"
+ # source = "tedilabs/network/aws//modules/subnet-group"
+ # version = "~> 0.2.0"
+
+ name = "test/private"
+
+ vpc_id = module.vpc.id
+
+ subnets = {
+ "test/private/az2" = {
+ availability_zone_id = "use1-az2"
+ ipv4_cidr = "10.0.200.0/24"
+ }
+ "test/private/az4" = {
+ availability_zone_id = "use1-az4"
+ ipv4_cidr = "10.0.201.0/24"
+ }
+ }
+
+
+ ## IP Assignments
+ public_ipv4_address_assignment = {
+ enabled = false
+ }
+ ipv6_address_assignment = {
+ enabled = false
+ }
+ customer_owned_ipv4_address_assignment = {
+ enabled = false
+ }
+
+
+ ## DNS Configurations
+ dns_config = {
+ hostname_type = "RESOURCE_NAME"
+ dns_resource_name_ipv4_enabled = true
+ dns_resource_name_ipv6_enabled = false
+ dns64_enabled = false
+ }
+
+ ## Integrations
+ dax_subnet_group = {
+ enabled = true
+ name = "test-dax"
+ description = "Test DAX Subnet Group"
+ }
+ dms_replication_subnet_group = {
+ enabled = true
+ name = "test-dms-replication"
+ description = "Test DMS Replication Subnet Group"
+ }
+ docdb_subnet_group = {
+ enabled = true
+ name = "test-docdb"
+ description = "Test DocumentDB Subnet Group"
+ }
+ elasticache_subnet_group = {
+ enabled = true
+ name = "test-elasticache"
+ description = "Test ElastiCache Subnet Group"
+ }
+ memorydb_subnet_group = {
+ enabled = true
+ name = "test-memorydb"
+ description = "Test MemoryDB Subnet Group"
+ }
+ neptune_subnet_group = {
+ enabled = true
+ name = "test-neptune"
+ description = "Test Neptune Subnet Group"
+ }
+ rds_subnet_group = {
+ enabled = true
+ name = "test-rds"
+ description = "Test RDS Subnet Group"
+ }
+ redshift_subnet_group = {
+ enabled = true
+ name = "test-redshift"
+ description = "Test Redshift Subnet Group"
+ }
+
+ tags = {
+ "project" = "terraform-aws-network-examples"
+ }
+}
+
+module "public_subnet_group" {
+ source = "../../modules/subnet-group"
+ # source = "tedilabs/network/aws//modules/subnet-group"
+ # version = "~> 0.2.0"
+
+ name = "test/public"
+
+ vpc_id = module.vpc.id
+
+ subnets = {
+ "test/public/az2" = {
+ availability_zone_id = "use1-az2"
+ ipv4_cidr = "10.0.100.0/24"
+ }
+ "test/public/az4" = {
+ availability_zone_id = "use1-az4"
+ ipv4_cidr = "10.0.101.0/24"
+ }
+ }
+
+
+ ## IP Assignments
+ public_ipv4_address_assignment = {
+ enabled = true
+ }
+ ipv6_address_assignment = {
+ enabled = false
+ }
+ customer_owned_ipv4_address_assignment = {
+ enabled = false
+ }
+
+
+ ## DNS Configurations
+ dns_config = {
+ hostname_type = "RESOURCE_NAME"
+ dns_resource_name_ipv4_enabled = true
+ dns_resource_name_ipv6_enabled = false
+ dns64_enabled = false
+ }
+
+
+ tags = {
+ "project" = "terraform-aws-network-examples"
+ }
+}
diff --git a/modules/subnet-group/README.md b/modules/subnet-group/README.md
index b7f4c59..662fd10 100644
--- a/modules/subnet-group/README.md
+++ b/modules/subnet-group/README.md
@@ -3,13 +3,14 @@
This module creates following resources.
- `aws_subnet`
+- `aws_dax_subnet_group` (optional)
- `aws_db_subnet_group` (optional)
+- `aws_dms_replication_subnet_group` (optional)
+- `aws_docdb_subnet_group` (optional)
- `aws_elasticache_subnet_group` (optional)
-- `aws_redshift_subnet_group` (optional)
+- `aws_memorydb_subnet_group` (optional)
- `aws_neptune_subnet_group` (optional)
-- `aws_docdb_subnet_group` (optional)
-- `aws_dax_subnet_group` (optional)
-- `aws_dms_replication_subnet_group` (optional)
+- `aws_redshift_subnet_group` (optional)
## Requirements
@@ -23,7 +24,7 @@ This module creates following resources.
| Name | Version |
|------|---------|
-| [aws](#provider\_aws) | 5.19.0 |
+| [aws](#provider\_aws) | 5.22.0 |
## Modules
@@ -44,40 +45,34 @@ This module creates following resources.
| [aws_neptune_subnet_group.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/neptune_subnet_group) | resource |
| [aws_redshift_subnet_group.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/redshift_subnet_group) | resource |
| [aws_subnet.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/subnet) | resource |
+| [aws_availability_zones.available](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/availability_zones) | data source |
## Inputs
| Name | Description | Type | Default | Required |
|------|-------------|------|---------|:--------:|
-| [name](#input\_name) | The name of the subnet group. | `string` | n/a | yes |
-| [subnets](#input\_subnets) | A map of subnet parameters to create subnets for the subnet group. | `map(map(any))` | n/a | yes |
-| [vpc\_id](#input\_vpc\_id) | The ID of the VPC which the subnet group belongs to. | `string` | n/a | yes |
-| [assign\_ipv6\_address\_on\_creation](#input\_assign\_ipv6\_address\_on\_creation) | Assign IPv6 address on subnet, must be disabled to change IPv6 CIDRs. This is the IPv6 equivalent of map\_public\_ip\_on\_launch. | `bool` | `false` | no |
-| [cache\_subnet\_group\_enabled](#input\_cache\_subnet\_group\_enabled) | Controls if Elasticache Subnet Group should be created. | `bool` | `false` | no |
-| [cache\_subnet\_group\_name](#input\_cache\_subnet\_group\_name) | Desired name for the Elasticache Subnet Group. | `string` | `""` | no |
-| [customer\_owned\_ipv4\_pool](#input\_customer\_owned\_ipv4\_pool) | The customer owned IPv4 address pool. `outpost_arn` argument must be specified when configured. | `string` | `""` | no |
-| [dax\_subnet\_group\_enabled](#input\_dax\_subnet\_group\_enabled) | Controls if DAX Subnet Group should be created. | `bool` | `false` | no |
-| [dax\_subnet\_group\_name](#input\_dax\_subnet\_group\_name) | Desired name for the DAX Subnet Group. | `string` | `""` | no |
-| [db\_subnet\_group\_enabled](#input\_db\_subnet\_group\_enabled) | Controls if RDS Subnet Group should be created. | `bool` | `false` | no |
-| [db\_subnet\_group\_name](#input\_db\_subnet\_group\_name) | Desired name for the RDS Subnet Group. | `string` | `""` | no |
-| [dms\_replication\_subnet\_group\_enabled](#input\_dms\_replication\_subnet\_group\_enabled) | Controls if DMS Replication Subnet Group should be created. | `bool` | `false` | no |
-| [dms\_replication\_subnet\_group\_name](#input\_dms\_replication\_subnet\_group\_name) | Desired name for the DMS Replication Subnet Group. | `string` | `""` | no |
-| [docdb\_subnet\_group\_enabled](#input\_docdb\_subnet\_group\_enabled) | Controls if DocumentDB Subnet Group should be created. | `bool` | `false` | no |
-| [docdb\_subnet\_group\_name](#input\_docdb\_subnet\_group\_name) | Desired name for the DocumentDB Subnet Group. | `string` | `""` | no |
-| [map\_customer\_owned\_ip\_on\_launch](#input\_map\_customer\_owned\_ip\_on\_launch) | Should be true if network interfaces created in the subnet should be assigned a customer owned IP address. | `bool` | `false` | no |
-| [map\_public\_ip\_on\_launch](#input\_map\_public\_ip\_on\_launch) | Should be false if you do not want to auto-assign public IP on launch. | `bool` | `false` | no |
-| [memorydb\_subnet\_group\_enabled](#input\_memorydb\_subnet\_group\_enabled) | Controls if MemoryDB Subnet Group should be created. | `bool` | `false` | no |
-| [memorydb\_subnet\_group\_name](#input\_memorydb\_subnet\_group\_name) | Desired name for the MemoryDB Subnet Group. | `string` | `""` | no |
-| [module\_tags\_enabled](#input\_module\_tags\_enabled) | Whether to create AWS Resource Tags for the module informations. | `bool` | `true` | no |
-| [neptune\_subnet\_group\_enabled](#input\_neptune\_subnet\_group\_enabled) | Controls if Neptune Subnet Group should be created. | `bool` | `false` | no |
-| [neptune\_subnet\_group\_name](#input\_neptune\_subnet\_group\_name) | Desired name for the Neptune Subnet Group. | `string` | `""` | no |
-| [outpost\_arn](#input\_outpost\_arn) | The ARN of the Outpost. | `string` | `""` | no |
-| [redshift\_subnet\_group\_enabled](#input\_redshift\_subnet\_group\_enabled) | Controls if Redshift Subnet Group should be created. | `bool` | `false` | no |
-| [redshift\_subnet\_group\_name](#input\_redshift\_subnet\_group\_name) | Desired name for the Redshift Subnet Group. | `string` | `""` | no |
-| [resource\_group\_description](#input\_resource\_group\_description) | The description of Resource Group. | `string` | `"Managed by Terraform."` | no |
-| [resource\_group\_enabled](#input\_resource\_group\_enabled) | Whether to create Resource Group to find and group AWS resources which are created by this module. | `bool` | `true` | no |
-| [resource\_group\_name](#input\_resource\_group\_name) | The name of Resource Group. A Resource Group name can have a maximum of 127 characters, including letters, numbers, hyphens, dots, and underscores. The name cannot start with `AWS` or `aws`. | `string` | `""` | no |
-| [tags](#input\_tags) | A map of tags to add to all resources. | `map(string)` | `{}` | no |
+| [name](#input\_name) | (Required) The name of the subnet group. | `string` | n/a | yes |
+| [subnets](#input\_subnets) | (Required) A configuration of subnets to create in the subnet group. Each block of `subnets` as defined below.
(Required) `type` - The type of subnet. Valid values are `DUALSTACK` and `IPV6`.
(Optional) `availability_zone` - The availability zone of the subnet. If the value of `availability_zone` and `availability_zone_id` are both not provided, the subnet will be created in random availability zone.
(Optional) `availability_zone_id` - The availability zone ID of the subnet. If the value of `availability_zone` and `availability_zone_id` are both not provided, the subnet will be created in random availability zone. |
map(object({
type = optional(string, "DUALSTACK")
availability_zone = optional(string)
availability_zone_id = optional(string)
ipv4_cidr = optional(string)
ipv6_cidr = optional(string)
}))
| n/a | yes |
+| [vpc\_id](#input\_vpc\_id) | (Required) The ID of the VPC which the subnet group belongs to. | `string` | n/a | yes |
+| [customer\_owned\_ipv4\_address\_assignment](#input\_customer\_owned\_ipv4\_address\_assignment) | (Optional) A configuration for Customer-owned IPv4 address assignment. `customer_owned_ipv4_address_assignment` as defined below.
(Optional) `enabled` - Whether to automatically request a Customer-owned IPv4 address for a new network interface in this subnet. Defaults to `false`.
(Optional) `outpost` - The Amazon Resource Name (ARN) of the Outpost.
(Optional) `pool` - The customer owned IPv4 address pool. | object({
enabled = optional(bool, false)
outpost = optional(string)
pool = optional(string)
})
| `{}` | no |
+| [dax\_subnet\_group](#input\_dax\_subnet\_group) | (Optional) A configuration of DAX Subnet Group. `dax_subnet_group` as defined below.
(Optional) `enabled` - Whether to create DAX Subnet Group. Defaults to `false`.
(Optional) `name` - The name of the DAX Subnet Group. If not provided, the value of `name` will be used.
(Optional) `description` - The description of the DAX Subnet Group. | object({
enabled = optional(bool, false)
name = optional(string)
description = optional(string, "Managed by Terraform.")
})
| `{}` | no |
+| [dms\_replication\_subnet\_group](#input\_dms\_replication\_subnet\_group) | (Optional) A configuration of DMS Replication Subnet Group. `dms_replication_subnet_group` as defined below.
(Optional) `enabled` - Whether to create DMS Replication Subnet Group. Defaults to `false`.
(Optional) `name` - The name of the DMS Replication Subnet Group. If not provided, the value of `name` will be used.
(Optional) `description` - The description of the DMS Replication Subnet Group. | object({
enabled = optional(bool, false)
name = optional(string)
description = optional(string, "Managed by Terraform.")
})
| `{}` | no |
+| [dns\_config](#input\_dns\_config) | (Optional) A configuration for DNS queries for the subnet. `dns_config` as defined below.
(Optional) `hostname_type` - The type of hostnames to assign to instances in the subnet at launch. For IPv6-only subnets, an instance DNS name must be based on the instance ID (`RESOURCE_NAME`). For dual-stack and IPv4-only subnets, you can specify whether DNS names use the instance IPv4 address (`IP_NAME`) or the instance ID (`RESOURCE_NAME`). Valid values are `IP_NAME`, `RESOURCE_NAME`. Defaults to `RESOURCE_NAME`.
(Optional) `dns_resource_name_ipv4_enabled` - Whether to respond to DNS queries for instance hostnames with DNS A records. Always `false` for IPv6 only subnet. Defaults to `false`.
(Optional) `dns_resource_name_ipv6_enabled` - Whether to respond to DNS queries for instance hostnames with DNS AAAA records. Always `true` for IPv6 only subnet. Defaults to `false`.
(Optional) `dns64_enabled` - Whether to enable DNS64 to allow IPv6-only services in Amazon VPC to communicate with IPv4-only services and networks. Defaults to `false`. | object({
hostname_type = optional(string, "RESOURCE_NAME")
dns_resource_name_ipv4_enabled = optional(bool, false)
dns_resource_name_ipv6_enabled = optional(bool, false)
dns64_enabled = optional(bool, false)
})
| `{}` | no |
+| [docdb\_subnet\_group](#input\_docdb\_subnet\_group) | (Optional) A configuration of DocumentDB Subnet Group. `docdb_subnet_group` as defined below.
(Optional) `enabled` - Whether to create DocumentDB Subnet Group. Defaults to `false`.
(Optional) `name` - The name of the DocumentDB Subnet Group. If not provided, the value of `name` will be used.
(Optional) `description` - The description of the DocumentDB Subnet Group. | object({
enabled = optional(bool, false)
name = optional(string)
description = optional(string, "Managed by Terraform.")
})
| `{}` | no |
+| [elasticache\_subnet\_group](#input\_elasticache\_subnet\_group) | (Optional) A configuration of ElastiCache Subnet Group. `elasticache_subnet_group` as defined below.
(Optional) `enabled` - Whether to create ElastiCache Subnet Group. Defaults to `false`.
(Optional) `name` - The name of the ElastiCache Subnet Group. If not provided, the value of `name` will be used.
(Optional) `description` - The description of the ElastiCache Subnet Group. | object({
enabled = optional(bool, false)
name = optional(string)
description = optional(string, "Managed by Terraform.")
})
| `{}` | no |
+| [ipv6\_address\_assignment](#input\_ipv6\_address\_assignment) | (Optional) A configuration for IPv6 address assignment. `ipv6_address_assignment` as defined below.
(Optional) `enabled` - Whether to automatically request a IPv6 address for a new network interface in this subnet. Defaults to `false`. | object({
enabled = optional(bool, false)
})
| `{}` | no |
+| [local\_network\_interface\_device\_index](#input\_local\_network\_interface\_device\_index) | (Optional) The device position for local network interfaces in this subnet. For example, `1` indicates local network interfaces in this subnet are the secondary network interface (eth1). A local network interface cannot be the primary network interface (eth0). | `number` | `null` | no |
+| [memorydb\_subnet\_group](#input\_memorydb\_subnet\_group) | (Optional) A configuration of MemoryDB Subnet Group. `memorydb_subnet_group` as defined below.
(Optional) `enabled` - Whether to create MemoryDB Subnet Group. Defaults to `false`.
(Optional) `name` - The name of the MemoryDB Subnet Group. If not provided, the value of `name` will be used.
(Optional) `description` - The description of the MemoryDB Subnet Group. | object({
enabled = optional(bool, false)
name = optional(string)
description = optional(string, "Managed by Terraform.")
})
| `{}` | no |
+| [module\_tags\_enabled](#input\_module\_tags\_enabled) | (Optional) Whether to create AWS Resource Tags for the module informations. | `bool` | `true` | no |
+| [neptune\_subnet\_group](#input\_neptune\_subnet\_group) | (Optional) A configuration of Neptune Subnet Group. `neptune_subnet_group` as defined below.
(Optional) `enabled` - Whether to create Neptune Subnet Group. Defaults to `false`.
(Optional) `name` - The name of the Neptune Subnet Group. If not provided, the value of `name` will be used.
(Optional) `description` - The description of the Neptune Subnet Group. | object({
enabled = optional(bool, false)
name = optional(string)
description = optional(string, "Managed by Terraform.")
})
| `{}` | no |
+| [public\_ipv4\_address\_assignment](#input\_public\_ipv4\_address\_assignment) | (Optional) A configuration for public IPv4 address assignment. `public_ipv4_address_assignment` as defined below.
(Optional) `enabled` - Whether to automatically request a public IPv4 address for a new network interface in this subnet. Defaults to `false`. | object({
enabled = optional(bool, false)
})
| `{}` | no |
+| [rds\_subnet\_group](#input\_rds\_subnet\_group) | (Optional) A configuration of RDS Subnet Group. `rds_subnet_group` as defined below.
(Optional) `enabled` - Whether to create RDS Subnet Group. Defaults to `false`.
(Optional) `name` - The name of the RDS Subnet Group. If not provided, the value of `name` will be used.
(Optional) `description` - The description of the RDS Subnet Group. | object({
enabled = optional(bool, false)
name = optional(string)
description = optional(string, "Managed by Terraform.")
})
| `{}` | no |
+| [redshift\_subnet\_group](#input\_redshift\_subnet\_group) | (Optional) A configuration of Redshift Subnet Group. `redshift_subnet_group` as defined below.
(Optional) `enabled` - Whether to create Redshift Subnet Group. Defaults to `false`.
(Optional) `name` - The name of the Redshift Subnet Group. If not provided, the value of `name` will be used.
(Optional) `description` - The description of the Redshift Subnet Group. | object({
enabled = optional(bool, false)
name = optional(string)
description = optional(string, "Managed by Terraform.")
})
| `{}` | no |
+| [resource\_group\_description](#input\_resource\_group\_description) | (Optional) The description of Resource Group. | `string` | `"Managed by Terraform."` | no |
+| [resource\_group\_enabled](#input\_resource\_group\_enabled) | (Optional) Whether to create Resource Group to find and group AWS resources which are created by this module. | `bool` | `true` | no |
+| [resource\_group\_name](#input\_resource\_group\_name) | (Optional) The name of Resource Group. A Resource Group name can have a maximum of 127 characters, including letters, numbers, hyphens, dots, and underscores. The name cannot start with `AWS` or `aws`. | `string` | `""` | no |
+| [tags](#input\_tags) | (Optional) A map of tags to add to all resources. | `map(string)` | `{}` | no |
+| [timeouts](#input\_timeouts) | (Optional) How long to wait for the subnet group to be created/deleted. | object({
create = optional(string, "10m")
delete = optional(string, "20m")
})
| `{}` | no |
## Outputs
@@ -86,23 +81,24 @@ This module creates following resources.
| [arns](#output\_arns) | A list of ARNs of subnets |
| [availability\_zone\_ids](#output\_availability\_zone\_ids) | A list of availability zone IDs which the subnet group uses. |
| [availability\_zones](#output\_availability\_zones) | A list of availability zones which the subnet group uses. |
-| [cache\_subnet\_group\_id](#output\_cache\_subnet\_group\_id) | The ID of the Elasticache Subnet Group. |
-| [cidr\_blocks](#output\_cidr\_blocks) | The CIDR blocks of the subnet group. |
-| [dax\_subnet\_group\_id](#output\_dax\_subnet\_group\_id) | The ID of the DAX Subnet Group. |
-| [db\_subnet\_group\_arn](#output\_db\_subnet\_group\_arn) | The ARN of the RDS Subnet Group. |
-| [db\_subnet\_group\_id](#output\_db\_subnet\_group\_id) | The ID of the RDS Subnet Group. |
-| [dms\_replication\_subnet\_group\_id](#output\_dms\_replication\_subnet\_group\_id) | The ID of the DMS Replication Subnet Group. |
-| [docdb\_subnet\_group\_arn](#output\_docdb\_subnet\_group\_arn) | The ARN of the DocumentDB Subnet Group. |
-| [docdb\_subnet\_group\_id](#output\_docdb\_subnet\_group\_id) | The ID of the DocumentDB Subnet Group. |
+| [customer\_owned\_ipv4\_address\_assignment](#output\_customer\_owned\_ipv4\_address\_assignment) | The configuration of Customer-owned IPv4 address assignment.
`enabled` - Whether to automatically assign Customer-owned IPv4 address to instances launched in the subnet group.
`outpost` - The ARN of the Outpost.
`pool` - The ID of the Customer-owned IPv4 address pool. |
+| [dax\_subnet\_group](#output\_dax\_subnet\_group) | The configuration of DAX Subnet Group.
`id` - The ID of the DAX Subnet Group.
`name` - The name of the DAX Subnet Group.
`description` - The description of the DAX Subnet Group. |
+| [dms\_replication\_subnet\_group](#output\_dms\_replication\_subnet\_group) | The configuration of DMS Replication Subnet Group.
`id` - The ID of the DMS Replication Subnet Group.
`arn` - The ARN of the DMS Replication Subnet Group.
`name` - The name of the DMS Replication Subnet Group.
`description` - The description of the DMS Replication Subnet Group. |
+| [dns\_config](#output\_dns\_config) | The DNS configuration for the subnet group.
`id` - The ID of the DAX Subnet Group. |
+| [docdb\_subnet\_group](#output\_docdb\_subnet\_group) | The configuration of DocumentDB Subnet Group.
`id` - The ID of the DocumentDB Subnet Group.
`arn` - The ARN of the DocumentDB Subnet Group.
`name` - The name of the DocumentDB Subnet Group.
`description` - The description of the DocumentDB Subnet Group. |
+| [elasticache\_subnet\_group](#output\_elasticache\_subnet\_group) | The configuration of ElastiCache Subnet Group.
`id` - The ID of the ElastiCache Subnet Group.
`arn` - The ARN of the ElastiCache Subnet Group.
`name` - The name of the ElastiCache Subnet Group.
`description` - The description of the ElastiCache Subnet Group. |
| [ids](#output\_ids) | A list of IDs of subnets |
-| [ipv6\_cidr\_blocks](#output\_ipv6\_cidr\_blocks) | The IPv6 CIDR blocks of the subnet group. |
-| [memorydb\_subnet\_group\_arn](#output\_memorydb\_subnet\_group\_arn) | The ARN of the MemoryDB Subnet Group. |
-| [memorydb\_subnet\_group\_id](#output\_memorydb\_subnet\_group\_id) | The ID of the MemoryDB Subnet Group. |
+| [ipv4\_cidrs](#output\_ipv4\_cidrs) | The IPv4 CIDR blocks of the subnet group. |
+| [ipv6\_address\_assignment](#output\_ipv6\_address\_assignment) | The configuration of IPv6 address assignment.
`enabled` - Whether to automatically assign IPv6 address to instances launched in the subnet group. |
+| [ipv6\_cidrs](#output\_ipv6\_cidrs) | The IPv6 CIDR blocks of the subnet group. |
+| [local\_network\_interface\_device\_index](#output\_local\_network\_interface\_device\_index) | The device position for local network interfaces in this subnet. |
+| [memorydb\_subnet\_group](#output\_memorydb\_subnet\_group) | The configuration of MemoryDB Subnet Group.
`id` - The ID of the MemoryDB Subnet Group.
`arn` - The ARN of the MemoryDB Subnet Group.
`name` - The name of the MemoryDB Subnet Group.
`description` - The description of the MemoryDB Subnet Group. |
| [name](#output\_name) | The name of the subnet group. |
-| [neptune\_subnet\_group\_arn](#output\_neptune\_subnet\_group\_arn) | The ARN of the Neptune Subnet Group. |
-| [neptune\_subnet\_group\_id](#output\_neptune\_subnet\_group\_id) | The ID of the Neptune DB Subnet Group. |
-| [redshift\_subnet\_group\_arn](#output\_redshift\_subnet\_group\_arn) | The ARN of the Redshift Subnet Group. |
-| [redshift\_subnet\_group\_id](#output\_redshift\_subnet\_group\_id) | The ID of the Redshift Subnet Group. |
+| [neptune\_subnet\_group](#output\_neptune\_subnet\_group) | The configuration of Neptune Subnet Group.
`id` - The ID of the Neptune Subnet Group.
`arn` - The ARN of the Neptune Subnet Group.
`name` - The name of the Neptune Subnet Group.
`description` - The description of the Neptune Subnet Group. |
+| [owner](#output\_owner) | The ID of the AWS account that owns subnets in the subnet group. |
+| [public\_ipv4\_address\_assignment](#output\_public\_ipv4\_address\_assignment) | The configuration of public IPv4 address assignment.
`enabled` - Whether to automatically assign public IPv4 address to instances launched in the subnet group. |
+| [rds\_subnet\_group](#output\_rds\_subnet\_group) | The configuration of RDS Subnet Group.
`id` - The ID of the RDS Subnet Group.
`arn` - The ARN of the RDS Subnet Group.
`name` - The name of the RDS Subnet Group.
`description` - The description of the RDS Subnet Group. |
+| [redshift\_subnet\_group](#output\_redshift\_subnet\_group) | The configuration of Redshift Subnet Group.
`id` - The ID of the Redshift Subnet Group.
`arn` - The ARN of the Redshift Subnet Group.
`name` - The name of the Redshift Subnet Group.
`description` - The description of the Redshift Subnet Group. |
| [subnets](#output\_subnets) | A list of subnets of the subnet group. |
| [subnets\_by\_az](#output\_subnets\_by\_az) | A map of subnets of the subnet group which are grouped by availability zone id. |
| [vpc\_id](#output\_vpc\_id) | The ID of the VPC which the subnet group belongs to. |
diff --git a/modules/subnet-group/integrations.tf b/modules/subnet-group/integrations.tf
new file mode 100644
index 0000000..f1eae91
--- /dev/null
+++ b/modules/subnet-group/integrations.tf
@@ -0,0 +1,169 @@
+###################################################
+# Subnet Group for DAX
+###################################################
+
+resource "aws_dax_subnet_group" "this" {
+ count = var.dax_subnet_group.enabled ? 1 : 0
+
+ name = coalesce(var.dax_subnet_group.name, var.name)
+ description = var.dax_subnet_group.description
+
+ subnet_ids = values(aws_subnet.this)[*].id
+
+ # INFO: Not support resource tags
+ # tags = {}
+}
+
+
+###################################################
+# Subnet Group for DMS Replication
+###################################################
+
+resource "aws_dms_replication_subnet_group" "this" {
+ count = var.dms_replication_subnet_group.enabled ? 1 : 0
+
+ replication_subnet_group_id = coalesce(var.dms_replication_subnet_group.name, var.name)
+ replication_subnet_group_description = var.dms_replication_subnet_group.description
+
+ subnet_ids = values(aws_subnet.this)[*].id
+
+ tags = merge(
+ {
+ "Name" = coalesce(var.dms_replication_subnet_group.name, var.name)
+ },
+ local.module_tags,
+ var.tags,
+ )
+}
+
+
+###################################################
+# Subnet Group for DocumentDB
+###################################################
+
+resource "aws_docdb_subnet_group" "this" {
+ count = var.docdb_subnet_group.enabled ? 1 : 0
+
+ name = coalesce(var.docdb_subnet_group.name, var.name)
+ description = var.docdb_subnet_group.description
+
+ subnet_ids = values(aws_subnet.this)[*].id
+
+ tags = merge(
+ {
+ "Name" = coalesce(var.docdb_subnet_group.name, var.name)
+ },
+ local.module_tags,
+ var.tags,
+ )
+}
+
+
+###################################################
+# Subnet Group for ElastiCache
+###################################################
+
+resource "aws_elasticache_subnet_group" "this" {
+ count = var.elasticache_subnet_group.enabled ? 1 : 0
+
+ name = coalesce(var.elasticache_subnet_group.name, var.name)
+ description = var.elasticache_subnet_group.description
+
+ subnet_ids = values(aws_subnet.this)[*].id
+
+ tags = merge(
+ {
+ "Name" = coalesce(var.elasticache_subnet_group.name, var.name)
+ },
+ local.module_tags,
+ var.tags,
+ )
+}
+
+
+###################################################
+# Subnet Group for MemoryDB
+###################################################
+
+resource "aws_memorydb_subnet_group" "this" {
+ count = var.memorydb_subnet_group.enabled ? 1 : 0
+
+ name = coalesce(var.memorydb_subnet_group.name, var.name)
+ description = var.memorydb_subnet_group.description
+
+ subnet_ids = values(aws_subnet.this)[*].id
+
+ tags = merge(
+ {
+ "Name" = coalesce(var.memorydb_subnet_group.name, var.name)
+ },
+ local.module_tags,
+ var.tags,
+ )
+}
+
+
+###################################################
+# Subnet Group for Neptune
+###################################################
+
+resource "aws_neptune_subnet_group" "this" {
+ count = var.neptune_subnet_group.enabled ? 1 : 0
+
+ name = coalesce(var.neptune_subnet_group.name, var.name)
+ description = var.neptune_subnet_group.description
+
+ subnet_ids = values(aws_subnet.this)[*].id
+
+ tags = merge(
+ {
+ "Name" = coalesce(var.neptune_subnet_group.name, var.name)
+ },
+ local.module_tags,
+ var.tags,
+ )
+}
+
+
+###################################################
+# Subnet Group for RDS
+###################################################
+
+resource "aws_db_subnet_group" "this" {
+ count = var.rds_subnet_group.enabled ? 1 : 0
+
+ name = coalesce(var.rds_subnet_group.name, var.name)
+ description = var.rds_subnet_group.description
+
+ subnet_ids = values(aws_subnet.this)[*].id
+
+ tags = merge(
+ {
+ "Name" = coalesce(var.rds_subnet_group.name, var.name)
+ },
+ local.module_tags,
+ var.tags,
+ )
+}
+
+
+###################################################
+# Subnet Group for Redshift
+###################################################
+
+resource "aws_redshift_subnet_group" "this" {
+ count = var.redshift_subnet_group.enabled ? 1 : 0
+
+ name = coalesce(var.redshift_subnet_group.name, var.name)
+ description = var.redshift_subnet_group.description
+
+ subnet_ids = values(aws_subnet.this)[*].id
+
+ tags = merge(
+ {
+ "Name" = coalesce(var.redshift_subnet_group.name, var.name)
+ },
+ local.module_tags,
+ var.tags,
+ )
+}
diff --git a/modules/subnet-group/main.tf b/modules/subnet-group/main.tf
index 4d51a2a..4506fce 100644
--- a/modules/subnet-group/main.tf
+++ b/modules/subnet-group/main.tf
@@ -14,6 +14,25 @@ locals {
} : {}
}
+data "aws_availability_zones" "available" {
+ state = "available"
+}
+
+locals {
+ available_availablity_zones = data.aws_availability_zones.available.names
+ available_availablity_zone_ids = data.aws_availability_zones.available.zone_ids
+
+ az = {
+ for idx, id in local.available_availablity_zone_ids :
+ id => local.available_availablity_zones[idx]
+ }
+
+ hostname_types = {
+ "RESOURCE_NAME" = "resource-name"
+ "IP_NAME" = "ip-name"
+ }
+}
+
locals {
availability_zones = distinct(
values(aws_subnet.this)[*].availability_zone
@@ -21,9 +40,6 @@ locals {
availability_zone_ids = distinct(
values(aws_subnet.this)[*].availability_zone_id
)
-}
-
-locals {
subnets = [
for subnet in aws_subnet.this : {
id = subnet.id
@@ -39,149 +55,85 @@ locals {
]
}
-resource "aws_subnet" "this" {
- for_each = var.subnets
-
- vpc_id = var.vpc_id
- availability_zone = lookup(each.value, "availability_zone", null)
- availability_zone_id = lookup(each.value, "availability_zone_id", null)
-
- cidr_block = lookup(each.value, "cidr_block", "")
- ipv6_cidr_block = lookup(each.value, "ipv6_cidr_block", null)
-
- map_public_ip_on_launch = var.map_public_ip_on_launch
- assign_ipv6_address_on_creation = var.assign_ipv6_address_on_creation
-
- outpost_arn = var.outpost_arn
- customer_owned_ipv4_pool = var.customer_owned_ipv4_pool
- map_customer_owned_ip_on_launch = var.map_customer_owned_ip_on_launch
-
- tags = merge(
- {
- "Name" = each.key
- },
- local.module_tags,
- var.tags,
- )
-}
-
###################################################
-# Subnet Groups for Managed Data Services
+# Subnets of the Subnet Group
###################################################
-resource "aws_db_subnet_group" "this" {
- count = var.db_subnet_group_enabled ? 1 : 0
-
- name = var.db_subnet_group_name
- subnet_ids = values(aws_subnet.this)[*].id
+# INFO: Not supported attributes
+# - `availability_zone_id`
+resource "aws_subnet" "this" {
+ for_each = var.subnets
- tags = merge(
- {
- "Name" = var.db_subnet_group_name
- },
- local.module_tags,
- var.tags,
+ vpc_id = var.vpc_id
+ availability_zone = (each.value.availability_zone != null
+ ? each.value.availability_zone
+ : (each.value.availability_zone_id != null
+ ? local.az[each.value.availability_zone_id]
+ : null
+ )
)
-}
-resource "aws_elasticache_subnet_group" "this" {
- count = var.cache_subnet_group_enabled ? 1 : 0
+ enable_lni_at_device_index = var.local_network_interface_device_index
- name = var.cache_subnet_group_name
- subnet_ids = values(aws_subnet.this)[*].id
- tags = merge(
- {
- "Name" = var.cache_subnet_group_name
- },
- local.module_tags,
- var.tags,
- )
-}
+ ## IP CIDR Blocks
+ ipv6_native = each.value.type == "IPV6"
-resource "aws_redshift_subnet_group" "this" {
- count = var.redshift_subnet_group_enabled ? 1 : 0
+ cidr_block = each.value.ipv4_cidr
+ ipv6_cidr_block = each.value.ipv6_cidr
- name = var.redshift_subnet_group_name
- subnet_ids = values(aws_subnet.this)[*].id
- tags = merge(
- {
- "Name" = var.redshift_subnet_group_name
- },
- local.module_tags,
- var.tags,
+ ## IP Assignments
+ map_public_ip_on_launch = (each.value.type == "IPV6"
+ ? false
+ : var.public_ipv4_address_assignment.enabled
)
-}
-
-resource "aws_neptune_subnet_group" "this" {
- count = var.neptune_subnet_group_enabled ? 1 : 0
-
- name = var.neptune_subnet_group_name
- subnet_ids = values(aws_subnet.this)[*].id
-
- tags = merge(
- {
- "Name" = var.neptune_subnet_group_name
- },
- local.module_tags,
- var.tags,
+ assign_ipv6_address_on_creation = (each.value.type == "IPV6"
+ ? true
+ : var.ipv6_address_assignment.enabled
)
-}
-
-resource "aws_docdb_subnet_group" "this" {
- count = var.docdb_subnet_group_enabled ? 1 : 0
-
- name = var.docdb_subnet_group_name
- subnet_ids = values(aws_subnet.this)[*].id
-
- tags = merge(
- {
- "Name" = var.docdb_subnet_group_name
- },
- local.module_tags,
- var.tags,
+ map_customer_owned_ip_on_launch = (each.value.type == "IPV6"
+ ? null
+ : (var.customer_owned_ipv4_address_assignment.enabled
+ ? true
+ : null
+ )
+ )
+ outpost_arn = (var.customer_owned_ipv4_address_assignment.enabled
+ ? var.customer_owned_ipv4_address_assignment.outpost
+ : null
+ )
+ customer_owned_ipv4_pool = (var.customer_owned_ipv4_address_assignment.enabled
+ ? var.customer_owned_ipv4_address_assignment.pool
+ : null
)
-}
-
-resource "aws_dax_subnet_group" "this" {
- count = var.dax_subnet_group_enabled ? 1 : 0
-
- name = var.dax_subnet_group_name
- subnet_ids = values(aws_subnet.this)[*].id
-
- # INFO: Not support resource tags
- # tags = {}
-}
-
-resource "aws_dms_replication_subnet_group" "this" {
- count = var.dms_replication_subnet_group_enabled ? 1 : 0
-
- replication_subnet_group_id = var.dms_replication_subnet_group_name
- replication_subnet_group_description = "Managed by Terraform."
- subnet_ids = values(aws_subnet.this)[*].id
- tags = merge(
- {
- "Name" = var.dms_replication_subnet_group_name
- },
- local.module_tags,
- var.tags,
+ ## DNS Configurations
+ private_dns_hostname_type_on_launch = (each.value.type == "IPV6"
+ ? "resource-name"
+ : local.hostname_types[var.dns_config.hostname_type]
)
-}
+ enable_resource_name_dns_a_record_on_launch = (each.value.type == "IPV6"
+ ? false
+ : var.dns_config.dns_resource_name_ipv4_enabled
+ )
+ enable_resource_name_dns_aaaa_record_on_launch = (each.value.type == "IPV6"
+ ? true
+ : var.dns_config.dns_resource_name_ipv6_enabled
+ )
+ enable_dns64 = var.dns_config.dns64_enabled
-resource "aws_memorydb_subnet_group" "this" {
- count = var.memorydb_subnet_group_enabled ? 1 : 0
- name = var.memorydb_subnet_group_name
- description = "Managed by Terraform."
- subnet_ids = values(aws_subnet.this)[*].id
+ timeouts {
+ create = var.timeouts.create
+ delete = var.timeouts.delete
+ }
tags = merge(
{
- "Name" = var.memorydb_subnet_group_name
+ "Name" = each.key
},
local.module_tags,
var.tags,
diff --git a/modules/subnet-group/outputs.tf b/modules/subnet-group/outputs.tf
index 381c981..a9d00d0 100644
--- a/modules/subnet-group/outputs.tf
+++ b/modules/subnet-group/outputs.tf
@@ -5,7 +5,7 @@ output "name" {
output "vpc_id" {
description = "The ID of the VPC which the subnet group belongs to."
- value = var.vpc_id
+ value = values(aws_subnet.this)[0].vpc_id
}
output "ids" {
@@ -18,12 +18,17 @@ output "arns" {
value = values(aws_subnet.this)[*].arn
}
-output "cidr_blocks" {
- description = "The CIDR blocks of the subnet group."
- value = values(aws_subnet.this)[*].cidr_block
+output "owner" {
+ description = "The ID of the AWS account that owns subnets in the subnet group."
+ value = values(aws_subnet.this)[0].owner_id
}
-output "ipv6_cidr_blocks" {
+output "ipv4_cidrs" {
+ description = "The IPv4 CIDR blocks of the subnet group."
+ value = compact(values(aws_subnet.this)[*].cidr_block)
+}
+
+output "ipv6_cidrs" {
description = "The IPv6 CIDR blocks of the subnet group."
value = compact(values(aws_subnet.this)[*].ipv6_cidr_block)
}
@@ -51,85 +56,209 @@ output "subnets_by_az" {
}
}
-output "db_subnet_group_id" {
- description = "The ID of the RDS Subnet Group."
- value = one(aws_db_subnet_group.this[*].id)
+output "local_network_interface_device_index" {
+ description = "The device position for local network interfaces in this subnet."
+ value = var.local_network_interface_device_index
}
-output "db_subnet_group_arn" {
- description = "The ARN of the RDS Subnet Group."
- value = one(aws_db_subnet_group.this[*].arn)
+output "public_ipv4_address_assignment" {
+ description = < k
+ }[values(aws_subnet.this)[0].private_dns_hostname_type_on_launch]
+ dns_resource_name_ipv4_enabled = values(aws_subnet.this)[0].enable_resource_name_dns_a_record_on_launch
+ dns_resource_name_ipv6_enabled = values(aws_subnet.this)[0].enable_resource_name_dns_aaaa_record_on_launch
+ dns64_enabled = values(aws_subnet.this)[0].enable_dns64
+ }
}
-output "neptune_subnet_group_id" {
- description = "The ID of the Neptune DB Subnet Group."
- value = one(aws_neptune_subnet_group.this[*].id)
+output "dax_subnet_group" {
+ description = < 0
+ error_message = "At least one subnet must be provided."
+ }
+ validation {
+ condition = alltrue([
+ for subnet in values(var.subnets) :
+ contains(["DUALSTACK", "IPV6"], subnet.type)
+ ])
+ error_message = "Valid values for `type` of each subnet are `DUALSTACK` and `IPV6`."
+ }
+ validation {
+ condition = alltrue([
+ for subnet in values(var.subnets) :
+ subnet.ipv4_cidr != null
+ if subnet.type == "DUALSTACK"
+ ])
+ error_message = "IPv4 CIDR block must be provided for `DUALSTACK` subnet."
+ }
+ validation {
+ condition = alltrue([
+ for subnet in values(var.subnets) :
+ subnet.ipv6_cidr != null && subnet.ipv4_cidr == null
+ if subnet.type == "IPV6"
+ ])
+ error_message = "IPv6 CIDR block must be provided for `IPV6` subnet."
+ }
}
-variable "customer_owned_ipv4_pool" {
- description = "The customer owned IPv4 address pool. `outpost_arn` argument must be specified when configured."
- type = string
- default = ""
+variable "local_network_interface_device_index" {
+ description = <