Search code examples
amazon-web-servicesterraformterraform-provider-aws

Terraform computed_ingress_with_prefix_list_ids usage


Am I just dumb or is there no clear way or documentation on how to use computed_ingress_with_prefix_list_ids? There is documentation on the official security-group terraform page, but I cannot seem to get a hold on how to use this feature.

My scenario is the following:

I have a module, official, of security group:

module "security_group" {
  source = "terraform-aws-modules/security-group/aws"
  version = "5.1.0"
  for_each         = var.security_groups
  name             = each.value.name
  description      = each.value.description
  vpc_id           = module.vpc.vpc_id
  ingress_with_cidr_blocks = each.value.ingress_with_cidr_blocks
  egress_with_cidr_blocks = each.value.egress_with_cidr_blocks
}

And I have variable "security-groups" in which I have multiple security groups aligned like this:

variable "security_groups" {
  description = "value"
  type        = map(any)
  default = {
    first-sg = {
      "name"             = "first-sg"
      "description"      = "desc"
      "ingress_with_cidr_blocks"      = [
        {
          from_port   = somePort
          to_port     = somePort
          protocol    = "tcp"
          description      = "first-sg"
          cidr_blocks = "1.0.0.0/16"
        }
      ],
      "egress_with_cidr_blocks"      = []
      "tag"              = "some-sg"
    },
    second-sg = {
      "name"             = "second-sg"
      "description"      = "second-sg"
      "ingress_with_cidr_blocks"      = [
        {
          from_port   = somePort
          to_port     = somePort
          protocol    = "tcp"
          description      = "secod-sg"
          cidr_blocks = "1.2.3.4/32"
        },
        {
          from_port   = somePort
          to_port     = somePort
          protocol    = "tcp"
          description     = "second-sg"
          cidr_blocks = "5.6.7.8/32"
        }
      ],
      "egress_with_cidr_blocks"      = [
        {
          from_port        = 0
          to_port          = 0
          protocol         = "-1"
          cidr_blocks      = "0.0.0.0/0"
        }
      ]
      "tag"              = "some-sg"
    }
 }

And the idea behind this is that I can use official security-group module, and iterate over this variable with for-each, creating multiple security groups with multiple ingress/egress rules.

Now I want to combine this, with my custom vpc_prefix_list which contains some batch of IP's I need to whitelist.

I tried adding ingress_with_prefix_list_ids = [data.aws_ec2_managed_prefix_list.my-prefix-list] to the module, but I've been spinning around all day and not being able to integrate it.

MY QUESTION - Can I integrate both security group solutions to my one module, or not?

My ideal scenario is that I have something like this:

data "aws_ec2_managed_prefix_list" "my-prefix-list" {
  filter {
    name   = "prefix-list-name"
    values = ["my-prefix-name"]
  }
}
module "security_group" {
  source = "terraform-aws-modules/security-group/aws"
  version = "5.1.0"
  for_each         = var.security_groups
  name             = each.value.name
  description      = each.value.description
  vpc_id           = module.vpc.vpc_id
  ingress_with_prefix_list_ids = [data.aws_ec2_managed_prefix_list.my-prefix-list]
  ingress_with_cidr_blocks = each.value.ingress_with_cidr_blocks
  egress_with_cidr_blocks = each.value.egress_with_cidr_blocks
}

And I would create sg's from both data.aws_ec2_managed_prefix_list.my-prefix-list output, and from each.value.ingress_with_cidr_blocks.

The error:

The given value is not suitable for module.security_group["first-sg"].var.ingress_with_prefix_list_ids declared at .terraform/modules/security_group/variables.tf:121,1-40: element 0: map of string required.


Solution

  • UPDATE

    I've resolved the issue by extracting the security group from variables that I wanted to import as prefix list, and created a resource on it's own. Something like this:

    The module stays untouched:

    module "security_group" {
      source = "terraform-aws-modules/security-group/aws"
      version = "5.1.0"
      for_each         = var.security_groups
      name             = each.value.name
      description      = each.value.description
      vpc_id           = module.vpc.vpc_id
      ingress_with_cidr_blocks = each.value.ingress_with_cidr_blocks
      egress_with_cidr_blocks = each.value.egress_with_cidr_blocks
    }
    

    Removed the wanted SG from 'for_each' variable, and move it to a standalone one:

    variable "security_groups" {
      description = "value"
      type        = map(any)
      default = {
        first-sg = {
          "name"             = "first-sg"
          "description"      = "desc"
          "ingress_with_cidr_blocks"      = [
            {
              from_port   = somePort
              to_port     = somePort
              protocol    = "tcp"
              description      = "first-sg"
              cidr_blocks = "1.0.0.0/16"
            }
          ],
          "egress_with_cidr_blocks"      = []
          "tag"              = "some-sg"
        }
     }
    
    variable "standalone-sg" {
      description = "value"
      type        = map(any)
      default = {
            second-sg = {
              from_port   = 443
              to_port     = 443
              protocol    = "tcp"
              description      = "tcp"
              cidr_blocks = "1.2.3.4/32"
          },
        third-sg =  {
              from_port   = 443
              to_port     = 443
              protocol    = "tcp"
              description     = "tcp"
              cidr_blocks = "5.6.7.8/21"
          },
        fourth-sg = {
              from_port   = 5090
              to_port     = 5090
              protocol    = "tcp"
              description     = "tcp"
              cidr_blocks = "9.10.11.12/32"
          }
    }
    

    And create a resource that takes those values:

    resource "aws_security_group" "standalone-sg" {
      vpc_id      = module.vpc.vpc_id
      name        = "standalone-sg"
      description = "Standalone security group"
    
      ingress {
        from_port   = 443
        to_port     = 443
        protocol    = "tcp"
        prefix_list_ids = [data.aws_ec2_managed_prefix_list.first-sg.id, data.aws_ec2_managed_prefix_list.second-sg.id]
      }
    
      ingress {
        from_port        = var.standalone-sg.second-sg.from_port
        to_port          = var.standalone-sg.second-sg.to_port
        protocol         = "${var.standalone-sg.second-sg.protocol}"
        cidr_blocks      = ["${var.standalone-sg.second-sg.cidr_blocks}"]
      }
      ingress {
        from_port        = var.standalone-sg.third-sg.from_port
        to_port          = var.standalone-sg.third-sg.to_port
        protocol         = "${var.standalone-sg.third-sg.protocol}"
        cidr_blocks      = ["${var.standalone-sg.third-sg.cidr_blocks}"]
      }
      ingress {
        from_port        = var.standalone-sg.fourth-sg.from_port
        to_port          = var.standalone-sg.fourth-sg.to_port
        protocol         = "${var.standalone-sg.fourth-sg.protocol}"
        cidr_blocks      = ["${var.standalone-sg.fourth-sg.cidr_blocks}"]
      }
      egress {
        from_port   = 0
        to_port     = 0
        protocol    = "-1"
        cidr_blocks = ["0.0.0.0/0"]
      }
      tags = {
        Name = "standalone-sg"
      }
    }