dshimizu/blog/alpha

とりとめのないITブログ

Terraform の設計時に考えたりしていること

はじめに

数年振りに Terraform を触っていて、設計時に検討すべきことが色々あっていつも迷うので簡単にまとめてみます。

目次

検討項目

以下のようなことを検討します。

命名規則

細かいルールに関してはチーム内で決める必要はありますが、大枠は以下に則ります。

Google Cloud のドキュメントの下記は参考になります。

単語の区切りにはアンダースコアを使用します。 リソースタイプの 1 つ(モジュール全体の単一のロードバランサなど)に対する参照を簡素化するため、リソースに main という名前を付けます。 同じタイプのリソースを区別するには(たとえば、primary と secondary)、意味のあるリソース名を指定します。 リソース名を単数形にします。 リソース名でリソースタイプを繰り返さないでください。

Terraform と provider のバージョン管理

下記のような env 毎にディレクトリを細分化する場合、特に初期構築時等は terraform init をするタイミングによって provider のバージョンに微妙な差分が出やすいので、共通のものを利用できるようにパッチバージョンまで定義します。

terraform {
  # * Terraform のバージョン定義
  required_version = "~> 1.2.0"

  # * provider とそのバージョンの定義
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 5.8.0"
    }
  }

  backend "s3" {
    bucket = "hogehoge-terraform-bucket"
    key = "xxxx/terraform.tfstate"
    region = "ap-northeast-1"
  }
}

Terraform 自体のバージョン管理のベストプラクティスは、required_version = "~> 1.0.0" のような形として、 ~> を利用してメジャーバージョンとマイナーバージョンを固定することのようです。

Provider のバージョンは Provider によると思いますが、AWS用のProviderは結構頻繁にマイナーバージョンもリリースされている印象なので、慎重に行くなら、メジャーバージョンとマイナーバージョンを固定した方が安全かなと思います。 メジャーバージョンがリリースされると原則旧バージョンへの修正はされなくなるようなので、定期的なバージョンアップは必要になりそうです。

.terraform.lock.hcl

.terraform.lock.hcl は、利用している Provider の各プラットフォーム用のバージョンのチェックサムを記録したロックファイルになると思ってます。

これの扱いについてはあまりわかっておらず、v1.4 未満の環境では .gitignore で誤魔化してましたが v1.4 から色々変わったようで、特にローカルと外部でCIなどを組み合わせて動かしている場合は運用を検討する必要がありそうでした。

modules /ディレクトリ構成、tfstate の粒度/分割範囲

例では main.tf ファイルとしていて、それのみ記載してますが、variables.tf, outputs.tf など配置します。場合によっては main.tf の中身を hogehoge.tf などに分割していきます。 main.tf には特定のAWSリソース単位で定義するのではなく、ある程度ライフサイクルの同じものでまとめるようにしてます。 modules もある程度のカタマリになるように検討します。

tfstate を小さく保ちたいのでディレクトリ構成自体は結構ごちゃごちゃしてますが、この辺はトレードオフと割り切ってます。やっていくうちに変更したくなると思います。 provider に関しては、1つファイルを作って、必要なディレクトリにシンボリックリンクを貼る、とかが良さそうです。

├── backend/
│   ├── environments/
│   │   ├── dev/
│   │   │    └── main.tf
│   │   └── prod/
│   │      └── main.tf
│   └── modules/
│       ├──  backend/
│       │   └── main.tf
│       └──  waf/
│           └── main.tf
├── database/
│   ├── environments/
│   │  ├── dev/
│   │  │    └── main.tf
│   │  └── prod/
│   │     └──  main.tf
│   └── modules/
: 
:  
└── common/
   └── networks/
        ├── environments/
        │  ├── dev/
        │  │   └──  main.tf
        │  └── prod/
        │       └──  main.tf
        └── modules/
                └──  vpc/
                      └──  main.tf

その他

全体的に複雑にならないように、凝った書き方や三項演算子の多用を避けて、シンプルに素朴に書くようにしてます。 この辺も Google Cloud のドキュメントが参考になります。

参考