自己文書化スクリプト
Lambda Smalltalkの構文は英語のように読める。スクリプトがそのままドキュメントになる。
従来のスクリプトの問題点
シェルスクリプト:
#!/bin/bash
for h in $(cat hosts.txt); do
ssh $h "systemctl restart nginx" && \
curl -s -o /dev/null -w "%{http_code}" http://$h/health | grep -q 200 && \
echo "$h: OK" || echo "$h: FAILED"
done
これが何をしているか?構文を頭の中でパースする必要がある。
Python:
for host in open('hosts.txt'):
subprocess.run(['ssh', host.strip(), 'systemctl restart nginx'])
r = requests.get(f'http://{host.strip()}/health')
print(f"{host.strip()}: {'OK' if r.status_code == 200 else 'FAILED'}")
まだマシだが、読むにはプログラミングの知識が必要。
Smalltalkの書き方
"全サーバーでnginxを再起動し、ヘルスチェックを実行"
hosts := (File read: 'hosts.txt') lines.
hosts do: [:host |
host restart: 'nginx'.
(host healthCheck)
ifTrue: [ (host, ': OK') printNl ]
ifFalse: [ (host, ': FAILED') printNl ].
].
声に出して読んでみろ:
- 「各ホストに対して、nginxを再起動」
- 「ヘルスチェックが通れば、OKを出力」
- 「そうでなければ、FAILEDを出力」
コード自体がドキュメントだ。
なぜこれが重要か
1. 監査可能な運用
監査人に「このスクリプトは何をしているか?」と聞かれたら、コードをそのまま見せられる:
"日次バックアップ手順"
Database dump: 'production' to: '/backup/daily/'.
S3 upload: '/backup/daily/' to: 'company-backups' prefix: (Date today asString).
Slack notify: '#ops' message: 'Daily backup completed'.
別途手順書を用意する必要がない。スクリプトがそのまま手順書だ。
2. 属人化の排除
新しいチームメンバーが運用スクリプトをすぐに理解できる:
"ステージングへデプロイ"
Git pull: 'origin/main'.
Docker build: '.' tag: 'app:staging'.
Kubernetes apply: 'k8s/staging.yaml'.
(App healthCheck: 'staging')
ifTrue: [ Slack notify: 'Staging deploy successful' ]
ifFalse: [ Slack notify: 'Staging deploy FAILED' ].
暗黙知は不要。
3. ミスの削減
意図が明確なら、バグも明らか:
"古いログをアーカイブ(バグ - アーカイブではなく削除している!)"
Logs olderThan: 30 days delete.
"古いログをアーカイブ(正しい)"
Logs olderThan: 30 days moveTo: '/archive/'.
コードを読めば誰でもバグに気づく。
実践パターン
ヘルス監視
"全サービスを5分ごとにチェック"
services := #('web-01' 'web-02' 'db-primary' 'cache-01').
services do: [:svc |
(svc isHealthy) ifFalse: [
PagerDuty alert: svc , ' is DOWN'.
svc restart.
(svc isHealthy)
ifTrue: [ PagerDuty resolve: svc , ' recovered after restart' ]
ifFalse: [ PagerDuty escalate: svc , ' still DOWN after restart' ].
].
].
データパイプライン
"ETL: ソースから抽出、変換、ウェアハウスにロード"
data := Postgres query: 'SELECT * FROM events WHERE date = today()'.
data := data
select: [:row | row at: 'status' = 'completed']
collect: [:row | row transform: TransformRules].
BigQuery insert: data into: 'analytics.daily_events'.
('Processed ', data size asString, ' records') printNl.
ロールバック付きデプロイ
"ブルーグリーンデプロイメント(自動ロールバック付き)"
| previousVersion |
previousVersion := App currentVersion.
App deploy: newVersion to: 'green'.
(App healthCheck: 'green')
ifTrue: [
LoadBalancer switchTo: 'green'.
Slack notify: 'Deployed ', newVersion, ' successfully'.
]
ifFalse: [
App rollbackTo: previousVersion.
Slack notify: 'Deploy failed, rolled back to ', previousVersion.
PagerDuty alert: 'Deployment failure'.
].
はじめよう
Lambda Smalltalkは基本的な構成要素を提供する。以下と組み合わせて使え:
- シェル統合:
System run: 'any shell command' - HTTPクライアント:
Http get:,Http post:body: - ファイル操作:
File read:,File write:content: - JSON/YAML/TOML:
Json parse:,Yaml parse: - プラグイン: Rustで複雑な処理を拡張
詳しいパターンは Examples を参照。