Summary:
Your Manager told you to come up with a solution for the situation in which developers are not able to launch the Ec2 instance in all availability zone within your VPC. To solve this problem you want to come up with a solution that can dynamically launch desired ec2 instances in all availability zone within your VPC.
Solution: After some research, you decided to use data source block "aws_ec2_instance_type_offerings" that can look for instance type supported per az within a region.
In this solution, we have different files such as:
var.tf- For storing variable names
data.tf - contains the data block
main.tf - contains resource block
output.tf- contains output block
I have also used loops and dynamic filters to achieve our end result.
Code-Link: Click on the code link to download and use code.
Var.tf
##Var.tf###
variable "aws_region" {
type = string
default = "us-east-1"
}
variable "aws_instance" {
type = string
default = "t2.micro"
}
data.tf
# getting ami id
data "aws_ami" "ubuntu" {
most_recent = true
filter {
name = "name"
values = ["ubuntu/images/hvm-ssd/ubuntu-focal-20.04-amd64-server-*"]
}
filter {
name = "virtualization-type"
values = ["hvm"]
}
filter {
name = "architecture"
values = ["x86_64"]
}
owners = ["099720109477"] # Canonical official
}
# getting list of az in a region
data "aws_availability_zones" "az" {
filter {
name = "opt-in-status"
values = ["opt-in-not-required"]
}
}
# pass list of az into instance supported in the az
data "aws_ec2_instance_type_offerings" "example" {
# for each can help you to iterate and it should be convereted into map or set
for_each = toset(data.aws_availability_zones.az.names)
filter {
name = "instance-type"
values = [var.aws_instance]
}
#each.key will iterate all the values
filter {
name = "location"
values = [each.key]
}
location_type = "availability-zone"
}
main.tf
# Get instance implemented on available az
resource "aws_instance" "myec2_Instances" {
ami = data.aws_ami.ubuntu.id
instance_type = var.aws_instance
# Create EC2 Instance in all Availabilty Zones of a VPC
for_each = toset(keys({ for az, instance in data.aws_ec2_instance_type_offerings.example : az => instance.instance_types if length(instance.instance_types) != 0 }))
availability_zone = each.key # You can also use each.value because for list items each.key == each.value
tags = {
"Name" = "For-Each-Demo-${each.key}"
}
}
output.tf
# get instance list
output "output_v1_1" {
# output should be in for loop for list of supported instances
value = [for instance in data.aws_ec2_instance_type_offerings.example : instance.instance_types]
}
# now lets see how we can get available instance type with az as a output
output "output_v1_1" {
value = { for az, instance in data.aws_ec2_instance_type_offerings.example : az => instance.instance_types }
}
# remove unsupported az and only get supported ec2 instance with az
output "output_v1_2" {
value = { for az, instance in data.aws_ec2_instance_type_offerings.example : az => instance.instance_types if length(instance.instance_types) != 0 }
}
# only getting list of az using key function
output "availability_zone_that_supported_instance_type" {
value = keys({ for az, instance in data.aws_ec2_instance_type_offerings.example : az => instance.instance_types if length(instance.instance_types) != 0 })
}
# get public dns of our instances
output "instance_publicdns" {
description = "EC2 Instance Public DNS"
value = toset([for instance in aws_instance.myec2_Instances : instance.public_dns])
}