こんにちは、後藤です。
みなさま、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オプションを使うことが多いです。
みなさんも、ぜひオプションを使ってみてください。