Search code examples
amazon-web-servicesnetwork-programmingterraformsubnet

Split Top Level CIDR to to netmask length (to be used by nested object) - Terraform


A netmask length is a number requested and provisioned into pool based off the top cidr range

Assuming I have a top_cidr = ["10.0.0.0/8"]

How do you split the cidrs to netmask_length and pass the values dynamically to other sub netmask_length based off the top_cidr

I need to make the netmask_length

module "basic" {
  source  = "aws-ia/ipam/aws"

  top_cidr = ["10.0.0.0/8"]
  top_name = "basic ipam"

  pool_configurations = {
    corporate-us-west-2 = {
      description = "2nd level, locale us-west-2 pool"
    #   cidr        = ["10.0.0.0/16", "10.1.0.0/16"]
    netmask_length = ?

      sub_pools = {

        sandbox = {
          name                 = "mysandbox"
        #   cidr                 = ["10.0.0.0/20"]
        netmask_length = ?
          ram_share_principals = var.sandbox_ou_arn
          allocation_resource_tags = {
            env = "sandbox"
          }
        }
        dev = {
          netmask_length = 20

          sub_pools = {
            team_a = {
              netmask_length       = 24
              locale               = "us-west-2"
            }

            team_b = {
              netmask_length       = 26
            }
          }
        }
        prod = {
        #   cidr   = ["10.1.16.0/20"]
        netmask_length = ?
          locale = "us-west-2"

          sub_pools = {
            team_a = {
            #   cidr                 = ["10.1.16.0/24"]
            netmask_length = ?
              ram_share_principals = var.prod_account # prod account
            }

            team_b = {
            #   cidr                 = ["10.1.17.0/24"]
            netmask_length = ?
              ram_share_principals = var.prod_account # prod account
            }
          }
        }
      }
    }
    us-east-1 = {
    #   cidr   = ["10.2.0.0/16"]
    netmask_length = ?
      locale = "us-east-1"

      sub_pools = {

        team_a = {
        #   cidr                 = ["10.2.0.0/20"]
        netmask_length = ?
        }

        team_b = {
        #   cidr                 = ["10.2.16.0/20"]
        netmask_length = ?
        }
      }
    }
  }
}

Any help on this will be greatly appreciated

Thanks


Solution

  • I suggest using the Terraform cidrsubnet function to calculate the subnet addresses. For example:

    locals {
      top_cidr = "10.0.0.0/8"
    }
    
    module "basic" {
      source  = "aws-ia/ipam/aws"
    
      top_cidr = [local.top_cidr]
      top_name = "basic ipam"
    
      pool_configurations = {
        corporate-us-west-2 = {
          description = "2nd level, locale us-west-2 pool"
          cidr        = [cidrsubnet(local.top_cidr, 8, 0), cidrsubnet(local.top_cidr, 8, 1)]
        
    
          # The rest of your code
      }
    }
    

    I suggest opening the terraform console to play around with the cidrsubnet function to find the correct parameters you need to pass it to get the resulting CIDR blocks that you want to generate.


    Alternatively if you want to pass the netmask_length parameters instead, which conflict with the cidr parameters, you could use a CIDR Netmask calculator to figure out the values you need.

    Terraform has one of those built-in as well, but it seems like your goal is to calculate the subnets dynamically instead of having them hard-coded in your Terraform template, and you would still have to hard-code them as arguments for the cidrnetmask function, so at that point it would be cleaner to just hard-code them directly as cidr parameters.