does anyone dynamically make subnets from a cidr u...
# golang
s
does anyone dynamically make subnets from a cidr using the number of available availability zones?
b
I kind of do this, though not exactly.
s
how are you doing it?
b
Copy code
state := "available"
	availableAZ, err := aws.GetAvailabilityZones(ctx, &aws.GetAvailabilityZonesArgs{
		State: &state,
	}, pulumi.Provider(awsProvider))
	if err != nil {
		return nil, err
	}

	subnets := make([]*ec2.Subnet, 0, 8)
	privateCidrs := make([]string, 0, 8)
	publicCidrs := make([]string, 0, 8)
	privateSubnetIDs := make([]pulumi.StringOutput, 0, 8)
	publicSubnetIDs := make([]pulumi.StringOutput, 0, 8)
	privateSubnetNames := make([]string, 0, 8)
	publicSubnetNames := make([]string, 0, 8)
	privateSubnetRouteTables := make([]*ec2.RouteTable, 0, 8)
	publicSubnetRouteTables := make([]*ec2.RouteTable, 0, 8)
	vpcCidrAssociations := make([]pulumi.Resource, 0, 8)
	natGateways := make([]*ec2.NatGateway, 0, 8)
	azNames := availableAZ.Names
	sort.Strings(azNames)
	for idx, az := range azNames {
		// Ignore it if we have more than 4 AZs
		if idx > 3 {
			continue
		}

		publicCidr := cidrs.Public[idx]
		privateCidr := cidrs.Private[idx]

		publicCidrs = append(publicCidrs, publicCidr)
		privateCidrs = append(privateCidrs, privateCidr)

		publicAssoc, err := ec2.NewVpcIpv4CidrBlockAssociation(ctx, fmt.Sprintf("okera-ssa-vpc-cidr-public-%s", az), &ec2.VpcIpv4CidrBlockAssociationArgs{
			VpcId:     vpc.ID(),
			CidrBlock: pulumi.String(publicCidr),
		}, pulumi.Provider(awsProvider))
		if err != nil {
			return nil, err
		}
		privateAssoc, err := ec2.NewVpcIpv4CidrBlockAssociation(ctx, fmt.Sprintf("okera-ssa-vpc-cidr-private-%s", az), &ec2.VpcIpv4CidrBlockAssociationArgs{
			VpcId:     vpc.ID(),
			CidrBlock: pulumi.String(privateCidr),
		}, pulumi.Provider(awsProvider))
		if err != nil {
			return nil, err
		}

		publicSubnetName := fmt.Sprintf("subnet-ssa-public-%s", az)
		publicSubnet, err := ec2.NewSubnet(ctx, publicSubnetName, &ec2.SubnetArgs{
			VpcId:               vpc.ID(),
			CidrBlock:           publicAssoc.CidrBlock,
			AvailabilityZone:    pulumi.String(az),
			MapPublicIpOnLaunch: pulumi.Bool(true),
			Tags: pulumi.StringMap{
				"Name": pulumi.String(fmt.Sprintf("%s-%s-%s", ctx.Stack(), "public", az)),
			},
		}, pulumi.Provider(awsProvider))
		if err != nil {
I’m eliding some things here, but to give you a sense
The CIDRs are pre-defined in the Pulumi config file, but in a prior version of the code it dynamically computed them
Based on a starting IP
s
yeah we are doing something like this
Copy code
config:
  network:createVPCs: true
  network:data:
    regions:
      - us-east-1:
          vpcs:
            - my-vpc-us-east-1:
                vpc-cidr: 10.20.0.0/16
                availability-zones: 
                - us-east-1c
                - us-east-1d
                - us-east-1e
                data-cidrs:
                - 10.20.100.0/24
                - 10.20.101.0/24
                - 10.20.102.0/24
                app-cidrs:
                - 10.20.200.0/24
                - 10.20.201.0/24
                - 10.20.202.0/24
                pub-cidrs:
                - 10.20.180.0/24
                - 10.20.181.0/24
                - 10.20.182.0/24
I would like do away with the az's and pub/app/data-cidrs and just replace it with a subnet size and auto break it up based off the number of az's
b
Yeah, it’s definitely possible
You can see from the code snippet I posted that the AZs are fetched dynamically, and auto-calculating the CIDR (+ a size and starting IP) from that is relatively simple
In the end though, I had decided that I wanted more control over the CIDRs since it falls under overall network management, and didn’t want it going out of control (or a simple arithmetic change meaning I would need to destroy my subnets and everything attached to them.
s
ahh makes sense