Help us understand the problem. What is going on with this article?

Terraformのかゆい所に手をのばす 〜 meta-arguments 〜

この記事はフューチャー Advent Calendar 2019(2)の5日目の記事です。4日目の記事はKhdbbleさんのEbitenでImage操作 ~キャラクターを動かす~でした。筆者もゲームエンジンで遊びたくなりました。

はじめに

業務内で、Terraformのコードやissueを見ていると、「案外、知られていないのでは?」と思うような設定項目いくつかあることに気づきました。また、resourceごとにそれらが作成される際の個数や挙動を変えたいことがしばしばあり、ちょうどそのような内容のissueをいくつか担当しました。

本記事では、そんなTerraformのかゆい所に手が届く(かもしれない)resourceのmeta-argumentについてまとめてみます。

意外と知られていないmeta-argumentたち

resourceのmeta-argumentとは、どんなリソースタイプにも使えて、そのリソースの動作を変更できる設定のことです。

resourceで設定できるmeta-argumentは以下の通りです。

  • depends_on
  • count
  • for_each
  • provider
  • lifecycle
  • provisioner
  • connection

ここでは、depends_on, count, lifecycleを紹介します。
その他のmeta-argumentについては、こちらを参照してください。

depends_on

depends_onは、resourceの依存関係を解決するmeta-argumentです。すべてのresourceブロック内で利用可能です。「Terraformって、依存関係を自動的に見てくれるのでは?」と疑問に思われるかもしれませんが、参照関係がないresource間で依存関係を設定したい場合に、depends_onを利用します。

以下はAWSでの例です。リファレンスのコードを抜粋しました。

resource "aws_iam_role_policy" "example" {
  name   = "example"
  role   = aws_iam_role.example.name
  policy = jsonencode({
    "Statement" = [{
      # EC2がS3にアクセスするためのポリシー
      "Action" = "s3:*",
      "Effect" = "Allow",
    }],
  })
}

resource "aws_instance" "example" {
  ami           = "ami-a1b2c3d4"
  instance_type = "t2.micro"

  # aws_iam_instance_profile.exampleは定義済み
  # Terraformが参照から依存関係を推測します
  iam_instance_profile = aws_iam_instance_profile.example

  # S3へのアクセスが必要になるので、aws_iam_role_policy.exampleが作成されていて欲しい
  depends_on = [
    aws_iam_role_policy.example,
  ]
}

便利なdepends_onですが、リファレンスに「最終手段(last resort)」と、強気な書き方がされている1ように、利用する際は注意が必要です。

依存関係の管理はできるだけTerraformに任せるべきであり、、開発者が依存関係を考えながらコードを書くのは好ましくありません。
どうしてもdepends_onを利用する場合は、他の編集者に設定の意図が伝わるようにドキュメントやコメントを残し、depends_onに設定する依存関係は最小限なるように心掛けましょう。

count

countは数値を設定することで、設定されたリソースの個数を指定することができます。これもresourceブロックで利用可能です。例えば、GCPのリソースの場合は以下に使います。

variable "count_standard" {
  default = {
    "prod" = 1
    "dev"  = 2
  }
}

resource "google_compute_instance" "standard" {
  name         = "sample"
  count        = var.count_standard["${terraform.workspace}"]
  machine_type = "n1-standard-1"
  zone         = "asia-northeast1-b"

  boot_disk {
    initialize_params {
      image = "debian-cloud/debian-9"
    }
  }
  ...(以下略)...
}

この場合、prod環境2では1つ、dev環境では2つのGCEインスタンスが作成されます。
variableのブロックを別ファイルに書き出すことで、リソースの個数を別のファイルで管理することもできます。

lifecycle

lifecycleではTerraformのリソース操作を変更できます。こちらも全てのresourceブロック内で利用可能です。項目としては以下のようなものがあります。

  • create_before_destroy
  • prevent_destroy
  • ignore_changes

例えば、リソースによっては設定に変更があった場合、そのリソースを一度削除して再作成します。このとき、リソースの削除が再作成に先行してしまうと、もしそのリソースのへの参照を持ったリソースがある場合に名前解決ができなくなってしまいます。
そこでcreate_before_destroyを用います。先に新しい設定を取り込んだリソースを作成し、参照を切り替えた後に古いリソースを削除することで、参照元が名前解決できるようになります。

また、ignore_changesは特定の設定を無視するためのmeta-argumentです。

再作成の生じるリソースにおいて、設定を変更するたびに削除・作成が行われるのは、時間がかかることもあり、好ましくありません。そこで、ignore_changesで例えば、Terraform管理外のラベル(タグ)の変更を実体に反映させないことで、無駄な再作成を防ぐことができます。

終わりに

resourceのmeta-argumentについて紹介させていただきました。筆者もTerraform歴がまだまだ浅いので、これからもTerraformの利用方法についても考えていければと思います。


  1. https://www.terraform.io/docs/configuration/resources.html#depends_on-explicit-resource-dependencies 

  2. Workspace機能を利用すると、同じコードを環境ごとに使い分けることができます 

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした