GitLab과 Terraform 통합의 문제 해결

Terraform과 GitLab을 통합하여 사용하는 경우, 문제가 발생할 수 있으며 이를 해결해야 합니다.

gitlab_group_share_group 리소스가 서브그룹 상태가 새로고침될 때 감지되지 않음

GitLab Terraform 제공자는 기존의 gitlab_group_share_group 리소스를 감지하지 못할 수 있습니다. 이는 문제“권한이 있는 사용자가 API에서 share_with_groups를 검색할 수 없음”으로 인합니다. 이로 인해 terraform apply를 실행할 때 에러가 발생하며, Terraform은 기존 리소스를 재생성하려고 시도합니다.

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

부모 그룹
├── 서브그룹-A
└── 서브그룹-B

이때:

  • 사용자 user-1부모 그룹, 서브그룹-A, 서브그룹-B를 생성합니다.
  • 서브그룹-A서브그룹-B와 공유됩니다.
  • 사용자 terraform-user부모 그룹의 구성원이며, 두 서브그룹에 대한 상속된 소유자 액세스를 갖습니다.

Terraform 상태를 새로 고칠 때, 제공자가 발행하는 API 쿼리 GET /groups/:subgroup-A_id에서는 shared_with_groups 배열에 서브그룹-B의 세부 정보를 반환하지 않습니다. 이로 인해 에러가 발생합니다.

이 문제를 해결하려면 다음 조건 중 하나를 적용하십시오:

  1. terraform-user가 모든 서브그룹 리소스를 생성합니다.
  2. terraform-user에게 서브그룹-B에서 관리자 또는 소유자 역할을 부여합니다.
  3. terraform-user서브그룹-B에 상속된 액세스를 받고, 서브그룹-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 단계와 작업이 제거되었기 때문에 발생합니다. 구문 오류를 해결하려면 .init을 확장하는 모든 작업을 안전하게 제거할 수 있습니다.
  • 다른 모든 작업의 경우, 이 실패의 원인은 기본 작업이 이름이 변경되었기 때문입니다: 모든 작업 이름에 .terraform: 접두사가 추가되었습니다. 예를 들어, .apply.terraform:apply로 변경되었습니다. 이 오류를 해결하려면 기본 작업 이름을 업데이트할 수 있습니다. 예를 들어:

      my-terraform-job:
    -   extends: .apply
    +   extends: .terraform:apply
    
  • GitLab 15.0에서는 템플릿이 rules 구문을 사용하며, only/except 대신에 사용합니다. .gitlab-ci.yml 파일의 구문이 두 가지 모두 포함되지 않도록 하십시오.

이전 버전의 템플릿 사용

주요 릴리스 중에는 호환성이 없을 수 있습니다. 호환되지 않는 변경 사항이 발생하거나 이전 버전의 템플릿을 사용하려는 경우 .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의 CI 작업에서 Terraform 상태 파일을 잠그지 못함

terraform init-backend-config=를 전달하면, Terraform은 이러한 값들을 계획 캐시 파일 내부에 유지합니다. 이에는 password 값도 포함됩니다.

따라서 계획을 생성하고 나중에 동일한 계획을 다른 CI 작업에서 사용하려고 할 때, -backend-config=password=$CI_JOB_TOKEN를 사용할 때 Error: Error acquiring the state lock 오류가 발생할 수 있습니다. 이는 $CI_JOB_TOKEN 값이 현재 작업의 유효 기간 동안만 유효하기 때문에 발생합니다.

이 문제를 해결하려면 CI 작업에서 HTTP 백엔드 구성 변수를 사용하십시오. 이는 GitLab CI를 통해 테라폼 상태를 백엔드로 초기화하는 방법을 따를 때 내부적으로 발생하는 일입니다.

오류: “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 상태를 이전할 수 있습니다.