IaC

Terraform - (7) Advanced

Operation CWAL 2021. 6. 19. 18:50

리소스 간의 의존성(Dependency) 처리

Terraform 리소스 정의 순서에 관계없이, 의존성을 위해 특정 리소스를 먼저 생성해야 할 필요가 있다. 예를 들어, VPC를 추가한 후 ec2 인스턴스를 해당 VPC 안에 생성하는 동작을 수행하는 경우이다. 이를 위해 Terraform은 resource 블록 안에 'depends_on' 필드를 설정하여, 다른 리소스에 의존성이 있는 것을 명시할 수 있다.

 

다음은 ec2 인스턴스 'web'과 'db'를 생성하는 main.tf 이다. 'web' 인스턴스는 'db' 인스턴스에 의존성이 있기 때문에 반드시 'db' 인스턴스가 먼저 생성되어야 한다.

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

resource "aws_instance" "db" {
    ami = "ami-0094965d55b3bb1ff"
    instance_type = "t2.micro"
}

resource "aws_instance" "web" {
    ami = "ami-0094965d55b3bb1ff"
    instance_type = "t2.micro"

    depends_on = [
      aws_instance.db
    ]
}

'depends_on' 필드에 해당 리소스가 의존하는 다른 리소스의 ID를 명시함으로써 간단하게 생성 순서를 설정 가능하다. 실제 'terraform apply' 명령어 실행시 'db' 인스턴스가 'web' 인스턴스에 앞서 생성되는 것을 볼 수 있다.

terraform apply

리소스 제거는 생성의 역순으로 'terraform destroy' 명령어 실행시, 'web' 인스턴스가 먼제 삭제되고 그 다음에 'db' 인스턴스가 제거된다.

terraform destroy

동일한 리소스 여러개 생성하기

Terraform을 통해 동일한 속성의 리소스를 여러개 생성할 수 있다. 물론, resource 블록을 복사/붙여넣기하는 방식이 아니라, 'count' 값을 설정하는 것만으로 가능하다. 예를 들어, 동일한 ec2 인스턴스를 3개 생성한다고 가정하면, 다음과 같은 main.tf 파일을 정의할 수 있다.

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

resource "aws_instance" "ec2" {
    ami = "ami-0094965d55b3bb1ff"
    instance_type = "t2.micro"
    count = 3
}

한가지 재밌는 점은 'count'를 설정하여 리소스를 정의하는 경우, 병렬로 생성/제거작업이 진행된다는 것이다.

terraform apply
terraform destroy

 

이번엔 'count'를 보다 세련되게 사용하는 방법을 알아보자. 이전 시간에 Module에 대해 배워본 적이 있다. 이번엔 Module을 사용하여 여러개의 ec2 인스턴스를 사용하되, 사전에 준비한 list(string) 타입의 variable을 통해 각각의 이름을 지정하고 싶다. 먼저 ec2/ec2.tf 파일을 다음과 같이 작성한다.

variable "ec2_names" {
    type = list(string)
}
resource "aws_instance" "ec2" {
    ami = "ami-0094965d55b3bb1ff"
    instance_type = "t2.micro"
    count = length(var.ec2_names)
    tags = {
        Name = var.ec2_names[count.index]
    }
}

output "instance_ids" {
    value = [aws_instance.ec2.*.id]
}

ec2 인스턴스의 경우, 'var.ec2_names'의 길이만큼 count 값을 설정하게 하였다. 그리고 각각의 인스턴스는 'count.index'를 인덱스로 사용하여, 'var.ec2_names'에서 이름을 가져올 수 있다. 'output.instance_ids'의 경우, '*'를 통해 모든 aws_instance.ec2 리스트의 모든 id값을 접근 가능하다.

 

다음은 main.tf 이다. 기존과 거의 동일하며, 'ec2module'의 'ec2_names' 변수에 list(string) 타입의 값을 할당하는 부분이 변경되었다. 길이가 4이므로 4개의 ec2 인스턴스가 생성될 것이며, 각각 문자열에 해당하는 이름을 가져야 한다. 그리고 'module_output'을 통해 'ec2module'에서 설정한 'instance_ids'가 출력된다.

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

module "ec2module" {
    source = "./ec2"
    ec2_names = ["hello","world","foo","bar"]
}

output "module_output" {
    value = module.ec2module.instance_ids
}

 

다음은 'terraform apply' 명령어를 실행한 결과이다. 4개의 인스턴스가 생성되었으며, 각 인스턴스의 ID를 list 타입으로 출력하고 있다.

EC2 대시보드에서 각 인스턴스의 이름을 확인해볼 차례이다. 각각 'hello', 'world', 'foo', 'bar'로 설정된 것을 볼 수 있다.

 

'count'의 보다 자세한 사용 방법은 Terraform 공식 문서에서 확인 가능하다.

 

The count Meta-Argument - Configuration Language - Terraform by HashiCorp

Terraform by HashiCorp

www.terraform.io

 

Variable File

Prod, Dev 등의 환경에 따라 인스턴스 타입이나 갯수 등 인프라 구성에 차이가 발생할 수 있다. 이런 경우, 굳이 Terraform 프로젝트를 따로 가져가는 것보다, Variable을 나누어 별도 파일로 관리하는 방법을 적용할 수 있다. 우선 다음과 같이 main.tf를 작성하자.

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

variable "number_of_instances" {
    type = number
}

resource "aws_instance" "ec2" {
    ami = "ami-0094965d55b3bb1ff"
    instance_type = "t2.micro"
    count = var.number_of_instances
}

var.number_of_instances" 갯수만큼 't2.micro' 타입 인스턴스를 생성한다. 그럼 var.number_of_instances 값을 어디서 가져오는지 궁금해진다. 같은 경로에 test.tfvars 파일을 아래와 같이 추가해보자.

number_of_instances = 2

 

이제 실제 리소스를 생성해볼 차례이다. 기존 명령어와는 달리 '-var-file' 옵션을 추가해야 한다. test.tfvars 파일을 사용한다면 'apply' 명령어는 다음과 같다. 인스턴스 2개가 생성되는지 확인해보자.

terraform apply -var-file=test.tfvars

 

'IaC' 카테고리의 다른 글

Terraform - Azure(2)  (0) 2022.03.13
Terraform - Azure(1)  (0) 2022.03.11
Terraform - (6) IAM  (0) 2021.06.18
Terraform - (5) Modules  (0) 2021.06.10
Terraform - (4) 기본 AWS 리소스  (0) 2021.06.08