DevOps

[ IaC ] Terraform이란?

궁금한게 많은 개발자 2023. 10. 10. 17:16

Terraform은 선언적(declarative) 방식으로 인프라를 관리하는 도구입니다. 선언적이란 원하는 결과(state)를 명시하면, Terraform이 그 결과를 달성하기 위해 필요한 일련의 작업들을 자동으로 수행한다는 의미입니다. 선언적인 방식은 인프라 관리를 단순화하고, 일관성을 유지할 수 있게 도와줍니다. 또한, 변경 내역을 추적하기도 용이합니다. 

예를 들어, Terraform으로 AWS EC2 인스턴스를 생성한다고 가정해보겠습니다. 이때 우리는 EC2 인스턴스의 속성들을 Terraform 구성에 선언적으로 명시합니다. 그리고 Terraform을 실행하면, Terraform이 EC2 인스턴스를 생성하고, 필요한 보안 그룹, 키페어 등을 모두 자동으로 설정해줍니다.

Terraform은 자체적인 DSL(Domain Specific Language)을 사용합니다. DSL은 특정 분야에 특화된 언어를 말하며, Terraform에서는 HCL(HashiCorp Configuration Language)이라는 DSL을 사용합니다.

HCL은 Terraform을 위해 개발된 언어이며, HCL은 JSON과 유사한 구문을 사용하며, 구조화된 데이터를 표현하기 적합합니다. 그러나 HCL은 JSON보다 가독성이 높고 유연하다는 장점이 있습니다. 
또한, HCL에서는 변수와 함수를 사용할 수 있어서, 코드를 재사용하고 유연하게 구성할 수 있습니다. (변수, 함수, 조건문, 반복문 등을 사용할 수 있어, 복잡한 구성을 쉽게 표현할 수 있습니다.)
예를 들어, Terraform 파일에서 AWS EC2 인스턴스를 생성하는 작업은 다음과 같이 작성됩니다.

<block name> <resource type name> <resource name(logical)> {
    key1 = value1
    key2 = value2
    # arguments
}
# resource type name => provider name + "_" + resource type


resource "aws_instance" "example" {  
  ami = "ami-0c55b159cbfafe1f0"  
  instance_type = "t2.micro"  
}

 

위 Terraform 파일에서는 EC2 인스턴스를 생성하고, AMI ID와 인스턴스 유형을 설정하는 작업을 명시하고 있습니다. HCL에서는 resource 키워드로 리소스를 정의하고, aws_instance로 리소스 타입을 지정합니다. example는 리소스 이름을 나타내며, 중괄호 안에는 리소스의 속성을 설정합니다.

 

 

 

Terraform은 크게 세 가지 주요 명령어를 사용하여 인프라를 관리합니다: init, plan, apply.

init: 이 명령어는 Terraform 구성을 초기화하는 데 사용됩니다. 이 단계에서 Terraform이 구성을 이해하고, provider(aws, gcp, azure, local, etc)들이 필요한 플러그인과 모듈을 registry로 부터 다운로드합니다.또한, .terraform 디렉토리를 생성하여 이전에 다운로드한 리소스를 캐시합니다. (version 명시를 통해 lock down configuration file가능)

# configuration file은 하나일 필요 없으며 한 파일에 여러 resource block이 존재할 수 있습니다.

(주로, main.tf, variables.tf, outputs.tf, provider.tf등으로 구성) # init명령 후 .terraform.*파일들이 생성


plan: 이 명령어는 인프라 변경을 계획하는 데 사용됩니다. Terraform 파일에 변경사항을 작성한 후, plan 명령을 실행하면 Terraform이 변경 사항을 검토하고, 인프라에 어떤 변경이 생길지 보여줍니다. 이 단계에서는 실제 인프라 변경이 일어나지 않습니다. 단지 예상되는 변경사항만 보여주는 것입니다.
apply: 이 명령어는 실제로 인프라 변경을 적용하는 데 사용됩니다. plan 단계에서 검토한 변경사항을 실제로 적용합니다. 이 단계에서는 Terraform이 필요한 리소스를 만들고, 변경사항을 인프라에 반영합니다.
따라서, 일반적인 Terraform 워크플로우는 다음과 같습니다. 먼저, init 명령을 사용하여 구성을 초기화합니다. 그 다음, plan 명령을 사용하여 변경사항을 계획하고, apply 명령을 사용하여 변경사항을 실제로 적용합니다.
# 간단한 변경 사항이 있을지라도 old resource는 제거되고 new resource는 새로 생성됩니다. 이러한 특성을 가진 terraform은 immutable infrastructure로 분류됩니다.

 

또한 인프라를 관리하기 위해 .tfstate 파일을 사용합니다. 이 파일은 Terraform이 관리하는 리소스의 현재 상태를 저장하는 파일입니다. apply명령 후에 생성되며 .tfstate 파일을 사용하여 이전 state와 현재 state를 비교하고, 변경 내역을 추적합니다.

.tfstate 파일에는 다음과 같은 정보가 포함됩니다:

  • 리소스의 종류, 이름, 속성 등
  • 리소스가 생성된 시간, 변경된 시간 등
  • 리소스와 관련된 다른 리소스에 대한 정보

tfstate 파일을 사용하여 다음을 수행합니다:

  • 이전 state와 현재 state를 비교하여, 변경 내역을 파악합니다.
  • 필요한 리소스를 만들고, 불필요한 리소스를 삭제합니다.
  • 인프라 관리에 필요한 정보를 제공합니다.

.tfstate 파일은 일반적으로 버전 관리 시스템(VCS)에 포함되지 않으며, 대신 별도의 백엔드(ex: S3 버킷)에 저장됩니다. 이를 통해 Terraform 구성을 안전하게 보관할 수 있으며, 여러 사용자가 동시에 작업을 수행할 때도 동기화를 유지할 수 있습니다.

# 인프라에 대한 중요한 정보를 담고 있으므로 보안 상의 이유로 VCS에 포함하지 않을 수 있으나, 팀에서 협업을 통해 Infra를 구성하는 경우 같은 파일을 사용하여 작업을 수행할 경우 VCS에 포함하여 변경 내용을 쉽게 파악할 수 있습니다.

또한, Terraform은 .tfstate 파일을 기반으로 자동 복구 기능을 제공합니다. 만약 인프라가 예기치 않게 변경될 경우, Terraform은 이전 state를 참고하여 인프라를 다시 구성할 수 있습니다. 이를 통해 우리는 인프라 변경 내역을 쉽게 파악하고, 필요한 경우 이전 상태로 돌아갈 수 있습니다.

 

 

.terraform디렉토리와 .terraform.lock.hcl파일은 어떤 것인지 알아보고자 합니다.

둘 다 init명령 후에 생성되며, .terraform 폴더 내부의 providers 폴더는 Terraform이 provider에서 필요한 플러그인을 설치하고 관리하는 데 중요한 역할을 합니다. 그 이외에도 재 사용 가능한 구성 요소를 정의하는 modules폴더, 이전 실행 결과를 캐싱하여 다음 실행에 사용하는 cache폴더 등이 존재합니다.

 

.terraform.lock.hcl파일은 terraform이 모듈을 다운로드할 때 사용하는 잠금 파일로, 모듈 다운로드 시 필요한 정확한 버전 정보와 다른 의존성 정보를 포함합니다. 이는 해당 파일을 사용하여 모듈 버전을 잠그고 지정된 버전의 모듈만 다운로드 받게 하여 모듈 간 버전 충돌을 해결해줄 수 있으며, 여러 사람이 terraform을 사용할 때 같은 환경을 제공하는데에 사용됩니다.