-1

I want to call csv function from variable.

Here is my main.tf file of security group

resource "aws_security_group" "names" {
  count = length(var.ams_prod_sg_list)
  name        = var.ams_prod_sg_list[count.index].sg_name
  vpc_id = module.vpc.vpc_id_sg
  tags = {
    Name = var.ams_prod_sg_list[count.index].sg_tags
  }
}

resource "aws_security_group_rule" "sg_rule" {
  count             = length(var.ams_prod_sg_list)
  security_group_id = "${aws_security_group.this.*.id}"
  type              = var.ams_prod_sg_list[count.index].sg_rules.type
  protocol          = var.ams_prod_sg_list[count.index].sg_rules.protocol
  from_port         = var.ams_prod_sg_list[count.index].sg_rules.from
  to_port           = var.ams_prod_sg_list[count.index].sg_rules.to
  cidr_blocks       = [var.ams_prod_sg_list[count.index].sg_rules.cidr_blocks]
  description       = var.ams_prod_sg_list[count.index].sg_rules.description
}

Here is the variable.tf file

locals {
  test = csvdecode(file("${path.module}/csv/test.csv"))
  test1 = csvdecode(file("${path.module}/csv/test1.csv"))
}

variable "ams_prod_sg_list" {
  description = "sg_name rules"
  type        = list(map(string))
  default = [
    {
      sg_name = "test"
      sg_rules = local.test
      sg_tags = "sg"
    },
    {
      sg_name = "test1"
      sg_rules = local.test1
      sg_tags = ""
    },
  ]
}

When I do terraform apply , it shows Variables may not be used here which means we cannot use local in variable. And also when I directly put sg_rules = csvdecode(file("${path.module}/csv/test.csv")) , it shows Functions may not be called here

Here is the test.csv file

type,protocol,from,to,cidr_blocks,description
ingress,-1,0,0,10.100.0.0/16,test
ingress,tcp,80,80,10.100.0.0/16,

I also tried by putting this in variable and local

variable "ams_prod_sg_list" {
  description = "sg_name rules"
  type        = list(map(string))
  default     = null
}

locals {
  default_ams_prod_sg_list = [
    {
      sg_name = "test"
      sg_rule = "${local.test}"
      sg_tags = "sg"
    },
    {
      sg_name = "test1"
      sg_rule = "${local.test1}"
      sg_tags = ""
    },
  ]

  ams_prod_sg_list = var.ams_prod_sg_list != null ? var.ams_prod_sg_list : local.default_ams_prod_sg_list
}

now getting this error

Error: Inconsistent conditional result types
│ 
│   on sg-variable.tf line 46, in locals:
│   46:   ams_prod_sg_list = var.ams_prod_sg_list != null ? var.ams_prod_sg_list : local.default_ams_prod_sg_list
│     ├────────────────
│     │ local.default_ams_prod_sg_list is tuple with 2 elements
│     │ var.ams_prod_sg_list is a list of map of string, known only after apply
│ 
│ The true and false result expressions must have consistent types. The given
│ expressions are list of map of string and tuple, respectively.

and I also tried putting this

variable "ams_prod_sg_list" {
  description = "sg_name rules"
  type        = list(map(string))
  default     = null
}

locals {
  default_ams_prod_sg_list = tolist([
    tomap({
      sg_name = "test"
      sg_rule = "${local.test}"
      sg_tags = "sg"
    }),
    tomap({
      sg_name = "test1"
      sg_rule = "${local.test1}"
      sg_tags = ""
    }),
  ])

  ams_prod_sg_list = var.ams_prod_sg_list != null ? var.ams_prod_sg_list : local.default_ams_prod_sg_list
}

getting this error

Error: Unsupported attribute
│ 
│   on security-group.tf line 91, in resource "aws_security_group_rule" "sg_rule":
│   91:   type              = var.ams_prod_sg_list[count.index].sg_rules.type
│     ├────────────────
│     │ count.index is a number, known only after apply
│     │ var.ams_prod_sg_list is a list of map of string, known only after apply
│ 
│ This value does not have any attributes.
╵
╷
│ Error: Unsupported attribute
│ 
│   on security-group.tf line 92, in resource "aws_security_group_rule" "sg_rule":
│   92:   protocol          = var.ams_prod_sg_list[count.index].sg_rules.protocol
│     ├────────────────
│     │ count.index is a number, known only after apply
│     │ var.ams_prod_sg_list is a list of map of string, known only after apply
│ 
│ This value does not have any attributes.
╵
╷
│ Error: Unsupported attribute
│ 
│   on security-group.tf line 93, in resource "aws_security_group_rule" "sg_rule":
│   93:   from_port         = var.ams_prod_sg_list[count.index].sg_rules.from
│     ├────────────────
│     │ count.index is a number, known only after apply
│     │ var.ams_prod_sg_list is a list of map of string, known only after apply
│ 
│ This value does not have any attributes.
╵
╷
│ Error: Unsupported attribute
│ 
│   on security-group.tf line 94, in resource "aws_security_group_rule" "sg_rule":
│   94:   to_port           = var.ams_prod_sg_list[count.index].sg_rules.to
│     ├────────────────
│     │ count.index is a number, known only after apply
│     │ var.ams_prod_sg_list is a list of map of string, known only after apply
│ 
│ This value does not have any attributes.
╵
╷
│ Error: Unsupported attribute
│ 
│   on security-group.tf line 95, in resource "aws_security_group_rule" "sg_rule":
│   95:   cidr_blocks       = [var.ams_prod_sg_list[count.index].sg_rules.cidr_blocks]
│     ├────────────────
│     │ count.index is a number, known only after apply
│     │ var.ams_prod_sg_list is a list of map of string, known only after apply
│ 
│ This value does not have any attributes.
╵
╷
│ Error: Unsupported attribute
│ 
│   on security-group.tf line 96, in resource "aws_security_group_rule" "sg_rule":
│   96:   description       = var.ams_prod_sg_list[count.index].sg_rules.description
│     ├────────────────
│     │ count.index is a number, known only after apply
│     │ var.ams_prod_sg_list is a list of map of string, known only after apply
│ 
│ This value does not have any attributes.
╵
╷
│ Error: Invalid function argument
│ 
│   on sg-variable.tf line 34, in locals:
│   34:     tomap({
│   35:       sg_name = "test"
│   36:       sg_rule = "${local.test}"
│   37:       sg_tags = "sg"
│   38:     }),
│     ├────────────────
│     │ local.test is list of object with 2 elements
│ 
│ Invalid value for "v" parameter: cannot convert object to map of any single
│ type.
╵
╷
│ Error: Invalid function argument
│ 
│   on sg-variable.tf line 39, in locals:
│   39:     tomap({
│   40:       sg_name = "test1"
│   41:       sg_rule = "${local.test1}"
│   42:       sg_tags = ""
│   43:     }),
│     ├────────────────
│     │ local.test1 is list of object with 1 element
│ 
│ Invalid value for "v" parameter: cannot convert object to map of any single
│ type.
  • Hi, I've noticed that all your questions got answers, yet not a single was accepted. Accepting useful answers is not only a good practice, but it helps others and reduces number of duplicates. Also, people my just keep skipping your questions if they know there is no chance for them being ever accepted or even commented on why the answers given don't work. – Marcin May 21 '21 at 05:28

1 Answers1

1

Variables must be fully defined at run time. You can make them "dynamic".

The true and false result expressions must have consistent types

The error means that your if expression has different types, which is not allowed. To fix that you can use the following:

variable "ams_prod_sg_list" {
  description = "sg_name rules"
  type        = list(map(string))
  default     = []
}

locals {
  default_ams_prod_sg_list = [
    {
      sg_name = "test"
      sg_rule = "local.test"
      sg_tags = "sg"
    },
    {
      sg_name = "test1"
      sg_rule = "local.test1"
      sg_tags = ""
    },
  ]

  ams_prod_sg_list = length(var.ams_prod_sg_list) > 0  ? var.ams_prod_sg_list : local.default_ams_prod_sg_list
}
Marcin
  • 215,873
  • 14
  • 235
  • 294