본문 바로가기
terraform

[terraform] 테라폼 backend, tfstate란

by devjh 2022. 5. 24.
반응형

이번게시글에서는 테라폼의 backend, tfstate에 대해 정리합니다.

 

1. 테라폼의 동작순서와 상태

먼저 테라폼의 동작순서와 .tfstate 에 대해 정리합니다.

 

(1). terraform init

tf파일(provider가 지정되어 있어 어떤 인프라를 관리할지 정해져있는)이 있는곳에서 terraform init 명령어를 입력하면 

provider, module, state 설정을 진행하며 테라폼을 시작하기 위한 준비를 진행합니다.

표면적으로는 .terraform 디렉토리가 생성되며 관련 테라폼 관련 라이브러리 모듈 등을 가져옵니다.(내부에 .tfstate에 정의된 내용도 포함)

인프라 관련 동시성처리를 안전하게 해줄 .terraform.lock.hcl 파일도 생성됩니다.

 

(2). terraform plan

테라폼 코드로 변경될 인프라의 내역을 보여줍니다.

 

(3). terraform apply

테라폼으로 적용한 인프라 상태를 저장한 .tfstate 파일이 생성됩니다.

backend는 저장공간을 지정할때 사용되며 따로 설정하지 않으면 로컬에 terraform.tfstate파일이 생성됩니다.

여러사람과 협업하려면 테라폼으로 관리한 상태정보를 로컬에서 혼자 보관하면 안됩니다.

아래와같은 방법을 사용해서 backend를 지정하면 s3에 .tfstate파일이 저장되어 여러사람과 협업할 수 있습니다.

terraform {
  backend "s3" {
    bucket  = "your-bucket"
    key     = "your-object-name"
    region  = "your region"
    profile = "your profile"
  }
}

추후 다른사람이 terraform init을 하게 되면 .terraform이 생길때 내부에 .tfstate에 정보가 함께 들어가게 되고, terraform plan을 했을때 인프라 상태와 비교할 수 있게 됩니다.  

 

2. tfstate를  다루는 방법

tfstate와 인프라를 일치시키는게 테라폼의 핵심이라고 말할정도로 tfstate는 중요합니다.

아래는 tfstate를 다루는 방법과 주의점입니다.

(1). terraform state 명령어를 사용하기

$ terraform state list

tfstate파일이 s3에 저장되어있을때 해당 명령어로 현재 tfstate파일이 관리하고 있는 인프라들을 확인할 수 있습니다.

list에서 나온 결과물을 이용해서 아래와 같이 활용이 가능합니다.

// tfstate가 관리하는 resource 상세정보 확인하기
$ terraform state show XX

// plan시 원하는 resource만 진행시키기
$ terraform plan -target XX

// apply시 원하는 resource만 apply하기
$ terraform apply -target XX

이 외에도 terraform state에는 다양한 기능을 지원합니다.

terraform state --help 를 입력하여 확인할 수 있습니다.

3. 테라폼을 사용하지 않고 인프라를 변경한 경우

terraform apply를 하게 되면 지정된 provider의 인프라가 변경되고 tfstate에 인프라정보가 저장됩니다.

그러나 aws콘솔이나 aws sdk를 활용한 애플리케이션에 의해 인프라가 변경되는 경우에는 tfstate에는 반영되지 않습니다.

 

(1). 내 테라폼코드로 관리하지 않던 리소스인 경우

terraform import 명령어를 활용합니다.

$ terraform import {테라폼 리소스}.{이름} {실제 인프라에 있는 리소스 이름}

해당 명령어로 테라폼에서 관리를 시작하게 할 수 있습니다.

아래와같이 resource와 이름을 정의해준후 실제 인프라의 리소스를 가져오면 됩니다. (버킷명이 my-bucket-01라고 가정)

resource "aws_s3_bucket" "this" {

}
$ terraform import aws_s3_bucket.this my-bucket-01

 

$ terraform plan

테라폼 import후에는 terraform plan을 합니다. 내 스코프는 비워져 있으므로 뭐가 없어질꺼라는 경고창이 뜨면 채워줍니다.

 

$ terraform state show aws_s3_bucket.this 
terraform plan에서 모든 설정을 반영해주는것은 아닙니다.

해당 명령어를 통해 state파일을 확인하고 내가 설정한 셋팅은 모두 실제 테라폼 코드에 모두 옮겨주는것이 좋습니다.(default 설정이 아닌경우 모두 옮겨주도록 합니다)

 

(2). 테라폼코드로 관리하던 리소스인 경우

테라폼 코드로 관리하던 리소스를 외부에서 변경한 경우,

tfstate파일과 실제 인프라가 다르기 때문에 plan단계에서 아래와 같은 로그가 떨어집니다.

aws_s3_bucket.this: Refreshing state... 



Note: Objects have changed outside of Terraform

Terraform detected the following changes made outside of Terraform since the last "terraform apply":

Note: Objects have changed outside of Terraform

기존에 관리하던 리소스라면 외부에서 변경된걸 테라폼이 알고있습니다.

그 아래에는 외부에서 변경한 변경사항을 보여줍니다(외부에서 변경된 점을 +로 보여줍니다. 내 테라폼 코드에 의해 추가된다는 얘기가 아니니 plan으로 인해 변경될 것을 보여준 것으로 착각하지 않도록 주의합니다)

 

plan단계에서 외부에서 생긴 변경을 보여준후에는 테라폼은 실제 인프라에 적용됐을때 일어날 변경점을 두가지 케이스로 보여줍니다.

 

A. 내가 관리하던 리소스인데 맘대로 추가 or 변경했어? -> 이거 그대로 apply하면 외부에서 만든거 삭제시킬꺼야

외부에서 변경한점들이 마이너스기호로 표시되며 삭제될꺼라고 알려줍니다.

이제 그 부분을 복사해서 terraform 코드에 추가하면 테라폼 코드, 인프라, tfstate가 일치하게 됩니다.

 

B. 내가 관리하던 리소스에 외부에서 뭔가를 추가했구나 -> 이거 테라폼코드로 쓸라면 힘들지..? 우리도 모든걸 관리하게 하지는 않아, 일부는 내가 state 파일에 넣어주기도 해(0.15.4 버전 이상의 테라폼)

No changes. Your infrastructure matches the configuration.

 

B 가 진행됐을때 테라폼 코드를 수정하지 않고 terraform apply 를 적용하더라도 state 파일에 인프라 정보가 올라가게 됩니다.

 

A vs B

둘다 tfstate와 실제 인프라는 동일한 상태지만

개인적인 생각으로 B는 이상적인 상황이 아닌것 같습니다.

 

tfstate와 테라폼 코드가 100프로 일치할수는 없지만(디폴트 설정 들도 모두 tfstate에 올라감)

테라폼 코드를 그대로 재 사용했을때 두개의 인프라는 동일한 인프라여야 유지보수하기가 편합니다.

반응형

댓글