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
의 세부 정보를 반환하지 않습니다. 이로 인해 에러가 발생합니다.
이 문제를 해결하려면 다음 조건 중 하나를 적용하십시오:
-
terraform-user
가 모든 서브그룹 리소스를 생성합니다. -
terraform-user
에게서브그룹-B
에서 관리자 또는 소유자 역할을 부여합니다. -
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
중 하나에 접근할 수 있도록 하십시오:
- 작업을 위해 CI/CD 환경 범위를 구성하세요.
- 이전 단계에서 구성한 환경 범위와 일치하도록, 작업의 환경을 설정하세요.
상태 새로고침 오류: HTTP 원격 상태 엔드포인트에 인증이 필요함
이를 해결하려면, 다음 사항을 확인하세요:
- 사용하는 액세스 토큰이
api
범위를 가지고 있는지 확인하세요. -
TF_HTTP_PASSWORD
CI/CD 변수를 설정했다면, 다음 중 하나를 확인하세요:-
TF_PASSWORD
에 동일한 값을 설정하세요. - CI/CD 작업에서 명시적으로 사용하지 않는 경우
TF_HTTP_PASSWORD
변수를 제거하세요.
-
파괴적 명령에 대한 개발자 역할 액세스 활성화
개발자 역할을 가진 사용자가 파괴적 명령을 실행할 수 있도록 하려면, 다음 대안이 필요합니다:
-
api
범위를 가진 프로젝트 액세스 토큰을 만드세요. - CI/CD 변수에
TF_USERNAME
과TF_PASSWORD
를 추가하세요:-
TF_USERNAME
의 값을 프로젝트 액세스 토큰의 사용자 이름으로 설정하세요. -
TF_PASSWORD
의 값을 프로젝트 액세스 토큰의 암호로 설정하세요. - 선택 사항. 이러한 변수를 보호하여 보호된 브랜치 또는 보호된 태그에서 실행되는 파이프라인에서만 사용할 수 있도록 만드세요.
-
상태 이름에 점이 포함되어 있으면 상태를 찾을 수 없음
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 상태를 이전할 수 있습니다.