GitLab과의 Terraform 통합 문제 해결

Terraform과 GitLab을 통합하여 사용할 때, 해결해야 할 문제가 발생할 수 있습니다.

gitlab_group_share_group 자원이 서브그룹 상태를 새로 고칠 때 감지되지 않음

GitLab Terraform 공급자는 기존의 gitlab_group_share_group 자원을 감지하지 못할 수 있습니다. 이는 “사용 권한이 있는 사용자가 API에서 share_with_groups을 검색할 수 없음” 문제로 인한 것입니다. 이로 인해 terraform apply를 실행할 때 이미 존재하는 자원을 재생성하려고 하면 오류가 발생합니다.

예를 들어, 다음과 같은 그룹/서브그룹 구성을 고려해보십시오:

상위 그룹
├── 서브그룹-A
└── 서브그룹-B

여기서:

  • 사용자 user-1parent-group, subgroup-A, subgroup-B를 생성합니다.
  • subgroup-Asubgroup-B와 공유됩니다.
  • terraform-userparent-group의 멤버로, 두 서브그룹에 대한 상속된 소유자 액세스를 갖습니다.

Terraform 상태가 새로 고쳐질 때, 공급자에 의해 발급된 GET /groups/:subgroup-A_id API 쿼리는 shared_with_groups 배열에서 subgroup-B의 세부 정보를 반환하지 않습니다. 이로 인해 오류가 발생합니다.

이 문제를 해결하기 위해 다음 중 하나의 조건을 적용하세요:

  1. terraform-user가 모든 서브그룹 자원을 생성합니다.
  2. terraform-user에게 subgroup-B에서 Maintainer 또는 Owner 역할을 부여합니다.
  3. terraform-usersubgroup-B에 대한 상속된 액세스 권한을 갖도록 하고, subgroup-B에 적어도 하나의 프로젝트가 포함되어 있어야 합니다.

기본 템플릿을 사용할 때 CI/CD 구문 오류

Terraform 템플릿을 사용할 때 CI/CD 구문 오류가 발생할 수 있습니다:

  • GitLab 14.2 이상에서 latest 템플릿을 사용하는 경우.
  • GitLab 15.0 이상에서 해당 템플릿의 모든 버전을 사용하는 경우.

예를 들어:

include:
  # 14.2 버전 이상에서 다음 중 하나를 사용하는 경우:
  - template: Terraform/Base.latest.gitlab-ci.yml
  - template: Terraform.latest.gitlab-ci.yml
  # 15.0 버전 이상에서 다음 템플릿도 업데이트되었습니다:
  - template: Terraform/Base.gitlab-ci.yml
  - template: Terraform.gitlab-ci.yml

my-terraform-job:
  extends: .apply

오류의 원인으로는 세 가지가 있습니다:

  • .init의 경우, 초기화 단계와 작업이 더 이상 필요하지 않아서 템플릿에서 삭제되었습니다. 구문 오류를 해결하려면 .init를 확장하는 모든 작업을 안전하게 제거할 수 있습니다.
  • 기타 작업의 경우, 기본 작업 이름에 .terraform: 접두사가 추가되어 이름이 변경되었습니다. 예를 들어, .apply.terraform:apply로 변경되었습니다. 이 오류를 수정하려면 기본 작업 이름을 업데이트할 수 있습니다. 예를 들어:

      my-terraform-job:
    -   extends: .apply
    +   extends: .terraform:apply
    
  • GitLab 15.0부터 템플릿은 rules 구문을 사용하기 때문에 only/except는 포함하면 안 됩니다.

이전 버전의 템플릿 사용

주요 릴리스 중에는 파괴적인 변경이 발생할 수 있습니다. 파괴적인 변경이 발생하거나 이전 버전의 템플릿을 사용하려는 경우, .gitlab-ci.yml을 이전 버전으로 참조하도록 업데이트할 수 있습니다. 예를 들어:

include:
  remote: https://gitlab.com/gitlab-org/configure/template-archive/-/raw/main/14-10/Terraform.gitlab-ci.yml

사용 가능한 템플릿을 확인하려면 template-archive를 참조하세요.

Terraform 상태 문제 해결

이전 작업에서 생성한 계획을 사용하여 terraform apply를 위한 Terraform 상태 파일을 CI 작업에서 잠글 수 없음

terraform init-backend-config=를 전달하면, Terraform은 이러한 값을 계획 캐시 파일 내에 지속합니다. 이는 password 값을 포함하여 $CI_JOB_TOKEN의 값이 현재 작업의 기간 동안만 유효하기 때문에 다른 CI 작업에서 동일한 계획을 생성하고 나중에 사용할 때 Error: Error acquiring the state lock 오류가 발생할 수 있습니다.

이 문제를 해결하려면 http 백엔드 구성 변수를 사용하여 CI 작업에서, 내부적으로 GitLab CI를 사용하여 Terraform 상태를 시작하기 지침을 따를 때 사용하는 것과 동일하게 하십시오.

오류: “address”: 필수 필드가 설정되지 않았습니다

기본적으로 TF_ADDRESS${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/terraform/state/${TF_STATE_NAME}로 설정합니다. 작업에서 TF_STATE_NAME 또는 TF_ADDRESS를 설정하지 않은 경우, 작업에서 Error: "address": required field is not set 오류 메시지와 함께 작업이 실패합니다.

이를 해결하려면 오류가 발생한 작업에서 TF_ADDRESS 또는 TF_STATE_NAME 중 하나에 접근할 수 있도록 다음 단계를 수행하세요:

  1. 작업에 대한 CI/CD 환경 범위를 구성합니다.
  2. 이전 단계에서 정의한 환경 범위와 일치하도록 작업의 환경을 설정합니다.

상태 새로 고침 오류: HTTP 원격 상태 엔드포인트는 인증이 필요함

이 문제를 해결하려면 다음 확인 사항을 준수하세요:

  • 사용하는 액세스 토큰이 api 범위를 갖고 있는지 확인합니다.
  • TF_HTTP_PASSWORD CI/CD 변수를 설정한 경우, 다음 중 하나를 수행합니다:
    • TF_PASSWORD와 동일한 값을 설정합니다.
    • CI/CD 작업에서 명시적으로 사용하지 않는 경우 TF_HTTP_PASSWORD 변수를 제거합니다.

파괴적인 명령을 실행하려면 개발자 역할 액세스를 활성화

파괴적인 명령을 실행하려면 개발자 역할을 가진 사용자에게 해결 방안이 필요합니다:

  1. 프로젝트 액세스 토큰 생성api 범위를 부여합니다.
  2. CI/CD 변수에 TF_USERNAMETF_PASSWORD를 추가합니다:
    1. TF_USERNAME의 값을 프로젝트 액세스 토큰의 사용자 이름으로 설정합니다.
    2. TF_PASSWORD의 값을 프로젝트 액세스 토큰의 암호로 설정합니다.
    3. 안전한 브랜치 또는 보호된 태그에서 실행되는 파이프라인에서만 사용할 수 있도록 변수를 보호할 수 있습니다(선택 사항).

상태 이름에 점이 포함된 경우 상태를 찾을 수 없음

GitLab 15.6 및 이전 버전에서 상태 이름에 점이 포함되어 있고 Terraform이 상태 잠금을 시도하면 404 오류가 반환되었습니다.

이 문제를 해결하려면 Terraform 명령에 -lock=false를 추가하여 이용할 수 있습니다. GitLab 백엔드는 요청을 수락하지만 내부적으로 점과 이를 따르는 문자를 상태 이름에서 제거했습니다. 예를 들어, foo.bar라는 상태는 foo로 저장되었습니다. 그러나 이 해결 방법은 권장되지 않으며 심지어 상태 이름 충돌을 일으킬 수 있습니다.

GitLab 15.7 이상에서는 점이 포함된 상태 이름을 지원합니다. -lock=false 해결 방법을 사용하다가 GitLab 15.7 이상으로 업그레이드하면 작업이 실패할 수 있습니다. 작업 실패는 GitLab 백엔드가 기존의 상태 이름과 달라진 전체 상태 이름으로 새 상태를 저장하기 때문에 발생합니다.

작업이 실패하는 경우, 상태 이름에서 점과 이를 따르는 문자를 제외하도록 상태 이름을 변경하세요. 예를 들어, 다음과 같이 Terraform 템플릿을 사용하는 경우:

include:
  - template: Terraform.gitlab-ci.yml

variables:
  TF_STATE_NAME: foo

TF_HTTP_ADDRESS, TF_HTTP_LOCK_ADDRESS, TF_HTTP_UNLOCK_ADDRESS를 설정한 경우 해당 상태 이름을 업데이트하세요.

대안으로, terraform 상태를 이전할 수 있습니다.