Using the Terraform Map Function

How many times have you had something you’re building in Terraform where you use dynamic counting or things that need you to map one value to another?

One clear example I had very recently for my fully automated EKS lab using Terraform for AWS was the need to distribute my nodes across availability zones. How can I easily have each node be assigned to a specific AZ without doing a bunch of crazy code inside Terraform?

Terraform makes this easy with two simple features which are count parameter and map function. Let’s dig in to see how these work together!

Map All the Things!

Well, how about we start with mapping 3 things. I have a simple situation that we are going to use which is to map 3 integers to 3 text strings. We call this our az_map because it will become an Availability Zone map within an AWS Region.

Each integer for 0, 1, and 2, are mapped to default values which are a, b, and c, respectively. Simple enough with this code:

variable "az_map" {
	type = map

	default = {
		0 = "a"
		1 = "b"
		2 = "c"
	}
}

Now the fun is where we make this value mapping work in our Terraform code. The above can go anywhere but I like to keep in it a vars.tf file just so I know where all my variables are.

Let me COUNT the Ways

Our use-case is that we want 3 nodes for a cluster (EKS nodes in this case) and we want them to the distributed for resiliency across 3 availability zones.

We could statically assign the AZ list…but that’s no fun (and not good practice). We know that each AWS Region has at least 3 AZs. The 3-node deployment only needs a simple mapping of a counter to the A/B/C Availability Zone lists for our subnets and then our node deployment.

e.g. US-east-2 is our Region and contains US-east-2a, US-east-2b, and US-east-2c (and more)

You should use variables wherever possible, and our Region is defined by var.aws_region which will be US-east-2 using our example.

Just create your AZ configuration to pull in the variable and

availability_zone = "${var.aws_region}${var.az_map[count.index]}"

Next we wrap this all inside a count parameter of 3 so that the code block is iterated over 3 times.

The full code of this code block is here (and also on Github):

resource "aws_subnet" "eks-lab-pub" {
    count = 3
    vpc_id = aws_vpc.eks-lab-vpc.id
    cidr_block = "10.0.${count.index}.0/24"
    map_public_ip_on_launch = "true"
    availability_zone = "${var.aws_region}${var.az_map[count.index]}"

    tags = {
    	Name = "eks-lab"
    	Terraform = "true"
    	Turbonomic = "true"
    	"kubernetes.io/cluster/eks-lab" = "shared"
    	"kubernetes.io/role/elb" = "1"
        net = "public"
  	}
}

The result will be AZs defined for 0,1,2 as a,b,c, which creates US-east-2a, US-east-2B, and US-east-2C. We even assign the networks using the ${count.index} to define the third octet of the IPv4 range. How cool is that?!

Now you can iterate over those same 3 subnets for your nodes, security groups, or anything that required the mapping across Availability Zones.

Hopefully you find this example helpful. Try out a few different methods as needed and you will be able to put map as a staple for your Terraform configurations in a variety of use-cases.




Podcast Episode 111 – How Building Self-Learning Became a Goal and a Career with Larry Smith Jr

Larry Smith Jr is both an incredible technologist and a superb human being.  Larry shares his thoughts and lessons on how he has turned his own journey towards self-learning into both a way to give yourself goals and it has become a career creator for him as a result.  There are a lot of profound lessons that will come from this for anyone who’s in technology on either a development or the ops side of the world because it is both informative and fun!

Listen to the episode here: https://discopossepodcast.com/episode-111-how-building-self-learning-became-a-goal-and-a-career-with-larry-smith-jr/

Listen and Subscribe on iTunes here:

Podcast Episode 111 – How Building Self-Learning Became a Goal and a Career with Larry Smith Jr

PODCAST LINK: https://discopossepodcast.com/episode-111-how-building-self-learning-became-a-goal-and-a-career-with-larry-smith-jr/




AWS Summit Toronto Presentation: Open-source Infrastructure-as-Code with Terraform and AWS

This is the summary post which will cover my Open-source Infrastructure-as-Code with Terraform and AWS presentation that I gave at the AWS Summit in Toronto.  The landing link from my presentation may have brought you here and this post has all the links to the Github repositories, the PDF of the presentation, and also the video of the entire presentation.

Make sure to drop in a comment if you have any questions and want to get connected.  You can set yourself up for Terraform Cloud at app.terraform.io 

Video Replay

Here is the video of my session that I recorded based on the presentation at the AWS Summit in Toronto

Presentation File

Here is the presentation which the team at AWS has confirmed can be shared.  Big thanks go to @RossBarich for allowing me to present at the event and to @mistwire for getting me connected with Ross.

Click here to view the PDF file: https://discoposse.com/aws-summit-toronto-2019-ericwright-pdf/

Code Links

These are the links to my Github repos used in the presentation examples.  Note that some code is currently static references to some resources which will be made into completely variable-driven resources shortly:

Simple EC2 image using Terraform Cloud: https://github.com/discoposse/terraform-cloud-aws-summit-toronto

Classroom example using EC2 from AMI with ALB and TLS: https://github.com/discoposse/terraform-cloud-aws-toronto-classroom-example