Terraform State 可視化ツール terraform-tuiを試してみた

2025/02/09に公開

はじめに

Terraform Stateファイルを軽易にわかりやすく確認したいと思い調べたところ terraform-tui というものに出会いました。(移行TFTUIと記述します)

こんな感じのUI、k9sみたいですね。

以前までは

$ terraform graph | dot -Tpng > graph.png

のようにして全体像を把握していました。(下図のような描画になります)

依存関係も可視化できてこれはこれでわかりやすいです。
でも、軽易に確認がしたいためTFTUIを使い始めました。

本記事でやること/やらないこと

やること

  • TFTUIの簡単な説明
  • インストール方法
  • 簡単な使用方法の紹介

やらないこと

  • 詳細な操作方法の説明

TFTUI とは

TFTUI = The Terraform textual UI

terraform-tui プロジェクトのREADME記載の通り以下の特徴を有します。

  • Terraform Stateのツリー表示
  • リソースの中身を簡単に表示
  • 検索機能
  • terraform plan/apply をTFTUIから直接実行できる
  • 単一/複数のリソースを選択して操作できる
  • リソースに対して taint, untaint, delete, destroy を行える(Terraform v0.15.2以降は taint/untaint非推奨 -replaceオプション推奨)
  • Terraformラッパーをサポート(terragruntなど)

余談ですが、TFTUIの使用状況をPostHogで追跡しているとのことでした。
個人データの送信はしていないとのことでしたが、気になる方は後述の tftuiコマンドに -d オプションを付けて実行すると追跡をオプトアウトできます。

インストール

brew, pip, pipx でのインストールをサポートしているとのこと
筆者はpipでのインストールを行いました。

$ pip install tftui

簡単な使用方法

まずは terraform init をしたディレクトリまで行きtftuiコマンドを実行します。

cd /path/to/terraform/project && tftui

カレントディレクトリのtfstateファイルを読み込んでTFTUIが起動します。
(リモートストレージに保存している場合はそれを読み込む)

TFTUIで使用できるもショートカットキーは以下のようなものがあります。
ちなみに、TFTUIはマウスクリックにも対応しています。(便利!)

ENTER: View resource details
ESC: Go back
S: / Space Select current resource (toggle)
F: Show resource/plan on full screen; Hold SHIFT/OPTIONS to copy text
X: Expose sensitive values in resource screen
D: Delete selected resources, or highlighted resource if none selected
T: Taint selected resources, or highlighted resource if none selected
U: Untaint selected resources, or highlighted resource if none selected
C: Copy selected resource's name or description to clipboard
R: Refresh state tree
P: Create execution plan, with optional var-file and target list
Ctrl+D: Create destruction plan, with optional var-file and target list
A: Apply current plan, available only if a valid plan was created
/: Filter tree based on text inside resources names and descriptions
0-9: Collapse the state tree to the selected level, 0 expands all nodes
W: Switch workspace
M: Toggle dark mode
Q: Quit
和訳的なもの
ENTER: リソースの詳細を表示
ESC: 戻る
S / スペース: 現在のリソースを選択(トグル)
F: リソース/プランをフルスクリーンで表示;SHIFT/OPTIONSキーを押しながらでテキストをコピー
X: リソース画面で機密値を表示
D: 選択されたリソースを削除(選択がない場合はハイライトされたリソース)
T: 選択されたリソースをTaint(選択がない場合はハイライトされたリソース)
U: 選択されたリソースをUntaint(選択がない場合はハイライトされたリソース)
C: 選択されたリソースの名前または説明をクリップボードにコピー
R: 状態ツリーを更新
P: 実行プランを作成(オプションでvar-fileとターゲットリストを指定可能)
Ctrl+D: 破棄プランを作成(オプションでvar-fileとターゲットリストを指定可能)
A: 現在のプランを適用(有効なプランが作成されている場合のみ利用可能)
/: リソース名と説明のテキストに基づいてツリーをフィルタリング
0-9: 状態ツリーを選択したレベルまで折りたたむ(0ですべてのノードを展開)
W: ワークスペースを切り替え
M: ダークモードを切り替え
Q: 終了

View Details

試しにリソースの詳細を見てみましょう

oci_core_vcn.vcnリソースを選択してクリック or Enter

このようにstateファイルに記述されている内容を軽易に表示できます。
sensitive valueは 下部メニューの "X Sensitive"をクリックするか "X"ショートカットキー で表示できます。

Plan/Apply

TFTUIでは Plan/Applyを実行することができます。
内部的には下記コマンドを行っているようです。

$ terraform plan -out=tftui.plan
$ terraform apply "tftui.plan"

今の構成は以下のような感じです。

$ tree
.
├── main.tf
├── provider.tf
├── terraform.tfstate
├── terraform.tfstate.backup
├── terraform.tfvars
└── variables.tf

"P"を押すと下記のようなメニューが表示されます。

Var-fileには変数で指定したいファイルがあれば入力します。
"Target only selected resoureces" は"P"を押す前にリソースをスペースキーで選択していた場合それらにのみ実行します。(-targetオプションと同じです。)

Yesをクリックします。
今回はsubnet3をコメントアウトして削除されるようにしてみました。

するとtftui.planという計画ファイルが作成されました。

$ tree
.
├── main.tf
├── provider.tf
├── terraform.tfstate
├── terraform.tfstate.backup
├── terraform.tfvars
├── tftui.plan  ### これ
└── variables.tf

$ terraform show tftui.plan

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

Terraform will perform the following actions:

  # oci_core_subnet.subnet3 will be destroyed
  # (because oci_core_subnet.subnet3 is not in configuration)
  - resource "oci_core_subnet" "subnet3" {
      - cidr_block                 = "10.0.30.0/24" -> null
      - compartment_id             = (sensitive value) -> null
      - defined_tags               = {
          - "Bugdet-Tags.RootTenancy" = "xxxxxxxxxxxxxxx"
          - "Oracle-Tags.CreatedBy"   = "xxxxxxxxxxxxxxx"
          - "Oracle-Tags.CreatedOn"   = "2025-02-09T00:25:06.153Z"
        } -> null
      - dhcp_options_id            = "ocid1.dhcpoptions.oc1.ap-tokyo-1.aaaaaaaankmpncnj5yt5gcanyqb2ff6b7itok475mov7zk74pzmbyz32dqva" -> null
      - display_name               = "subnet3" -> null
      - freeform_tags              = {} -> null
      - id                         = "ocid1.subnet.oc1.ap-tokyo-1.aaaaaaaaucuo6mqlvogbsbfbzpce5ld5o6lynqielppl7pk4lfktpcdweuzq" -> null
      - ipv6cidr_blocks            = [] -> null
      - prohibit_internet_ingress  = false -> null
      - prohibit_public_ip_on_vnic = false -> null
      - route_table_id             = "ocid1.routetable.oc1.ap-tokyo-1.aaaaaaaaeot2zbhgfvsgwqc66uxscxrwlsorr2kk5eefrfzcuvk3rxa5rkxa" -> null
      - security_list_ids          = [
          - "ocid1.securitylist.oc1.ap-tokyo-1.aaaaaaaayue5atw4wvlgfkhfvjqny4xatr7yye7rsecizdpqyvle6zxe7cnq",
        ] -> null
      - state                      = "AVAILABLE" -> null
      - time_created               = "2025-02-09 00:25:06.757 +0000 UTC" -> null
      - vcn_id                     = "ocid1.vcn.oc1.ap-tokyo-1.amaaaaaararg7sqammoiddljvhemlklleywzmabfawhl7dwrhvg3t3apyeta" -> null
      - virtual_router_ip          = "10.0.30.1" -> null
      - virtual_router_mac         = "00:00:17:74:D5:18" -> null
    }

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

ではこの計画ファイルを実行してみましょう。
先ほどのPlan時の"画面から" "A"ショートカットキーを実行します。

差分が問題なければ "Yes"をクリック

Escで初期画面に戻るとリソース oci_core_subnet.subnet3が削除されています。

apply後も計画ファイルが残り続けるのが少々気になりましたが、特に問題なくPlan/Applyを実行できました。

おわりに

簡単な紹介となりましたが、いかがでしたでしょうか?
なかなか軽易に使えて便利だと思います。
開発が現時点で8か月前から動いていなさそうなのとOSSなので自己責任でのしようというのがネックですが、使うメリットは多そうだと思います。

参考

Discussion