Yogafireがバージョンアップしてさらに捗る!
機能追加したら捗りすぎてまじつらい。
以下ChangeLog。
ChangeLog(主要なもののみ)
- 大幅なリファクタリング
- ターゲットインスタンスを決定するロジックを統一化
- ssh vpc サポート
- ssh proxy サポート
- インクリメンタルにフィルタを行えるように
- 'yogafire'を指定することにより、表示オブジェクトすべてに対してコマンド実行
- renderコマンドに'template-file'オプション追加
- 'change-instance-type'コマンド追加
- 'update-ec2-tags'コマンド追加
- selfオプション対応
- 'loop' オプション対応
- instance-typeを最新にUpdateしたのとカラーリング対応
- start / stop / reboot/ terminateなど複数同時実行出来ていなかったのを対応
- 'copy-and-launch' コマンドが外に出ていなかったので出した
ターゲットインスタンスを決定するロジックを統一化
今までコマンドによってまちまちだったりしたので統一しました。
ターゲット元の正規表現によって以下の判定を行います。
# private dnsとして接続 yoga ssh ip-10-199-60-10.us-west-1.compute.internal # public dnsとして接続 yoga ssh ec2-50-1-30-251.us-west-1.compute.amazonaws.com # インスタンスIDとして接続 yoga ssh --proxy=i-9bed5ac3 # タグ名(単独) yoga get www01 ./getfile ./ # タグ名(複数) yoga put 'www*' ./putfile /tmp
ipアドレスも対応する予定でしたが、諸事情によりTodo。
ssh vpc / proxy サポート
最近VPC使うことも多くなってきました。
しかしyogafireがバグっててそもそもssh繋がらなかったのでまずはそれを修正しました。
また、踏み台対応もyogafireだけで出来るようにしてみました。
以下のようにすると踏み台指定出来ます。
yoga ssh --proxy=<target_id> # get / put / cmdも対象。以下は「fumidai」というタグ名のインスタンスを踏み台に指定 yoga cmd www1 ls --proxy=fumidai yoga put www1 ./putfile.txt ./ --proxy=fumidai yoga get www1 ./getfile.txt ./ --proxy=fumidai
または、.yogaファイルに「proxy」を設定してもOKです。
共通でプロキシ通したい場合はこちらが良いでしょう。
application1: access_key_id: xxxxxxxxxxxxxxxxx ... proxy: fumidai ...
インスタンスの一覧表示時、インクリメンタルにフィルタ出来るようにした
※(詳しくは別記事にします)
対象はコマンドは
ssh / start / stop / reboot / terminate / copy-and-launch / change-instance-type / ls -i / ls-ami -i
です。
前バージョンまでは、重複したTagNameを指定すると「一つになるように再度指定してね」と弾いていたのですが
面倒なのでインクリメンタルっぽく絞り込めるようにしてみました。
これはマジで便利すぎて鼻がもげる!
'yogafire'指定で表示しているインスタンスを全対象にして実行
現状は start / stop / reboot / terminate のみ使用可能です。
インタラクティブ実行中に「yogafire」を実行すると
今表示しているオブジェクト全てに対してコマンドを実行します。*1
change-instance-typeも対応する予定ですがこちらはTodo。
renderコマンドに'template-file'オプション追加
yoga render --template-file=<file_name> # example yoga render --template-file=./example/render/simple.tt --state=running
前バージョンまでは文字列を直接指定するしかできなかったのですが
それに加えてテンプレートファイルを指定できるようにしました。
この機能により「インスタンスの"ロール"/"状態"などによりコンフィグファイルを生成する」
といったことが可能になりました。
テンプレートエンジン
Text::Xslate(TT2like)を利用しているので、基本Xslateの構文がそのまま使えます。
詳しく知りたい方は以下のドキュメントをご覧ください。
http://search.cpan.org/~gfuji/Text-Xslate-2.0000/lib/Text/Xslate/Syntax/TTerse.pm
http://search.cpan.org/~dmaki/Text-Xslate-Bridge-TT2Like-0.00010/lib/Text/Xslate/Bridge/TT2Like.pod
シンプルな例
テンプレートには条件に一致したインスタンスの配列が
「instances」という名前で渡ってきます。
以下のテンプレートはインスタンス毎にパブリックDNS名を出力します。
インスタンスのアトリビュートについてはVM::EC2のメソッドと同等になります。
[% FOREACH i IN instances %] [% i.dnsName %] [% END %]
シンプルな例:条件分岐
従来通り yoga render コマンド時にfilter指定して使うことももちろん可能ですが、
テンプレート内で条件分岐させることも可能です。
以下のテンプレートはタグ名が「www」で始まるインスタンスであれば
プライベートIPをインスタンス毎に出力します。
[% FOREACH i IN instances %] [% IF i.tags.Name.match('^www') %] [% i.privateIpAddress %] [% END %] [% END %]
シンプルな例:JSONの扱い
カスタムタグにJSON文字列を入れてゴニョゴニョしている方もいると思います。
そういったニーズにお応えしてJSONをデコードする関数も定義しました。
以下の例では「Role」というカスタムタグに
「{"Nagios":"1","Group":"www"}」
という文字列が入力されているのをデコードして利用するパターンです。
[% FOREACH i IN instances %] [% SET ROLE = decode_json(i.tags.Role) %] [% ROLE.Nagios %] # 「1」が表示される [% ROLE.Group %] # 「www」が表示される [% END %]
応用例:NagiosやMuninのコンフィグを自動生成してみる
もう少し具体的な例を上げてみましょう。
AWSでインフラ構築している方は
「インスタンス名」もしくは「独自タグ」を見て
Nagios/Munin/Capistoranoなどのコンフィグを生成する、といったスクリプトを
自前で実装したりしていないでしょうか?(自分はしています)
そのような要件があった時、yogafireがあればスクリプトを書くまでもなく
テンプレートファイルを作るだけで済むようになります!
例としていくつかテンプレートを作ってみました。
muninの場合
基本的な設定だけであれば
このような一つのファイルを作るだけで良いです。
nagiosの場合
全てに基本監視するだけならこのような一つのファイルを作るだけで良いです。
また、ロールによって監視項目を追加したいこともありますよね。
IF文で条件分岐しても良いですが、今回は例として外部のインクルードファイルを使うパターンを作ってみました。
参考にしてみてください*3
https://github.com/toritori0318/p5-Yogafire/blob/master/example/render/nagios/nagios_include.tt
https://github.com/toritori0318/p5-Yogafire/tree/master/example/render/nagios
他にもnginx のサンプルも置いてありますのでご参照ください。
上記の例題テンプレートをダウンロードして
自分の環境で動かしてみるだけでも感触がつかめると思います。
renderコマンドは標準出力に出すだけなので何も考えずに色々と試してみてください!
'change-instance-type'コマンド追加
yoga change-instance-type <target_id>
その名の通り、instance-typeを変更します。
このコマンドの何が嬉しいかというと、
暗黙的に以下のような手順を行なってくれることです。
- 1.を通っている場合
- インスタンスを起動し直す
- ステータスがrunninngになるまで待つ
- (a) のEIPがあれば、EIPを付け直す
EC2classicで運用しているのであれば、より便利なコマンドとなりますね。
また以下のように一度に複数のインスタンスに対しても実行可能です。
複数インスタンスを一気に「t1.micro」から「c1.xlarge」にスケールアップ、といった操作も簡単!
yoga change-instance-type 'www*' --type=c1.xlarge --force
さらに完全に蛇足ですが、
以前から使える expand-volumeコマンドも似たようなことをしています。
- ※インスタンスが起動していたら停止する。(a) EIPがついてたら保持しておく
- ステータスがstoppedになるまで待つ
- スナップショット作成
- スナップショットステータスが「completed」になるまで待つ
- 新しいサイズでボリュームを作る
- ボリュームステータスが「available」になるまで待つ
- 現在のボリュームをdetachする
- ボリュームステータスが「detached」になるまで待つ
- 新しいボリュームをattachする
- ボリュームステータスが「attached」になるまで待つ
- 1.を通っている場合
- インスタンスを起動し直す
- ステータスがrunninngになるまで待つ
- (a) のEIPがあれば、EIPを付け直す
- ※上記のどこかでエラーが発生したら元のボリュームにロールバックする
'update-ec2-tags'コマンド追加
※このAPIは将来コマンドインタフェースを変える可能性があります
yoga update-ec2-tags <target_id> --key='<tag_name>=<tag_value>'
基本的にはtagを更新するだけのコマンドですが、
自動で連番を付けてくれる機能もあります。
以下のコマンドは「image-id=ami-xxxxx」のインスタンス全てに対し
「Nameタグ=www<連番>」と「Roleタグ=webapp」のタグ更新を実行します。
yoga update-ec2-tags --filter='image-id=ami-xxxxx' --key='Name=www[% seqno %]' --key='Role=webapp'
selfオプション対応
自分自身のサーバを対象とする「self」オプションを追加しました。
もちろん、ec2インスタンス上で実行する場合限定となります。
以下簡単な例ですが、自殺コマンドです。ほげぇ
yoga terminate --self
応用編1
高額インスタンスを起動してテスト中、
「インスタンス落とし忘れたらどうしよう…ガクブル」
とビクビクしている人も多いことでしょう。
そんなとき、atコマンドを指定しておくと落とし忘れが無くなって良いですね。*4
# 2013/03/26 23:00 に自動的にインスタンスをstopする echo "yoga stop --self --force" | at "23:00 26.03.13"
応用編2
時間のかかるようなビルドを実行する時、
インスタンスを一時的に「t1.micorからc1.mediumにアップグレードする」
といったことは日常茶飯事ですね。
しかしインスタンスを戻し忘れて「あ”あ”ー!」となることも度々あります。
そんなときはコマンド終了と同時に
「インスタンスをstopする」または「インスタンスをt1.microに戻す」
などとしておくと安眠できますね。
# perlbrewの後は何が何でもstopする perlbrew install v5.16.3 ; yoga stop --self --force # コマンドが成功した時だけt1.microに戻す cpanm Task::Plack && yoga change-instance-type --type t1.micro --force
'loop' オプション対応
インタラクティブに入力できるコマンド全部が対象です。
前バージョンまではコマンド実行後に終了してしまいましたが
loopオプションを付けておくとコマンド終了後にインスタンス一覧選択画面に戻るため、
繰り返しインスタンスに対してコマンド実行することが出来ます。
yoga ls -i -l
Todo
- ログ出力整理
- VPCユーティリティを充実させたい
- cmd / put/ getのパラレル対応
- テストの充実(そもそもどうしよう)
まだ少しバギーな部分もあるかもですが、
よろしければアップデートしてみてください〜