единый модуль terraform для зависимых сетей аргументов

#terraform #terraform-provider-aws #terraform-modules

#terraform #terraform-provider-aws #terraform-модули

Вопрос:

Здесь я внедрял модули terraform для существующего сценария terraform. Я столкнулся с проблемой при взаимодействии с аргументами security_group_rules .

Проблема в том, что в aws_security_group_rule у нас есть два аргумента, т.Е. source_security_group_id и cidr_block, которые несовместимы друг с другом. Я имею в виду, что когда мы используем один из них, мы не можем использовать другой.

Это мой модуль.

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
  }))
}
 

использование

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"  }
  ]
}
 

При этом создаются первые два правила, а последнее правило не выполняется из-за недопустимого блока cidr.

Однако я знаю о проблеме здесь, было бы здорово, если бы кто-нибудь помог мне в создании более гибкого модуля, который может работать как с source_security_group_id, так и с cidr_block, так что, если используется один, другой должен ослепнуть.

Комментарии:

1. Однако это помогает мысленно, мне нужна техническая помощь 🙂

Ответ №1:

Вы можете представить динамическое отсутствие аргумента ресурса, установив для него значение null . Это означает, что вы можете определить переменную, которая принимает оба аргумента, если один из них равен null. Например:

 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
}
 

При вызове модуля вызывающий должен установить либо cidr_block или source_security_group_id в значение null, чтобы избежать ошибки конфликта:

 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"
    },
  ]
}