0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Terraformでのリソースの引数の並びの考え方

Last updated at Posted at 2022-11-30

Terraformの設定(*.tfファイルを設定(Configuration)と公式には呼びます)は逐次実行的なロジックがほとんど書けないので人によって極端にひどいコードになることは少ないです。
ただ、比較的人によってばらつきがあるのがリソースの引数です。この記事ではよりわかりやすいであろう引数の並び順について考えてみます。
以下で書くのはあくまで一般的な場合の推奨であり、各リソース宣言の事情によっては無視したほうが良いことは書いておきます。

特別で全体に影響する引数は先頭に書く

特別で全体に影響する引数 とは次のような引数のことです。

  • for_each
  • count
  • source
  • provider
  • providers

例えば count 引数によって場合により作らない設定になっているとします。もし count 引数がリソース末尾にあると、たくさんの引数を見た結果最終的にそのリソースを作らないことに最後に気づく場合があるかもしれません。
他の引数についてもリソースのより根本に関わる設定であるため、なるべく先頭に書いておいたほうがいいでしょう。

意味的集合ごとに固める(semantic)

意味合いが近い引数ごとに固めて書きましょう。理由は、同時に変更することが多く変更漏れが発生しづらいからです。

以下の例では azs, private_subnets, public_subnets の固まりなどがわかりやすいと思います。

module "vpc" {
  source = "terraform-aws-modules/vpc/aws"

  name = "my-vpc"
  cidr = "10.0.0.0/16"

  azs             = ["eu-west-1a", "eu-west-1b", "eu-west-1c"]
  private_subnets = ["10.0.1.0/24", "10.0.2.0/24", "10.0.3.0/24"]
  public_subnets  = ["10.0.101.0/24", "10.0.102.0/24", "10.0.103.0/24"]

  enable_nat_gateway = true
  enable_vpn_gateway = true

  tags = {
    Terraform = "true"
    Environment = "dev"
  }
}

悪い例をあげます。

resource "aws_wafv2_web_acl" "example" {
  name        = "example"
  scope       = "REGIONAL"

  default_action {
    allow {}
  }

  rule {
    ... 30行ぐらいの長い量
  }

  visibility_config {
    cloudwatch_metrics_enabled = false
    metric_name                = "example"
    sampled_requests_enabled   = false
  }
}

この例では、 name 引数と metric_name は明らかに同じ名前をつける意図があります。
しかし、その2つの引数の間に rule というとても長い行が入っているため name を書き換えたときに metric_name の書き換えを忘れるということが容易に発生しえます。そのため、 namemetric_name を含む visibility_config ブロックは隣り合わせるかすぐ上下に配置したほうがいいでしょう。

重要な引数を前に、そうでないものを後ろに書く

重要度低い引数とは以下のような性質を持つ引数です。

  • その値が何であってもどうでもいい
  • 非破壊的に値が変更可能

awsで言えばtagのような引数がそれに当たります。より重要度の高い引数がすぐに目に入ったほうがよいので、そのような重要度の低い引数は宣言の後半に持ってきましょう。

module "vpc" {
  source = "terraform-aws-modules/vpc/aws"

  name = "my-vpc"
  cidr = "10.0.0.0/16"

  azs             = ["eu-west-1a", "eu-west-1b", "eu-west-1c"]
  private_subnets = ["10.0.1.0/24", "10.0.2.0/24", "10.0.3.0/24"]
  public_subnets  = ["10.0.101.0/24", "10.0.102.0/24", "10.0.103.0/24"]

  enable_nat_gateway = true
  enable_vpn_gateway = true

  tags = {
    Terraform = "true"
    Environment = "dev"
  }
}

引数名のアルファベット順で書く

アルファベット順に引数を書く方式です。利点はルールが非常に単純であることと、Terraformのドキュメントの引数の説明はアルファベット順でソートされているため見やすいというちょっとした利点があります。

個人的にはこれはあまりいいルールだと思っていません。その理由は2点あります。1点目はセマンティックではないために関連する引数が一元化されておらず、設定変更漏れが発生しやすく認知負荷も高いからです。2点目はアルファベット順のソートは人間が努力で維持することは難しいためです。単純にアルファベット順に書いていることに気づいていない人が末尾に追加してしまうこともあるでしょうし、単純にアルファベット順の追加位置を間違う可能性があります(vpc_private_subnet_id と vpc_private_public_id のどちらがどちらの後であるかぱっとわかりますか?)。
formatterによる自動ソート機能があれば2つ目の問題は一応解決するためだいぶ選択肢としてマシになります1

sponsored

この記事はSpeeeでの業務中に60分で書きました。

  1. Terraform用のこういったフォーマッタがあるかは不明。たぶんない

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?