Soy nuevo en terraformar e intento crear un grupo de seguridad de AWS con reglas de entrada y salida. En lugar de codificar los valores y crear múltiples bloques de entrada y salida, estoy tratando de hacer uso de la función de lookup de terraformación.
El archivo main.tf se ve así:
provider "aws" { version = "~> 2.0" region = var.region profile = var.profile } resource "aws_security_group" "this" { name = "test-sg" description = "test security group" dynamic "ingress" { for_each = var.ingress_rules content { description = lookup(ingress.value, "description", null) from_port = lookup(ingress.value, "from_port", null) to_port = lookup(ingress.value, "to_port", null) protocol = lookup(ingress.value, "protocol", null) cidr_blocks = lookup(ingress.value, "cidr_blocks", null) } } egress { from_port = 0 to_port = 0 protocol = "-1" cidr_blocks = ["0.0.0.0/0"] } tags = { Name = "test-sg" } } El archivo variables.tf se ve así
variable "ingress_rules" { default = { "description" = ["For HTTP", "For SSH"] "from_port" = ["80", "22"] "to_port" = ["80", "22"] "protocol" = ["tcp", "tcp"] "cidr_blocks" = ["0.0.0.0/0", "0.0.0.0/0"] } type = map(list(string)) description = "Security group rules" } Cuando ejecuto la terraform validate , muestra que la configuración es válida, pero cuando ejecuto el terraform plan , muestra el siguiente error:
ingress.value is list of string with 2 elements Invalid value for "inputMap" parameter: lookup() requires a map as the first argument. Después de pasar mucho tiempo todavía, no puedo encontrar la manera de resolver este error. ¿Cuál es la forma correcta de pasar valores de búsqueda al archivo variables.tf ?
Ha construido el valor predeterminado de su variable como cinco mapas con una clave de cadena y una lista de valores de cadenas. Probablemente deseaba un solo mapa con una serie de claves y valores asociados con los diversos atributos de su regla de ingreso. Puede actualizar el valor de la variable en consecuencia como:
variable "ingress_rules" { default = { "my ingress rule" = { "description" = "For HTTP" "from_port" = "80" "to_port" = "80" "protocol" = "tcp" "cidr_blocks" = ["0.0.0.0/0"] }, "my other ingress rule" = { "description" = "For SSH" "from_port" = "22" "to_port" = "22" "protocol" = "tcp" "cidr_blocks" = ["0.0.0.0/0"] } } type = map(any) description = "Security group rules" } Ahora, en su iterador for_each , el valor del primer ingress.key será my ingress rule , y el valor del primer ingress.value será su mapa completo de claves y cadenas. Antes, el primer ingress.key habría sido description y el primer valor habría sido ["For HTTP", "For SSH"] . Es por eso que estaba recibiendo ese error: no puede buscar un valor con una description clave de una lista de ["For HTTP", "For SSH"] . Después de actualizar el valor de esta variable, debería tener el comportamiento esperado.
Tenga en cuenta que puede refinar su tipo aún más con un objeto:
default = { "my ingress rule" = { description = "For HTTP" from_port = 80 to_port = 80 protocol = "tcp" cidr_blocks = ["0.0.0.0/0"] }, "my other ingress rule" = { description = "For SSH" from_port = 22 to_port = 22 protocol = "tcp" cidr_blocks = ["0.0.0.0/0"] } } type = map(object({ description = string from_port = number to_port = number protocol = string cidr_blocks = list(string) }))Yo lo implementaría de la siguiente manera:
resource "aws_security_group" "test_security_group" { name = "test-sg" description = "test security group" dynamic "ingress" { for_each = var.sg_ingress_rules content { from_port = ingress.value.from_port to_port = ingress.value.to_port protocol = ingress.value.protocol cidr_blocks = ingress.value.cidr_blocks description = ingress.value.description } } egress { from_port = 0 to_port = 0 protocol = "-1" cidr_blocks = ["0.0.0.0/0"] } tags = { Name = "test security group" } }variables.tf
variable "sg_ingress_rules" { description = "Ingress security group rules" type = map }mis_vars.tfvars
sg_ingress_rules = { "1" = { from_port = 80 to_port = 80 protocol = "tcp" cidr_blocks = ["0.0.0.0/0"] description = "HTTP" }, "2" = { from_port = 22 to_port = 22 protocol = "tcp" cidr_blocks = ["<my_private_ip>/32"] description = "SSH" } }¡Espero que ayude a entender más!