Terraform module 프로젝트간 참조 가이드 (opentofu)

강재민·2024년 3월 29일
0

Gitlab

목록 보기
5/5

Open tofu란?

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 tofuTerraform
gitlab-tofu validateterraform init
gitlab-tofu planterraform plan
gitlab-tofu plan-jsonterraform plan -out <파일명>
gitlab-tofu applyterraform apply
gitlab-tofu destroyterraform destory

사전준비

모듈 업로드 하기

  • Terraform module Upload Guide

Token Access 허용하기

GitLab에서 서로 다른 프로젝트에 접근하기 위해서는 외부 프로젝트의 접근을 모두 허용하거나 특정 프로젝트 리스트를 등록해서 화이트리스트 방식으로 허용할 수 있습니다.

  1. 모듈이 등록된 프로젝트 접속
  2. Settings/CICD/Token Access 접근
  3. Limit access to this project 토글 해제 또는 허용하고싶은 프로젝트 등록


Open-tofu 이미지 설정

방법 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.

Trouble shooting

아래 방식으로 진행할 경우, 401 error와 함께 불러올 수 없습니다. 해당 방식은 프로젝트간 참조하는 것이 아닌 GitLab이 아닌 다른 환경에서 모듈을 참조하는 방식입니다. GitLab에서는 해당 방식을 통해 프로젝트간 참조하는 것을 막아놓았습니다.

~/.terraformrc

credentials "gitlab.com" {
  token = "<TOKEN>"
}

https://docs.gitlab.com/ee/user/packages/terraform_module_registry/#reference-a-terraform-module

0개의 댓글