Terraform.tfvars parsing lists for variables.tf file

I’ve got a couple of variables set in my variables.tf files which are of type list and I am trying to find the correct syntax on my .tfvars file

variables.tf

variable "subnet_cidrs" {
  type        = list(string)
  description = "A list of Subnets CIDR's - Should consist of minimum 2"
}

variable "aws_region" {
  type        = string
  description = "Region where all AWS Resources will be created"
}

variable "az" {
  type        = list(string)
  description = "Availability-Zones - Should match numbers of CIDRs given and AWS Region"
}

terraform.tfvars

subnet_cidrs    = ["192.168.1.100", "192.168.4.100"]
aws_region      = "eu-central-1"
az              = ["eu-central-1a", "eu-central-1b"]

A typical output i’ll receive is :

│ Error: Incorrect attribute value type
│
│   on ..\ec2\ec2.tf line 21, in resource "aws_subnet" "public":
│   21:   availability_zone       = var.az
│     ├────────────────
│     │ var.az is a list of dynamic
│
│ Inappropriate value for attribute "availability_zone": string required.

When brackets are removed for example : az = "eu-central-1a", "eu-central-1b"

It will return the following instead Argument definitions must be separated by newlines, not commas. An argument definition must end with a newline.

Edit

ec2.tf

I’ve made this as short as possible and included only the variables

# Main VPC
resource "aws_vpc" "main" {
  cidr_block = var.vpc_cidr

  tags = {
    Name = "vpc-${var.name_prefix}"
  }
}

# Two Subnets in different AZ - Public IP on launch
resource "aws_subnet" "public" {
  count = length(var.subnet_cidrs)

  cidr_block              = var.subnet_cidrs
  availability_zone       = var.az

  tags = {
    Name = "subnet-${var.name_prefix}-${count.index}"
  }
}

resource "aws_security_group" "ec2_sg" {
  name        = var.ec2_name
  ...
  tags = {
    Name = "EC2-SG-${var.name_prefix}"
  }
}

# VM Key pair
resource "aws_key_pair" "auth" {
  key_name   = var.key_pair_name
  public_key = file("~/.ssh/${var.ssh_file_name}.pub")
}

# EC2 Instance within 2 AZ's
resource "aws_instance" "ec2" {
  count = length(var.subnet_cidrs)

  tags = {
    Name = "ubuntu-${var.name_prefix}-${count.index}"
  }
}

>Solution :

Based on the variable definition and the way subnet resource is created, the following change is required:

resource "aws_subnet" "public" {
  count = length(var.subnet_cidrs)

  cidr_block              = var.subnet_cidrs
  availability_zone       = var.az[count.index] # <---- using count.index here

  tags = {
    Name = "subnet-${var.name_prefix}-${count.index}"
  }
}

This is needed because otherwise the problem will occur as availability_zone requires a single string value and passing only var.az will be an entire list. Using the count.index with the var.az will fetch a single value as is required.

Leave a Reply