인프라스트럭처를 코드로 다루는 소프트웨어 전문가로서, 당신은 아마도 많은 작업을 Terraform과 함께 진행할 것입니다. 새로운 고객을 도와 IaC를 사용하게 하려면 간단히 만드는 것이 일반적이지만, Terraform 상태 파일을 관리하는 것이 첫 번째 과제입니다. 기본적으로 Terraform 상태에는 민감한 정보가 포함되어 있으며, 소스 제어에 저장되어서는 안 되지만, 동시에 동일한 Terraform 상태에서 여러 사용자가 작업하는 경우 확장되지 않습니다. 그 해답은? 백엔드입니다.
핵심적으로, 해당 상태 파일을 S3 버킷에 저장하고 DynamoDB를 사용하여 잠금 상태를 관리할 수 있다는 점에 유의해야 합니다. 그러나 이러한 접근 방식은 추가 리소스를 생성하도록 강제하여 특히 고객이 GitLab을 사용하는 경우 복잡한 옵션이 됩니다. GitLab은 최근에 Terraform을 통합하기 위한 진입 장벽을 낮추기 위해 Terraform 상태를 저장하고 관리하는 방법 및 이에 대한 CI를 설정하는 간단한 방법을 제공했습니다.
이 기사에서는 Terraform 상태 파일이 무엇인지, 어떻게 GitLab에 마이그레이션하는지, 그리고 CI 파이프라인을 설정하는 방법을 설명합니다. 저희 저장소를 방문하시려면 여기를 클릭하세요.
목차
- Terraform 상태란?
- GitLab이 Terraform 상태를 관리하게 하는 방법
- GitLab이 IaC를 CI 파이프라인을 통해 실행하게 하는 방법
- 보너스 팁: Infracost
- 결론
Terraform 상태란?
Terraform은 코드에 정의된 인프라에 대한 정보를 상태 파일을 통해 기록합니다. JSON으로 작성되어 있으며, 기본적으로 Terraform 코드에서 생성된 실제 리소스로의 매핑을 기록합니다. 아래는 terraform.tfstate
가 어떻게 보이는지 예시입니다. 주로, Terraform을 실행할 때마다 최신 상태의 EC2 인스턴스를 가져와 Terraform 구성과 비교하여 어떤 변경이 필요한지 결정합니다:
{
"version": 4,
"terraform_version": "0.12.0",
"serial": 1,
"lineage": "1f2087f9-4b3c-1b66-65db-8b78faafc6fb",
"outputs": {},
"resources": [
{
"mode": "managed",
"type": "aws_instance",
"name": "example",
"provider": "provider.aws",
"instances": [
{
"schema_version": 1,
"attributes": {
"ami": "ami-0c55b159cbfafe1f0",
"availability_zone": "us-west-2a",
"id": "i-00a123a0accffffff",
"instance_state": "running",
"instance_type": "t2.micro",
"(...)": "(truncated)"
}
}
]
}
]
}
기본적으로 이 terraform.tfstate
는 Terraform 파일, 계획 및 변경 사항을 적용하는 로컬 위치에 저장됩니다. 개인 프로젝트에서 일부 테스트를 실행하는 경우 괜찮지만 추천되는 방식은 아닙니다. 그 이유는 다음과 같습니다:
- 공유 위치에 저장됨: 이 상태 파일을 로컬 워크스테이션에 호스팅하고 다른 엔지니어와 함께 작업해야 한다면 상황이 복잡해집니다. 둘 다 최신 버전의 상태를 사용하고 있는지 확인해야 하며, 동시에 Terraform 계획이나 적용을 실행하면 경쟁 조건이 발생할 수 있습니다.
- 민감한 정보 보호: 생성된 상태 파일은 암호화 키와 인프라 비밀번호를 포함할 수 있습니다. 그러나 상태 파일은 기본적으로 암호화되지 않으며, 일반 텍스트로 민감한 정보를 저장하는 것은 좋지 않습니다.
- 잠금: 대부분의 버전 관리 시스템은 잠금 기능을 지원하지 않으므로, 두 명의 팀원이 동일한 상태 파일에 대해 Terraform 적용을 동시에 실행하는 것을 방지합니다. 이것은 상태 파일이 소스 제어에 의해 관리되지 않을 또 다른 이유입니다.
테라폼 상태를 관리하기 위해 깃랩 사용하기
클라우드 인프라 프로비저닝에서 테라폼이 표준으로 인정되면서, 깃랩에서 테라폼 상태를 저장하고 관리할 수 있는 방법을 제공하기 시작한 지 일 년 정도 되었습니다. 따라서 최근 저희가 깃랩을 사용하여 IaC를 관리하기 시작한 과정을 공유하고자 합니다.
이 글에서는 로컬 상태를 사용하고 있으며, AWS S3 버킷이나 다른 백엔드 솔루션으로 상태를 관리하고 있다고 가정합니다.
먼저, backend.tf
를 HTTP를 사용하도록 변경해야 합니다.
terraform {
backend "http" {}
}
다음으로, 터미널에서 네 가지 변수를 설정해야 합니다:
1. PROJECT_ID
: 이 정보는 “프로젝트 개요” 페이지에서 쉽게 찾을 수 있습니다.
2. TF_USERNAME
: 작업 중인 레포지토리에 접근할 수 있는 깃랩 사용자 이름.
3. TF_PASSWORD
: 깃랩 사용자로부터 생성된 액세스 토큰.
4. TF_ADDRESS
: 원격 상태 백엔드의 URL.
PROJECT_ID="28450092"
TF_USERNAME="florianpialoux"
TF_PASSWORD="123456789"
TF_ADDRESS="https://gitlab.com/api/v4/projects/${PROJECT_ID}/terraform/state/aws-buckets"
이제 다음 명령어를 실행하여 테라폼 상태를 이전 위치에서 깃랩으로 이전할 수 있습니다:
terraform init \
-migrate-state \
-backend-config=address=${TF_ADDRESS} \
-backend-config=lock_address=${TF_ADDRESS}/lock \
-backend-config=unlock_address=${TF_ADDRESS}/lock \
-backend-config=username=${TF_USERNAME} \
-backend-config=password=${TF_PASSWORD} \
-backend-config=lock_method=POST \
-backend-config=unlock_method=DELETE \
-backend-config=retry_wait_min=5
깃랩이 상태 파일을 관리하기 시작할 수 있도록 “예”를 입력하여 확인을 제공해야 합니다. 로컬 상태에서 깃랩으로의 예시는 다음과 같습니다:
S3에서 깃랩으로의 예시:

I noticed for some of the state files I had from S3 will be blank even after using the migrate-state
command ran previously. In this case, you can run this:
terraform state pull > aws-buckets.json
S3 상태의 내용을 복사하여 푸시를 실행합니다.
terraform state push -lock=true aws-buckets.json
GitLab은 테라폼 상태 파일에 대한 버전 관리를 지원하지만, 웹 UI를 통해 이전 버전을 보거나 복원하려면 GitLab 프리미엄 플랜을 사용하고 있어야 합니다. 그렇지 않으면 GraphQL API 요청을 해야 합니다.
CI 파이프라인을 통해 IaC를 실행하도록 GitLab 설정하는 방법
GitLab은 공식 Terraform 바이너리를 감싼 얇은 래퍼 스크립트인 GitLab-Terraform을 포함하는 Docker 이미지를 제공합니다. 또는 Hashicorp가 제공하는 공식 Docker 이미지를 사용할 수도 있습니다. GitLab Terraform 이미지에 대한 자세한 내용은 여기에서 확인하실 수 있습니다.
Terraform apply 작업이 실행되면 상태가 언제 사용되었고 어떤 파이프라인과 함께 사용되었는지 볼 수 있습니다.
gitlab-ci.yml
looks like here. Below, are the variables that will need to be defined on the project level.보너스 팁: Infracost
우리의 gitlab-ci.yaml
을 살펴보면 Infracost를 추가했음을 알 수 있습니다. Infracost는 IaC에 새 리소스를 정의할 때마다 비용 추정치를 제공하여 클라우드 대금 청구에 대한 제어를 더 많이 확보할 수 있게 해줍니다.
결론
Terraform 상태와 CI가 GitLab에서 실행되는 것은 GitOps 모범 사례를 따르는 훌륭한 방법입니다. 둘은 IaC를 개발 및 배포하기에 훌륭한 조합입니다. 대부분의 분들이 이미 저장소를 위해 GitLab을 사용하고 계실테니, IaC를 한 곳에서 관리하고 GitLab이 트래픽 중 암호화와 휴지 상태에서의 암호화를 지원하면서 상태의 버전 관리, 잠금 및 잠금 해제를 담당하게 하는 것이 훨씬 간단해집니다.
Source:
https://dzone.com/articles/how-to-migrate-terraform-state-to-gitlab-cicd