tech.guitarrapc.cóm

Technical updates

PowerShell による デプロイ ライブラリ "valentia" β版 の公開

謎社 での 私の責務の1つが Linux から Windows 環境に移行時に、デプロイ環境を低下させることなく維持、向上、移行することでした。 (今もですが

今回、その案件に対応すべく制作した PowerShell による CUI デプロイモジュール valentia β版を公開します。

valentia - guitarrapc/valentia

β版なのは動作優先で作成したため、まだまだ機能不足、冗長、性能の改善が可能なためです。

しかし valentia運用を開始した2013年7月 ~ 2013年9月現在まで 謎社において日々のデプロイで 数十台~百を超えるサーバー群を運用している実績があります。

よって、少なくともデプロイ基盤の無い IT管理者や Windows の Ops担当にとって便利に使っていただけるかと思います。 *1

目次

求められた要件

Linux 時点において、謎社で利用していたのが Ruby製デプロイツールの定番である capistranoでした。

これに対して、 2013年2月~7月においては、Windows における 代替モジュールがありませんでした。 *2

そのためWindowsにおける デプロイツール基盤を用意するにあたり、Capistranoを置き換えれるようにする必要がありました。*3

環境 : Windows Server 2012 on AWS VPC

  1. capistrano とコマンド体系を近くする
  2. capistrano 同様の任意のリモートコマンド実行環境
  3. capistrano 同様の任意のスクリプトファイル実行環境
  4. デプロイ対象のIP ファイル定義
  5. デプロイ対象のIP 直接指定
  6. ファイル転送 *4
  7. デプロイ対象増加での影響を抑える
  8. エラー検知とロールバック *5
  9. Windows Native動作 *6
  10. 認証にWindows認証マネージャーを利用し意識しない

valentiaにおける PowerShell デプロイ対応

上記の要件を受けて作成したのが、 valentiaです。

それぞれ、以下のように対応しています。

1. capistrano とコマンド体系を近くする

capistranoでは、次のようにコマンドを実行します。

スクリプトファイルの実行

cap デプロイ対象グループファイル 実行するタスクファイル

シェルモードへの移行

cap デプロイ対象グループファイル shell

よって、valentia では次のようなコマンド体系を持っています。*7

vale(p|a) デプロイ対象グループファイル|またはIPAddress 実行するタスクファイル

任意のスクリプト実行はこうです。

vale(p|a) デプロイ対象グループファイル|またはIPAddress {実行するCmdlet}

ほぼ、同様の形式での実行を可能にしています。

2. capistrano 同様の任意のリモートコマンド実行環境

PowerShell の PSRemoting を基盤とすることで、コマンド実行を可能にしています。

例えば、上記の例でいうと、{実行するCmdlet}が ScriptBlockに当たります。

vale(p|a) デプロイ対象グループファイル|またはIPAddress {実行するCmdlet}

対象192.168.0.1 に対して、Get-Processコマンドを送るならこうするだけです。

valea 192.168.0.1 {Get-Process}

3. capistrano 同様の任意のスクリプトファイル実行環境

コマンドの代わりに、Task形式で記述された .ps1ファイルを指定することで-Actionパラメータ内部の コマンドをScriptBlockに格納して実行します。

例えば、あらかじめ、Get-ChildItem | where extension -eq ".exe" というコマンドを埋め込んで置いたファイルtasktest.ps1を作る場合はこうします。

task task-name -Action {Get-ChildItem | where extension -eq ".exe"}

あとは、対象192.168.0.1 に対して、tasktest.ps1ファイルに書かれたコマンドを送るならdot-sourceで読み取るだけです。

cd tasktest.ps1があるパスへ移動
valea 192.168.0.1 .\tasktest.ps1

4. デプロイ対象のIP ファイル定義

デプロイ対象のIPも記述し、 c:\deployment\deploygroup\任意のファイル名.ps1として保持が可能です。

  • 単純に、IP AddressやHostNameの羅列で問題ありません
  • # や タブ、空白スペースがあるラインはリマークとみなします
  • 改行は無視します

例えばこのように記述してtestgroup.ps1と保存可能です。

192.168.0.1
# このラインは無視される
 hoghoge #ここも無視される
192.168.0.2

5. デプロイ対象のIP 直接指定

先ほどの例にあげたとおり、valentiaコマンドではIPアドレスをファイルに書かずとも指定可能です。

また、カンマ,で区切ることで複数のIPアドレスや、デプロイファイル、あるいは両方の組み合わせが可能です。

valea 192.168.0.3 {hostname}

また、カンマ,で区切ることで複数のIPアドレスや、デプロイファイル、あるいは両方の組み合わせが可能です。

valea 192.168.0.3,192.168.0.4 {hostname}
valea 192.168.0.3,testgroup.ps1 {hostname}

6. ファイル転送

BITS Transferを利用した、デプロイサーバーから対象サーバーへの送信であるuploaduploadLがあります。

逆に、対象サーバーからデプロイサーバーへのファイル取得は、downloadコマンドを利用します。

7. デプロイ対象増加での影響を抑える

valetia のコマンド実行は非同期です。つまり、対象のホストが増えても処理時間が大きく変わりません。

  • valeで利用している、PowerShell RemotingのJobはバックグラウンドで処理が一斉に非同期に走ります
  • valeaは、任意のRunspace分のプールを使ってPipeLine非同期実行するため、台数が多い場合により処理が早まります。 *8

vale は valep に比べて高速に動作する場合が多いですが、 valea の方が 安定した結果が得られ、対象ホストの完了進捗がわかります。

vale は Job を利用しているのですが、 重い処理をjobに差し込むと1つのホストで詰まると結果取得が遅れる傾向にあります。

8. エラー検知とロールバック

コマンド実行時の最後に結果表示されます。

また、結果をJson出力したログファイルが、 C:\Logs\Deployment\日付\deployment_日付_時間.log として生成されます。

ロールバックに関しては、TransactionTranscriptでの対応を予定していますが、まだ未実装です。

9. Windows Native動作

PowerShell ですから。何もいりません。

PowerShell 3.0と PSRemotingとSet-ExecutionPolicyだけ必要です。

10. 認証にWindows認証マネージャーを利用し意識しない

PSRemoting では認証が毎回手間になります。が、valentia では Windows 認証マネージャーに初回に設定しておくことで、認証の読み込みを意識せずに済みます。

謎社での利用例

謎社では、対象サーバーへの PowerShellコマンド実行 やファイル転送、インストール、レジストリ操作などは全て valentiaを通して行っています。

実際にアプリケーションのデプロイは、 WPF製の社内デプロイツール + MSDeploy も併用しています。

もちろん、自動スケーリングでの復帰時などでは、valentiaからのmsdeploy も自動実行され、社内の人間が操作せずとも動作を続けています。

まとめ

ざっくりと求められた要件と、対応を書き連ねましたが、一度試していただけると幸いです。

導入手順は、 ReadMeを見ていただけると! ((おいこら

Twitterなどで @guitarrapc_tech に質問を投げかけていただければ、時間を探して応えます。(たぶん、きっと

まだまだvalentia はβ版で、見苦しいコードも散乱しています。

今後も鋭意改善を続けていくのでよろしくお願いします。

*1:プルリクなどフィードバックなどいただけると泣いて喜びます。

*2: capistranoに感銘を受けた某PowerShell Moduleは一年前から開発が止まっていたりで、決定版がない

*3:GitHub 連携は C/Iサーバーがあるので不要だが、Deployもできる素質が必要

*4:主に Deploy Server から Client Server への 送信

*5:Transaction Rollbackが理想、コマンドレットの逆操作を作成も可

*6:各サーバーで追加モジュールなどは望ましくない

*7:動作モードによって、 vale か valea があります。

*8:デフォルトは CPU core に応じて変化させています