APC 技術ブログ

株式会社エーピーコミュニケーションズの技術ブログです。

株式会社 エーピーコミュニケーションズの技術ブログです。

Terraform CloudでModuleをPrivate Registryに登録して利用する

はじめに

こんにちは、ACS事業部の安藤です。
これまでOSSのIaCツールとしてTerraformを使ってきて、Github ActionsやAzure PipelinesでCI/CDを実施してきたのですが、
Terraform Cloudのみで使える魅力的な機能が続々と登場しているので遅まきながら触り始めました。

早速、魅力的な機能を使っていきたいところですが、まずはFreeプランで利用できる基本的な機能であるPrivate Registryから触っていきたいと思います。

準備

  • Terraform Cloud アカウント(Freeプランで可能)
  • Githubアカウント

実践

Terraform Module用リポジトリの作成

ここでは例としてAzureのResource Groupを作成するモジュールを作成します。
利用可能なAzure環境がない場合などは Terraform Registry から適当なモジュールのリポジトリをフォークしてきましょう。

Terraform Module用リポジトリの命名規則

リポジトリ名なんてなんでもいいように思いますが、Private Registryとして登録するためには命名規則に従う必要があります。
terraform-<PROVIDER>-<NAME>という3部構成の名前形式になります。

必ずterraform-で始まり、<PROVIDER>にはazureやawsなどのプロバイダー名を小文字で記載し、
それ以降が<NAME>ブロックとして識別され、Private Registryに登録された際のモジュール名に当たる部分になります。

developer.hashicorp.com

Terraform Moduleの作成

リポジトリができたので早速モジュールを作っていきます。
以下のファイルを作成してリポジトリにCommit&Pushします。

main.tf

resource "azurerm_resource_group" "group" {
  name     = var.name
  location = var.location
  tags     = var.tags
}

variable "name" {
  type  = string
}

variable "location" {
  type  = string
}

variable "tags" {
  default = {}
}

output "name" {
  value = azurerm_resource_group.group.name
}

output "id" {
  value = azurerm_resource_group.group.id
}

リリースタグを付けてリリースする

以上で通常のTerraform Moduleとしては機能しますが、Private Registryに登録するにはもう一手間あります。
x.y.zというセマンティックバージョンの形式でリリースタグを付与する必要があります。

Terraform CloudのPrivate RegistryにModuleを登録する

Terraform Module用のリポジトリにリリースタグを付けたらTerraform Cloudの操作に移ります。

初期状態でGitHubとの連携が済んでない場合は、以下の記事のWorkspace の作成で認証を済ませてください。

techblog.ap-com.co.jp

Registryの画面を開くとこのような画面が表示されていると思いますので、Publish a moduleをクリックします。

Add Moduleの画面が出てくるのでConnect to a version control providerと指示があるのでGitHubのアイコンをクリックします。

GitHub連携に問題がなければ以下のように先程作成したTerraform Moduleのリポジトリが表示されるはずですので、リポジトリ名をクリックします。

確認画面が出てくるのでPublish moduleを選択しましょう。

登録をしばらく待つと以下のような画面が出てきて登録が完了します。

各メニューを見てみるとコードに書いた各ブロックの説明が自動的に作成されます。
各ブロックにDescriptionパラメーターに説明を記述すればこちらにも反映されます。

Input

Output

Resources

画面の右側にもいくつかメニューがあり、Copy configuration detailsにこのモジュールの使い方の例が記載されています。

Terraform デプロイ用リポジトリの作成

それでは上で登録したPrivate Registryのモジュールを利用してデプロイをしてみようと思います。
こちらもGitHubに別のリポジトリとして作成します。今度は特に命名規則はないので適当にsample-resource-groupとしました。

terraformファイルの作成

リポジトリに以下の内容でファイルを作成します。
実際に作成する場合はmodule内のsourceは各自のPrivate Registryで記載されているアドレスに変更してください。

main.tf

provider "azurerm" {
  features {}
}

module "resource-group" {
  source  = "app.terraform.io/trail-ando/resource-group/azure"
  version = "0.1.0"
  
  name     = "test"
  location = "japaneast"
}

Terraform CloudにWorkspaceを作成

今作成したリポジトリを今度はTerraform CloudのWorkspaceとして追加します。

sample-resource-groupを選択して、sample-resource-groupというWorkspaceを作成しました。

Azureの認証情報を作成

早速デプロイしたいところですが、今のままではAzureのどのサブスクリプションに作成するかやそのクレデンシャル情報がありません。
ドキュメントもしくは別記事のAzureの認証設定からOIDC認証の設定をしましょう。

Azure側でAzure AD アプリを作成し、フェデレーション資格情報には、
サブジェクト識別子としては organization:<Organization名>:project:<Project名>:workspace:<Workspace名>:run_phase:<action>
<action>にはplan, applyの2つの資格情報を登録します。

Project名は特に設定していない場合は Default Projectに所属しています。スペースはそのまま記入してOKです。
私の場合は以下のような識別子になります。

organization:trail-ando:project:Default Project:workspace:sample-resource-group:run_phase:plan
organization:trail-ando:project:Default Project:workspace:sample-resource-group:run_phase:apply

Azureの認証情報をWorkspaceの環境変数に設定

WorkspaceのメニューにあるVariablesで以下の変数を登録しましょう。
変数はデフォルトではTerraform変数として登録されるのでEnvironment variableにチェックして環境変数として登録してください。
TFC_AZURE_PROVIDER_AUTH 以外はセキュアな情報なので Sensitiveのチェックを入れて値が見えないようにしたほうがいいでしょう。

変数名 変数種別
TFC_AZURE_PROVIDER_AUTH true 環境変数
TFC_AZURE_RUN_CLIENT_ID アプリのクライアントID 環境変数
ARM_SUBSCRIPTION_ID サブスクリプションID 環境変数
ARM_TENANT_ID テナントID 環境変数

これでようやく準備は完了です!

※補足情報 複数モジュールの一括登録(サブモジュール)

いまご紹介した方法では1リポジトリに1モジュールが配置されていました。
モジュール数が多い場合などは、1リポジトリで複数のモジュールを管理していることもあると思います。私もそうでした。

そういった場合に利用できる機能としてサブモジュールがあります。

利用方法は簡単でGitHubリポジトリの直下にmodules/ディレクトリを作成し、
その中にモジュール毎のディレクトリを配置していくだけです。

.
├── README.md
└── modules
    ├── module_a
    │   ├── main.tf
    │   └── variables.tf
    ├── module_b
    ├── module_c
…

このようなファイル構成にしてからPrivate Registryに登録すると以下のようにSubmodulesのプルダウンから複数のモジュールが選択できるようになります。

module "module_a" {
  source  = "app.terraform.io/trial-ando/multi-modules/azure//modules/module_a"
  version = "0.1.0"
  # insert required variables here
}

Terraform Plan & Deploy!

Workspace内であればどこでもActionsボタンがあります。
ActionsボタンをクリックしてStart new runのプルダウンを選択し、
さらに出てくるメニューでPlan and applyのままStart runすればPlan & Deployが開始します。

登録情報に問題なければデプロイ用リポジトリに記載したリソースグループが作成されるはずです。
もしうまくいかないようであればエラーに従って、Azureの認証情報やモジュールのsource URL等を見直してみてください。

Terraform Destroy

動作の確認ができたらクリーンアップしましょう。Terraform CloudからDestroyを実行することも可能です。
WorkspaceメニューのDestruction and DeletionからQueue destroy planボタンをクリックしましょう。

GitHubなどと同様に削除にはWorkspace名を記入する必要があるので、記入して改めてQueue destroy planボタンをクリックします。

Planの内容を確認して問題なければConfirm & ApplyをクリックしてDestroyを実行しましょう。

おわりに

Private Registryの登録方法およびモジュールの利用法をご紹介しました。いかがだったでしょうか?
個人的には思っていたよりルールや制約があるんだなあ、というのが印象的でした。
モジュールのリリースタグの発行が必要な部分については、
利用する側にとっては内容の不変性が保証されていたり任意のタイミングでバージョンアップができるなどのメリットはありますが、
モジュールを開発する側にとっては一癖あるな、と感じました。
リリースタグを発行(=Private Registryの登録)する前にどこかで動作確認してその後リリース、というフローが必要そう…GitHub Actionsで実現できるだろうか?など色々考えることがありそうですね。

その辺りの良さげなプラクティスが出てきたらまたお知らせしたいと思います。

私達ACS事業部はAzure・AKSなどのクラウドネイティブ技術を活用した内製化のご支援をしております。

www.ap-com.co.jp

また、一緒に働いていただける仲間も募集中です!
今年もまだまだ組織規模拡大中なので、ご興味持っていただけましたらぜひお声がけください。

www.ap-com.co.jp

本記事の投稿者: 安藤 知樹
AzureとTerraformをメインにインフラ系のご支援を担当しています。 Shunsuke Yoshikawa - Credly