💨

terraform モジュールとは(基本内容のメモ)

2024/08/28に公開

概要

terraformは業務で1年程使ってたのについ最近になってterraformモジュールという概念を知ったオジサンがモジュールについて改めて学習(公式doc読んだ)した時のメモ書きみたいな内容です。

ちなみにterraformモジュールはこちらで教わりました。
【8月23日開催】Getting Started with Terraform for Google Cloud
ありがとうございますG-genさん。(過去イベなんでその内リンク消えるかも。。)

同様のイベントは定期的に開催してるようなので、terraformはじめの方にはおすすめです。
私はG-genの関係者ではありません。

terraformモジュールとは

.tfファイルで構成されるディクトリ単位で区切られた再利用可能なファイル群。
また公開されてる利用可能なモジュールも沢山あって便利に活用できる。
再利用可能という所で、一部のみ設定の違う同様の複数リソースを簡潔なコードで書くことができたり、"resource"ブロックをいちいち書かなくて済むようになるし、便利だから積極的に利用すると良いよ、といったもの。

ちなみに公式docはこちらのページ

公式docメモ(モジュールブロック、モジュールソース)

terraformモジュールについて公式docのモジュールブロック、モジュールソースのページを見ながら概要を確認してきます。

モジュールブロック(呼び出し側)

モジュールブロック(公式doc)

まず呼び出し側のモジュールブロックの使い方を確認。

モジュールブロック定義の基本形

module "servers" {
  source = "./app-cluster"

  servers = 5
}

呼び出しについては以下のように記載されてます。
この入力変数に、、、という所が結構要なわけですが気づいたら記事が長々になったので今回は割愛します。
(ほんとは割愛すべきじゃないとこな気がしてますが)

モジュールを呼び出すということは、そのモジュールの内容を、入力変数に特定の値を指定して構成に含めることを意味します 。モジュールはmodule、ブロックを使用して他のモジュール内から呼び出されます。

main.tfなどこれまでresourceブロックをツラツラと書いているファイルにこのようなmoduleブロックの定義を書く事でモジュールを呼び出すことができるようになります。
(ドキュメントにこのような書き方はされてないですが、そういうことです)

モジュールブロックの定義について(引数の説明など)

  • "servers"の部分は任意の名前つける部分
  • source引数は必須。ここでlocalのモジュールのあるパスやリモートのモジュール名を指定
    • sourceについては後述のモジュールソースの部分でも詳細を記載
  • version引数は省略可能だが、registryのモジュールを使う際はバージョン更新による予期せぬ挙動変更などの可能性があるので、バージョン固定で使うのが推奨のようです。
  • その他の引数はモジュールごとに変わってくる。呼び出し元となるモジュールで定義してる値を使用することになります。
  • for_each, depends_onなども使えるよ、とのこと

モジュールブロックを使う時はterraform init
このモジュールブロックの追加、削除、修正などを行った際は、その後必ずterrafomr initを実行すること。
また、利用するモジュールの最新バージョンを利用するようにversionを更新した際はinitコマンドに-upgradeのオプションをつけてね、とのことです。

モジュールブロックを削除すると、リソースは削除される

デフォルトでは、moduleブロックを削除すると、Terraform はそのモジュールで宣言された管理中のリソースをすべて破棄するように計画します。

でもremovedブロックで書き換えておく事で、実際のリソースは削除されないで済むようになるとのこと。
これはちょっと頭の片隅に置いておいた方が良さそうですね。

公式doc上ではこのほかにメタ引数、output、removedブロックなど詳細が書かれておりますが本記事では割愛とさせていただきます。(というか自分が現段階でその辺の理解追いついてない)

モジュールソース(呼び出される側)

モジュールソース(公式doc)

上述もしてますが、モジュール使う時はterraform initしようと。
これでインストールするよと。

モジュール種別
モジュールのsourceで指定できる種別としてはこれだけあるよと。
公式docにはそれぞれのsourceの種別ごとの詳細な使い方も記載してます。

ローカルパス
テラフォームレジストリ
GitHub
ビットバケット
汎用Git、Mercurialリポジトリ
HTTP URL
S3 バケット
GCS バケット
パッケージサブディレクトリ内のモジュール

ローカルのモジュールとリモートのモジュールの使い分けについて

繰り返しのコード要素を分離する目的で主に使用される密接に関連するモジュールにはローカル ファイル パスを使用し、複数の呼び出し構成で共有することを目的としたモジュールにはネイティブ Terraform モジュール レジストリを使用することをお勧めします。

何となく分かるような、分からないような、、

とりあえず今回の記事でも一部モジュール種別の定義方法について簡単に記載してこうと思います。

ローカル

./または../で始まる必要がある。リモートのものとの区別のためで、絶対パス記法だとリモートモジュール扱いになる、といった説明があります。

テラフォームレジストリ(Terraform Registry)

こちらから"Browse Modules"一覧を検索できます。

各種クラウド対応のものも配置されてるリモートのモジュールファイル一覧といったところでしょうか。

定義の基本形は以下のような形式。

module "consul" {
  source = "hashicorp/consul/aws"
  version = "0.1.0"
}

sourceの部分は<NAMESPACE>/<NAME>/<PROVIDER>という形式になってるようです。
各種モジュールごとの詳細ページに正確なアドレスが定義されてます。

GitHub

githubにあるモジュールの定義の基本形はこれ

モジュール"consul" {
  ソース= "github.com/hashicorp/example" 
}

この記法はHTTPS 経由でクローンされるようです。
SSH経由のクローンの場合はsource = "git@github.com:hashicorp/example.git"の形式。

ちなみにgithubにあるものも使えるものは多くあるけど、第三者によって作成されたもので信憑性が薄いモノもあるので、基本的にはterraform registryの公式のものがお勧めですよ、との話も。
込み入った用途での利用時にregistryには無くて、githubに第三者による作成の丁度良いモジュールとかあるかもですね。

S3バケット(aws)

awsのS3にモジュールを配置して使うことも可能。
定義の基本形はこんな感じでオブジェクトURLを使うようでs3::のプレフィックスで識別してる。

module "consul" {
  source = "s3::https://s3-eu-west-1.amazonaws.com/examplecorp-terraform-modules/vpc.zip"
}

注意: AWS の us-east-1 リージョンのバケットでは、ホスト名s3.amazonaws.com( ではなくs3-us-east-1.amazonaws.com) を使用する必要があります。

という注意点があるようです。

あとはS3(aws)に接続するってことで、ローカルからS3のモジュール取得する際はAPI使用時同様AWS_ACCESS_KEY_IDなどの変数設定やら.aws/credentialsなど設定しておいてくださいねと。

GCSバケット(Google Cloud)

awsのS3同様、GCSバケットに配置も可能だよと。
定義の基本形はこんな感じでオブジェクトURLを使うようでgcs::のプレフィックスで識別してる。

module "consul" {
  source = "gcs::https://www.googleapis.com/storage/v1/modules/foomodule.zip"
}

gcs::https://www.googleapis.com/storage/v1/BUCKET_NAME/PATH_TO_MODULEという形式のようです。

こちらもaws同様、Google Cloudに接続するってことで、API利用時に設定するような環境変数GOOGLE_OAUTH_ACCESS_TOKENなどの設定してくださいねと。(Google Cloudわからんです)

ちなみに私が受けた【8月23日開催】Getting Started with Terraform for Google Cloudの会では、Google Cloudのcloudshellを使う事で上記のような変数設定とか不要でterraformもすぐ使えて便利、といった感じでcloudshellを用いてterraform実行のハンズオンを行ってました。

awsとGoogle Cloudのregistry

この2大クラウドのレジストリはきっとよく使う事になると思われるので自身のためにもリンク貼り。

awsのリモートモジュール(registry)

awsのリモートモジュール集の探索はこちら。
https://registry.terraform.io/search/modules?namespace=terraform-aws-modules

Google cloud(registry)

Google cloudのリモートモジュール集の探索はこちら。
https://registry.terraform.io/search/modules?namespace=terraform-google-modules

さいごに
そもそも当初はこの2大クラウドのregistryのモジュールを使って基本的なリソース作成を行ってみるような内容にしようと思ったのですが、入りのモジュールについての把握(ドキュメント読み)を始めたら思いのほか時間がかかってしまい記事もただの説明オンリーになってしまいました。
次は実際に使ってリソース作成を試みる、という宣言で今回はこれにて終了。

Discussion