简体   繁体   中英

Terraform for loop to generate security group rules

I'm trying to generate security group rules in Terraform to be fed to aws_security_group as the ingress block. I'm not with aws_security_group_rule because I want the module to be flexible if do self source etc.

Example pulling private subnet cidr_block and description of the rule as the availability zone.

simplified example: I'm actually pulling from Terraform state etc.

Environment

Terraform v1.0.8

Source

list of maps

locals {
  subnets = [
    {
      availability_zone = "us-east-1a"
      cidr_block = "10.0.0.0/23"
    },
    {
      availability_zone = "us-east-1b"
      cidr_block = "10.0.2.0/23"
    },
    {
      availability_zone = "us-east-1c"
      cidr_block = "10.0.4.0/23"
    }
  ]
}

Expected Results

list of maps

[
    {
      description               = "us-east-1a"
      type                      = "ingress"
      from_port                 = "0"
      to_port                   = "0"
      protocol                  = "-1"
      cidr_blocks               = ["10.0.0.0/23"]
      ipv6_cidr_blocks          = []
      prefix_list_ids           = []
      security_groups           = []
      self                      = false
    },
    {
      description               = "us-east-1b"
      type                      = "ingress"
      from_port                 = "0"
      to_port                   = "0"
      protocol                  = "-1"
      cidr_blocks               = ["10.0.2.0/23"]
      ipv6_cidr_blocks          = []
      prefix_list_ids           = []
      security_groups           = []
      self                      = false
    },
    {
      description               = "us-east-1c"
      type                      = "ingress"
      from_port                 = "0"
      to_port                   = "0"
      protocol                  = "-1"
      cidr_blocks               = ["10.0.4.0/23"]
      ipv6_cidr_blocks          = []
      prefix_list_ids           = []
      security_groups           = []
      self                      = false
    }
]

None Working Draft (Need help here)

ingress_rules = flatten([
    for subnets, values in local.subnets : [
      for key in values: {
        description               = key.availability_zone
        type                      = "ingress"
        from_port                 = "0"
        to_port                   = "0"
        protocol                  = "-1"
        cidr_blocks               = [key.cidr_block]
        ipv6_cidr_blocks          = []
        prefix_list_ids           = []
        security_groups           = []
        self                      = false
      }
    ]
  ])

You have one for too much. It should be:

  ingress_rules = [
    for subnets, values in local.subnets : {
        description               = values.availability_zone
        type                      = "ingress"
        from_port                 = "0"
        to_port                   = "0"
        protocol                  = "-1"
        cidr_blocks               = [values.cidr_block]
        ipv6_cidr_blocks          = []
        prefix_list_ids           = []
        security_groups           = []
        self                      = false
    }
  ] 

AWS Security Group Rule Generating Examples

Examples for others based on @Marcin help

VPC and Remote WAN IP Access

access_lists.tfvars

access_lists = {
  office = {
    hq                    = "102.55.22.34/32"
  },
  remote = {
    first_last            = "12.32.211.243/32"
  }
}

local.tf

locals {
  cidr_list_office              = var.access_lists.office
  cidr_list_remote              = var.access_lists.remote

  public_access_cidrs           = merge(
    local.cidr_list_office,
    local.cidr_list_remote
  )

  ingress_rule_vpc = [
    {
      description               = "vpc - Managed by Terraform"
      type                      = "ingress"
      from_port                 = 0
      to_port                   = 0
      protocol                  = "-1"
      cidr_blocks               = [data.terraform_remote_state.network.outputs.vpc.cidr_block]
      ipv6_cidr_blocks          = []
      prefix_list_ids           = []
      security_groups           = []
      self                      = false
    }
  ]

  ingress_rules_public = [
    for desc, cidr in local.public_access_cidrs : {
      description               = "${desc} - Managed by Terraform"
      type                      = "ingress"
      from_port                 = "0"
      to_port                   = "0"
      protocol                  = "-1"
      cidr_blocks               = [cidr]
      ipv6_cidr_blocks          = []
      prefix_list_ids           = []
      security_groups           = []
      self                      = false
    }
  ]

  ingress_rules                 = concat(local.ingress_rule_vpc, local.ingress_rules_public)
}

EFS (2 Options)

Nested for_each calls. Could have more added to tfvar and then setup sg rules in local that are mapped to egress_rules.xyz/ingress_rules.xyz

efs.tfvars

efs = {
  jenkins = {
    encrypted                 = "false"
    performance_mode          = "generalPurpose"
    throughput_mode           = "bursting"
    throughput_in_mibps       = "0"
  }
}

local.tf (Option 1 - Private Subnets)

locals {
  # Allow all Private Subnets
  jenkins_ingress_rules = [
    for subnets, values in data.terraform_remote_state.network.outputs.subnets.private : {
      description               = values.availability_zone
      type                      = "ingress"
      from_port                 = "0"
      to_port                   = "0"
      protocol                  = "-1"
      cidr_blocks               = [values.cidr_block]
      ipv6_cidr_blocks          = []
      prefix_list_ids           = []
      security_groups           = []
      self                      = false
    }
  ]

  # VPC Private Subnets Only
  jenkins_egress_rules = [
    {
      description               = "Managed by Terraform"
      type                      = "egress"
      from_port                 = "0"
      to_port                   = "0"
      protocol                  = "-1"
      cidr_blocks               = ["0.0.0.0/0"]
      ipv6_cidr_blocks          = []
      prefix_list_ids           = []
      security_groups           = []
      self                      = false
    }
  ]

  egress_rules = {
    jenkins                     = local.jenkins_egress_rules
  }

  ingress_rules = {
    jenkins                     = local.jenkins_ingress_rules
  }
}

local.tf (Option 2 - Self Source)

locals {
  # Self sourced security group. Have to be in the SG for access.
  jenkins_ingress_rules = [
    {
      description               = "Managed by Terraform"
      from_port                 = 0
      to_port                   = 0
      protocol                  = "-1"
      self                      = true
      cidr_blocks               = []
      ipv6_cidr_blocks          = []
      prefix_list_ids           = []
      security_groups           = []
    }
  ]

  # VPC Private Subnets Only
  jenkins_egress_rules = [
    {
      description               = "Managed by Terraform"
      type                      = "egress"
      from_port                 = "0"
      to_port                   = "0"
      protocol                  = "-1"
      cidr_blocks               = ["0.0.0.0/0"]
      ipv6_cidr_blocks          = []
      prefix_list_ids           = []
      security_groups           = []
      self                      = false
    }
  ]

  egress_rules = {
    jenkins                     = local.jenkins_egress_rules
  }

  ingress_rules = {
    jenkins                     = local.jenkins_ingress_rules
  }
}

main.tf

module "security_groups" {
  for_each                      = var.efs
  base_aws_tags                 = module.aws_tags.aws_tags
  name_suffix                   = "efs-${each.key}"
  egress_rules                  = lookup(local.egress_rules, each.key)
  ingress_rules                 = lookup(local.ingress_rules, each.key)
  source                        = "../../../modules/security_group"
  vpc                           = data.terraform_remote_state.network.outputs.vpc
}

Hope that helps some others out! -=Levon

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM