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担当にとって便利に使えます。

求められた要件

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

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

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

環境 : Windows Server 2012 on AWS VPC

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

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

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

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

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

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

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

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

シェルモードへの移行

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

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

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アドレスをファイルに書かずとも指定可能です。

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非同期実行するため、台数が多い場合により処理が早まる。 *7

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: capistranoに感銘を受けた某PowerShell Moduleは一年前から開発が止まっていたりで、決定版がない

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

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

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

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

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

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