본문 바로가기
공부/IaC

[Terraform] 메타변수 count로 반복문, 조건문 사용하기

by haejang 2021. 3. 26.
728x90
728x90

 

테라폼은 count라는 메타 변수를 사용해서 반복문과 조건문을 구현할 수 있다

리소스나 모듈에 count를 지정해주면 그 수만큼 반복을 하며, index라는 object를 사용할 수 있다

근데 내가 생각하는 것들을 구현하기엔 한계가 있었다 (내 능력 부족일수도...)

일단 해보자!

 


1. 반복문

처음에 내가 생각했던건 모듈을 불러올 때 숫자를 입력받아서 count로 지정해주고, 그 숫자만큼 모듈 내의 리소스가 반복 생성되면서 원하는 변수들을 반복 입력받는 형태였다

 

처음에 원했던 구조

 

이렇게 하고 싶었던 이유는 모듈이 반복될 때 마다 새로운 변수를 입력받길 원했기 때문이다

모듈에만 입력 변수를 정의해두면 모듈 내의 리소스 구문이 실행될 때 마다 변수를 입력받을거라고 생각했다

 

그러나...

 

 

모듈에서 사용할 변수는 실행 문서에서 정의를 해줘야했다 어이없어

여러 고민을 해봤지만 반복적으로 입력을 받는 구조는 불가능할거같아서...결국 모듈에서 count를 정의한 후 리스트 형태의 변수를 미리 정의해 사용하기로 했다

 

stage/vpc/main.tf

provider "aws" {
  region = "ap-northeast-2"
}

module "vpc" {
  source = "./module/vpc"
  count  = length(var.vpc_cidr)

  number   = count.index
  alltag   = var.alltag
  vpc_cidr = element(var.vpc_cidr, count.index)
}

variable "alltag" {
  default = "honglab"
}

variable "vpc_cidr" {
  description = "VPC CIDR BLOCK LIST"
  default     = ["10.0.0.0/16", "10.10.0.0/16"]
}

module/vpc/main.tf

resource "aws_vpc" "vpc" {
  cidr_block           = var.vpc_cidr
  enable_dns_hostnames = true

  tags = {
    Name = "${var.alltag}-vpc-${var.number}"
  }
}

variable "vpc_cidr" {}
variable "alltag" {}
variable "number" {}

vpc_cidr 변수를 리스트 형식으로 만들고 만들어야 할 vpc 대역들을 미리 정의해주면, 그 숫자만큼 반복하면서 vpc를 만들도록 했다

 

 

이대로 실행해보면

 

vpc 2개가 만들어진다

원하는 대로 태깅까지 적용된 vpc 2개가 생성되었다

 

2. 조건문

count가 0이면 해당 리소스는 생성을 안한다는걸 이용하면 된다

 

서브넷을 생성할 때, 자동으로 해당 서브넷과 연결된 라우팅 테이블을 같이 생성하되, public인 경우에만 igw 경로를 추가해주고싶다

지난 글에서 사용한 모듈을 조금 바꿔서 사용해보겠다

지난번엔 subnet 모듈과 rtb 모듈을 별개로 진행했었지만, rtb 모듈을 삭제하고 subnet 모듈을 아래와 같이 수정했다

module/subnet/main.tf

resource "aws_subnet" "subnet" {
  vpc_id                  = var.vpc_id
  cidr_block              = var.public_subnet_cidr
  availability_zone       = var.public_subnet_az
  map_public_ip_on_launch = var.is_public

  tags = {
    Name = "${var.alltag}-subnet-${var.public_or_private[var.is_public]}"
  }
}

resource "aws_route_table" "rtb" {
  vpc_id = var.vpc_id

  tags = {
    Name = "${var.alltag}-rtb-${var.public_or_private[var.is_public]}"
  }
}

resource "aws_route" "rtb" {
  count                  = var.is_public ? 1 : 0
  route_table_id         = aws_route_table.rtb.id
  destination_cidr_block = "0.0.0.0/0"
  gateway_id             = var.igw_id
}

resource "aws_route_table_association" "rtb" {
  subnet_id      = aws_subnet.subnet.id
  route_table_id = aws_route_table.rtb.id
}

is_public 변수가 true일 때 1을, flase일 때 0을 반환하도록 했다 (삼항 구문 사용)

그걸 aws_route 구문의 count에다가 적용해서 모듈 실행 시 public 서브넷인 경우에만 igw가 연결된 경로가 붙어져서 나온다

전체 코드는 깃헙을 참고하자 (지난 글과 크게 다르지 않다)

 

아무튼 이대로 stage에서 apply를 실행해주면

 

 

원하는대로 public 라우팅 테이블에만 igw가 붙어있다

 

728x90
728x90

댓글