0
votes

Here, I have been implementing terraform modules for existing terraform script. I have been facing an issue while interacting with arguments of security_group_rules.

The issue is,in aws_security_group_rule, we have two arguments i.e., source_security_group_id & cidr_block which are incompatible with each other. I mean when we use one of it, we can't use another.

This is my module.

main.tf

resource "aws_security_group_rule" "arvn" {
  count = length(var.security_group_rules)

  type              = var.security_group_rules[count.index].type
  from_port         = var.security_group_rules[count.index].from_port
  to_port           = var.security_group_rules[count.index].to_port
  protocol          = var.security_group_rules[count.index].protocol
  cidr_blocks       = var.security_group_rules[count.index].cidr_block
  description       = var.security_group_rules[count.index].description
  security_group_id = var.security_group_id
}

variable.tf

variable "security_group_id" {
  type = string
}

variable "security_group_rules" {
  type = list(object({
    type        = string
    from_port   = number
    to_port     = number
    protocol    = string
    cidr_block  = list(string)
    description = string
  }))
}

usage

sg.tf

module "security_group_ecsInstance" {
  source = "./modules/security_group"
  vpc_id = aws_vpc.arvn.id
  name = "${local.name}-ecsInstance"
}

module "sg_rules_instance" {
  source = "./modules/security_group_rules"
  security_group_id = module.security_group_instance.id
  security_group_rules = [
    { type = "ingress", from_port = 22, to_port = 22, protocol = "tcp", cidr_block = [var.vpc_cidr], description = "ssh"  },
{ type = "egress", from_port = 0, to_port = 65535, protocol = "-1", cidr_block = ["0.0.0.0/0"], description = ""  },
    { type = "ingress", from_port = 0, to_port = 65535, protocol = "tcp", cidr_block = [module.security_group_alb.id], description = "alb"  }
  ]
}

In this, first two rules are being created and last rule is failing because of invalid cidr block.

I'm aware of the issue here however, It would be great if anyone help me in creating more flexible module that can work on both source_security_group_id & cidr_block such that if one is used another should go blind.

1
That helps mentally however, I need technical help :-) - Arvin

1 Answers

1
votes

You can represent the dynamic absence of a resource argument by setting it to null. That means you can define a variable that accepts both arguments as long as one of them is null. For example:

variable "security_group_rules" {
  type = list(object({
    type                     = string
    from_port                = number
    to_port                  = number
    protocol                 = string
    cidr_blocks              = list(string)
    source_security_group_id = string
    description              = string
  }))
}

resource "aws_security_group_rule" "arvn" {
  count = length(var.security_group_rules)

  type                     = var.security_group_rules[count.index].type
  from_port                = var.security_group_rules[count.index].from_port
  to_port                  = var.security_group_rules[count.index].to_port
  protocol                 = var.security_group_rules[count.index].protocol
  cidr_blocks              = var.security_group_rules[count.index].cidr_blocks
  description              = var.security_group_rules[count.index].description
  source_security_group_id = var.security_group_rules[count.index].source_security_group_id
  security_group_id        = var.security_group_id
}

When calling the module, the caller must set either cidr_block or source_security_group_id to null in order to avoid the conflict error:

module "sg_rules_instance" {
  source = "./modules/security_group_rules"

  security_group_id = module.security_group_instance.id
  security_group_rules = [
    {
      type                     = "ingress"
      from_port                = 22
      to_port                  = 22
      protocol                 = "tcp"
      cidr_blocks              = [var.vpc_cidr]
      source_security_group_id = null
      description              = "ssh"
    },
    {
      type                     = "egress"
      from_port                = 0
      to_port                  = 65535
      protocol                 = "-1"
      cidr_blocks              = ["0.0.0.0/0"]
      source_security_group_id = null
      description              = ""
    },
    {
      type                     = "ingress"
      from_port                = 0
      to_port                  = 65535
      protocol                 = "tcp"
      cidr_blocks              = null
      source_security_group_id = module.security_group_alb.id
      description              = "alb"
    },
  ]
}