Terraform CloudのPrivate Registryを使ってmoduleを組織内に公開してみる
「組織内でmoduleを使い回したい」
Terraformを運用しているとリポジトリを跨いでmoduleを使い回したくなることがあると思います。
そんな時には、Terraform CloudのPrivate Registryが便利です。
Private RegistryはTerraform CloudのFreeプランでも使えます。
HashiCorp Terraform Cloud Pricing
Terraform moduleの公開
Terraformは、moduleを公開することで別のリポジトリでも公開したmoduleを使うことができます。
moduleを公開する方法はいくつかありますが、今回は以下の2つを紹介します。
- Terraform Registry
- 全世界に公開
- Terraform Cloud Private Registry
- 組織内に公開
Module Sources | Terraform | HashiCorp Developer
Terraform Registry
Publicに公開する場合は、Terraform Registryを使うことができます。 Terraform Registryに公開したmoduleは、全世界の誰でも使用することができます。
Terraform Registryに公開する条件は以下です。
- リポジトリはGithubで、公開設定がPublicに設定されている
- リポジトリの命名が、
terraform-[PROVIDER]-[NAME]
- 例) terraform-aws-ec2-instance
- リポジトリのdescriptionが設定されていること
- 標準モジュール構造に準拠していること
- リリースタグ名がセマンティックバージョンであること
- 例) v1.0.5 v0.9.2
Terraform Registry - Publishing Modules | Terraform | HashiCorp Developer
Terraform Cloud Private Registry
Private Registryでできることは、主に2つあります。
- 組織内にmodule/providerを公開
- Public module/providerを登録
1つ目は、先ほど紹介したリポジトリの公開設定をPrivateのまま、組織内にmoduleを公開できることです。
2つ目は、Public module/providerを登録できることです。 事前にチーム内で承認されたPublic module/providerを登録しておくことで、「このmoduleは使っていいんだっけ」という確認の手間を減らせます。
ガバナンスを効かせることにもつながると思います。
Private Registry - Terraform Cloud | Terraform | HashiCorp Developer
Private RegistryとTerraform Registryの異なる点
異なる点としては以下です。
- Private Registryでは、リポジトリの公開設定がPrivateでもOK
- Private RegistryではGithub以外のVCSも使用可能
- Terraform Cloudが対応しているVCS(Gitlab、Bitbucketなど) を使用できる
moduleを公開する条件(モジュール構造、命名規則)は、Terraform RegistoryとPrivate Registryはほぼ同様です。
他にはNo-Code provisioningという機能が使えることも、Private Registryの特徴かと思います。
No-Code provisioningはTerraform CloudのGUI上からパラメータを渡すだけで、リソースを作成できる機能です。
やってみた
実際にTerraform CloudのPrivate Registryを使って、moduleを公開してみます。
以下のチュートリアルをやってみます。 Githubを使った手順はこちらのチュートリアルにあるので、今回はGitlabを使ってみます。
このチュートリアルでは、S3静的Webサイトホスティングのリソースを構築できるmoduleをPrivate Registryに登録します。 その後、実際に他のリポジトリで登録したmoduleを使用できるか確認します。
サンプルリポジトリの用意
Gitlab上で、terraform-aws-s3-webapp
という名前でリポジトリを作成しておきます。
この際、リポジトリの公開範囲はPrivateとしておきます。
サンプルリポジトリをローカルにCloneして、Gitlab上にPushします。
hashicorp/learn-private-module-aws-s3-webapp
$ git clone git@github.com:hashicorp/learn-private-module-aws-s3-webapp.git $ git remote add gitlab git@gitlab.com:[Organization名]/terraform-aws-s3-webapp.git $ git push gitlab HEAD
以下の状態になっていればOKです。
その後、Gitlab上でタグを切ってリリースします。
これでGitlab上の準備完了です。
Private Registryの設定
ここからはTerraform Cloudの設定です。
Registry
->Publish
-> Module
の順に選択します。
前の手順で作成したリポジトリを選択します。
ちなみに、terraform-[PROVIDER]-[NAME]
の命名規則に沿っていないものは表示されず選択できません。
今回は通常のmoduleのため、No-code provisioningのチェックは外したままにPublish module
を選択します。
moduleを登録できました!簡単ですね。
moduleのページでは、InputsやOutputの情報が確認できます。
この情報はterraform-docsのように、moduleのtfファイルから自動的に生成してくれます。
別リポジトリから登録したmoduleを使用する
登録したmoduleを使ってみましょう。
moduleを呼び出す用のサンプルリポジトリをForkして、ローカルにcloneします。
hashicorp/learn-private-module-aws-s3-webapp
s3-webappのmoduleを呼び出すだけのシンプルな構成です。 Organization名のところを置き換えて、Pushしておきます。
provider "aws" { region = var.region } module "s3-webapp" { source = "app.terraform.io/[Oragnization名]/s3-webapp/aws" name = var.name region = var.region prefix = var.prefix version = "1.0.0" }
実行の確認のために、変数を設定してWorkspaceを作成します。
認証情報をWorkspaceに設定したらRunを実行します。
Planの結果から、moduleを呼び出せていることが確認できたので成功です。
Tips: CLIでやってみる
まずは何も変更せず、前回のコードのままterraform init
してみます。
Tokenがない場合、Terraform Cloud内のPrivate Registryからmoduleを取得できないため失敗します。
(terraform login
でTokenをすでに作成している場合は成功します。)
$ terraform init Initializing modules... ╷ │ Error: Error accessing remote module registry │ │ Failed to retrieve available versions for module "s3-webapp" (main.tf:14) from app.terraform.io: error looking up module versions: 401 │ Unauthorized. ╵ ╷ │ Error: Error accessing remote module registry │ │ Failed to retrieve available versions for module "s3-webapp" (main.tf:14) from app.terraform.io: error looking up module versions: 401 │ Unauthorized.
失敗する場合は以下コマンドを実行して、Terraform CloudのTokenを作成します。
$ terraform login # プロンプトに従って情報を入力
再度コマンドを実行すると、コマンドが成功してmoduleがインストールされることを確認できます。
$ terraform init $ ls -1 .terraform/modules modules.json s3-webapp
一応上記の設定で、CLIから実行できます。
しかし、stateファイルがTerraform Cloudに保存されません。
そのため、cloud
ブロックを追加して利用するWorkspaceを指定することをお勧めします。
terraform { cloud { organization = "[Organization名]" workspaces { name = "learn-private-module-root" } } } provider "aws" { region = var.region } module "s3-webapp" { source = "app.terraform.io/[Oragnization名]/s3-webapp/aws" name = var.name region = var.region prefix = var.prefix version = "1.0.0" }
変更後、terraform init
を実行するとTerraform Cloudにファイルが保存されます。
おわりに
Terraform CloudのPrivate Registryを使用した組織内へのmodule公開でした。
マルチレポのケースであったり、インフラの中央チームがあってmoduleを提供・各チームはそのmoduleを使用したい場合かなり便利な機能かと思います。
今は小規模でも将来的にmoduleを使い回して効率を上げたい場合は、ぜひ利用してもらいたい機能です。
以上、AWS事業本部の佐藤(@chari7311)でした。