terraform.tfstateを読んでみる
はじめに
terraformのリソースの状態はterraform.tfstateファイルに保存されています。
いままでスルーしてきたのですが、今回はこれを読んでみようと思います。
検証方法として、applyなどの状態変化後のtfstateを見ていこうと思います。
環境
terraform 1.4.6
題材
これをapplyしました
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 4.65.0"
}
}
}
provider "aws" {
region = "ap-northeast-1"
default_tags {
tags = {
env = "test"
provision = "terraform"
}
}
}
resource "aws_s3_bucket" "s3" {
}
検証
apply後のtfstate
はこちら
{
"version": 4,
"terraform_version": "1.4.6",
"serial": 1,
"lineage": "d16af0bd-c329-ff5e-25d3-ae6de0058ef2",
"outputs": {},
"resources": [
{
"mode": "managed",
"type": "aws_s3_bucket",
"name": "s3",
"provider": "provider[\"registry.terraform.io/hashicorp/aws\"]",
"instances": [
{
"schema_version": 0,
"attributes": {
"acceleration_status": "",
"acl": null,
"arn": "arn:aws:s3:::terraform-xxxxxxxxxxxxxxxxxxxxxxxxxx",
"bucket": "terraform-xxxxxxxxxxxxxxxxxxxxxxxxxx",
"bucket_domain_name": "terraform-xxxxxxxxxxxxxxxxxxxxxxxxxx.s3.amazonaws.com",
"bucket_prefix": "terraform-",
"bucket_regional_domain_name": "terraform-xxxxxxxxxxxxxxxxxxxxxxxxxx.s3.ap-northeast-1.amazonaws.com",
"cors_rule": [],
"force_destroy": false,
"grant": [
{
"id": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
"permissions": [
"FULL_CONTROL"
],
"type": "CanonicalUser",
"uri": ""
}
],
"hosted_zone_id": "xxxxxxxxxxxx",
"id": "terraform-xxxxxxxxxxxxxxxxxxxxxxxxxx",
"lifecycle_rule": [],
"logging": [],
"object_lock_configuration": [],
"object_lock_enabled": false,
"policy": "",
"region": "ap-northeast-1",
"replication_configuration": [],
"request_payer": "BucketOwner",
"server_side_encryption_configuration": [
{
"rule": [
{
"apply_server_side_encryption_by_default": [
{
"kms_master_key_id": "",
"sse_algorithm": "AES256"
}
],
"bucket_key_enabled": false
}
]
}
],
"tags": null,
"tags_all": {
"env": "test",
"provision": "terraform"
},
"timeouts": null,
"versioning": [
{
"enabled": false,
"mfa_delete": false
}
],
"website": [],
"website_domain": null,
"website_endpoint": null
},
"sensitive_attributes": [],
"private": "xxxxxxxxxxxx"
}
]
}
],
"check_results": null
}
よくわかりません。
attributes
はリソースのパラメータでしょう、今後は省略します。
destroy後のtfstate
はこちら
{
"version": 4,
"terraform_version": "1.4.6",
"serial": 3,
"lineage": "d16af0bd-c329-ff5e-25d3-ae6de0058ef2",
"outputs": {},
"resources": [],
"check_results": null
}
destroyしたためでしょう、resources
の値がなくなっています。
またserial
は2インクリメントされ、lineage
は変化していません。
再apply後のtfstate
はこちら
{
"version": 4,
"terraform_version": "1.4.6",
- "serial": 1,
+ "serial": 5,
"lineage": "d16af0bd-c329-ff5e-25d3-ae6de0058ef2",
"outputs": {},
"resources": [
// 略
],
"check_results": null
}
再びserial
は2インクリメントされ、lineage
は変化していません。
outputをapply後のtfstate
このように追加しました
resource "aws_s3_bucket" "s3" {
}
+output "s3_bucket_domain_name" {
+ value = aws_s3_bucket.s3.bucket_domain_name
+}
tfstateは
{
"version": 4,
"terraform_version": "1.4.6",
"serial": 6,
"lineage": "d16af0bd-c329-ff5e-25d3-ae6de0058ef2",
"outputs": {
"s3_bucket_domain_name": {
"value": "terraform-xxxxxxxxxxxxxxxxxxxxxxxxxx.s3.amazonaws.com",
"type": "string"
}
},
"resources": [
{
"mode": "managed",
"type": "aws_s3_bucket",
"name": "s3",
"provider": "provider[\"registry.terraform.io/hashicorp/aws\"]",
"instances": [
// 略
outputs
に値が格納され、serialは1インクリメントされました。
ここは1なんですね
dataをapply後のtfstate
適当に転がっていたEC2をdataで追加してみます。
resource "aws_s3_bucket" "s3" {
}
+data "aws_instance" "foo" {
+ instance_id = "i-xxxxxxxxxxx"
+}
tfstateは
{
"version": 4,
"terraform_version": "1.4.6",
"serial": 7,
"lineage": "d16af0bd-c329-ff5e-25d3-ae6de0058ef2",
"outputs": {
"s3_bucket_domain_name": {
"value": "terraform-xxxxxxxxxxxxxxxxxxxxxxxxxx.s3.amazonaws.com",
"type": "string"
}
},
"resources": [
{
"mode": "data",
"type": "aws_instance",
"name": "foo",
"provider": "provider[\"registry.terraform.io/hashicorp/aws\"]",
"instances": [
// 略
{
"mode": "managed",
"type": "aws_s3_bucket",
"name": "s3",
"provider": "provider[\"registry.terraform.io/hashicorp/aws\"]",
"instances": [
{
// 略
mode
がdata
であるEC2リソースが追加され、serialに1インクリメントされました。
ここも1です。
まとめ
検証の結果からtfstateの要素をまとめてみました。
serial
とlineage
-
serial
:tfstateの変更回数。
output,dataを追加した場合は1,applyで変更した場合は2インクリメントされました。 -
lineage
:環境に対して払い出されるUUID。
最初のterraform init時に確定され、applyしても変化しません。
この2つでterraformは状態を管理していると思われます。
2つについて説明しているディスカッションがこちら
outputs
tfファイルのoutputブロックの値が格納されるようです。
resources
リソースごとの情報が格納されるようです。
mode
にはmanaged
かdata
が格納される。
terraformで管理しているか、外部リソースかで区別しているのだと思います。
attributes
リソースの情報が格納されているようです。
何が入るかはドキュメントのArgument Reference
,Attributes Reference
を参照すればよいはず。
以下はs3のドキュメントです。
check_results
リソースが想定通りの動作をするかテストを行う、check
ブロックがterrform 1.5で追加されました。
そのテスト結果が格納されるそうです。
今回はバージョン1.4を使用したため未検証ですが、いずれ試してみます。
所感
わからないことはまだまだ多いですが、
serial
がstate毎に変化するという点から、バックエンドでバージョン管理を行うのが大事なんだなあ
とざっくり思いました。
次回はtfstate周りのcliを試してみたいと思います。
参考
Discussion