Closed4

terraform の tfstate の "private" 属性について調べる

sikeda107sikeda107

terraform - What is the meaning of private attribute in tfstate (for a DynamoDB instance)? - Server Fault

private 「プロパティは、」attributes "内の実際のデータとは別に、プロバイダが内部のライフサイクル追跡のために必要なメタデータを保持できる場所です。
Terraform Coreから見ると、これはbase64エンコードされた任意のバイト列です。プロバイダが何を保存しているかは、base64デコードすればわかります。
プロバイダが何を保存するかは原則自由ですが、実際にはTerraform SDKがスキーマのバージョンを追跡するために使うのが一般的です。これをJSON形式でデコードすると、おそらくこれが見つかるだろう。Terraform 0.12の状態スナップショットフォーマットにはスキーマバージョンのファーストクラスプロパティがあります。
この文脈での 「private 」は、「secret 」ではなく 「providerのみが使用する 」という意味です。したがって、detect-secretsツールの観点からは、これは不幸な誤検出です。attributes "オブジェクトにもそうすることができるように、プロバイダーがプライベートなデータをそこに保存することは原理的には可能だが、このプロパティはそのために設計されたものではない。
(DeepL.com(無料版)で翻訳しました。)

what is the terraform remote state file "private" attribute used for? - Stack Overflow

ここでの「private」の意味は、Terraformから見て、プロバイダが決めた不透明なバイナリデータの塊であるということです。そのため、このフィールドが何に使われるかを一概に答えることはできません -- 特定のリソースタイプは原理的に何にでも使うことができます -- が、特に aws_kms_key に注目することで、それが今日どのように使われているかを議論することができます:
AWSプロバイダは公式のTerraform Go SDKで構築されているため、これを書いている現在、プライベートデータはプロバイダ固有のロジックではなくSDKのロジックで実際に使用されています。共有したBase64の値を解凍すると、中にいくつかのJSONがあります:
{"schema_version":"0"}
SDKはこれを使用して、このオブジェクトが現在どのスキーマバージョンを使用しているかを追跡しています。Terraform 0.12以降、スキーマバージョンはステートフォーマットの明示的な一部となったため、これは冗長なものとなっていますが、SDKはここに記録し続けています。なぜなら、今日のプロバイダはまだTerraform 0.10や0.11と互換性があり、"private "に設定することでこれらの古いバージョンでも実行時に保存されるからです。
原則的にプロバイダはここに何でも保存することができますが、プロバイダは実際のリソースデータではなく、リソースのライフサイクルを機能させるために必要なこの種の「退屈な」メタデータを追跡するためにこれを使用することを意図しています...データ自体はメインのオブジェクト属性に属します。
(DeepL.com(無料版)で翻訳しました。)

sikeda107sikeda107

実際に decode してみる

echo 'eyJlMmJmYjczMC1lY2FhLTExZTYtOGY4OC0zNDM2M2JjN2M0YzAiOnsiY3JlYXRlIjoxMjAwMDAwMDAwMDAwLCJkZWxldGUiOjEyMDAwMDAwMDAwMDAsInVwZGF0ZSI6MTIwMDAwMDAwMDAwMH0sInNjaGVtYV92ZXJzaW9uIjoiMSJ9' | base64 -D | jq -r
{
  "e2bfb730-ecaa-11e6-8f88-34363bc7c4c0": {
    "create": 1200000000000,
    "delete": 1200000000000,
    "update": 1200000000000
  },
  "schema_version": "1"
}
sikeda107sikeda107

e2bfb730-ecaa-11e6-8f88-34363bc7c4c0 はハードコードされてる
https://github.com/hashicorp/terraform-plugin-sdk/blob/0584e8adf3f23d5c1949a1c2aa8ba4119e0331de/helper/schema/resource_timeout.go#L16-L20

https://github.com/hashicorp/terraform-plugin-framework/issues/400

エンコード処理はおそらくここ
https://github.com/hashicorp/terraform-plugin-sdk/blob/0584e8adf3f23d5c1949a1c2aa8ba4119e0331de/helper/schema/resource_timeout.go#L174-L182

go の encoding/json は自動で base64 にしてくれるらしい
https://pkg.go.dev/encoding/json

Array and slice values encode as JSON arrays, except that []byte encodes as a base64-encoded string, and a nil slice encodes as the null JSON value.

apply
https://github.com/hashicorp/terraform-plugin-sdk/blob/0584e8adf3f23d5c1949a1c2aa8ba4119e0331de/helper/schema/grpc_provider.go#L1282-L1287

新しい state を json encode してるので、ここでそのまま base64 エンコードもされてる
https://github.com/hashicorp/terraform-plugin-sdk/blob/62e2d2d909610f2178634a2b84f999726ded1166/helper/schema/grpc_provider.go#L1062-L1067

このスクラップは4ヶ月前にクローズされました