https://gitlab.com/gitlab-org/terraform-images/-/issues/114
라이센스와 관련된 이슈로 인해서, GitLab에서 helper image를 BuSL licensed Terraform versions에서 지금 소개드리는 Open tofu 이미지를 사용하는 것으로 정책을 변경하였습니다.
기존에 테라폼을 사용하시던 기능은 동일하게 사용 가능합니다.
또한 GitLab은 기존 module registry기능, GitLab managed Terraform state, MR widget 기능도 계속해서 유지할 예정입니다.
Open tofu 명령어 요약
Open tofu | Terraform |
---|---|
gitlab-tofu validate | terraform init |
gitlab-tofu plan | terraform plan |
gitlab-tofu plan-json | terraform plan -out <파일명> |
gitlab-tofu apply | terraform apply |
gitlab-tofu destroy | terraform destory |
모듈 업로드 하기
GitLab에서 서로 다른 프로젝트에 접근하기 위해서는 외부 프로젝트의 접근을 모두 허용하거나 특정 프로젝트 리스트를 등록해서 화이트리스트 방식으로 허용할 수 있습니다.
방법 1. 최신 이미지 사용 (인터넷에서 image pull이 가능한 경우)
variables:
OPEN_TOFU_IMAGE: registry.gitlab.com/components/opentofu/gitlab-opentofu:latest
방법 2. 고정 이미지 사용 (인터넷 사용이 불가능한 경우)
variables:
OPEN_TOFU_IMAGE: registry.gitlab.com/components/opentofu/gitlab-opentofu:0.17.0
release note 링크: https://gitlab.com/components/opentofu/-/releases#available-gitlab-opentofu-images
🚨
고정 이미지 사용시 관리자가 해당 이미지를 수동으로 업그레이드 해주어야 합니다. opentofu는 주로 bugfix 관련된 업그레이드가 진행되기 때문에 매번 최신이미지를 사용할 필요는 없습니다. 하지만 문제 발생시 opentofu 사용에 관한 히스토리를 파악하고 있어야합니다.
terraform-module-test-external
이라는 프로젝트에서 terraform-module-test
라는 프로젝트에 등록된 모듈을 가져와서 사용해보겠습니다.
등록된 모듈 확인
terraform-module-test-external
프로젝트에서 해당 모듈 참조
module.tf
module "my_module_name" {
source = "gitlab.mzc-dpt.com/customer/tf-modules/local"
version = "0.0.1"
}
.gitlab-ci.yml
# To contribute improvements to CI/CD templates, please follow the Development guide at:
# https://docs.gitlab.com/ee/development/cicd/templates.html
# This specific template is located at:
# https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/ci/templates/Terraform.gitlab-ci.yml
variables:
# The relative path to the root directory of the OpenTofu project
TF_ROOT: ${CI_PROJECT_DIR}
# The name of the state file used by the GitLab Managed Terraform state backend
TF_STATE_NAME: default
OPEN_TOFU_IMAGE: "registry.gitlab.com/components/opentofu/gitlab-opentofu:0.17.0"
stages:
- validate
- plan
- apply
- destroy
validate:
extends: .opentofu:validate
needs: []
plan:
extends: .opentofu:plan
environment:
name: $TF_STATE_NAME
action: prepare
apply:
extends: .opentofu:apply
dependencies:
- plan
environment:
name: $TF_STATE_NAME
action: start
destroy:
extends: .opentofu:destroy
dependencies:
- apply
environment:
name: $TF_STATE_NAME
action: stop
# This template is a port of the OpenTofu CI/CD component at
# https://gitlab.com/components/opentofu
# It is generated with the `make backports` command from that project.
#
# Please make sure to use the component (https://gitlab.com/components/opentofu)
# when your project is hosted on GitLab.com
# or when you are willing to mirror the component project into your self-managed
# instance and use it from there.
#
# Attention: This template will be removed in favor of the OpenTofu CI/CD component following components
# are available for self-managed instances.
#
# This specific template is located at:
# https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/ci/templates/OpenTofu/Base.latest.gitlab-ci.yml
opentofu:use-component-instead-of-template:
stage: .pre
needs: []
allow_failure: true
rules:
- if: '$CI_SERVER_HOST == "gitlab.com"'
image: alpine:3.19
script:
- |
echo "You are using the OpenTofu CI/CD template on GitLab.com, which is not recommended."
echo "This template is available for self-managed users only until CI/CD components are "
echo "available. See https://gitlab.com/gitlab-org/gitlab/-/issues/415638"
echo " "
echo "You should use the OpenTofu CI/CD component instead."
echo "To include the CI/CD component with a default configuration:"
echo " "
echo "include:"
echo " - component: gitlab.com/components/opentofu/full-pipeline@<VERSION>"
echo " inputs:"
echo " version: <VERSION>"
echo " opentofu_version: 1.6.0"
echo ""
echo "stages: [validate, plan, apply, destroy]"
echo " "
echo "You can read about more about the OpenTofu CI/CD component here:"
echo "https://gitlab.com/components/opentofu"
- 'false'
'.opentofu:validate':
stage: validate
rules:
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
- if: $CI_OPEN_MERGE_REQUESTS # Don't add it to a *branch* pipeline if it's already in a merge request pipeline.
when: never
- if: $CI_COMMIT_BRANCH # If there's no open merge request, add it to a *branch* pipeline instead.
cache:
key: "$TF_ROOT"
paths:
- $TF_ROOT/.terraform/
image:
name: '$OPEN_TOFU_IMAGE'
script:
- gitlab-tofu validate
'.opentofu:plan':
stage: plan
environment:
name: $TF_STATE_NAME
action: prepare
resource_group: $TF_STATE_NAME
artifacts:
# Terraform's cache files can include secrets which can be accidentally exposed.
# Please exercise caution when utilizing secrets in your Terraform infrastructure and
# consider limiting access to artifacts or take other security measures to protect sensitive information.
#
# The next line, which disables public access to pipeline artifacts, is not available on GitLab.com.
# See: https://docs.gitlab.com/ee/ci/yaml/#artifactspublic
public: false
paths:
- $TF_ROOT/plan.cache
reports:
terraform: $TF_ROOT/plan.json
rules:
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
- if: $CI_OPEN_MERGE_REQUESTS # Don't add it to a *branch* pipeline if it's already in a merge request pipeline.
when: never
- if: $CI_COMMIT_BRANCH # If there's no open merge request, add it to a *branch* pipeline instead.
cache:
key: "$TF_ROOT"
paths:
- $TF_ROOT/.terraform/
image:
name: '$OPEN_TOFU_IMAGE'
script:
- gitlab-tofu plan
- gitlab-tofu plan-json
'.opentofu:apply':
stage: apply
environment:
name: $TF_STATE_NAME
action: start
resource_group: $TF_STATE_NAME
rules:
- if: '$CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH && "$_TF_AUTO_APPLY" == "true"'
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
when: manual
cache:
key: "$TF_ROOT"
paths:
- $TF_ROOT/.terraform/
image:
name: '$OPEN_TOFU_IMAGE'
script:
- gitlab-tofu apply
'.opentofu:destroy':
stage: destroy
environment:
name: $TF_STATE_NAME
action: stop
resource_group: $TF_STATE_NAME
rules:
- if: '$CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH && "$_TF_AUTO_DESTROY" == "true"'
- when: manual
cache:
key: "$TF_ROOT"
paths:
- $TF_ROOT/.terraform/
image:
name: '$OPEN_TOFU_IMAGE'
script:
- gitlab-tofu destroy
'.opentofu:delete-state':
stage: delete-state
resource_group: $TF_STATE_NAME
image: curlimages/curl:latest
script:
- curl --request DELETE -u "gitlab-ci-token:$CI_JOB_TOKEN" "$CI_API_V4_URL/projects/$CI_PROJECT_ID/terraform/state/$TF_STATE_NAME"
rules:
- if: '$CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH'
- when: manual
결과
$ gitlab-tofu plan
Initializing the backend...
Successfully configured the backend "http"! OpenTofu will automatically
use this backend unless the backend configuration changes.
Initializing modules...
Initializing provider plugins...
- Finding latest version of hashicorp/local...
- Installing hashicorp/local v2.5.1...
- Installed hashicorp/local v2.5.1 (signed, key ID 0C0AF313E5FD9F80)
Providers are signed by their developers.
If you'd like to know more about provider signing, you can read about it here:
https://opentofu.org/docs/cli/plugins/signing/
OpenTofu has created a lock file .terraform.lock.hcl to record the provider
selections it made above. Include this file in your version control repository
so that OpenTofu can guarantee to make the same selections by default when
you run "tofu init" in the future.
OpenTofu has been successfully initialized!
OpenTofu used the selected providers to generate the following execution
plan. Resource actions are indicated with the following symbols:
+ create
OpenTofu will perform the following actions:
# module.my_module_name.local_file.abc will be created
+ resource "local_file" "abc" {
+ content = "abc!"
+ content_base64sha256 = (known after apply)
+ content_base64sha512 = (known after apply)
+ content_md5 = (known after apply)
+ content_sha1 = (known after apply)
+ content_sha256 = (known after apply)
+ content_sha512 = (known after apply)
+ directory_permission = "0777"
+ file_permission = "0777"
+ filename = ".terraform/modules/my_module_name/abc.txt"
+ id = (known after apply)
}
Plan: 1 to add, 0 to change, 0 to destroy.
아래 방식으로 진행할 경우, 401 error와 함께 불러올 수 없습니다. 해당 방식은 프로젝트간 참조하는 것이 아닌 GitLab이 아닌 다른 환경에서 모듈을 참조하는 방식입니다. GitLab에서는 해당 방식을 통해 프로젝트간 참조하는 것을 막아놓았습니다.
~/.terraformrc
credentials "gitlab.com" {
token = "<TOKEN>"
}
https://docs.gitlab.com/ee/user/packages/terraform_module_registry/#reference-a-terraform-module