🔍

tfstateを読む tfstate-lookup - fujiwara-ware advent calendar 2024 day 11

2024/12/11に公開

この記事は fujiwara-ware advent calendar 2024 の11日目です。

tfstate-lookup とは

https://github.com/fujiwara/tfstate-lookup

tfstate-lookup は、Terraform の tfstate ファイルを読んで、指定したリソースの情報を取得するためのコマンド兼ライブラリです。

同様のことは terraform 自体が用意している terraform state show でできますが、tfstate-lookup は Go のライブラリとして利用できるため、他のツールに組み込んで使うことができます。

terraform がインストールされていない環境でも単体のコマンドとして利用できます。また、実装は Terraform 自身のコードには一切依存していません。起動も terraform に比べて高速です。

なぜ作ったのか

Amazon ECS デプロイツールの ecspresso を作っているときに、Terraform で管理している、ECS が依存する他のリソースの情報を取得したくなりました。具体的には VPC の情報(サブネット、セキュリティグループ)などです。これらのリソースは ecspresso が使うファイルの中に ID で指定する必要がありますが、ID をハードコードしたくありません。

Terraform でこれらのリソースを管理している場合、.tf ファイルでの論理的な名前 (例: aws_vpc.main) に対応する作成されたリソースの情報は tfstate ファイルに保存されています。tfstate-lookup は、この tfstate ファイルを読んで、リソースの ID やその他の属性を取得するために作りました。

使い方

tfstate-lookup は、コマンドラインツールとしてもライブラリとしても利用できます。

コマンドラインツールとして使う

-state オプションで tfstate ファイルを指定します。

なにも引数を指定しない場合は、tfstate ファイルに含まれるリソース名一覧を表示します。

$ tfstate-lookup -state terraform.tfstate
aws_security_group.default
aws_subnet.public-a
aws_subnet.public-c
aws_subnet.public-d
aws_vpc.main

引数にリソース名を指定すると、そのリソースの属性を表示します。

$ tfstate-lookup -state terraform.tfstate aws_vpc.main
{
  "id": "vpc-0123456789abcdef0",
  "cidr_block": "...
    ...
}

リソースの属性は JSON 形式で出力されます。JSONの中の値を取り出すためには、リソースの属性名まで含めたパスを指定します。

$ tfstate-lookup -state terraform.tfstate aws_vpc.main.id
vpc-0123456789abcdef0

terraform state show と同様に使えますが、tfstate-lookup は .terraform ディレクトリが初期化されている必要はありません。直接 tfstate の URL (http, s3(Amazon S3), gs(Google Cloud Storage)など) を指定できます。

$ tfstate-lookup -state s3://my-bucket/terraform.tfstate aws_vpc.main
{
  "id": "vpc-0123456789abcdef0",
  "cidr_block": "...
    ...
}

便利な使い方

tfstate-lookup -i というオプションを使うと、tfstate に含まれるリソース一覧を表示した上で、インタラクティブにリソース名を選択できます。

tfstate-lookup -j というオプションを使うと、リソースの属性を JSON 形式で出力後、その JSON を simeji/jid で探索できます。

2つのオプションは同時に指定できます。大量のリソースや属性を持つ tfstate ファイルを扱うときに便利です。

tfstate-lookup -dump は tfstate に含まれるリソース全てを JSON 形式で出力します。キーはリソース名、値はリソースの属性です。

ライブラリとして使う

tfstate-lookup はライブラリとしても利用できます。以下は、tfstate を S3 から読んで、aws_vpc.main の ID を取得する例です。

package main

import(
    "fmt"
    "os"

    "github.com/fujiwara/tfstate-lookup/tfstate"
)

func main() {
    state, _ := tfstate.ReadURL(ctx, "s3://mybucket/terraform.tfstate")
    attrs, _ := state.Lookup("aws_vpc.main.id")
    fmt.Println(attrs.String())
}

tfstate-lookup を他のアプリケーションに組み込んで便利に使うために、Go 標準の text/template のテンプレート関数を生成したり、go-jsonnet の native function を生成する機能もあります。

詳細は次のドキュメントを参照してください。

https://pkg.go.dev/github.com/fujiwara/tfstate-lookup/tfstate

利用例

tfstate-lookup は ecspresso や lambroll で利用されています。また、Songmu/ecschedulehemlfile にもライブラリとして組み込まれています。

まとめ

tfstate-lookup は Terraform の tfstate ファイルを読んで、リソースの情報を取得するためのコマンド兼ライブラリです。

CLI として使う場合は tfstate の中を探索するのに便利ですし、ライブラリとして使うと他のツールに tfstate の参照機能を容易に組み込むことができます。

Terraform で管理しているリソースの情報を他のツールで使うときに便利なので、ぜひ使ってみてください。

それでは、明日もお楽しみに!

Discussion