Terraform: Variable error "should be type string, got list" dependent on where the .tf file containing the variable is

Created on 3 May 2017  ยท  7Comments  ยท  Source: hashicorp/terraform

Terraform Version

Terraform v0.9.4

Affected Resource(s)

Trying to create multiple aws_sqs_queue by looping through a .tf file with declared variables

Terraform Configuration Files

This is a component in my module...

resource "aws_sqs_queue" "standard-queue" {
  count                     = "${length(var.myapp_sqs_queues)}"
  name                      = "myapp-${var.app_environment}-${element(var.myapp_sqs_queues, count.index)}"
  fifo_queue                = false
  delay_seconds             = 0
  max_message_size          = 262144
  message_retention_seconds = 86400
  receive_wait_time_seconds = 1
}

This is a variable file in my providers folder

variable "myapp_sqs_queues" {
  description = "My App SQS Queues"
  default     = ["mystandardqueue1", "mystandardqueue2", "mystandardqueue3"]
}

Debug Output

Please provider a link to a GitHub Gist containing the complete debug output: https://www.terraform.io/docs/internals/debugging.html. Please do NOT paste the debug output in the issue; just paste a link to the Gist.

Panic Output

If Terraform produced a panic, please provide a link to a GitHub Gist containing the output of the crash.log.

Expected Behavior

Terraform will loop through the variable and create a queue for each.

Actual Behavior

2nd Error omitted since it's just another variable with a number of SQS queues like the first.
```$ terraform plan
Error asking for user input: 2 error(s) occurred:

  • module.myapp-prod.var.myapp_sqs_queues: variable myapp_sqs_queues in module myapp-prod should be type string, got list

### Steps to Reproduce
Please list the steps required to reproduce the issue, for example:
1. Setup Terraform according to best practices repo (with modules/providers structure)
2. Create module to create the SQS queues as stated above
3. Create provider file

```hcl
provider "aws" {
  shared_credentials_file = "${var.shared_credentials_file}"
  profile                 = "${var.profile}"
  region                  = "${var.region}"
}
module "myapp-prod" {
  source = "../../../modules/aws/sqs"
  myapp_sqs_queues         = "${var.myapp_sqs_queues}"
}
  1. Create variable.tf file in the same directory as the above provider file
variable "myapp_sqs_queues" {
  description = "My App SQS Queues"
  default     = ["mystandardqueue1", "mystandardqueue2", "mystandardqueue3"]
}
  1. terraform plan

Important Factoids

If I place variable.tf in the same folder as the module, terraform does not return an error and will create the queues with no issue. Obviously this won't work since the module isn't reusable.

bug core

Most helpful comment

Hi @toanctruong! Sorry for the confusing behavior here.

For non-string variables it's necessary to specify what type is expected, like this:

variable "myapp_sqs_queues" {
  type        = "list"
  description = "My App SQS Queues"
  default     = ["mystandardqueue1", "mystandardqueue2", "mystandardqueue3"]
}

Do you still see the issue if you specify the type in this way?

All 7 comments

Hi @toanctruong! Sorry for the confusing behavior here.

For non-string variables it's necessary to specify what type is expected, like this:

variable "myapp_sqs_queues" {
  type        = "list"
  description = "My App SQS Queues"
  default     = ["mystandardqueue1", "mystandardqueue2", "mystandardqueue3"]
}

Do you still see the issue if you specify the type in this way?

@apparentlymart

That worked, thanks!

@apparentlymart when I specify type = "list", I get this error:

Variable 'security_groups' must be of type string or map - 'list' is not a valid type

Do you know what the issue might be?

The trick when passing lists to modules is that when declaring them at the top of the module you need to specify the variable's type.

variable "name"             {}
variable "cidr"             {}
variable "azs"              { type = "list" }
variable "private_subnets"  { type = "list" }
variable "public_subnets"   { type = "list" }

module "vpc" {
  source  = "terraform-aws-modules/vpc/aws"
  version = "1.53.0"

  name = "${var.name}"
  cidr = "${var.cidr}"

  azs             = ["${var.azs}"]
  private_subnets = ["${var.private_subnets}"]
  public_subnets  = ["${var.public_subnets}"]
}

@slmingol this doesn't seem to work.
Error: Variable 'public_subnets': duplicate found. Variable names must be unique.

@hgfranco

That error means you have public_subnets:

variable "public_subnets" {}

Declared twice in the same scope. Not sure what your setup is. Maybe you have it declared inline in your main file (like the example above) and again in your variables file (if you use variables.tf)?

I'm going to lock this issue because it has been closed for _30 days_ โณ. This helps our maintainers find and focus on the active issues.

If you have found a problem that seems similar to this, please open a new issue and complete the issue template so we can capture all the details necessary to investigate further.

Was this page helpful?
0 / 5 - 0 ratings