Carina State Management

2026-01-28 21:40:00 +0900

Carina にS3バックエンドによるState管理機能を実装した。


背景

Terraform Stateと同等の機能はやっぱり必要だよね、ということで、CarinaにもState管理機能とS3バックエンドを実装した。


DSL構文

バックエンド設定は以下のように記述する。ほぼTerraformと同じ。

backend s3 {
  bucket      = "my-carina-state"
  key         = "prod/carina.crnstate"
  encrypt     = true
  auto_create = true
}

auto_create = true はTerraformにはない機能。Terraformでは、Stateを保存するS3バケットは事前に作成しておく必要がある。Carinaでは auto_create を有効にすると、初回 apply 時にバケットが自動作成され、さらにそのバケットのリソース定義が .crn ファイルに自動で追加される。


Stateファイル

StateファイルはJSON形式で、以下のような構造になっている。とりあえずClaude Codeに適当に決めてもらった。後で色々変えることになると思う。

{
  "version": 1,
  "serial": 3,
  "lineage": "358893ec-5a07-49bf-acbc-940d9563c7f5",
  "carina_version": "0.1.0",
  "resources": [
    {
      "resource_type": "s3.bucket",
      "name": "my-bucket",
      "provider": "aws",
      "attributes": {
        "name": "my-bucket",
        "region": "ap-northeast-1",
        "versioning": "Enabled"
      },
      "protected": false
    }
  ]
}

plan

plan 実行時に、Stateバケットが作成されることが Bootsrap Plan: として表示される。

carina plan の出力


apply

apply実行時に、Stateバケットが自動作成される。

carina apply の出力

また、backendが定義されているファイルに、Stateバケットのリソース定義が自動追加される。

# Auto-generated by carina (state bucket)
aws.s3.bucket {
  name       = "my-carina-state"
  versioning = "Enabled"
}

destroy

StateバケットはState内で protected フラグが設定されるため、通常の destroy では削除されない。

carina destroy の出力

「⚠ s3.bucket.carina-state-test-mizzy (protected - will be skipped)」と表示され、destroy対象からスキップされる。

Stateバケットを削除したい場合は、 state bucket-delete コマンドを使う。

$ carina state bucket-delete <bucket-name> --force

state lock/unlock

チーム開発にはstate lock/unlockは必要だよね、ってことでTerraformのようなstate lock/unlock機能も実装した。


今後

Terraform Stateに関する不満として一番大きいのは、やはりstate refreshの速度だと思う。 Terraform State Refreshの高速化手法と実装 という記事で、高速化するための手法や実装をいくつか挙げたが、あくまでもTerraformを前提としたものだった。Carinaではその前提が取っ払えるので、もっとよい形での高速化が実現できるかもしれないし、できないかもしれない。今後の課題として取り組んでいきたい。