最近、Terraform のベストプラクティス迷子です

記事タイトルとURLをコピーする

技術 1 課の水本です。

最近 Terraform のリファクタリングを行っているのですが、ベストプラクティス迷子になっています。

HashiCorp でも明確な方針は打ち出していない為、Terraform を利用する各プロジェクトで方針を決めているのが現実のようです。

今回は私が出会ってきた問題と、それについての対応、見解を書き連ねていきます。 あくまでも私が思ったことですので、「こうしたほうがいいよ!」というネタも募集しています。

workspace 使うのか使わないのか問題

結論として、私自身は workspace という機能を知ったものの、使うことは考えませんでした。

Terraform では workspace という個別のエリアを設けることが可能で、これを prod や staging と命名し作成しておくと、完全に環境を分離できるというメリットがあります。

ただしデメリットとして、「今どの workspace にいるのか」という判断がしづらく、「prod だけど apply しちゃっていい??」とか、特別な判定もないです。(あったらすいません)

これが私には許容できなかったので、今も workspace は使ってません。

環境の分割方法問題

既に、環境分離の手段として workspace は使わない、という話をしましたが、となると問題は「どのように環境を分離するのか」になります。

結論としては「環境別にディレクトリを作る」で、結局はこれがシンプルでした。

module 設計問題

Terraform ではルートディレクトリにある.tfファイルを自動的に読み込みます。(root module とも呼んだりします)

これとは別に、指定のディレクトリやリポジトリにあるファイル群を明示的に読み取ることが可能で、これを module と呼んでいます。

主な利用ケースとしては、module で変数を受け取れるようにしておき、設定内容の違うリソースを容易に作ったりする、といったものです。

module 自体は便利な機能なのですが、ここでもいくつか問題はあります。 それが分割単位の問題です。

分割単位というのは、主にリソースが構築/利用されるタイミングの洗い出しです。 私は下記のケースを考えています。

  • prod/stg 両方でそれぞれ構築する・・・common
    • 同一ではない、差分があるといったものはこの中で条件分岐処理する
  • 環境別に構築したりはしないが、両方で利用する・・・shared
  • 片方だけ構築する・・・prod or stg

私が出会ったものだと、「shared にあるべきものが common にあり、stg 側のリソースに利用実態が無かった」「prod にあるべきものが common にあった」が実際にありました。

これは後々のリファクタリングに影響を及ぼす為、最初に定義しておいたほうが良いでしょう。

自作 module か、公式 module か問題

Terraform で使える module は自身で作成する他に HashiCorp でも提供しており、自由に選ぶことができます(便宜的に公式 module と呼びます)。

ただし公式 module は実際に設定したい内容ができない、いわゆる「かゆいところに手が届かない」ということもあり、止む無く自作するということが少なくないと思います。

なるべくなら手間を省きたいところなのですが、私も上記の経験があり、「結局は自作だな」というところに落ち着いてしまっています。

仕様を公式 module に合わせる、というスタンスなら公式 module で良いでしょう。

variable の配置方法問題

Terraform で変数を使うにはvariableにて宣言が必要です。

root module と module の間でパラメータとして利用する場合、両方に同じ変数の宣言が必要なのですが、これらの配置について様々な検討事項があります。

  • ファイル分割するか
    • ケースによる。定義数が膨らんだ場合はvariables.tfなどに切り出す
  • 格納データの型
  • デフォルト値設定有無
    • 基本的に設定せず、root module で指定する

おわり

「今も迷子である」という記事ですので特に締める言葉もないのですが、Terraform の利用にあたって現状浮かぶ問題は大体こんな感じだと思います。

他にもvar.envを必ず Name タグに含めるとかはありますが、CloudFormation でも変わらずやることについては割愛しています。