推しアイデア
「ふっかつのじゅもん」風のIaC
「ふっかつのじゅもん」風のIaC
テーマの「伝説」「リメイク」辺りから、ドラクエに着想
LocalStackでAWSのTerraform(ふっかつのじゅもん) IaC体験ができる!
このプロダクトは、 ハックツハッカソン モサカップ2026 (裏ハックツハッカソン) の作品です
20文字のひらがな ふっかつのじゅもん を唱えると、Terraform が LocalStack 上に AWS 構成を復活させます。
じゅもん Terraform LocalStack ゆうていうあうあああ… ──────▶ HCL の割り算と剰余で復号 ──────▶ Lambda, S3, DynamoDB … │ ステータス画面 ◀────── terraform output ◀───────┘

起動方法はREADME参照
20文字のひらがなを唱えて、AWS構成を作ります

じゅもんを唱えると、terraform apply が走り、リソースが1つ生えるたびにメッセージが流れます

LocalStackにデプロイが完了すると、ふっかつした!という画面が表示されます

b を押して「ぼうけん」に行くと、実際にLocalStackにデプロイされたリソースを叩くことができます

操作すると連鎖が起きたかが出て、起きなければ何文字目のせいかも出ます。 じゅもんを 1 文字変えるだけで、生える部品も繋がり方も変わるので、ぜひ色々試してみてください。
タイトル画面で「はじめから」を選ぶと、ふっかつのじゅもんのひらがなが、実際に何のリソースに対応しているかを確認することができます

対応表

じゅもんに応じて変化する部分があり、とりうる構成を全て並べると以下の通り

Goで実装 Bubble Teaというフレームワークを使用した https://github.com/charmbracelet/bubbletea
ベースのIaCにはTerraformを採用
存在しうる全てのリソースをtfファイルで定義しておき、ひらがな 20 文字をそのまま変数として渡す。復号は Terraform 側が HCL の式で行い、その結果がそのまま count / for_each になることで、ふっかつのじゅもん IaC を実現している。
流れは「文字 → 数値 → count」の3段。
1. 呪文は1個の文字列変数として入る
# world/variables.tf variable "spell" { type = string description = "ふっかつのじゅもん。ひらがな20文字。" }
2. 文字を数値にして、割り算と剰余で欄に分解する
HCL にはビット演算が無いので、下位ビットは %、上位ビットは floor(/) で取り出す。
# world/decode.tf(抜粋) locals { kana_index = { for i, c in local.kana : c => i } # あ=0, い=1, … 64文字 spell_chars = split("", var.spell) v = [for i in range(20) : lookup(local.kana_index, local.spell_chars[i], 0)] region = local.t_region[local.v[0] % 8] # 1文字目の下3ビット → 地域 sla = local.t_sla[floor(local.v[0] / 8)] # 1文字目の上3ビット → SLA fn_count = (local.v[4] % 8) + 1 # 5文字目 → 関数の数 1〜8 table_count = local.v[6] % 4 == 0 ? 0 : (floor(local.v[6] / 4) % 4) + 1 # 7文字目 → テーブル数 conn = { for i, name in local.t_conn_bits : # 16文字目の6ビット → 繋がり name => floor(local.v[15] / pow(2, i)) % 2 == 1 } }
3. 分解した数がそのまま count / for_each になる
# world/main.tf module "env" { for_each = toset(local.envs_real) # 15文字目 → dev / stg / prod / dr fn_count = local.fn_count # … } # world/env/compute.tf resource "aws_lambda_function" "fn" { count = var.fn_count # 5文字目 → 関数がこの数だけ生える # … } # world/env/connections.tf resource "aws_lambda_event_source_mapping" "queue" { count = local.c_queue_to_fn ? var.queue_count : 0 # 16文字目のビットが立っていれば繋がる # … }
参考: Terraform の関数一覧: https://developer.hashicorp.com/terraform/language/functions (ビット演算子は存在しない)
Terraformでふっかつのじゅもん → IaC変換を実装したためか、(テストを除いた)本体の .go ファイルが13個に対して、.tf ファイルは20個も生まれてしまった...
コード行数的に、GitHub上ではGoがメインにはなっています

IaCを実際にデプロイする先として、LocalStackを採用 LocalStackの無料版を使用する都合上、サーバーレスのリソースがメインとなっている
以下の設定により、terraform apply の実行先を LocalStack に指定している。
# world/main.tf provider "aws" { region = local.region access_key = "test" secret_key = "test" skip_credentials_validation = true skip_metadata_api_check = true skip_requesting_account_id = true s3_use_path_style = true endpoints { apigateway = "http://localhost:4566" dynamodb = "http://localhost:4566" lambda = "http://localhost:4566" s3 = "http://localhost:4566" sqs = "http://localhost:4566" # … 19 サービスすべて同じ向き先 } }
Go 側からは、LocalStack を指定するオプションなどは一切付けず、純粋に terraform apply を実行するだけで LocalStack にデプロイが行われている。
// cmd/fukkatsu/terraform.go(抜粋) exec.CommandContext(ctx, "terraform", "apply", "-auto-approve", "-var", "spell="+spell)
参考: https://docs.localstack.cloud/aws/connecting/infrastructure-as-code/terraform/
実際にLocalStackにデプロイされているため、 awslocal コマンドでリソースが存在すること・呼び出せることを確認できる
$ awslocal lambda list-functions --region eu-west-1 --query 'Functions[].FunctionName' [ "wagazatsu-4b7113-stg-fn-2", "wagazatsu-4b7113-dev-fn-1", "wagazatsu-4b7113-dev-fn-0", "wagazatsu-4b7113-stg-fn-1", "wagazatsu-4b7113-dev-fn-2", "wagazatsu-4b7113-stg-fn-0" ] $ awslocal logs describe-log-groups --region eu-west-1 --query 'logGroups[].logGroupName' [ "/aws/lambda/wagazatsu-4b7113-dev-fn-0", "/aws/lambda/wagazatsu-4b7113-dev-fn-1", "/aws/lambda/wagazatsu-4b7113-dev-fn-2", "/aws/lambda/wagazatsu-4b7113-stg-fn-0", "/aws/lambda/wagazatsu-4b7113-stg-fn-1", "/aws/lambda/wagazatsu-4b7113-stg-fn-2" ]