GitLab 관리 Terraform 상태

Tier: Free, Premium, Ultimate Offering: GitLab.com, 자체 관리, GitLab 전용

Terraform은 인프라 구성에 대한 세부 정보를 저장하는 상태 파일을 사용합니다.
Terraform 원격 백엔드를 사용하면 상태 파일을 원격 및 공유 저장소에 저장할 수 있습니다.

GitLab은 상태 파일을 최소한의 구성으로 안전하게 저장하는 Terraform HTTP 백엔드를 제공합니다.

GitLab에서는 다음을 할 수 있습니다:

  • Terraform 상태 파일 버전 관리
  • 상태 파일을 전송 및 휴식 중 암호화
  • 상태를 잠그고 잠금 해제
  • 원격으로 terraform planterraform apply 명령 실행

경고: 재해 복구 계획 Terraform 상태 파일은 디스크 및 객체 저장소에서 휴식 중에 lockbox Ruby gem으로 암호화됩니다.
상태 파일을 해독하려면 GitLab을 사용할 수 있어야 합니다.
오프라인 상태이고 GitLab이 GitLab이 필요로 하는 인프라를 배포하는 경우 (가상 머신, Kubernetes 클러스터 또는 네트워크 구성 요소 등) 상태 파일에 쉽게 액세스하거나 해독할 수 없습니다.
또한, GitLab이 GitLab을 부트스트래핑하는 데 필요한 Terraform 모듈 또는 기타 종속 항목을 제공하는 경우 이러한 항목에 액세스할 수 없습니다.
이 문제를 해결하려면 이러한 종속 항목을 호스팅하거나 백업하거나 고려하세요. 또는 공유된 장애 요소가 없는 별도의 GitLab 인스턴스를 사용할 수 있습니다.

전제 조건

자체 관리 GitLab을 사용하기 전에 Terraform 상태 파일에 GitLab을 사용하려면:

  • 관리자는 Terraform 상태 저장소를 설정해야 합니다.
  • 프로젝트에 대한 인프라 메뉴를 활성화해야 합니다. Settings > General로 이동하여, Visibility, project features, permissions를 확장하고, Infrastructure에서 토글을 켜야 합니다.

GitLab CI/CD를 사용하여 백엔드로 Terraform 상태를 초기화하려면

terraform init 명령을 실행한 후 GitLab CI/CD를 사용하여 terraform 명령을 실행할 수 있습니다.

전제 조건:

  • terraform apply를 사용하여 상태를 잠그고 해제 및 쓰기 위해서는 적어도 Maintainer 역할이 있어야 합니다.
  • terraform plan -lock=false를 사용하여 상태를 읽으려면 적어도 Developer 역할이 있어야 합니다.

경고: 다른 작업 아티팩트와 마찬가지로 Terraform plan 데이터는 리포지토리에서 Guest 역할을 가진 사람은 누구나 볼 수 있습니다.
Terraform 또는 GitLab은 계획 파일을 기본적으로 암호화하지 않습니다. Terraform plan.json 또는 plan.cache 파일에 암호, 액세스 토큰 또는 인증서와 같은 중요한 데이터가 포함된 경우 계획 출력을 암호화하거나 프로젝트 가시성 설정을 수정해야 합니다.
또한 public pipelines를 비활성화하고 artifact의 public 플래그를 false로 설정 (public: false)해야 합니다.
이 설정은 아티팩트에 대한 액세스 권한이 GitLab 관리자 및 적어도 Reporter 역할을 가진 프로젝트 멤버에게만 제공됨을 보장합니다.

GitLab CI/CD를 백엔드로 구성하려면:

  1. .tf 파일 (예: backend.tf)에서 HTTP 백엔드를 정의하세요.

    terraform {
      backend "http" {
      }
    }
    
  2. 프로젝트 리포지토리의 루트 디렉터리에 .gitlab-ci.yml 파일을 만드세요. 이를 채우려면 Terraform.gitlab-ci.yml 템플릿을 사용하세요.
  3. 프로젝트를 GitLab에 푸시하세요. 이 작업은 gitlab-terraform init, gitlab-terraform validate, 및 gitlab-terraform plan 명령을 실행하는 파이프라인을 트리거합니다.
  4. 이전 파이프라인에서 수동으로 deploy 작업을 트리거하세요. 이 작업은 정의된 인프라를 프로비저닝하기 위해 gitlab-terraform apply 명령을 실행합니다.

상기 terraform 명령의 출력은 작업 로그에서 볼 수 있어야 합니다.

gitlab-terraform CLI는 terraform CLI를 래핑한 것입니다. 자세한 정보는 GitLab Terraform 헬퍼 또는 gitlab-terraform의 소스 코드 보기를 참조하세요.

명시적으로 terraform 명령을 호출하려면 템플릿을 재정의하고 달리 사용할 수 있습니다.

Terraform 환경 변수 사용자 정의

Terraform.gitlab-ci.yml 템플릿을 사용할 때 Terraform HTTP 구성 변수를 사용하여 CI/CD 작업을 정의할 수 있습니다.

terraform init를 사용하여 Terraform 구성을 사용자 정의하고 덮어쓰려면, -backend-config=... 방식 대신 환경 변수를 사용하세요. -backend-config를 사용하면, 구성이:

  • terraform plan 명령어의 출력에 캐시됩니다.
  • 보통 terraform apply 명령으로 전달됩니다.

이러한 구성은 이전 작업에서 생성된 계획을 사용하여 terraform apply에서 Terraform 상태 파일을 잠글 수 없는 문제를 야기할 수 있습니다.

로컬 머신에서 상태 접근

로컬 머신에서 GitLab 관리 Terraform 상태에 접근할 수 있습니다.

경고: GitLab의 클러스터 배포에서는 로컬 스토리지를 사용하지 마십시오. 분할된 상태가 발생하여 후속 Terraform 실행이 일관되지 않을 수 있습니다. 대신 원격 스토리지 리소스를 사용하십시오.

  1. Terraform 상태가 CI/CD를 위해 초기화되었는지 확인하십시오.
  2. 사전으로 채워진 Terraform init 명령을 복사합니다:

    1. 왼쪽 사이드바에서 검색 또는 이동을 선택하고 프로젝트를 찾습니다.
    2. 작동 > Terraform 상태를 선택합니다.
    3. 사용하려는 환경 옆에서 작업 ()을 선택하고 Terraform init 명령 복사를 선택합니다.
  3. 터미널을 열고 이 명령을 로컬 머신에서 실행합니다.

GitLab 관리 Terraform 상태로 이동

Terraform은 백엔드가 변경되거나 재구성될 때 상태를 복사하는 것을 지원합니다. 다른 백엔드에서 GitLab 관리 Terraform 상태로 마이그레이션하기 위해 이러한 작업을 사용하세요.

GitLab 관리 Terraform 상태로 이동하는 데 필요한 명령을 실행하려면 로컬 터미널을 사용해야 합니다.

다음 예제는 상태 이름을 변경하는 방법을 보여줍니다. 다른 상태 저장 백엔드에서 GitLab 관리 Terraform 상태로 마이그레이션하기 위해서는 동일한 워크플로우가 필요합니다.

초기 백엔드 설정

PROJECT_ID="<gitlab-project-id>"
TF_USERNAME="<gitlab-username>"
TF_PASSWORD="<gitlab-personal-access-token>"
TF_ADDRESS="https://gitlab.com/api/v4/projects/${PROJECT_ID}/terraform/state/old-state-name"

terraform init \
  -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
백엔드 초기화 중...

성공적으로 백엔드 "http"를 구성했습니다! Terraform은 자동으로
이 백엔드를 사용할 것입니다. 백엔드 구성이 변경되지 않는 이상.

제공자 플러그인 초기화 중...

Terraform이 성공적으로 초기화되었습니다!

이제 Terraform을 사용할 수 있습니다. 인프라에 필요한 변경 사항을 보려면 "terraform plan"을 실행해 보십시오. 모든 Terraform 명령이 이제 작동해야 합니다.

Terraform에 대한 모듈 또는 백엔드 구성을 설정하거나 변경하면,
작업 디렉토리를 다시 초기화하려면 이 명령을 다시 실행하십시오. 잊어버리면 다른
명령어가 이것을 감지하고 필요한 경우에 이렇게 하라고 알려줄 것입니다.

백엔드 변경

이제 terraform init가 이전 상태가 있는 위치를 아는 .terraform/ 디렉터리를 만들었기 때문에, 새 위치에 대해 알려줄 수 있습니다:

TF_ADDRESS="https://gitlab.com/api/v4/projects/${PROJECT_ID}/terraform/state/new-state-name"

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
백엔드 초기화 중...
백엔드 구성이 변경되었습니다!

Terraform이 백엔드 구성이 변경되었음을 감지했습니다. Terraform은 이제 백엔드에서 기존 상태를 확인합니다.


상태 잠금 확보. 시간이 다소 걸릴 수 있습니다...
이전 "http" 백엔드에서 새로 구성된 "http" 백엔드로 마이그레이션될 때 기존 상태를 복사하시겠습니까?
  이전 "http" 백엔드를 새 "http" 백엔드로 마이그레이션하는 동안 기존 상태가 발견되었습니다. 새로 구성된 "http" 백엔드에 기존 상태가 발견되지 않았습니다. 이 상태를 새 "http" 백엔드로 복사하시겠습니까? 복사하려면 "yes"를 입력하고 빈 상태로 시작하려면 "no"를 입력하십시오.

  값을 입력하십시오: yes


백엔드 "http"를 성공적으로 구성했습니다! Terraform은 자동으로
이 백엔드를 사용할 것입니다. 백엔드 구성이 변경되지 않는 이상.

제공자 플러그인 초기화 중...

Terraform이 성공적으로 초기화되었습니다!

이제 Terraform을 사용할 수 있습니다. 인프라에 필요한 변경 사항을 보려면 "terraform plan"을 실행해 보십시오. 모든 Terraform 명령이 이제 작동해야 합니다.

Terraform에 대한 모듈 또는 백엔드 구성을 설정하거나 변경하면,
작업 디렉토리를 다시 초기화하려면 이 명령을 다시 실행하십시오. 잊어버리면 다른
명령어가 이것을 감지하고 필요한 경우에 이렇게 하라고 알려줄 것입니다.

“yes”를 입력하면 이전 위치에서 새 위치로 상태를 복사합니다. 그런 다음 GitLab CI/CD에서 다시 실행할 수 있습니다.

GitLab 백앤드를 원격 데이터 원본으로 사용하기

당신은 Terraform 데이터 소스로 GitLab 관리 Terraform 상태 백앤드를 사용할 수 있습니다.

  1. main.tf나 관련 파일에서 다음 변수들을 선언하세요. 값은 비워두세요.

    variable "example_remote_state_address" {
      type = string
      description = "Gitlab remote state file address"
    }
    
    variable "example_username" {
      type = string
      description = "리모트 상태를 조회할 Gitlab 사용자 이름"
    }
    
    variable "example_access_token" {
      type = string
      description = "리모트 상태를 조회할 때 사용할 GitLab 액세스 토큰"
    }
    
  2. 이전 단계에서의 값들을 덮어쓰려면, example.auto.tfvars 파일을 생성하세요. 이 파일은 프로젝트 저장소에 버전 관리되지 않아야 합니다.

    example_remote_state_address = "https://gitlab.com/api/v4/projects/<TARGET-PROJECT-ID>/terraform/state/<TARGET-STATE-NAME>"
    example_username = "<GitLab username>"
    example_access_token = "<GitLab Personal Access Token>"
    
  3. .tf 파일에서, Terraform 입력 변수를 사용하여 데이터 소스를 정의하세요:

    data "terraform_remote_state" "example" {
      backend = "http"
    
      config = {
        address = var.example_remote_state_address
        username = var.example_username
        password = var.example_access_token
      }
    }
    
    • address: 데이터 소스로 사용할 원격 상태 백앤드의 URL입니다. 예: https://gitlab.com/api/v4/projects/<TARGET-PROJECT-ID>/terraform/state/<TARGET-STATE-NAME>.
    • username: 데이터 소스와의 인증에 사용할 사용자 이름입니다. 개인 액세스 토큰을 사용하여 인증하는 경우, 이 값은 GitLab 사용자 이름입니다. GitLab CI/CD를 사용하는 경우, 이 값은 'gitlab-ci-token'입니다.
    • password: 데이터 소스와의 인증에 사용할 암호입니다. 개인 액세스 토큰을 사용하여 인증하는 경우, 이 값은 토큰 값입니다(토큰에는 API 범위가 있어야 함). GitLab CI/CD를 사용하는 경우, 이 값은 ${CI_JOB_TOKEN} CI/CD 변수의 내용입니다.

데이터 소스로부터의 출력은 이제 data.terraform_remote_state.example.outputs.<OUTPUT-NAME>을 사용하여 당신의 Terraform 리소스에서 참조될 수 있습니다.

대상 프로젝트에서 Terraform 상태를 읽으려면, 적어도 Developer 역할이 필요합니다.

Terraform 상태 파일 관리

Terraform 상태 파일을 보려면:

  1. 왼쪽 사이드바에서 검색 또는 이동을 선택하고 프로젝트를 찾으세요.
  2. 운영 > Terraform 상태를 선택하세요.

이 UI 개선을 추적하기 위해 에픽이 존재합니다.

개별 Terraform 상태 버전 관리

개별 상태 버전은 GitLab REST API를 사용하여 관리할 수 있습니다.

적어도 Developer 역할이 있다면, 상태 버전을 그들의 일련 번호를 사용하여 가져올 수 있습니다::

curl --header "Private-Token: <your_access_token>" "https://gitlab.example.com/api/v4/projects/<your_project_id>/terraform/state/<your_state_name>/versions/<version-serial>"

Maintainer 역할 이상을 가지고 있다면, 상태 버전을 그들의 일련 번호를 사용하여 삭제할 수 있습니다:

curl --header "Private-Token: <your_access_token>" --request DELETE "https://gitlab.example.com/api/v4/projects/<your_project_id>/terraform/state/<your_state_name>/versions/<version-serial>"

상태 파일 제거

적어도 Maintainer 역할이 있다면, 상태 파일을 제거할 수 있습니다.

  1. 왼쪽 사이드바에서 운영 > Terraform 상태를 선택하세요.
  2. 작업 열에서 작업()을 선택한 다음 상태 파일 및 버전 제거를 선택하세요.

API를 사용하여 상태 파일 제거

개인 액세스 토큰을 사용하여 REST API에 요청을 보내어 상태 파일을 제거할 수 있습니다:

curl --header "Private-Token: <your_access_token>" --request DELETE "https://gitlab.example.com/api/v4/projects/<your_project_id>/terraform/state/<your_state_name>"

CI/CD 작업 토큰 및 기본 인증을 사용할 수도 있습니다:

curl --user "gitlab-ci-token:$CI_JOB_TOKEN" --request DELETE "https://gitlab.example.com/api/v4/projects/<your_project_id>/terraform/state/<your_state_name>"

GraphQL API를 사용할 수도 있습니다.

관련 주제