How to dynamically create ec2 instances using a Terraform for_each

I am attempting to dynamically create ec2 instances using a for_each. But I am getting this error:

│ Error: Missing required argument
│
│   with aws_instance.ec2-instance,
│   on main.tf line 76, in resource "aws_instance" "ec2-instance":
│   76: resource "aws_instance" "ec2-instance" {
│
│ "instance_type": one of `instance_type,launch_template` must be specified

Here is the Terraform:

terraform {
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 3.27"
    }
  }

  required_version = ">= 0.14.9"
}

variable "instance_name" {
  description = "Value of the Name tag for the EC2 instance"
  type        = string
  default     = "ChangedName"
}

variable "aws_region" {
  description = "AWS Region"
  type        = string
  default     = "eu-west-2"
}

variable "instance_size_small" {
  description = "Instance size small"
  type        = string
  default     = "t3.micro"
}

variable "redundant_count" {
  description         = "Default redundancy - base number of instances to create for redundant services"
  type                = number
  default             = 1
}

variable "ami" {
  description = "Ubuntu 20.04 AMI"
  type        = string
  default     = "ami-0015a39e4b7c0966f"
}

provider "aws" {
  profile = "sandbox"
  region  = var.aws_region
}

variable "environment_name" {
  description         = "Environment Name"
  type                = string
  default             = "dev"
}

variable "client_name" {
  description         = "Client Name"
  type                = string
  default             = "sandbox"
}

variable "instances" {
  description = "Map of modules names to configuration."
  type        = map
  default     = {
    testing-sandbox-dev = {
      instance_count          = 2,
      instance_type           = "t3.micro",
      environment             = "dev"
    },
    testing-sandbox-test = {
      instance_count          = 1,
      instance_type           = "t3.micro",
      environment             = "test"
    }
  }
}

resource "aws_instance" "ec2-instance" {
  ami                = var.ami

  for_each           = var.instances

  tags = {
    Name = "testing-${var.instances.index}.${var.environment_name}.${var.client_name}"
    client = var.client_name
    environment = var.environment_name
  }
}

instance_type is one of the keys defined in the map being iterated on. So why is Terraform not picking it up?


You haven't defined an instance_type argument inside the resource "aws_instance" "ec2-instance" block, which is where Terraform is reporting the error.

You'll need to write out each argument you want to set with an expression which tells Terraform how you'd like to set it. If you want to set to values derived from your for_each elements then you can write it like this:

resource "aws_instance" "ec2-instance" {
  for_each = var.instances

  ami           = var.ami
  instance_type = each.value.instance_type

  tags = {
    Name = "testing-${var.instances.index}.${var.environment_name}.${var.client_name}"
    client = var.client_name
    environment = var.environment_name
  }
}

It seems like you also have another question about how to create each.value.instance_count instances from each element of this mapping, but I think that'd be best as a separate question once you've successfully populated instance_type for a single instance per element.