Manera fácil de administrar grupos de seguridad de AWS con Terraform
El código para administrar grupos de seguridad en AWS con Terraform es muy simple.
Sin embargo, si usa el código tal como está y lo configura, puede ser difícil reconocer las reglas de numerosos grupos de seguridad de un vistazo.
Con un poco de esfuerzo, puede crear módulos de terraformación que sean fáciles de reconocer y administrar.
contenido clave
Para administrar grupos de seguridad con Terraform, debe crear un aws_security_group y varias aws_security_group_rules debajo de él.
Este código multiestructurado se compone con la sintaxis for_each de Terraform y se reorganiza con variables locales para que el código tfvars sea más fácil de ver.
tfvars
# Cofiguration for AWS Provider Auth aws = { region = "Region Id" profile = "AWS CLI profile name" } # Configuration for Security Groups security_groups = { # terraform map for a security group "[Your SecurityGroupName]" = { vpc_id = "[VPC Id for SecurityGroup]" description = "[Description]" tags = {} # tags for SecurityGroup ingress = [ [<from port as number>, <to port as number>, "[protocol]", ["[source as string]]"], "[description]", <self as bool>] ] egress = [ [<from port as number>, <to port as number>, "[protocol]", ["[target as string]]"], "[description]", <self as bool>] ] } }
Para configurar las variables de tfvars como se indicó anteriormente, conviértalas de variables locales y configúrelas para su uso.
variables locales
locals {sg_rules = { for rules in flatten([ for key, val in var.security_groups : concat( [ for index, rule in val.ingress : { security_group_name = key index = index type = "ingress" from_port = rule[0] to_port = rule[1] protocol = rule[2] cidr_blocks = (rule[3] == null || length(rule[3]) == 0) ? null : ( (((rule[5] == true) || ((substr(rule[3][0], 0, 3) == "sg-" || lookup(var.security_groups, rule[3][0], null) != null) && length(rule[3]) == 1))) ? null : [ for x in rule[3] : x if can(regex(".+[.].+", x)) ] ) source_security_group_id = ((rule[5] != true) && length(rule[3]) == 1) ? ( substr(rule[3][0], 0, 3) == "sg-" ? rule[3][0] : ( can(regex(".+[.].+", rule[3][0])) || can(regex(".+[:].+", rule[3][0])) || substr(rule[3][0], 0, 3) == "pl-" ? null : aws_security_group.security_groups[rule[3][0]].id ) ) : null ipv6_cidr_blocks = [for x in rule[3] : x if can(regex(".+[:].+", x))] prefix_list_ids = [for x in rule[3] : x if substr(x, 0, 3) == "pl-"] description = rule[4] self = rule[5] == false ? null : rule[5] } ], [ for index, rule in val.egress : { security_group_name = key index = index type = "egress" from_port = rule[0] to_port = rule[1] protocol = rule[2] cidr_blocks = (rule[3] == null || length(rule[3]) == 0) ? null : ( (((rule[5] == true) || ((substr(rule[3][0], 0, 3) == "sg-" || lookup(var.security_groups, rule[3][0], null) != null) && length(rule[3]) == 1))) ? null : [ for x in rule[3] : x if can(regex(".+[.].+", x)) ] ) source_security_group_id = ((rule[5] != true) && length(rule[3]) == 1) ? ( substr(rule[3][0], 0, 3) == "sg-" ? rule[3][0] : ( can(regex(".+[.].+", rule[3][0])) || can(regex(".+[:].+", rule[3][0])) || substr(rule[3][0], 0, 3) == "pl-" ? null : aws_security_group.security_groups[rule[3][0]].id ) ) : null ipv6_cidr_blocks = [for x in rule[3] : x if can(regex(".+[:].+", x))] prefix_list_ids = [for x in rule[3] : x if substr(x, 0, 3) == "pl-"] description = rule[4] self = rule[5] == false ? null : rule[5] } ] ) ]): "${rules.security_group_name}.${rules.type}[${rules.index}]" => rules }}
La variable local utilizada aquí parece complicada, pero en realidad no es una sintaxis muy compleja.
Se compone resolviendo las variables de tfvars compuestas por un arreglo bidimensional y asignando las variables especificadas a los elementos de cada tupla.
Además, acepta varios elementos como cidr-blocks y security-group-id como una variable, reconoce el patrón de la variable y realiza un análisis básico de cadenas para asignarlo al elemento correcto en aws_security_group_rule.
Código de archivo Terraform tf para que los grupos de seguridad se apliquen realmente
resource "aws_security_group" "security_groups" { for_each = var.security_groups name = each.key description = each.value.description vpc_id = data.aws_vpc.sg_vpc[each.key].idtags = merge({"Name": each.key}, each.value.tags) }resource "aws_security_group_rule" "sg-rules" { for_each = local.sg_rules type = each.value.type from_port = each.value.from_port to_port = each.value.to_port protocol = each.value.protocol cidr_blocks = each.value.cidr_blocks source_security_group_id = each.value.source_security_group_id ipv6_cidr_blocks = length(each.value.ipv6_cidr_blocks) == 0 ? null : each.value.ipv6_cidr_blocks prefix_list_ids = each.value.prefix_list_ids description = each.value.description self = each.value.self security_group_id = aws_security_group.security_groups[each.value.security_group_name].id }
Como puede ver, este código consta de divisiones bastante simples.
Simplemente asigne los valores calculados en la variable local a cada elemento.
Sincronice el código de Terraform con la configuración de grupos de seguridad de AWS
Incluso con la configuración anterior, lleva mucho tiempo crear el archivo tfvars porque la configuración del grupo de seguridad puede ser bastante grande y compleja.
Sin embargo, la ruta del repositorio de github de este módulo de Terraform incluye un módulo que crea automáticamente tfvars al traer información de los grupos de seguridad actualmente configurados en AWS, e incluso crea declaraciones de script para importar a Terraform.
Dado que el archivo jar se configura según la función de este módulo de Terraform, administrarlo con el módulo tiene muchas ventajas.
Si la sincronización se rompe en algún momento durante la gestión con Terraform, basta con eliminar los archivos tfvars y tfstate existentes y reconfigurarlos.
Sintaxis para la generación automática de código a través de la extracción
PS>./export.cmd [AWS CLI Profile Name] [Region ID]
Conclusión
La fuente completa del dispositivo se encuentra en el siguiente repositorio de github:
Gracias por llegar hasta aquí, si encuentras esto útil no olvides aplaudir 👍🏼suscribirse para recibir más contenido.
Si necesita ayuda adicional, por favor contácteme.
Si le interesa, puede echar un vistazo a algunos de los otros artículos que he escrito recientemente sobre AWS y Laravel: