Creación de una regla de entrada dinámica para Terraform (AWS): lectura desde un archivo
Llevo varios días golpeándome la cabeza contra la pared con esto y estoy desquiciado. El problema parece simple: cree una regla de entrada dinámica para terraform leyendo los puertos de un archivo. Tengo dificultades para que una regla for_each se aplique de manera consistente aquí; ¿Qué estoy pasando por alto?
Los archivos que se están leyendo, algo1.txt y algo2.txt, pueden manejar bien un único número de puerto, pero cualquier nueva línea agregada por 'echo "22" >> algo1.txt' provocará el siguiente error:
│ Al expandir el plan para aws_security_group. Desea incluir nuevos valores aprendidos hasta ahora durante la aplicación, el proveedor "registry.terraform.io/hashicorp/aws" │ produjo un nuevo valor no válido para .ingress: la longitud cambió de 3 a 4. │ │ Este es un error en el proveedor, que debe informarse en el rastreador de problemas del propio proveedor.
resource "null_resource" "create_files" {
provisioner "local-exec" {
command = "bash ${path.module}/portdecoder.sh" # This is a command querying local config files about what ports they need open and which they need pointed somewhere else, often in the form of cat file | grep '[0-9]+' >> something1.txt
}
}
data "local_file" "something1" {
filename = "${path.module}/something1.txt"
depends_on = [null_resource.create_files]
}
data "local_file" "something2" {
filename = "${path.module}/something2.txt"
depends_on = [null_resource.create_files]
}
locals {
ingress_ts_ports = split("\n", trimspace(data.local_file.something1.content))
ingress_rd_ports = split("\n", trimspace(data.local_file.something2.content))
}
resource "aws_security_group" "YouWish" {
name = "YouWish"
description = "YOUWISH Security Group - Autogen"
vpc_id = "vpc-***************"
dynamic "ingress" { # ingress something1
for_each = local.ingress_ts_ports
content {
from_port = tonumber(ingress.value)
to_port = tonumber(ingress.value)
protocol = "tcp"
cidr_blocks = ["*.*.*.*/**"] # This is obfuscated, not actual value
}
}
dynamic "ingress" { # ingress rd
for_each = local.ingress_rd_ports
content {
from_port = tonumber(ingress.value)
to_port = tonumber(ingress.value)
protocol = "tcp"
cidr_blocks = ["*.*.*.*/**"] # This is obfuscated, not actual value
}
}
}
El 'decodificador de puertos'
base64 -d someconfigfile | grep NGINX_PORT | grep -oE '[0-9]+' >> something1.txt
# Below will be some 'default' ports to run over that need to be pointed somewhere else
echo "80" >> something2.txt
echo "443" >> something2.txt
# ideally wanted to use echo "80\n443\n8080\n" >> something2.txt
Lo que sugeriría es utilizar un recurso aws_security_group_rule independiente . De esa manera, puede tener más control sobre lo que se agrega y no necesita usar dynamic
y ingress
dentro del recurso del grupo de seguridad. En resumen, pasaría a utilizar lo siguiente:
resource "aws_security_group" "YouWish" {
name = "YouWish"
description = "YOUWISH Security Group - Autogen"
vpc_id = "vpc-***************"
}
resource "aws_security_group_rule" "ts_ports" {
for_each = toset(local.ingress_ts_ports)
type = "ingress"
from_port = tonumber(each.value)
to_port = tonumber(each.value)
protocol = "tcp"
cidr_blocks = ["*.*.*.*/**"]
security_group_id = aws_security_group.YouWish.id
}
resource "aws_security_group_rule" "rd_ports" {
for_each = toset(local.ingress_rd_ports)
type = "ingress"
from_port = tonumber(each.value)
to_port = tonumber(each.value)
protocol = "tcp"
cidr_blocks = ["*.*.*.*/**"]
security_group_id = aws_security_group.YouWish.id
}
Mi mejor suposición es que Terraform se complica por el hecho de que tienes dos bloques dinámicos del mismo tipo, por lo que esto debería resolver el problema al que te enfrentas. Además, si desea ser aún más preciso, podría considerar utilizar aws_vpc_security_group_ingress_rule
recursos.