Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

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"

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

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.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading