본문 바로가기
공부/IaC

[Terraform on AWS] CSV 파일 참조해서 Security Group Rule 만들기

by haejang 2021. 10. 10.
728x90
728x90

 

 

CSV 파일 형식

 

module/main.tf

variable "sg_id" {}
variable "rule_type" {} # ingress / egress
variable "from_port" {}
variable "to_port" {}
variable "protocol" {} # tcp / udp / icmp
variable "src_or_dst_type" {} # cidr(list) / pl(list) / sg
variable "destination" {}
variable "description" {}

# Rule with CIDR Blocks
resource "aws_security_group_rule" "sg_cidr_rule" {
  count = var.src_or_dst_type == "cidr" ? 1:0
  type              = var.rule_type
  from_port         = var.from_port
  to_port           = var.to_port
  protocol          = var.protocol
  cidr_blocks       = [var.destination]
  security_group_id = var.sg_id
  description       = var.description
}

# Rule with Prefix List
resource "aws_security_group_rule" "sg_pl_rule" {
  count = var.src_or_dst_type == "pl" ? 1:0
  type              = var.rule_type
  from_port         = var.from_port
  to_port           = var.to_port
  protocol          = var.protocol
  prefix_list_ids   = [var.destination]
  security_group_id = var.sg_id
  description       = var.description
}

# Rule with Security Group
resource "aws_security_group_rule" "sg_sg_rule" {
  count = var.src_or_dst_type == "sg" ? 1:0
  type              = var.rule_type
  from_port         = var.from_port
  to_port           = var.to_port
  protocol          = var.protocol
  source_security_group_id   = var.destination
  security_group_id = var.sg_id
  description       = var.description
}

 

main.tf

locals {
    sg_csv = file("./csv_file.csv")
    sg_rules = csvdecode(local.sg_csv)
}

module "sg_rule" {
    source          = "./module"
    for_each        = { for rule in local.sg_rules : rule.key=> rule }
    sg_id           = aws_security_group.sg_group.id
    rule_type       = each.value.rule_type
    from_port       = each.value.from_port
    to_port         = each.value.to_port
    protocol        = each.value.protocol
    src_or_dst_type = each.value.src_or_dst_type
    destination     = each.value.src_or_dst
    description     = each.value.desc
}

 

Routing Module 만들 때 처럼, Security Group도 넣는 src나 destination에 따라 리소스 옵션이 달라지기 때문에 Module 내에서 Case문을 구현해뒀다

 

실제론 여러개의 보안그룹을 각각의 csv 파일로 관리하기 위해 모듈의 모듈 형식으로 구현해서 사용 중이다

 

 

+ 21/11/5 추가

security rule module을 저렇게 나눌 필요가 없었다 - 함수를 사용하면 됨

resource "aws_security_group_rule" "sg_rule" {
  for_each          = { for rule in var.sg_rules : rule.key=> rule }
  security_group_id = var.sg_group.id
  type              = each.value.rule_type
  from_port         = each.value.from_port
  to_port           = each.value.to_port
  protocol          = each.value.protocol
  cidr_blocks = length(regexall("[a-z]",each.value.src_or_dst)) == 0 ? [each.value.src_or_dst] : null
  prefix_list_ids = substr(each.value.src_or_dst,0,2) == "pl" ? [each.value.src_or_dst] : null
  source_security_group_id = contains(var.sg_id_list, each.value.src_or_dst) ? var.sg_id_list["${each.value.src_or_dst}"] : null
  self = each.value.src_or_dst == "self" ? true : null
  description       = lookup(each.value, "desc", null)
}

이렇게 하면 csv 파일에 src_or_dst_type 을 제외하고 작성해도 된다

그러나 문제는 다른 보안그룹을 참조시킬 때, 직접 보안그룹의 id를 적어줘야 한다는 점이다....

이 부분은 그냥 따로 구성해야 하나 싶다

 

 

 

 

728x90
728x90

댓글