型で守るインフラ管理ツールCarina

Carinaとは

Rustで書かれた、強く型付けされたインフラ管理ツール。実験的プロジェクトとして開発中。
validate / plan / apply / destroy のTerraformライクなワークフロー
インフラは独自DSL(.crnファイル)で記述
スキーマ検証により、設定ミスをparse時に検出
LSP対応 — エディタで補完・診断・シンタックスハイライト
carina fmt でフォーマットも揃う

.crnファイルを書く

letで名前を付けたリソースは、他のリソースから参照できる。

provider aws {
  region = aws.Region.ap_northeast_1
}

let main_vpc = aws.vpc {
  name       = 'main-vpc'
  cidr_block = '10.0.0.0/16'
}

let web_sg = aws.security_group {
  name   = 'web-sg'
  vpc_id = main_vpc.id
}

enum値はスキーマが解決する

enum値は3通りの書き方をサポート。省略形はスキーマの文脈から自動で解決される。

# フルネームスペース形式
instance_tenancy = aws.ec2.Vpc.InstanceTenancy.dedicated

# Type.value形式
instance_tenancy = InstanceTenancy.dedicated

# 値のみ(最短・推奨)
instance_tenancy = dedicated

既存インフラはreadで参照

readはデータソース。ライフサイクル管理の対象外で、planでは<=で表示される。

let existing_vpc = read aws.vpc {
  name = 'production-vpc'
}

let app_subnet = aws.subnet {
  name       = 'app-subnet'
  vpc_id     = existing_vpc.id
  cidr_block = '10.0.100.0/24'
}

モジュールにも型が付く

inputとoutputは型付き。carina module infoで構造と依存を確認できる。

input {
  vpc: aws.vpc
  cidr_blocks: list(cidr)
  enable_https: bool = true
}

output {
  security_group: aws.security_group = web_sg.id
}

Effects as Values

副作用はすぐ実行せず、Create/Update/Delete/Readを表す値として組み立てる。Planはその集まり。

DSL (.crn)
  -> Parser     parse to Resources
  -> Differ     desired vs current state
  -> Plan       collection of Effects
  -> Provider   execute (AWS, ...)

プロバイダはWASMプラグイン

core本体はプロバイダ非依存。プロバイダは別リポジトリで開発され、WASMプラグインとしてロードされる。
carina-provider-aws — Smithyベースのcodegen
carina-provider-awscc — AWS Cloud Control API
プラグインSDKがあるので、プロバイダは外部からも作れる

Stateはリモートに置ける

S3バックエンドでチームやCI/CDとstateを共有。ロックで同時変更を防ぐ。

backend s3 {
  bucket      = 'my-carina-state'
  key         = 'infra/prod/carina.crnstate'
  region      = aws.Region.ap_northeast_1
  encrypt     = true
  auto_create = true
}

これから

EC2・IAM・Lambdaなど、AWSリソースの拡充
GCPプロバイダ
既存リソースのimport

github.com/carina-rs/carina