目次


万人のためのオートメーション

デプロイメントの自動化パターン、第 1 回

ワン・クリックでデプロイするためのパターン

Comments

コンテンツシリーズ

このコンテンツは全#シリーズのパート#です: 万人のためのオートメーション

このシリーズの続きに乞うご期待。

このコンテンツはシリーズの一部分です:万人のためのオートメーション

このシリーズの続きに乞うご期待。

ソフトウェア・デプロイメントは、ソフトウェアを存続させるために事前にどうにか取り繕うべき必要悪として扱われることがよくあります。しかし、そんなデプロイメントにも他の開発サイクルと同様にソフトウェア・エンジニアリングの原則を適用することはできます。そして、本来そうあるべきです。手作業でのデプロイメントは、エラーを起こしやすい繰り返しのプロセスだからです。ビルドを自動化することでエラーの削減とソフトウェア開発期間の短縮を実現できるのとまったく同様に、デプロイメント・プロセスを自動化することによって、エラーを削減し、ソフトウェア・デリバリーを迅速に行うことができます。

「万人のためのオートメーション」の以前の記事、「オートメーションによるデプロイメントの円滑化」では、リモートでソフトウェアを複数のターゲット環境にデプロイする方法を説明しました。今回の 2 回からなる連載記事では、さらに高度な自動デプロイメントを紹介します。ソフトウェア開発にパターンがあるように、デプロイメントにもパターンがあります。私はこの数年の間、これらのパターンを集めてきました。第 1 回目のこの記事では、以下の 8 つのデプロイメント・パターンとそれぞれの事例を説明します。

  • 中央リポジトリーでの全構成ファイルの管理。このように管理することによって、スクリプト化デプロイメントを使用して実動ソフトウェアを生成できるようになります。
  • スクリプト化デプロイメント。すべてのデプロイメント・アクションをスクリプトにすることで、人間が介入しなくてもデプロイメントを実行できるようにします。
  • シングル・コマンド。デプロイメントの複雑さを軽減するとともに、デプロイメント・プロセスのヘッドレス実行を確実にします。
  • 構成のトークン化。繰り返し可能な方法で可変情報を構成ファイルに注入できるようになります。
  • 構成の外部化。ターゲット環境間で異なる情報の入力が一度だけでよくなり、簡単になります。
  • テンプレート・ベリファイヤー。すべてのターゲット環境プロパティーが同じであることを確実にします。
  • ヘッドレス実行。自動プロセスで複数のマシンにアクセスするセキュアな方法です。
  • 統一されたデプロイメント。1 つのデプロイメント・スクリプトを多数のターゲット環境で実行できるようにします。

第 2 回では、上記以外のデプロイメント・パターンについても説明します。

図 1 に、この記事で取り上げるデプロイメント・パターンの相関関係を示します。

図 1. デプロイメント自動化パターン
デプロイメント自動化パターン
デプロイメント自動化パターン

これから、上記のパターンについて 1 つひとつ説明していきます。説明を読んでいくうちに、図 1 に示した相関関係がわかってくるはずです。

すべてのファイルをバージョン管理リポジトリーにコミットする

名前: リポジトリー

パターン: すべてのファイルをバージョン管理リポジトリーにコミットします。デプロイメントのコンテキストで言うと、すべての構成ファイルとツールをコミットします。

アンチパターン: この情報をアクセスが制御された共有ドライブに保管しているチームや、自分たちのマシンにだけ情報を保持し、ターゲット環境には情報をコピーするという方法を採っているチームがあります。

原則として、開発チームは実動ソフトウェアの作成に必要となる自分たちのファイルをすべて、チェックインすることを推奨します。この原則に当てはまらない場合もあるにせよ、そのような例外は多くありません。デプロイメントのコンテキストでは、チームがサーバーとサーバー構成を固定資産、つまり変更されることのない資産だと思っていることがありますが、それは誤った見方です。大規模なバイナリーをチェックインする上で制約が課せられる場合もありますが、構成ファイル、データベース・スクリプト、そしてすべてのビルド・スクリプトとデプロイメント・スクリプトは、バージョン管理リポジトリーにコミットするべきです。このリポジトリーのパターンを使用すると、これから説明するパターン (スクリプト化デプロイメントのパターン、そしてシングル・コマンドのパターンの場合は特に) に非常に役に立ちます。

すべてのデプロイメント・プロセスをスクリプトにする

名前: スクリプト化デプロイメント

パターン: すべてのデプロイメント・プロセスをスクリプトにします。

アンチパターン: Web コンテナーのインストールや構成などのタスクを手作業で構成する人もいれば、特定の環境に合わせてコンテナーを変更するために、コンテナーが提供する GUI ベースの管理ツールを使う人もいます。構成を手作業で変更する人はあまりいないかもしれませんが、最初のうちは簡単なこの方法は、多数のターゲット環境を対象に 1 週間に何度もデプロイメントを行うとしたら、手作業では対応しきれなくなります。また、デプロイメントには GUI ベースの管理ツールが大いに役立つものの、それも最初のうちに過ぎません。GUI ベースの管理ツールでデプロイするとしても、多数の人々がその手順を何度も実行することになれば、拡張に対応できないだけでなく、エラーの原因にもなりがちです。

リスト 1 に記載するスクリプト化デプロイメント・パターンでは、デプロイメントをスクリプトにすることで、Tomcat Web コンテナーの (再) 起動プロセスを自動化しています。このプロセスは、Apache Ant ビルド・スクリプト言語によって作成されています。

リスト 1. Tomcat Web コンテナーの起動例
<available file="@{tomcat.home}/server/@{tomcat.server.name}/bin" 
   property="tomcat.bin.exists"/>
<if>
  <isset property="tomcat.bin.exists"/>
<then>
  <echo message="Starting tomcat instance at @{tomcat.home} with start_tomcat" />
  <exec executable="@{tomcat.home}/server/@{tomcat.server.name}/bin/start_tomcat" 
   osfamily="unix" />
</then>
<else>
  <echo message="Starting tomcat instance at @{tomcat.home} with startup.sh" />
  <exec osfamily="unix" executable="chmod" spawn="true">
    <arg value="+x" />
    <arg file="@{tomcat.home}/bin/startup.sh" />
    <arg file="@{tomcat.home}/bin/shutdown.sh" />
  </exec>
		
  <exec executable="sh" osfamily="unix" dir="@{tomcat.home}/bin" spawn="true">
    <env key="NOPAUSE" value="true" />
    <arg line="startup.sh" />
  </exec>

    <exec osfamily="windows" executable="cmd" dir="@{tomcat.home}/bin" spawn="true" >
      <env key="NOPAUSE" value="true" />
        <arg line="/c startup.sh" />
    </exec>
    <sleep seconds="15" />
    </else>
  </if>

このプロセスをスクリプトにすると、(この例の場合は Tomcat が提供する) GUI 管理コンソールでのクリック操作が必要なくなります。さらに、プロセスがスクリプト化されていることから、包括的自動デプロイメントの一環として、ヘッドレス・プロセスによって実行することも可能になります。

1 つのコマンドによってデプロイメントを実行する

名前: シングル・コマンド

パターン: デプロイヤー、つまりヘッドレス・プロセスが、1 つのコマンドを入力することによって、ユーザーのために実動ソフトウェアを生成します。

アンチパターン: 一部のデプロイメント・プロセスでは、いくつものコマンドや手順を入力しなければならず (ファイルのコピー、構成ファイルの変更、サーバーの再起動、パスワードの設定など)、またその他のエラーを起こしやすい繰り返しのアクションを実行しなければなりません。運が良ければ、ステップバイステップで文書化された手順に従うことで一連のアクションを実行することもできますが、それでもなお、デプロイメント手順の実行に人手が必要だということは、エラーのリスクが伴うということで、それが原因で複数のターゲット環境へのソフトウェア・リリースに遅れが生じることになり兼ねません。

デプロイメントを作成する時点でのクライアントは、同じチームや組織、会社側には属していないことがよくあります。さらに、使用するマシンまで異なることもあります。デプロイメントの実行が複雑であればあるほど、他の誰かやヘッドレス・プロセスがエラーもなくデプロイメントを完了できる可能性は少なくなります。リスト 2 に、デプロイメントを実行する単純なシングル・コマンドの例を記載します。

リスト 2. Ant を使用したシングル・コマンドによるデプロイメント
ant -Dproperties.file=$USERHOME/projects/petstore/properties/dev-install.properties \
  deploy:remote:install

リスト 2 のコマンドは、環境に固有の .properties ファイルを渡して deploy:remote:install という名前の Ant タスクを実行し、他のマシンからリモートでソフトウェアをデプロイします。このタスクは、SCP (Secure Copy Protocol) を使用したセキュアなファイル・コピー、SSH (Secure SHell) によるリモート・マシンでのセキュアなコマンド実行、Web コンテナーのインストール、構成、再起動などのアクションをはじめ、他にもさまざまなプロセスを、人手を介さずに実行します。当然、ユーザーがコマンドを入力するのでも構いませんが、コマンドは極めて簡潔なので、継続的インテグレーション・サーバーやビルド管理サーバーなどといったヘッドレス・プロセスでも簡単に実行することができます。

可変情報を構成ファイルに注入する

名前: 構成のトークン化

パターン: トークンの値を構成ファイルに入力し、リポジトリーにチェックインされた外部化構成プロパティーに基づいたスクリプト化デプロイメントの際に、トークンの値を置換します。

アンチパターン: それぞれの環境で、構成ファイルにターゲット固有のデータを入力します。

リスト 3 は、Web コンテナーとデータベース・サーバーとの間で構成を管理する XML ファイルです。このファイルには、@ 記号を使用してトークンを配置しました。これらのトークンは、自動デプロイメント・プロセス中に、スクリプトによって外部化構成ファイルからの実際の値に置換されます。

リスト 3. トークン化された Web コンテナーの構成ファイル
<datasources>
  <local-tx-datasource>
    <jndi-name>@application.context.name@</jndi-name>
    <use-java-context>false</use-java-context>
    <connection-url>@database.url@</connection-url>
    <user-name>@database.user@</user-name>
    <password>@database.password@</password>
    <driver-class>@database.driver@</driver-class>
  </local-tx-datasource>
</datasources>

環境固有の値に設定される内容をトークンにすることで、スクリプト化デプロイメントが、統一されたデプロイメントによって複数の環境をサポートできるようになります。

環境に固有のすべてのプロパティーを抽出する

名前: 構成の外部化

パターン: アプリケーション構成のすべての変数値をビルド時プロパティーに外部化します。

アンチパターン: ターゲット環境ごとに変数値を手作業でハードコーティングします。変数値をハードコーディングするために、GUI ツールが使用されることもあります。

リスト 4 に示しているプロパティーは、アプリケーション固有の構成ファイルにコード・ベースで含まれていることの多いプロパティーの例です。このような変数値をすべて 1 つの .properties ファイルにまとめることで、データ (可変プロパティー) を振る舞い (デプロイメント・スクリプト) から切り離すことができます。つまり、ターゲット環境が何であれ、自動デプロイメント・プロセスは常に同じように動作するということです。

リスト 4. アプリケーション固有のファイルから外部化されたプロパティーの例
authentication.type=db
application.url=http://${tomcat.server.hostname}:${tomcat.server.port}/brewery-webapp
database.type=mysql
database.server=localhost
database.port=3306
database.name=mydb
database.user=myuser!
database.password=mypa$$!
database.url=jdbc:mysql://${database.server}:${database.port}/${database.name}
tomcat.server.hostname=localhost
tomcat.server.name=default
tomcat.web.password=pa$$123!
tomcat.cobraorb.port=12748

リスト 4 に示されている値は大抵の場合、ソース・コードやサーバー構成、XML、.properties やその他のファイルに散らばっています。さらに私が気付いたのは、このデータがシステム全体で複数存在しているために、デバッグするのが困難なデプロイメント時の複雑な問題がもたらされるという事実です。このような情報を多数のソースから単一の .properties ファイルに抽出することによって、デプロイメント時に発生する可能性のある無数の問題が解消されることになります。

ヘッドレス実行でデプロイメント作業を楽にする

名前: ヘッドレス実行

パターン: コマンドを入力せずに複数のマシンとセキュアなインターフェースを取ります。

アンチパターン: 複数のマシンにアクセスするために、各マシンにそれぞれ別のユーザーとしてログインしてから、ファイルのコピー、値の構成などの作業を手作業で行います。

残酷に聞こえる名前ですが、ヘッドレス実行は、自動プロセスによってリモートから他のマシンにアクセスしなければならない場合に極めて有効なソリューションです。通常は開発者、ビルド・エンジニア、ソフトウェア構成管理 (SCM)、あるいはオペレーターに頼らなければならないコマンドを、公開鍵基盤 (PKI) を使用することによって、自動ソリューションに統合することができます。図 2 では、秘密鍵ファイルがビルド・マシンと SSH にインストールされています。固有の値は、ターゲットそれぞれに固有の .properties ファイルで定義します。これらの値には通常、秘密鍵のファイル名と場所、SSH ポート番号、ホスト名が含まれます。ターゲット・マシンには、SSH ハンドシェークを行うための公開 SSH 鍵ファイルが収容されます。

図 2. SSH 鍵を使用したヘッドレス実行パターンの実装
SSH 鍵を使用したヘッドレス実行パターンの実装
SSH 鍵を使用したヘッドレス実行パターンの実装

この方法を使用すれば、スクリプト化デプロイメントが人手を介さずに、ビルド環境から 1 つ以上のターゲット環境に対してデプロイメント・プロセスを実行することができます。

プロパティーが環境全体で同じであることを検証する

名前: テンプレート・ベリファイヤー

パターン: すべてのターゲット環境のプロパティーのベースとなる単一のテンプレート・ファイルを作成します。

アンチパターン: 手動による検証で (デプロイメントが失敗するたびに、その理由を確かめるために)、試行錯誤を繰り返したり、マシン上のファイルを非公開のままにしたりします。

問題は、すべてのターゲット環境での属性に一切違いがないことを確認しなければならないことです。しかし、自動化された環境の場合は、どうやってこれを検証すればよいのでしょうか。その方法は、ターゲット環境ファイルのすべてが検証対象とする単一のテンプレートの .properties ファイルを使うことです。それによって、どの環境で実行しているとしても、すべての属性が同じであることを確実にできます。図 3 では、ビルド・スクリプトが Ant タスクを実行し、template.properties とターゲット固有の .properties ファイル (dev.properties、qa.properties など) との間で (値ではなく) 属性を比較します。比較して違いが見つかった場合には、デプロイメントに失敗します。

図 3. テンプレート・ベリファイヤー・パターンの実装
テンプレート・ベリファイヤー・パターンの実装

リスト 5 は、図 3 に示されている template.properties ファイルの一例です。このファイルには属性しか含まれていないことに注目してください。この場合、値は関係しないからです。

リスト 5. 属性だけが含まれ、値は含まれないテンプレート・ファイル
db.database=
db.username=
db.password=
db.hostname=
db.driver=
db.port=
db.url=

リスト 6 には、図 3 に示されている dev.properties (または qa.properties など) のスニペットを記載します。このファイルには、属性だけでなく値も含まれています。これらの値は、ターゲット環境に固有の値です。

リスト 6. テンプレート・ファイルに基づいたターゲット環境のプロパティー・ファイル
db.database=brewery
db.username=root
db.password=p@ssword
db.hostname=dev1.domain.com
db.driver=com.mysql.jdbc.Driver
db.port=3306
db.url=jdbc:mysql://${db.hostname}:${db.port}/${db.database}

複数のターゲット環境に同時にデプロイする

名前: 統一されたデプロイメント

パターン: さまざまなプラットフォームとターゲット環境で実行可能な単一のデプロイメント・スクリプトを作成します。

アンチパターン: ターゲット環境ごとに異なるデプロイメント・スクリプト、さらには特定のマシンを対象としたデプロイメント・スクリプトを使用します。

デプロイメント・プロセスは特定の環境で実行することができますが、すべてのプロセスは、あらゆるターゲット環境で実行可能でなければなりません。例えば、同じスクリプト化デプロイメントは開発環境、テスト環境、ステージング環境、そして本番環境で実行されますが、使用する外部化構成ファイルはそれぞれに異なります。そこで、テンプレート・ベリファイヤーを使用して、外部化された構成属性を検証します。

図 4 に、複数のターゲット環境にデプロイすることが可能な単一のデプロイメント・スクリプトを示します。

図 4. 単一のデプロイメント・スクリプトと複数のターゲット環境
単一のデプロイメント・スクリプトと複数のターゲット環境
単一のデプロイメント・スクリプトと複数のターゲット環境

パターンはこれだけではありません

デプロイメントもまた、ソフトウェアの作成において自動化するのにふさわしい 1 つの側面です。自動化されたデプロイメントには、信頼性が高く、繰り返し可能なプロセスによるメリットがもたらされます。このメリットとは、つまり正確さ、スピード、制御が改善されることです。この記事では、ソフトウェア・デプロイメントの自動化に効果を発揮する 8 つのパターンについて説明しました。第 2 回では、リモート・デプロイメント、使い捨てコンテナー、デプロイメント・テスト、環境ロールバックなど、他にも利用できるパターンを取り上げます。


ダウンロード可能なリソース


関連トピック


コメント

コメントを登録するにはサインインあるいは登録してください。

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=60
Zone=Java technology
ArticleID=369274
ArticleTitle=万人のためのオートメーション: デプロイメントの自動化パターン、第 1 回
publish-date=01132009