[Terraform] output, data 블록의 활용 (terraform.tfstate 파일 관리법, 리소스 참조)

나른한 개발자·2023년 3월 14일
2

👉 이전 포스팅: 테라폼 폴더구조 및 블록 쓰임새

이전 포스팅에서는 테라폼에서 많이 쓰이게 되는 블록들의 쓰임새에 대해 알아보았다. 이번 시간에는 output, data를 활용하여 타 디렉터리의 리소스를 참조하는 방법과 terraform.tfstate 파일을 관리하는 방법에 대해 알아보도록 하자.

💡 terraform.tfstate?
terraform 의 설정 파일로, 실제 인프라에 적용되어 있는 리소스의 상태들이 관리되는 파일이다. 리소스를 수정 후 apply 하면 terraform.tfstate파일과 비교하여 달라진 상태를 판단한다.


terraform.tfstate 관리 필요성

이 파일을 관리를 해야하는 이유는 바로 리소스 참조 때문이다. 작은 규모의 프로젝트가 아니라면 보통은 리소스 별로 디렉터리를 나눌 것이다. 이때 디렉터리마다 terraform.tfstate 파일이 생성될테니, ec2 디렉터리에서 vpc 디렉터리 내의 리소스에 접근하려면 리소스가 존재하지 않다고 판단할 것이다. 따라서 타 디렉터리 내의 리소스에 접근하려면 terraform.tfstate 파일을 로컬에서 가져오거나 원격 저장소에 저장해야한다.

.
└──dev
      └── vpc
      └── ec2
      └── rds
└──prod

관리 방법

1. 로컬에서 관리하기

ec2 디렉터리 내에서 vpc 리소스에 접근하려면 우선 다음과 같이 vpc 디렉터리 내의 terraform.tfstate 파일을 가져와야 한다. local의 어느 경로에 위치하는지 path도 지정해준다.
상황은 ec2에서 vpc 내의 리소스에 접근한다고 가정하자.

(1) output 정의

우선 어떤 값을 내보낼지에 대한 정의가 필요하다. vpc라는 이름의 리소스가 이미 정의되어 있다고 할 때, vpc의 id를 내보내도록 하자.

# dev/vpc/outputs.tf

output "vpc_id" {
    value = aws_vpc.vpc.id
}

(2) data로 타 디렉터리의 terraform.tfstate 접근

위와 같이 output을 정의하면 vpc의 terraform.tfstate에 output이 추가될 것이다. 이번에는 ec2 디렉터리에서 vpc의 상태 파일에 접근할 수 있도록 가져오자.

# dev/ec2/data.tf

data "terraform_remote_state" "vpc" {
	backend = "local" {
    	path = "../vpc/terraform.tfstate"
    }
}

이렇게하면 로컬의 vpc디렉터리의 상태파일에 접근하여 vpc_id를 참조할 수 있게 된다.

# dev/ec2/ec2.tf

locals {
  vpc_id = data.terraform_remote_state.vpc.outputs.vpc_id
}

문제점

이 방법은 타 저장소가 아닌 로컬에서 상태파일을 관리하기 때문에 파일 유실 위험이 있고, 리소스 간 순환 참조를 해야하는 경우에는 상태파일이 꼬일 수가 있다. 또한 보통 테라폼도 공동작업을 하기 때문에 작업하고 있는 리소스의 상태가 모두 동일해야하는데, terraform.tfstate는 민감한 정보가 담겨있어 git에 추적되지 않는 것을 권고한다. 이 경우 작업하는 사람마다 상태 파일값이 달라져 안정성이 떨어지고 예기치 않은 변경사항이 생길 수도 있다.

이러한 문제를 피하기 위해 테라폼에서는 원격에서 상태파일을 관리하는 방법을 지원하고 있다.


2. 원격 저장소(S3)에서 관리하기

테라폼에서 지원하는 백엔드는 Azure, etcd, AWS S3, Terraform Enterprise, Google Cloud를 지원하는데, 이 중에서 AWS S3에 저장하는 방법에 대해 알아보자.

(1) 상태 파일을 저장할 S3버킷과 DynamoDB 생성

resource "aws_s3_bucket" "tfstate" {
    bucket = "terraform"
}

resource "aws_dynamodb_table" "tfstate-lock" {
    name = "tfstate-lock"
    hash_key = "LockID"
    billing_mode = "PAY_PER_REQUEST"
    attribute {
      name = "LockID"
      type = "S"
    }
}

여기서 dynamodb 테이블을 같이 생성해주는 이유는 locking을 이용하기 위해서다. Dynamodb locking을 설정해두면 다른 사람이 terraform plan, terraform apply 하고 있을 경우 state lock 에러를 발생시켜 수정이 일어나지 못하게 한다. 이로써 공동 작업으로 상태 값이 꼬이는 것을 방지할 수 있다.

(2) 백엔드 설정하기

# dev/vpc/backend.tf

terraform {
  backend "s3" {
      bucket = "terraform"
      key = "dev/vpc/terraform.tfstate"
      region = "ap-northeast-2"
      dynamodb_table = "tfstate-lock"
      encrypt = true
    }
}

이렇게 설정해두면 terraform apply 후 vpc 디렉터리의 상태파일은 s3의 dev/vpc/~ 이하의 경로에 저장될 것이다.

(3) output, data 설정

이후의 과정은 로컬에 저장했을 때와 동일하다. 다만 data에서 backend 설정을 s3로 바꾸어주기만 하면 vpc_id에 접근할 수 있다.

# dev/vpc/outputs.tf

output "vpc_id" {
    value = aws_vpc.vpc.id
}


# dev/ec2/data.tf

data "terraform_remote_state" "vpc" {
    backend = "s3"
    config = {
      bucket = "terraform"
      key = "dev/vpc/terraform.tfstate"
      region = "ap-northeast-2"
    }
}


# dev/ec2/ec2.tf
locals {
  vpc_id = data.terraform_remote_state.vpc.outputs.vpc_id
}

마치며

오늘은 output, data 블록과 terraform.tfstate 파일을 이용하여 타 리소스에 접근하는 방법에 대해 알아보았다. 이 방법을 알고나면 테라폼을 더 자유로이 활용할 수 있으니 꼭 한번 참고해보았으면 좋겠다.

👉 다음 포스팅: module이란? 사용법 및 주의사항

profile
Start fast to fail fast

0개의 댓글