Skip to main content

Lookup Function and Variable Types

Updated Jan 24, 2021 ·

Overview

In this lab, we'll do the following:

  • Deploy a VPC and an EC2 instance
  • Look into "lookup" functions
  • Understand different type of variables

This is a fairly simple lab and is an iteration of the first few labs, but here we'll checkout how to use the lookup function and see what sort of variables can we define in the vars.tf file.

Pre-requisites

  • Setup Keys and Permissions
  • Setup your Local Environment and Install Extensions
  • Configure the Credentials File
  • Install Terraform

Core Config files

Initially create the core configuration files which we will populate in the succeeding steps.

touch main.tf
$ touch provider.tf
$ touch vars.tf
$ touch terraform.tfvars

Create the Provider file

provider.tf
terraform {
required_version = ">= 0.12"

required_providers {
aws = {
source = "hashicorp/aws"
version = ">= 4.16.0"
}
}
}

provider "aws" {
region = var.aws_region
shared_credentials_files = var.my_credentials
profile = var.my_profile
}

Create the Main file

We can see that the main.tf file is populated with a lot of variables which we'll declare in the variables files. One important thing to notice here is the use of lookup function.

The ami field is basically looking through the values inside the map-type ami_ids and using os_type as a filter. If the os_type is given a "Windows" value, it will then check the ami_ids map and see use the AMI ID that is assocciated with a "windows" key.

main.tf
### main.tf
#--------------------------------------------------------

resource "aws_vpc" "lab09-vpc" {
cidr_block = var.cidr_block
}

resource "aws_subnet" "lab09-subnet" {
vpc_id = aws_vpc.lab09-vpc.id
cidr_block = var.subnet
availability_zone = var.availability_zone
tags = {
Name = "${var.servername}subnet"
}
}

resource "aws_instance" "server" {
ami = lookup(var.ami_ids, var.os_type, null)
instance_type = var.instance_size
monitoring = var.ec2_monitoring
vpc_security_group_ids = [aws_vpc.lab09-vpc.default_security_group_id]
subnet_id = aws_subnet.lab09-subnet.id
root_block_device {
delete_on_termination = var.disk.delete_on_termination
encrypted = var.disk.encrypted
volume_size = var.disk.volume_size
volume_type = var.disk.volume_type
}
tags = {
Name = var.servername
}
}

Create the variable files

Here we can see that the vars.tf file declares alot of variables. The first three is what we'll use to connect from our local machine to our AWS account

The availability_zone, cidr_block, servername, subnet, and os_type are all string-type variables. On the other hand, ec2_monitoring is a bool-type variable, which means it will only accept True or False.

The disk is an object-type variable which allows grouping of values with different types together. This can be see when we assign the value to this variable in the terraform.tfvars file.

The ami_ids is a map-type variable which consists of a key-value pair.

vars.tf
# Variables for setting up terraform

variable "aws_region" {
description = "AWS region"
type = string
}

variable "my_profile" {
description = "Profile to be used to connect to AWS"
type = string
}

variable "my_credentials" {
description = "Credentials to be used to connect to AWS"
type = list(string)
}

# variables for the lab

variable "availability_zone" {
description = "Availability zone"
type = string
}

variable "cidr_block" {
description = "IP Range"
type = string
}

variable "servername" {
description = "Name of the server"
type = string
}

variable "subnet" {
description = "subnet IP address space"
type = string
}

variable "os_type" {
description = "OS to deploy, Linux or Windows"
type = string
}

variable "ec2_monitoring" {
description = "Configure monitoring on the EC2 instance"
type = bool
}

variable "disk" {
description = "OS image to deploy"
type = object({
delete_on_termination = bool
encrypted = bool
volume_size = string
volume_type = string
})
}

variable "ami_ids" {
type = map(any)
description = "AMI ID's to deploy"
}

variable "instance_size" {
description = "Size of the EC2 instance"
type = string
default = "t2.micro"
}

Now that we've declared the variables, we can assign values to them through the terraform.tfvars.

terraform.tfvars
# Variables for setting up terraform
aws_region = "ap-southeast-1"
my_credentials = ["/mnt/c/Users/Eden.Jose/.aws/credentials"]
my_profile = "vscode-dev"

# Variables for the lab
cidr_block = "10.0.0.0/16"
availability_zone = "ap-southeast-1a"
servername = "lab09-server"
subnet = "10.0.1.0/24"
os_type = "linux"
ec2_monitoring = true

disk = {
delete_on_termination = false
encrypted = true
volume_size = "20"
volume_type = "standard"
}

ami_ids = {
linux = "ami-04d9e855d716f9c99"
windows = "ami-07d9bd7bc4f2370d0"
}

Time to Apply!

Initialize the working directory.

terraform init

Check if there are errors with the formatting.

terraform fmt

Then check if the config files are valid.

terraform validate

Finally, do a review to check what changes will be introduce when you actually run the template.

terraform plan

If it doesn't return any error, you can now apply it.

terraform apply -auto-approve

It should return the Apply complete! message, along with the output values.

Apply complete! Resources: 3 added, 0 changed, 0 destroyed.

Verify in the AWS Console if the resources are provisioned.

Cleanup

To delete all the resources, just run the destroy command.

terraform destroy -auto-approve

Resources