連休に入って酒量が増え体重も増え、昼夜わからない生活をし、ridgepoleのRails5対応はFが減らず、必要に駆られて使い始めたElasticBeanstalkの闇が見え始めた現実から目をそらすため、以前から懸案だったCloudFormation用ツールKumogataの次世代版を作ってみました。
なにが問題だったのか
- aws-sdk-v1
- v1もまだまだ現役で使えるとはいえ状況を見る感じだいぶv2が主流になってきて、このままv1を使い続けるのはリスキー…なんだけどライブラリを変更するのが地味に大変。大量のFでモチベーション低下
- モノリシック
- Kumogataは「フォーマットコンバーター+便利ツール」というもので、この2つは論理的に切り離すことができるはずなんだけど、初期の設計に建て増しを繰り返した結果、拡張がひっじょーにしづらい状況。おまけに対応フォーマットの追加に付随してgemもばかすか追加したからインストールが重い・めんどい。さすがにtherubyracerへの依存はやりすぎだった。申し訳ない
- Ruby DSLの黒魔術
- Ruby DSLでJSONをはくためにdslhという連想配列をRuby DSLで書くライブラリを作ったんですが、裏で結構変なことをやっているので、テンプレート全体をRubyDSLとして評価するのはリスキーな感じです。できれば「template do ... end」というブロック内だけでDSLを評価して、外部に黒魔術の影響を漏れ出さないようにすべきと考えていたけれど、すでに込み入ったソースを回収するのはちょっと大変
- いくつかの不要そうな機能
- パラメータの暗号化とか初期に必要そうだったので追加した謎機能がいくつかあって、たぶんほとんどのユースケースで使われておらず、コードのスパゲッティ化に貢献
Kumogata2
ということで、連休と現実逃避とビール・チューハイ20本ぐらいの結果、Kumogata2が爆誕しました。
github.com
改善点
- aws-sdk-v2!
- プラガブルなアーキテクチャ
- 不要機能の削除
- 暗号化みたいな謎機能は削除。またsshの実行なんかも普通にRubyコードとして実行できるようになった(はず)なので内部のコードは削除しました
- ChangeSet対応
- 待望…だけど割とびみょーな機能のChangeSetにも対応。いろいろとインターフェースを考えた結果、dry-runコマンドを実行するとChangeSetつくって、差異を出力して、ChangeSetを削除する、という動作になりました(ChangeSetを作って実行…ってだれがあの機能考えたんだろう…)
Usage
Kumogata v1とだいたい同じです。出力もだいたい同じ。
Usage: kumogata2 <command> [args] [options]
Commands:
create PATH_OR_URL [STACK_NAME] Create resources as specified in the template
update PATH_OR_URL STACK_NAME Update a stack as specified in the template
delete STACK_NAME Delete a specified stack
validate PATH_OR_URL Validate a specified template
list [STACK_NAME] List summary information for stacks
export STACK_NAME Export a template from a specified stack
convert PATH_OR_URL Convert a template format
diff PATH_OR_URL1 PATH_OR_URL2 Compare templates logically (file, http://..., stack://...)
dry-run PATH_OR_URL STACK_NAME Create a change set and show it
show-events STACK_NAME Show events for a specified stack
show-outputs STACK_NAME Show outputs for a specified stack
show-resources STACK_NAME Show resources for a specified stack
Support Format:
json, js, template
Options:
-k, --access-key ACCESS_KEY
-s, --secret-key SECRET_KEY
-r, --region REGION
--profile PROFILE
--credentials-path PATH
--output-format FORMAT
-p, --parameters KEY_VALUES
-j, --json-parameters JSON
--[no-]deletion-policy-retain
--[no-]disable-rollback
--timeout-in-minutes TIMEOUT_IN_MINUTES
--notification-arns NOTIFICATION_ARNS
--capabilities CAPABILITIES
--resource-types RESOURCE_TYPES
--on-failure ON_FAILURE
--stack-policy-body STACK_POLICY_BODY
--stack-policy-url STACK_POLICY_URL
--[no-]use-previous-template
--stack-policy-during-update-body STACK_POLICY_DURING_UPDATE_BODY
--stack-policy-during-update-url STACK_POLICY_DURING_UPDATE_URL
--result-log PATH
--command-result-log PATH
--[no-]detach
--[no-]force
--[no-]color
--[no-]ignore-all-space
--[no-]debug
github.com
ほぼ一緒ですが、
- プラグインになって本体と分離された
- DSLを「template do ... end」内に定義
- post処理の実行が変わった
- _post()メソッドがなくなって、template()と同階層post()メソッドでコマンドを実行するようになります。これにより任意のRubyコマンドがたたけるので、sshなりシェルコマンドの実行なりはそこでやってください、とう感じです。
template do
AWSTemplateFormatVersion "2010-09-09"
Description (<<-EOS).undent
Kumogata Sample Template
You can use Here document!
EOS
Parameters do
InstanceType do
Default "t2.micro"
Description "Instance Type"
Type "String"
end
end
Resources do
myEC2Instance do
Type "AWS::EC2::Instance"
Properties do
ImageId "ami-XXXXXXXX"
InstanceType { Ref "InstanceType" }
KeyName "your_key_name"
UserData do
Fn__Base64 (<<-EOS).undent
#!/bin/bash
yum install -y httpd
service httpd start
EOS
end
end
end
end
end
post do |output|
puts output
end
Plugin
parse()とdump()メソッドを定義したクラスを作れば簡単に作れます。
たとえばyamlをパースするプラグインを作ろうと思ったらlib/kumogata2/plugin/yaml.rb
を含むgemをkumogata2-plugin-yaml
という名前で作って、yaml.rbを以下のようにすればOK。
require 'yaml'
class Kumogata2::Plugin::YAML
Kumogata2::Plugin.register(:yaml, ['yml'], self)
def initialize(options)
@options = options
end
def parse(str)
YAML.load(str)
end
def dump(hash)
YAML.dump(hash).colorize_as(:yaml)
end
end
CodeRayが対応していれば、いい感じに色づけしてくれます。(もちろんttyをみて適時色なしにします)。
連想配列を扱えるならhclでもperlでもpythonでもjsでもjson5でもcoffeescriptでも、論理的には対応可能なはずなので、JSONに疲れて自分の好きな言語で書きたい…というかたは新しくプラグインを書いてみるとよいのではないでしょうか?
ということで、Kumogataを細々と使っている方がいましたら、人柱バグレポやプルリクお待ちしていますm(_ _)m