Terraform モジュールレジストリ

  • GitLab 14.0 で導入されました
  • Infrastructure registryとTerraform Module RegistryはGitLab 15.11でTerraform Module Registry機能にマージされました。

Terraform Module Registryを使えば、GitLabプロジェクトをTerraformモジュールの非公開レジストリとして使うことができます。GitLab CI/CDでモジュールを作成・公開し、他の非公開プロジェクトから利用することができます。

Terraformモジュールを見る

プロジェクト内の Terraform モジュールを表示します:

  1. プロジェクトに移動します。
  2. 左サイドバーで、Operate > Terraform modulesを選択します。

このページでは、モジュールの検索、並べ替え、フィルタリングができます。

パッケージの作成とアップロード方法については、パッケージの種類に応じた GitLab ドキュメントをご覧ください:

Terraform モジュールレジストリへの認証

Terraform モジュールレジストリに認証するには、以下のどちらかが必要です:

ここで説明されている以外の認証方法は使用しないでください。文書化されていない認証方法は、将来削除される可能性があります。

Terraformモジュールの公開

Terraformモジュールを公開すると、モジュールが存在しない場合は作成されます。

API の使用

TerraformModule Registry APIを使ってTerraformモジュールを公開することができます。

前提条件:

PUT /projects/:id/packages/terraform/modules/:module-name/:module-system/:module-version/file
属性種類必須説明
id整数/文字列yes プロジェクトのIDまたはURLエンコードされたパス
module-name文字列です。yesモジュール名。サポートされている構文:小文字 (a ~ z) と数字 (0 ~ 9) を含む、1 ~ 64 文字の ASCII 文字。モジュール名は64文字を超えることはできません。
module-system文字列です。yesモジュールシステム。サポートされる構文:小文字 (a ~ z) と数字 (0 ~ 9) を含む、1 ~ 64 文字の ASCII 文字。モジュールシステムは64文字を超えることはできません。詳細はTerraform Module Registry protocol documentationを参照してください。
module-version文字列です。yesモジュールのバージョン。セマンティックバージョン指定に従って有効でなければなりません。

リクエストボディにファイルの内容を記述します。

次の例が示すように、リクエストは/file で終わらなければなりません。 もし他の何かで終わるリクエストを送ると、404 エラー{"error":"404 Not Found"} になります。

個人アクセストークンを使用したリクエスト例:

curl --fail-with-body --header "PRIVATE-TOKEN: <your_access_token>" \
     --upload-file path/to/file.tgz \
     "https://gitlab.example.com/api/v4/projects/<your_project_id>/packages/terraform/modules/my-module/my-system/0.0.1/file"

デプロイトークンを使ったリクエスト例:

curl --fail-with-body --header "DEPLOY-TOKEN: <deploy_token>" \
     --upload-file path/to/file.tgz \
     "https://gitlab.example.com/api/v4/projects/<your_project_id>/packages/terraform/modules/my-module/my-system/0.0.1/file"

応答例

{
  "message":"201 Created"
}

GitLab 15.9 で導入されました

Terraform-Module.gitlab-ci.yml または advancedTerraform/Module-Base.gitlab-ci.yml CI/CD template を使って、Terraform モジュールを GitLab terraform レジストリに公開することができます:

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

パイプラインには以下のジョブが含まれます:

  • fmt - Terraformモジュールのフォーマットを検証します。
  • kics-iac-sast - Terraformモジュールのセキュリティ問題をテストします。
  • deploy - タグパイプラインの場合のみ。Terraform モジュールを Terraform モジュールレジストリにデプロイします。

パイプライン変数

パイプラインは以下の変数で設定できます:

変数デフォルト説明
TERRAFORM_MODULE_DIR${CI_PROJECT_DIR}Terraformプロジェクトのルートディレクトリへの相対パス。
TERRAFORM_MODULE_NAME${CI_PROJECT_NAME}Terraformモジュールの名前。スペースやアンダースコアはコンテナに入れてはいけません。
TERRAFORM_MODULE_SYSTEMlocalTerraformモジュールがターゲットとするシステムまたはプロバイダ。例えば、local,aws,google
TERRAFORM_MODULE_VERSION${CI_COMMIT_TAG}Terraformモジュールのバージョン。セマンティックバージョニング仕様に従うべきです。

CI/CDの手動利用

GitLab CI/CDでTerraformモジュールを扱うには、コマンドで個人アクセストークンの代わりにCI_JOB_TOKEN

例えば、このジョブはlocal システムプロバイダの新しいモジュールをアップロードし、Git commit タグからモジュールのバージョンを使用します:

stages:
  - deploy

upload:
  stage: deploy
  image: curlimages/curl:latest
  variables:
    TERRAFORM_MODULE_DIR: ${CI_PROJECT_DIR}    # The relative path to the root directory of the Terraform project.
    TERRAFORM_MODULE_NAME: ${CI_PROJECT_NAME}  # The name of your Terraform module, must not have any spaces or underscores (will be translated to hyphens).
    TERRAFORM_MODULE_SYSTEM: local             # The system or provider your Terraform module targets (ex. local, aws, google).
    TERRAFORM_MODULE_VERSION: ${CI_COMMIT_TAG} # The version - it's recommended to follow SemVer for Terraform Module Versioning.
  script:
    - TERRAFORM_MODULE_NAME=$(echo "${TERRAFORM_MODULE_NAME}" | tr " _" -) # module-name must not have spaces or underscores, so translate them to hyphens
    - tar -vczf /tmp/${TERRAFORM_MODULE_NAME}-${TERRAFORM_MODULE_SYSTEM}-${TERRAFORM_MODULE_VERSION}.tgz -C ${TERRAFORM_MODULE_DIR} --exclude=./.git .
    - 'curl --fail-with-body --location --header "JOB-TOKEN: ${CI_JOB_TOKEN}"
         --upload-file /tmp/${TERRAFORM_MODULE_NAME}-${TERRAFORM_MODULE_SYSTEM}-${TERRAFORM_MODULE_VERSION}.tgz
         ${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/packages/terraform/modules/${TERRAFORM_MODULE_NAME}/${TERRAFORM_MODULE_SYSTEM}/${TERRAFORM_MODULE_VERSION}/file'
  rules:
    - if: $CI_COMMIT_TAG

このアップロードジョブをトリガーするには、コミットに Git タグを追加します。タグはTerraformが要求するSemantic versioning仕様に従っていることを確認してください。rules:if: $CI_COMMIT_TAG は、タグが付けられたリポジトリへのコミットのみがモジュールのアップロードジョブをトリガーすることを保証します。CI/CD パイプラインでジョブを制御する他の方法については、.gitlab-ci.yml キーワードリファレンスを参照してください。

Terraform モジュールの参照

前提条件:

  • APIで認証を行う必要があります。個人アクセストークンで認証する場合は、read_api スコープを設定する必要があります。

認証トークン (ジョブトークンまたはパーソナルアクセストークン) は~/.terraformrc または%APPDATA%/terraform.rc ファイルでterraform に対して提供することができます:

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

gitlab.com は、自分で管理する GitLab インスタンスのホスト名に置き換えることができます。

これで、ダウンストリームの Terraform プロジェクトから Terraform モジュールを参照できるようになります:

module "<module>" {
  source = "gitlab.com/<namespace>/<module-name>/<module-system>"
}

<namespace> は Terraform モジュールレジストリの名前空間です。

Terraformモジュールのダウンロード

Terraformモジュールをダウンロードします:

  1. 左サイドバーで、Operate > Terraform modulesを選択します。
  2. ダウンロードしたいモジュール名を選択します。
  3. アクティビティセクションで、ダウンロードしたいモジュールの名前を選択します。

モジュール解決の仕組み

新しいモジュールをアップロードすると、GitLab はモジュールのパスを生成します。例えば、https://gitlab.example.com/parent-group/my-infra-package.

  • このパスはTerraform の仕様に準拠しています。
  • パスの名前は名前空間内で一意でなければなりません。

サブグループのプロジェクトでは、GitLab はモジュール名がネームスペースのどこにも既に存在しないことをチェックします。

例えば

  • プロジェクトはgitlab.example.com/parent-group/sub-group/my-project
  • Terraform モジュールはmy-infra-package です。

プロジェクト名はparent-group のすべてのグループのすべてのプロジェクトで一意でなければなりません。

Terraformモジュールの削除

Terraform Module Registryで公開した後のTerraformモジュールは編集できません。代わりに、削除して再作成する必要があります。

モジュールを削除するには、適切な権限が必要です。

packages APIまたは UI を使ってモジュールを削除できます。

UI で、プロジェクトからモジュールを削除するには、次のようにします:

  1. 左サイドバーで、Operate > Terraform modulesを選択します。
  2. 削除したいパッケージ名を探します。
  3. 削除]を選択します。

パッケージが完全に削除されます。

Terraformモジュールのレジストリを無効にします。

Terraformモジュールレジストリは自動的に有効になります。

自分で管理するインスタンスでは、GitLab管理者はPackages and registriesを 無効にすることができ、サイドバーからこのメニュー項目を削除することができます。

特定のプロジェクトの Terraform モジュールレジストリを削除することもできます:

  1. プロジェクトで、Settings > Generalに進みます。
  2. Visibility, project features, permissionsセクションを展開し、Packagesをオフ(グレー)に切り替えます。
  3. 変更を保存を選択します。

有効に戻すには、上記と同じ手順でオン(青色)に切り替えます。

プロジェクト例

Terraformモジュールレジストリの例として、以下のプロジェクトをご覧ください:

トラブルシューティング

  • 重複した名前のモジュールを公開すると、{"message":"Access Denied"} エラーが発生します。重複するモジュール名の許可については、このイシューで議論が続いています。