gfxさんの 個人が静的型付き言語のコンパイラをゼロから作れる時代が来た! という記事を読んで、自分も何か、以前だったらつくろうと思っても面倒で手が出なかったようなものをつくってみよう、と思ってつくりはじめた。
自分のことを知ってる方ならご存じかと思うが、自分はInfrastructure as Codeが大好きで、普段からIaCのことばかり考えている。最近だとこんなことを考えて発表した。
Terraformは好きで、公私ともにとてもお世話になっているのだが、こうなっているといいな、と思う点が色々ある。だが、Terraformはそれなりに歴史も実績もあるツールで、とてもよくできているので、自分でいちからつくって、Terraformと同レベルで使えるようになるまで育てるのは大変すぎるな、と思っていた。が、gfxさんの記事を読んで、今ならいけそうだな、と思ってつくりはじめた。
Carina は、Rustで実装したTerraformライクなインフラ管理ツール。
基本的にはTerraformと同じなんだけど、今のところ違う点を挙げると以下のような感じ。
ap-northeast-1
と書くが、Carina aws providerではenumで定義されていて、
aws.Region.ap_northeast_1
のように書く
ちなみに、自分はツールに名前をつけるときは天体に関連する言葉を使うことが多い。Carinaはりゅうこつ座のことで、竜骨は船の重要な骨格部分。インフラを支えるツールにふさわしいかな、と思ってこの名前にした。
言語選定はClaude Codeと相談して決めた。候補としてはRust、Go、TypeScriptあたりが挙がった。
Rustを選んだ理由としては、
といったあたりをClaude Codeが挙げてくれたけど、まあなんとなくRust使ってみるか、ぐらいで決めた。自分はRustにあまり馴染みがないけど、Claude Codeに書いてもらうなら問題ないだろうし、Rustを学ぶ良い機会になるかな、と。
.crn
という拡張子のファイルにインフラを定義する。
provider aws {
region = aws.Region.ap_northeast_1
}
# 匿名リソース
aws.s3.bucket {
name = "my-app-logs"
region = aws.Region.ap_northeast_1
versioning = true
expiration_days = 90
}
# 名前付きリソース
let backup = aws.s3.bucket {
name = "my-app-backup"
region = aws.Region.ap_northeast_1
}
Terraformと似たような感じだけど、以下の点が異なる。
aws.s3.bucket
のようにドット区切り
aws_s3_bucket
のようにアンダースコア区切り
let
で宣言
resource "aws_s3_bucket" "backup"
のように書くし、リソース名が必須になるが、Carinaでは、他リソースから参照する必要がなければ、匿名にできるようにしている
Terraformだと、
resource "aws_s3_bucket" "my_app_logs"
のように書くが、リソースタイプがアンダースコア区切りなので、それに合わせてリソース名もアンダースコア区切りにすべきか、それともハイフン区切りにすべきか、といつも悩む。別にどちらでもいいんだけど、どちらでもいいということは、その時々で判断がぶれてしまうので、ぶれないようにしたい、と思ったのがこのような設計にした理由の一つ。
Terraformと同様に
validate
、
plan
、
apply
というコマンドがある。
$ carina validate example.crn
Validating...
✓ 2 resources validated successfully.
• s3_bucket.my-app-logs
• s3_bucket.my-app-backup
$ carina plan example.crn
Using AWS provider (region: ap-northeast-1)
Execution Plan:
+ s3_bucket.my-app-logs
name: "my-app-logs"
versioning: true
expiration_days: 90
+ s3_bucket.my-app-backup
name: "my-app-backup"
Plan: 2 to add, 0 to change, 0 to destroy.
$ carina apply example.crn
Applying changes...
✓ Create s3_bucket.my-app-logs
✓ Create s3_bucket.my-app-backup
Apply complete! 2 changes applied.
DSL (.crn) → Parser → Resources → Differ → Plan (Effects) → Interpreter → Provider → Infrastructure
Effectは
Create
、
Update
、
Delete
、
Read
の4種類があり、それぞれが値として扱われる。
現状、AWSのS3バケットのみ対応している。今後、Terraformこうなっているといいのにな、と思っていることが実際に実現できるのか、を実験する場にしていこうと考えている。
リポジトリはこちら。