The following error occurs during a plan
Errors:
* aws_security_group_rule.my_rule: cidr_blocks: should be a list
This occurs only when one of the variables originates from a remote_state_management data source.
If the variable is declared as a normal tf variable, the error doesn't occur
Background:
I'm trying to dynamically build a cidr block array for a security group rule.
The array is to be made up from 2 parts:
In the first iteration, additional_cidrs is a single cidr block, e.g. "1.2.3.4/32" but I'm keen on making the code work in case the list has to be extended to more than one value.
The following resource fails during a plan when var.additional_cidrs is passed down from a remote_state_management data source
resource "aws_security_group_rule" "my_rule" {
type = "egress"
from_port = 80
to_port = 80
protocol = "tcp"
security_group_id = "${aws_security_group.my_group.id}"
cidr_blocks = "${split(",", format("%s,%s", var.core_network_cidr, var.additional_cidrs))}"
}
I've narrowed down further what works and doesn't work
Works when additional_cidrs is a single cidr block and the cidr_blocks is constructed as a list
cidr_blocks = ["${var.core_network_cidr}", "${var.additional_cidrs}"]
this proves that var.additional_cidrs is successfully retrieved from the remote_state_management data source
Doesn't work even though the value for var.core_network_cidr is "10.0.0.0/8" (but DOES work if var.core_network_cidr is NOT obtained from a remote_state_management data source)
cidr_blocks = "${split(",", var.core_network_cidr)}"
I've also tried to use native 0.7 lists and the concat function, but the same error occurred.
This might be related to Issue 3888 - When using count parameter w/ a split in aws_security_group_rule, receive parsing error "strconv.ParseInt" .. " invalid syntax" as this issue occurs only when using remote_state_management data
Hey @marionettist –
Using the syntax cidr_blocks = "<anything>" should result in a string for cidr_blocks. In your example above sometimes you have cidr_blocks = "<things>" and others you have cidr_blocks = ["<things>"], including a time you mention it works. I'm curious, do you get these errors if you consistently use the [] formatting?
Thanks for your quick reply @catsby
When using the [] syntax, things always work, but I can't use that syntax because I don't know how many items there are in the list I'm building.
That's why I'm trying to build the list using interpolation. To my knowledge, functions like concat and split are only available within a string, hence me using them in that way.
To give you really simple examples, the following works as expected:
cidr_blocks = "${split(",", "10.0.0.0/8,1.2.3.4/32")}"
cidr_blocks = "${split(",", "10.0.0.0/8")}"
Yet, when using
cidr_blocks = "${split(",", var.core_network_cidr)}"
and with var.core_network_cidr set to "10.0.0.0/8" as in the 2nd example just above, the success is mixed:
core_network_cidr is set as a normal tf variable the above workscore_network_cidr comes from a terraform_remote_state data source, it errors (I use core_network_cidr = "${data.terraform_remote_state.management.core_network_cidr}" when calling the module)I forgot to specify that the aws_security_group_rule resource is managed in a tf module
I am seeing a similar issue to @marionettist, it seems that list outputs loaded via the terraform_remote_state data source do not behave as expected.
In my case I have a VPC defined like so with a public subnet list output:
# Excerpt from vpc
resource "aws_subnet" "public" {
depends_on = ["aws_vpc.vpc"]
vpc_id = "${aws_vpc.vpc.id}"
cidr_block = "${var.aws_cidrs_public[count.index]}"
availability_zone = "${var.aws_azs[count.index]}"
count = "${length(var.aws_cidrs_public)}"
map_public_ip_on_launch = true
lifecycle { create_before_destroy = true }
}
output "public_subnets" { value = ["${aws_subnet.public.*.id}"] }
I then have another plan that passes this output into a module,
# Excerpt from app plan
data "terraform_remote_state" "vpc" {
backend = "s3"
config {
bucket = "some-bucket"
key = vpc.tfstate"
region = "${var.aws_region}"
}
}
module "app" {
source = "../../../modules/app_stack"
aws_public_subnets = "${data.terraform_remote_state.vpc.public_subnets}"
}
However when I try to actually use this variable in the module I get an error that the variable is not a list, eg:
# Excerpt from app module
resource "aws_autoscaling_group" "autoscaling_group" {
...
vpc_zone_identifier = "${var.aws_public_subnets}"
lifecycle {
create_before_destroy = true
}
}
I get the following error:
Errors:
* aws_autoscaling_group.autoscaling_group: vpc_zone_identifier: should be a list
If I switch out the output and hardcode a list then everything works.
My temporary fix is to join the list into a string when passing into the module, I then split it into a list in the module.
Having the same issue. It would be nice to use terraform_remote_state list outputs as inputs without the need to do these splits and joins. Would love to use splat. Just to add a little bit of info
If one were to use a list output from terraform_remote_state as an input into of type string and of type list. Both would fail. The string input fails after fetching remote state. The list input fails immediately.
Type list failure
Local and remote state in sync
var.environment
Enter a value: qa
var.region
Enter a value: us-east-1
There are warnings and/or errors related to your configuration. Please
fix these before continuing.
Errors:
* aws_alb.curalate_alb: subnets: should be a list
Type String failure
var.environment
Enter a value: qa
var.region
Enter a value: us-east-1
Refreshing Terraform state in-memory prior to plan...
The refreshed state will be used to calculate this plan, but
will not be persisted to local or remote state storage.
data.terraform_remote_state.remote_env_state: Refreshing state...
data.aws_caller_identity.current: Refreshing state...
module.curalate_iam_policies.data.aws_iam_policy_document.manage_passwords_keys_ssh: Refreshing state...
Error refreshing state: 1 error(s) occurred:
* variable name in module example_curalate_alb should be type string, got list
Same issue
output private_subnet_ids {
value = ["${aws_subnet.private.*.id}"]
}
# ... other module
variable "private_subnet_ids" {
type = "list"
}
resource "aws_autoscaling_group" "application_server_asg" {
vpc_zone_identifier = "${var.private_subnet_ids}"
}
got
Errors:
* aws_autoscaling_group.application_server_asg: vpc_zone_identifier: should be a list
Now i use some way to avoid. Not elegance, but worked
output private_subnet_ids {
value = "${join(",", aws_subnet.private.*.id)}"
}
# ...other module
variable "private_subnet_ids" { }
resource "aws_autoscaling_group" "application_server_asg" {
# vpc_zone_identifier = "${split(",", var.private_subnet_ids)}" // this one get error "should be a list", too
vpc_zone_identifier = ["${element(split(",", var.private_subnet_ids), 0)}", "${element(split(",", var.private_subnet_ids), 1)}"]
}
Found a way to solve this problem
output private_subnet_ids {
value = ["${aws_subnet.private.*.id}"]
}
# ... other module
variable "private_subnet_ids" {
type = "list"
}
resource "aws_autoscaling_group" "application_server_asg" {
vpc_zone_identifier = ["${var.private_subnet_ids}"] // ADD [] outside of "", It works...
}
@xuet0ng I don't believe it works if the input is using a remote data source though.
Here i'm getting the error like "Error loading configuration: Error parsing /home/ec2-user/tera_usecase/main.tf: At 59:1: heredoc not terminated"**
Here i have attached my terraform file.
provider "aws" {
region = "${var.aws_region}"
}
resource "aws_security_group" "default" {
name = "terraform_sg"
description = "Used in the terraform"
ingress {
from_port = 5985
to_port = 5986
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
# outbound internet access
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
}
data "aws_ami" "amazon_windows_2012R2" {
most_recent = true
owners = ["amazon"]
filter {
name = "name"
values = ["Windows_Server-2012-R2_RTM-English-64Bit-Base-*"]
}
}
resource "aws_instance" "winrm" {
# The connection block tells our provisioner how to
# communicate with the resource (instance)
connection {
type = "winrm"
user = "Administrator"
password = "${var.admin_password}"
# set from default of 5m to 10m to avoid winrm timeout
timeout = "10m"
}
instance_type = "t2.micro"
ami = "${data.aws_ami.amazon_windows_2012R2.image_id}"
key_name = "${var.key_name}"
security_groups = ["${aws_security_group.default.name}"]
user_data = <<-EOF
EOF
}
I am creating a security group and when creating the sg_rules and i put the cidr_blocks it gives me an error it is not a list and i don't know how to fix
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.
Most helpful comment
Found a way to solve this problem