Grupos de seguridad de AWS

grupos de seguridad

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:

grupos de seguridad


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:

Recent Post