Skip to content

Commit

Permalink
add subnet_tags
Browse files Browse the repository at this point in the history
  • Loading branch information
badra001 committed Apr 7, 2023
1 parent d20e84b commit 75376b5
Show file tree
Hide file tree
Showing 15 changed files with 287 additions and 1 deletion.
3 changes: 2 additions & 1 deletion common/version.tf
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
locals {
_module_version = "2.8.0"
_module_version = "2.8.1"
_module_names = {
"_main_" = "aws-vpc-setup"

Expand All @@ -17,6 +17,7 @@ locals {
"security-groups" = "aws-vpc-setup/security-groups"
"share-resources" = "aws-vpc-setup/share-resources"
"subnets" = "aws-vpc-setup/subnets"
"subnet_tags" = "aws-vpc-setup/subnet_tags"
"tag-shared-vpc-resources" = "aws-vpc-setup/tag-shared-vpc-resources"
"vpc" = "aws-vpc-setup/vpc"
"vpc-interface-endpoint" = "aws-vpc-setup/vpc-interface-endpoint"
Expand Down
124 changes: 124 additions & 0 deletions subnet_tags/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
# About aws-vpc-setup :: subnet\_tags

This submodule tags public and private subnets, using the same structure as for aws-vpc-setup//subnets. It is used
where a VPC is shared into an account. It will only add tags for subnets listed as _enabled_ in the structure, and only
add the specific _tags_ identified in that structure. All of the tags are initially set from the resources
in the shared account, in the `vpc/REGION/shared-setup` directory.

The only identified use case so far is for tagging for EKS clusters. It is also acceptable to simply list the
subnet object which need tags, to avoid looking for a subnet which may not be shared to this VPC.

# Usage

```hcl
# variables.subnets.auto.tfvars
public_subnets = []
private_subnets = [
{ base_cidr = "10.192.0.0/23", label = "endpoints", bits = 2, private = true, enabled = true, tags = {} },
{ base_cidr = "10.192.1.128/26", label = "attachment", bits = 2, private = true, enabled = true, tags = { "boc:vpc:route-table" = "attachment" } },
{ base_cidr = "10.192.2.0/23", label = "private-lb", bits = 2, private = true, enabled = true,
tags = {
"kubernetes.io/role/internal-elb" = 1
}
},
{ base_cidr = "10.192.4.0/22", label = "db", bits = 2, private = true, enabled = true, tags = {} },
{ base_cidr = "10.192.0.0/19", label = "apps", bits = 2, offset = 1, private = true, enabled = true, tags = {} },
]
module "subnets" {
source = "git@github.e.it.census.gov:terraform-modules/aws-vpc-setup.git//subnet_tags?ref=tf-upgrade"
vpc_id = var.vpc_id
availability_zones = var.availability_zones
public_subnets = var.public_subnets
private_subnets = var.private_subnets
vpc_name = var.vpc_name
vpc_short_name = var.vpc_short_name
vpc_full_name = var.vpc_full_name
tags = {}
}
# Subnet structure
Both `private_subnets` and `public_subnets` have the same structure. They are a list of subnet
information _objects_:
```hcl
type = list(object({
base\_cidr = string
label = string
bits = number
offset = optional(number, 0)
private = bool
tags = map(string)
enabled = optional(bool, true)
availability\_zone = optional(string)
}))
default = []
}
```

This file should be copied from the shared VPC. The only fields used from this structure are: label, private, enabled, and tags.
It will find the subnets with the specific VPC id and label component (`*-{label}-{az}`) and add the tags as lited.
Refer to the [docs](../subnets) for full details on the subnet definition.
```
## Requirements
| Name | Version |
|------|---------|
| <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) | >= 0.13 |
| <a name="requirement_aws"></a> [aws](#requirement\_aws) | >= 3.66.0 |
| <a name="requirement_ldap"></a> [ldap](#requirement\_ldap) | >= 0.5.4 |
| <a name="requirement_local"></a> [local](#requirement\_local) | >= 1.0.0 |
| <a name="requirement_null"></a> [null](#requirement\_null) | >= 3.0 |
| <a name="requirement_random"></a> [random](#requirement\_random) | >= 3.0 |
| <a name="requirement_template"></a> [template](#requirement\_template) | >= 2.0 |
## Providers
| Name | Version |
|------|---------|
| <a name="provider_aws"></a> [aws](#provider\_aws) | >= 3.66.0 |
## Modules
No modules.
## Resources
| Name | Type |
|------|------|
| [aws_arn.current](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/arn) | data source |
| [aws_availability_zone.zone](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/availability_zone) | data source |
| [aws_availability_zones.zones](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/availability_zones) | data source |
| [aws_caller_identity.current](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/caller_identity) | data source |
| [aws_iam_account_alias.current](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_account_alias) | data source |
| [aws_region.current](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/region) | data source |
| [aws_subnets.private](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/subnets) | data source |
| [aws_subnets.public](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/subnets) | data source |
## Inputs
| Name | Description | Type | Default | Required |
|------|-------------|------|---------|:--------:|
| <a name="input_account_alias"></a> [account\_alias](#input\_account\_alias) | AWS Account Alias (default: will pull from current account\_alias) | `string` | `""` | no |
| <a name="input_account_id"></a> [account\_id](#input\_account\_id) | AWS Account ID (default: will pull from current user) | `string` | `""` | no |
| <a name="input_availability_zones"></a> [availability\_zones](#input\_availability\_zones) | AWS Availability Zones to use (by default will use all available) | `list(string)` | `[]` | no |
| <a name="input_override_prefixes"></a> [override\_prefixes](#input\_override\_prefixes) | Override built-in prefixes by component. This should be used primarily for common infrastructure things | `map(string)` | `{}` | no |
| <a name="input_private_subnets"></a> [private\_subnets](#input\_private\_subnets) | List of objects with private subnet information to be created | <pre>list(object({<br> base_cidr = string<br> label = string<br> bits = number<br> offset = optional(number, 0)<br> private = bool<br> tags = map(string)<br> enabled = optional(bool, true)<br> availability_zone = optional(string)<br> # subnets = list(string)<br> # labels = list(string)<br> # availability_zones = list(string)<br> }))</pre> | `[]` | no |
| <a name="input_public_subnets"></a> [public\_subnets](#input\_public\_subnets) | List of objects with public subnet information to be created | <pre>list(object({<br> base_cidr = string<br> label = string<br> bits = number<br> offset = optional(number, 0)<br> private = bool<br> tags = map(string)<br> enabled = optional(bool, true)<br> availability_zone = optional(string)<br> # subnets = list(string)<br> # labels = list(string)<br> # availability_zones = list(string)<br> }))</pre> | `[]` | no |
| <a name="input_tags"></a> [tags](#input\_tags) | AWS Tags to apply to appropriate resources (S3, KMS). Do not include safeguard tags here, use the data\_safeguard field for such things. | `map(string)` | `{}` | no |
| <a name="input_vpc_environment"></a> [vpc\_environment](#input\_vpc\_environment) | VPC environment purpose (infrastructure, common, shared, dev, stage, ite, prod) | `string` | `null` | no |
| <a name="input_vpc_full_name"></a> [vpc\_full\_name](#input\_vpc\_full\_name) | VPC full name component (vpc{index}-{vpc\_name}) | `string` | `null` | no |
| <a name="input_vpc_id"></a> [vpc\_id](#input\_vpc\_id) | VPC ID | `string` | n/a | yes |
| <a name="input_vpc_index"></a> [vpc\_index](#input\_vpc\_index) | VPC index number (integer starting at 1) | `number` | `null` | no |
| <a name="input_vpc_name"></a> [vpc\_name](#input\_vpc\_name) | VPC name component used through the VPC descrbing its purpose (ex: dice-dev) | `string` | `null` | no |
| <a name="input_vpc_short_name"></a> [vpc\_short\_name](#input\_vpc\_short\_name) | VPC short name component (vpc{index}) | `string` | `null` | no |
## Outputs
| Name | Description |
|------|-------------|
| <a name="output_availability_zone_ids"></a> [availability\_zone\_ids](#output\_availability\_zone\_ids) | VPC Availability zone id list (3) |
| <a name="output_availability_zone_names"></a> [availability\_zone\_names](#output\_availability\_zone\_names) | VPC Availability zone name list (3) |
| <a name="output_availability_zone_suffixes"></a> [availability\_zone\_suffixes](#output\_availability\_zone\_suffixes) | VPC Availability zone suffix list (3) |
1 change: 1 addition & 0 deletions subnet_tags/availabilty_zones.tf
1 change: 1 addition & 0 deletions subnet_tags/data.tf
1 change: 1 addition & 0 deletions subnet_tags/defaults.tf
147 changes: 147 additions & 0 deletions subnet_tags/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
/*
* # About aws-vpc-setup :: subnet_tags
*
* This submodule tags public and private subnets, using the same structure as for aws-vpc-setup//subnets. It is used
* where a VPC is shared into an account. It will only add tags for subnets listed as _enabled_ in the structure, and only
* add the specific _tags_ identified in that structure. All of the tags are initially set from the resources
* in the shared account, in the `vpc/REGION/shared-setup` directory.
*
* The only identified use case so far is for tagging for EKS clusters. It is also acceptable to simply list the
* subnet object which need tags, to avoid looking for a subnet which may not be shared to this VPC.
*
* # Usage
*
* ```hcl
* # variables.subnets.auto.tfvars
* public_subnets = []
* private_subnets = [
* { base_cidr = "10.192.0.0/23", label = "endpoints", bits = 2, private = true, enabled = true, tags = {} },
* { base_cidr = "10.192.1.128/26", label = "attachment", bits = 2, private = true, enabled = true, tags = { "boc:vpc:route-table" = "attachment" } },
* { base_cidr = "10.192.2.0/23", label = "private-lb", bits = 2, private = true, enabled = true,
* tags = {
* "kubernetes.io/role/internal-elb" = 1
* }
* },
* { base_cidr = "10.192.4.0/22", label = "db", bits = 2, private = true, enabled = true, tags = {} },
* { base_cidr = "10.192.0.0/19", label = "apps", bits = 2, offset = 1, private = true, enabled = true, tags = {} },
* ]
*
* module "subnets" {
* source = "git@github.e.it.census.gov:terraform-modules/aws-vpc-setup.git//subnet_tags?ref=tf-upgrade"
* vpc_id = var.vpc_id
* availability_zones = var.availability_zones
* public_subnets = var.public_subnets
* private_subnets = var.private_subnets
* vpc_name = var.vpc_name
* vpc_short_name = var.vpc_short_name
* vpc_full_name = var.vpc_full_name
*
* tags = {}
* }
*
* # Subnet structure
* Both `private_subnets` and `public_subnets` have the same structure. They are a list of subnet
* information _objects_:
*
* ```hcl
* type = list(object({
* base_cidr = string
* label = string
* bits = number
* offset = optional(number, 0)
* private = bool
* tags = map(string)
* enabled = optional(bool, true)
* availability_zone = optional(string)
* }))
* default = []
* }
* ```
*
* This file should be copied from the shared VPC. The only fields used from this structure are: label, private, enabled, and tags.
* It will find the subnets with the specific VPC id and label component (`*-{label}-{az}`) and add the tags as lited.
* Refer to the [docs](../subnets) for full details on the subnet definition.
*/

locals {
account_id = var.account_id != "" ? var.account_id : data.aws_caller_identity.current.account_id
account_environment = data.aws_arn.current.partition == "aws-us-gov" ? "gov" : "ew"

base_tags = {
"boc:tf_module_version" = local._module_version
"boc:tf_module_name" = lookup(local._module_names, local._module_name, local._module_names["_main_"])
"boc:created_by" = "terraform"
}

availability_zones = length(var.availability_zones) != 0 ? var.availability_zones : data.aws_availability_zones.zones.names
az_count = length(local.availability_zones)
az_count_list = range(local.az_count)
az_list = toset(local.availability_zones)
empty = toset([])
}

#---
# public subnets
#---
locals {
public_subnets = { for v in var.public_subnets : v.label =>
{
base_cidr = v.base_cidr
label = v.label
bits = v.bits
private = v.private
subnets = [for i in local.az_count_list : cidrsubnet(v.base_cidr, v.bits, v.offset + i)]
labels = [for az in local.availability_zones : format("%v-%v", v.label, az)]
availability_zones = local.availability_zones
tags = lookup(v, "tags", {})
} if v.enabled
}
public_map = flatten([for k, v in local.public_subnets :
[for i in local.az_count_list : merge(tomap({ "subnet" = v.subnets[i], "label" = v.labels[i], "availability_zone" = v.availability_zones[i] }), { "tags" = v.tags })]])
}


data "aws_subnets" "public" {
for_each = { for subnet in local.public_map : subnet.label => subnet }
filter {
name = "vpc-id"
values = [var.vpc_id]
}
filter {
name = "tag:Name"
values = [format("*-%v-*", each.key)]
}
}

#---
# private subnets
#---
locals {
private_subnets = { for v in var.private_subnets : v.label =>
{
base_cidr = v.base_cidr
label = v.label
bits = v.bits
private = v.private
subnets = [for i in local.az_count_list : cidrsubnet(v.base_cidr, v.bits, v.offset + i)]
labels = [for az in local.availability_zones : format("%v-%v", v.label, az)]
availability_zones = local.availability_zones
tags = lookup(v, "tags", {})
} if v.enabled
}
private_map = flatten([for k, v in local.private_subnets :
[for i in local.az_count_list : merge(tomap({ "subnet" = v.subnets[i], "label" = v.labels[i], "availability_zone" = v.availability_zones[i] }), { "tags" = v.tags })]])
}

# ignore attachment, as it is not shared
data "aws_subnets" "private" {
for_each = { for subnet in local.private_map : subnet.label => subnet if subnet.label != "attachment" }
filter {
name = "vpc-id"
values = [var.vpc_id]
}
filter {
name = "tag:Name"
values = [format("*-%v-*", each.key)]
}
}
3 changes: 3 additions & 0 deletions subnet_tags/module_name.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
locals {
_module_name = "subnet_tags"
}
1 change: 1 addition & 0 deletions subnet_tags/prefixes.tf
1 change: 1 addition & 0 deletions subnet_tags/variables.common.availability_zones.tf
1 change: 1 addition & 0 deletions subnet_tags/variables.common.subnets.tf
1 change: 1 addition & 0 deletions subnet_tags/variables.common.tf
1 change: 1 addition & 0 deletions subnet_tags/variables.common.vpc.tf
1 change: 1 addition & 0 deletions subnet_tags/variables.common.vpc_id.tf
1 change: 1 addition & 0 deletions subnet_tags/version.tf
1 change: 1 addition & 0 deletions subnet_tags/versions.tf

0 comments on commit 75376b5

Please sign in to comment.