NRIネットコム Blog

NRIネットコム社員が様々な視点で、日々の気づきやナレッジを発信するメディアです

terraform planコマンドを見やすく効率的にする2つのオプション

こんにちは、後藤です。
みなさま、Terraformは使っていますでしょうか。私はようやく慣れてきたところです。
今回はTerraformの中でもterraform planコマンドについて話します。

はじめに

Terraformを使ってリソースを構築する際の一般的な流れは、terraform planで実際に設定されるリソースを事前確認し、terraform applyで実際に適用する、になるかと思います。この時、terraform plan > plan.txtのように証跡用や、表示結果を見やすくするためにファイル出力をすることがあると思います。しかし、このコマンドで出力されたファイルは決して見やすいものではありません。例えば、セキュリティグループとそのルールを定義したtfファイルで実行した結果は以下のようになります。
plan.txt

Terraform used the selected providers to generate the following execution
plan. Resource actions are indicated with the following symbols:
  [32m+[0m create[0m

Terraform will perform the following actions:

[1m  # aws_security_group.SG[0m will be created
[0m  [32m+[0m[0m resource "aws_security_group" "SG" {
      [32m+[0m[0m arn                    = (known after apply)
      [32m+[0m[0m description            = "Managed by Terraform"
      [32m+[0m[0m egress                 = (known after apply)
      [32m+[0m[0m id                     = (known after apply)
      [32m+[0m[0m ingress                = (known after apply)
      [32m+[0m[0m name                   = "exmaple"
      [32m+[0m[0m name_prefix            = (known after apply)
      [32m+[0m[0m owner_id               = (known after apply)
      [32m+[0m[0m revoke_rules_on_delete = false
      [32m+[0m[0m tags_all               = (known after apply)
      [32m+[0m[0m vpc_id                 = "vpc-XXXXXXXXXXXXX"
    }

[1m  # aws_security_group_rule.SG-rule[0m will be created
[0m  [32m+[0m[0m resource "aws_security_group_rule" "SG-rule" {
      [32m+[0m[0m cidr_blocks              = [
          [32m+[0m[0m "0.0.0.0/0",
        ]
      [32m+[0m[0m from_port                = 0
      [32m+[0m[0m id                       = (known after apply)
      [32m+[0m[0m protocol                 = "-1"
      [32m+[0m[0m security_group_id        = (known after apply)
      [32m+[0m[0m security_group_rule_id   = (known after apply)
      [32m+[0m[0m self                     = false
      [32m+[0m[0m source_security_group_id = (known after apply)
      [32m+[0m[0m to_port                  = 0
      [32m+[0m[0m type                     = "egress"
    }

[1mPlan:[0m 2 to add, 0 to change, 0 to destroy.
[0m[90m
─────────────────────────────────────────────────────────────────────────────[0m

Note: You didn't use the -out option to save this plan, so Terraform can't
guarantee to take exactly these actions if you run "terraform apply" now.

余計な情報が多くてぱっと見で分かりにくいですね。 そこでオプションをつけることで、より分かりやすくなるようにします。

方法1:-no-colorオプションを使う

オプションがいくつか用意されているので、terraform plan -no-color > plan.txtを実行してみると以下のようになります。

Terraform used the selected providers to generate the following execution
plan. Resource actions are indicated with the following symbols:
  + create

Terraform will perform the following actions:

  # aws_security_group.SG will be created
  + resource "aws_security_group" "SG" {
      + arn                    = (known after apply)
      + description            = "Managed by Terraform"
      + egress                 = (known after apply)
      + id                     = (known after apply)
      + ingress                = (known after apply)
      + name                   = "exmaple"
      + name_prefix            = (known after apply)
      + owner_id               = (known after apply)
      + revoke_rules_on_delete = false
      + tags_all               = (known after apply)
      + vpc_id                 = "vpc-XXXXXXXXXXXXX"
    }

  # aws_security_group_rule.SG-rule will be created
  + resource "aws_security_group_rule" "SG-rule" {
      + cidr_blocks              = [
          + "0.0.0.0/0",
        ]
      + from_port                = 0
      + id                       = (known after apply)
      + protocol                 = "-1"
      + security_group_id        = (known after apply)
      + security_group_rule_id   = (known after apply)
      + self                     = false
      + source_security_group_id = (known after apply)
      + to_port                  = 0
      + type                     = "egress"
    }

Plan: 2 to add, 0 to change, 0 to destroy.

─────────────────────────────────────────────────────────────────────────────

Note: You didn't use the -out option to save this plan, so Terraform can't
guarantee to take exactly these actions if you run "terraform apply" now.

分かりやすくなりましたね。

これはこれで良いのですが、他にも良いオプションがあるので紹介します。

方法2:-outオプションを使う

-outオプションを使ってterraform plan -out plan.txtを実行すると以下のようになります。

Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
  + create

Terraform will perform the following actions:

  # aws_security_group.SG will be created
  + resource "aws_security_group" "SG" {
      + arn                    = (known after apply)
      + description            = "Managed by Terraform"
      + egress                 = (known after apply)
      + id                     = (known after apply)
      + ingress                = (known after apply)
      + name                   = "exmaple"
      + name_prefix            = (known after apply)
      + owner_id               = (known after apply)
      + revoke_rules_on_delete = false
      + tags_all               = (known after apply)
      + vpc_id                 = "vpc-XXXXXXXXXXXXX"
    }

  # aws_security_group_rule.SG-rule will be created
  + resource "aws_security_group_rule" "SG-rule" {
      + cidr_blocks              = [
          + "0.0.0.0/0",
        ]
      + from_port                = 0
      + id                       = (known after apply)
      + protocol                 = "-1"
      + security_group_id        = (known after apply)
      + security_group_rule_id   = (known after apply)
      + self                     = false
      + source_security_group_id = (known after apply)
      + to_port                  = 0
      + type                     = "egress"
    }

Plan: 2 to add, 0 to change, 0 to destroy.

────────────────────────────────────────────────────

Saved the plan to: plan.txt

To perform exactly these actions, run the following command to apply:
    terraform apply "plan.txt"

こちらの方法でも分かりやすくなりましたね。

2つのオプションの違い

では-no-colorオプションを使った場合と-outオプションの場合とでどのような違いがあるのでしょうか。
まず表示結果を見比べてみると、表示結果の最後にある案内文が少し違います。

-no-colorオプションの場合

Note: You didn't use the -out option to save this plan, so Terraform can't
guarantee to take exactly these actions if you run "terraform apply" now.

-outオプションの場合

To perform exactly these actions, run the following command to apply:
   terraform apply "plan.txt"

そうなんです。
案内文の通り、-no-colorオプションで出力したファイルはterraform applyで使用できませんが、-outオプションに関しては出力したファイルを基にterraform applyで実行できるようになります。この差は効率面では非常に大きいです。

具体例を見てみましょう。terraform plan -no-color > plan.txtを実行してterraform applyを実行する場合は以下のようなフローになります。


terraform applyというコマンドはterraform plan(反映しようとしている設定を返す)を行った後に適用開始するような挙動になっているため、実質terraform planを2回実行することになります。

一方、terraform plan -out plan.txtを実行してterraform apply plan.txtを実行する場合は以下のようなフローになります。


出力したファイルを基に適用実行するため、反映しようとしている設定を確認する必要がありません。つまり実質terraform planは1回で済みます。
リソース数が膨大にある環境だと、この実行時間に数分かかってしまうので、オプションの使い方で短縮できるのであれば有効ではないでしょうか。

しかし、-outオプションにはちょっとした難点もあります。それはコマンドでしかファイルを確認できないことです。Terraform show ファイル名を実行することでしかファイルの中身を見られません。ファイルを開くだけだと、このように表示されてしまいます。 致命的ではありませんが、この特徴は人によって好き嫌いありそうです。

 さいごに

-outオプションは効率的だと思いますが、ビビりな私は、より多くの確認場面を設けられる-no-colorオプションを使うことが多いです。
みなさんも、ぜひオプションを使ってみてください。

執筆者: 後藤 涼太
AWSをメインとするクラウドエンジニア
AWS認定資格 全取得済み
執筆記事:https://tech.nri-net.com/archive/author/r-goto