4

Terraform cidrsubnets gives me the following subnets which is what I want.

Terraform Version I am using: Terraform v0.14.9

> cidrsubnets("172.16.0.0/18", 6, 6, 6, 6)
tolist([
  "172.16.0.0/24",
  "172.16.1.0/24",
  "172.16.2.0/24",
  "172.16.3.0/24",
])
Requirement
==========
Main CIDR range = 172.16.0.0/18
Public Subnets = [172.16.0.0/24, 172.16.1.0/24]
Private Subents = [172.16.2.0/24, 172.16.3.0/24]

How can I pass the above CIDR ranges for public and private subnets using Terraform cidrsubnets function to the below VPC module.

variable "vpc_cidr" {
  default = "172.16.0.0/18"
}

data "aws_availability_zones" "azs" {
  state = "available"
}

module "vpc" {
  
  source  = "terraform-aws-modules/vpc/aws"
  version = "2.77.0"

  name                 = "my-vpc"
  cidr                 = var.vpc_cidr
  azs                  = data.aws_availability_zones.azs.names
  private_subnets      = ["172.16.1.0/24", "172.16.2.0/24"] <= I want to pass these subnets from cidrsubnets function
  public_subnets       = ["172.16.3.0/24", "172.16.4.0/24"] <= I want to pass these subnets from cidrsubnets function
  enable_nat_gateway   = true
  single_nat_gateway   = true
  enable_dns_hostnames = true

}


Can someone help me with this, please?

Jwary
  • 137
  • 2
  • 16

3 Answers3

2

You could use slice function on top of the cidrsubnets one. Since cidrsubnets will return a list, slice it up according to the index and you'll have 2 lists with public and private IPs as requested:

module "vpc" {
  ...
  private_subnets      = slice(cidrsubnets(var.vpc_cidr, 6, 6, 6, 6),0,2)
  public_subnets       = slice(cidrsubnets(var.vpc_cidr, 6, 6, 6, 6),2,4)
  ...
}

Styszma
  • 447
  • 3
  • 13
0

slice(cidrsubnets(var.vpc_cidr, 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4),0,16) - This will give 16 /26 on a /22:

    slice(cidrsubnets(var.vpc_cidr, 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4),0,2)
    slice(cidrsubnets(var.vpc_cidr, 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4),2,4)
    slice(cidrsubnets(var.vpc_cidr, 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4),4,6)
    slice(cidrsubnets(var.vpc_cidr, 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4),6,8)
    slice(cidrsubnets(var.vpc_cidr, 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4),8,10)
    slice(cidrsubnets(var.vpc_cidr, 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4),10,12)
    slice(cidrsubnets(var.vpc_cidr, 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4),12,14)
    slice(cidrsubnets(var.vpc_cidr, 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4),14,16)        

slice(cidrsubnets(var.vpc_cidr, 3,3,3,3,3,3,3,3),0,8) - This will give 8 /25 on a /22

    slice(cidrsubnets(var.vpc_cidr, 3,3,3,3,3,3,3,3),0,2)
    slice(cidrsubnets(var.vpc_cidr, 3,3,3,3,3,3,3,3),2,4)
    slice(cidrsubnets(var.vpc_cidr, 3,3,3,3,3,3,3,3),4,6)
    slice(cidrsubnets(var.vpc_cidr, 3,3,3,3,3,3,3,3),6,8)

slice(cidrsubnets(var.vpc_cidr, 2,2,2,2),0,4) - This will give 4 /24 on a /22

    slice(cidrsubnets(var.vpc_cidr, 2,2,2,2),0,2)
    slice(cidrsubnets(var.vpc_cidr, 2,2,2,2),2,4)
Eyck
  • 1
  • 1
0

I had exactly the same requirement and found an elegant way with :

locals {
  azs = slice(data.aws_availability_zones.available.names, 0, 2)
}

public_subnets = [for k, v in local.azs : cidrsubnet(var.vpc_cidr, 6, k)]
private_subnets  = [for k, v in local.azs : cidrsubnet(var.vpc_cidr, 6, k + 2)]

The outputs of the above code will be :

  public_subnets      = ["172.16.0.0/24", "172.16.1.0/24"] 
  private_subnets       = ["172.16.2.0/24", "172.16.3.0/24"]
Wael Gabsi
  • 148
  • 10