aws-ia / terraform-aws-vpc

AWS VPC Module
https://registry.terraform.io/modules/aws-ia/vpc/aws/latest
Apache License 2.0
92 stars 98 forks source link

Output list of subnets, IDs and CIDRs #137

Closed vstthomas closed 5 months ago

vstthomas commented 10 months ago

The first thing some of us would want to do is map the subnets over to an EKS solution. Here's a quick example

module "eks" {
  source  = "terraform-aws-modules/eks/aws"
  version = "~> 19.0"

  cluster_name    = "my-cluster"
...
  vpc_id                   = "vpc-1234556abcdef"
  subnet_ids               = ["subnet-abcde012", "subnet-bcde012a", "subnet-fghi345a"]
  control_plane_subnet_ids = ["subnet-xyzde987", "subnet-slkjf456", "subnet-qeiru789"]

Given the above EKS requirements, what's the best way to extract availability_zone, availability_zone_id, (subnet) cidr_block and (subnet) ID?

This VPC module makes that fairly difficult. We have to really go digging for attributes; example:

vpc_details {
  "public_subnet_attributes_by_az" = {
    "us-gov-east-1a" = {
...
      "availability_zone" = "us-gov-east-1a"
      "availability_zone_id" = "usge1-az1"
      "cidr_block" = "10.0.0.0/18"
...
      "id" = "subnet-0d2dc9c4e190e15ae"
}

Please output these elements specifically:

it's worth noting that the output for "core_network_subnet_attributes_by_az" = {} <- is empty.

something like this in the EKS config would be ideal

  vpc_config {
...
    security_group_ids = [aws_security_group.apps_cluster.id]
    subnet_ids         = aws_subnet.vpc_network[*].id
  }

Or, perhaps work with the EKS module folks and output something like:

output "eks_outputs" {
  value = module.vpc....
}

So we can get outputs specifically for EKS with the rest.

drewmullen commented 10 months ago

Hello, thanks for opening this issue! We have a slightly different take on module outputs which we detailed here: https://github.com/aws-ia/terraform-aws-vpc#output-usage-examples

The concepts above you mentioned can all be achieved with the current module outputs. Here are some examples how you can munge the data

Given hcl example:

module "vpc" {
  source  = "aws-ia/vpc/aws"
  version = ">= 4.2.0"

  name       = "multi-az-vpc"
  cidr_block = "10.0.0.0/20"
  az_count   = 3

  subnets = {
    private = { netmask = 24 }
    eks = { netmask = 24 }
  }
}

In this module you can make n number of private subnet groups. Everything is considered a private subnet unless it is a reserved keyword (public, core_network, etc - see docs for full examples). In the above HCL i only have 2 private subnet groups (6 subnets total), you can see how the name labels are organized in the tf console:

$ tf console
> [ for subnet_name, value in module.vpc.private_subnet_attributes_by_az: subnet_name ]
[
  "eks/us-east-1a",
  "eks/us-east-1b",
  "eks/us-east-1c",
  "private/us-east-1a",
  "private/us-east-1b",
  "private/us-east-1c",
]

That means if you wanted the eks subnets to be the control plane and the private subnets to be subnet_ids you can do this:

module "eks" {
  source  = "terraform-aws-modules/eks/aws"
  version = "~> 19.0"

  cluster_name    = "my-cluster"
...
  vpc_id                   = module.vpc.vpc_attributes.id
  subnet_ids               = [ for subnet_name, subnet_attributes in module.vpc.private_subnet_attributes_by_az: subnet_attributes.id if startswith(subnet_name, "private") ]
  control_plane_subnet_ids = [ for subnet_name, subnet_attributes in module.vpc.private_subnet_attributes_by_az: subnet_attributes.id if startswith(subnet_name, "eks") ]

The reason core_network_subnet_attributes_by_az is empty is because core_network is a reserved subnet name referring to a AWS NetworkManager CoreNetwork which is admittedly a confusing name in this context. However, thats the service name :/

I hope this helps! I understand the output concepts are not quite as straight forward as other modules but we believe its easier to maintain and provides the maximum amount of outputs with the lowest amount of code

pablo19sc commented 5 months ago

Hello! Closing this Issue - as Drew provided an answer on how to obtain the outputs :)