はじめに
今回は、Azureが提供するチーム開発のためのサービス群であるAzure DevOpsの中から、CI/CDのサービスであるAzure Pipelinesを紹介します。
Azure Pipelinesとは
Azure Pipelinesとは、Azureのクラウド上にホスティングされているCI/CDのサービスです。Azure Pipelines上でコードのビルドやテスト、ビルドした成果物のリリースまでを自動化できます。CI/CDの仕組みはアジャイル開発にとって不可欠な要素の一つであり、Azure DevOpsのサービスラインナップの中でも中核的な存在となっています。
CI/CDとは
まずはCIとCDについて少し説明します。まずCIですが、これは「Continuous Integration」の略称で、日本語では「継続的インテグレーション」と呼ばれています。具体的には、ソースコードがGitなどのコードリポジトリにプッシュ(更新)されたことを起点に、ソースコードのビルドやユニットテストの実行、ビルドで作成された成果物の保存までのプロセスを自動化したものを指します。CIの仕組みを導入することで、手作業によるビルド手順の漏れや開発者ごとに微妙に異なるマシンでのビルドによる差異の発生など不具合に繋がる不安定な状況を排除し、何回実行しても同じようにビルドが行われる環境を提供することができます。またCI環境でビルドに失敗した場合は、即座に開発メンバーに通知を行うなどしてエラーの検知を即座に見落とすことなく行えるようにもなります。
一方CDは、「Continuous Delivery」の略で「継続的デリバリー」と呼ばれています。継続的デリバリーでは、CI(継続的インテグレーション)で作成した成果物を仮想マシンなどの運用環境へデプロイする、リリース作業の自動化が目的となっています。CDの導入による効果もCIと同じ部分が多く、作業の効率化や人的ミスの軽減、リリースサイクルの高速化などが挙げられます。
CIとCDはそれぞれ独立した概念ですが、一般的には組み合わせて使用する場合が大半です。ソースコードが開発者による実装・テストを終えた時点から運用環境へ反映されるまで、一連の作業として自動化されることがアジャイル開発のリズムを作り出し、アプリケーションの価値を高めることになります。
CI/CDツールについて
CI/CDによるビルド・リリースプロセスの自動化を行うにあたっては、CI/CDツールを使用することが一般的です。CIとCDに関する作業は多岐に渡るため、これまでのノウハウやベストプラクティスを反映しているツールの導入が最善となります。独自のスクリプトなどによってCI/CDを実現することも可能ですが、作成者に依存した独自のルールが適用されることで属人的なツールとなってしまい、かえって作業効率が下がってしまう可能性もあります。 そのようなリスクを避けるためにも、CI/CDにおけるフレームワークが適用されているCI/CDツールの使用は不可欠です。今回紹介するAzure Pipelinesは、Azureのクラウド上にホスティングされているCI/CDツールです。Azure PipelinesはCI/CDツールとしては比較的後発のものですが、その分機能面や使いやすさの点で優れた特徴が多くあります。
Azure Pipelinesの特徴
Azure Pipelinesには一般的なCI/CDツールが持つ機能の他に、以下に挙げるような特徴を持っています。
・多くの言語・プラットフォームのビルドをサポート
執筆時点でJava、JavaScript(Node.js)、C#(.NET)、Python、PHP、Ruby、C/C++、Goのビルドに対応しています。またAndroid、iOSといったモバイルアプリのビルドも可能です。 なお、エージェントと呼ばれるビルドを実行するマシンのOSには、Linux、macOS、Windowsを選択することができます。これらはもちろんAzureのクラウド上にホスティングされたものを使用するため、すぐに使用を開始することできます。
Azureリソースとの親和性
他のAzure DevOpsのサービスラインナップとシームレスに統合されいることはもちろんのこと、その他のAzureサービスとの連携に関しても柔軟に行うことができます。Azure App ServiceやAzure Functionsなどのデプロイ先となるサービスに対しては、それ専用のテンプレートが用意されているため簡単にデプロイを定義することが可能となっています。
様々なクラウドへのリリースが可能
Azureへのリリースだけでなく、AWSやGCPなどの他のクラウドプラットフォームへのアプリのデプロイもサポートしています。またオンプレミス環境へのデプロイも可能となっています。
Azure Pipelinesを見てみよう
ここからは実際にAzure Pipelinesの画面を見ながらCI/CDの流れについて確認していきましょう。Azure Pipelinesを使用するにはDevOpsプロジェクトの作成が必要です。本稿では、前回作成したDevOpsプロジェクトを使用して説明を進めます。まだDevOpsプロジェクトを作成していない場合は前回の記事にある「DevOpsプロジェクトの新規作成」の項を参考にプロジェクトの作成を行って下さい。
Azure Pipelinesのメニュー
DevOpsプロジェクトの作成まで完了したら、Azure DevOpsのプロジェクトダッシュボードを表示しましょう。
Azureポータルの左側メニューから「すべてのサービス」を選択して検索ボックスに「devops」と入力し、「DevOps Projects」を選択します。プロジェクトの一覧からDevOpsプロジェクトを選択し、画面上部の「Project homepage」を選択します。
プロジェクトダッシュボードの画面に遷移できたら、左側のメニューから「Pipelines」を選択してAzure Pipelines用のサブメニューを展開します。
Azure Pipelinesは以下5つのサブメニューから構成されています。
・Builds
ビルドパイプラインと呼ばれるコードのビルドやテストなどの手順をまとめたものを管理する画面です。BuildsはCI/CDの「CI」に相当します。Buildsではビルドパイプラインの作成、実行、結果の確認を行うことができます。なお、DevOpsプロジェクトダッシュボードの左側メニューで「Pipelines」を選択すると、このBuildsの画面が表示されるようになっています。
・Releases
ビルドパイプラインで作成された成果物をターゲットとなる環境へデプロイする、リリースパイプランの管理を行う画面です。Releasesは「CD」の役割を担います。Builds同様にリリースパイプラインの作成、実行、確認を行うことができます。
・Library
Libraryには複数のパイプラインが参照できる情報を登録できます。登録できるものは大きく分けて「Variable groups」と「Secure files」の2種類があります。
「Variable groups」にはキーと値からなる、いわゆる環境変数を登録できます。登録した環境変数はビルドパイプラインやリリースパイプライン内のスクリプトから、通常の環境変数と同様の方法で参照できます。
「Secure files」には証明書や鍵などの機密性の高いファイルを安全に保存できます。ここにファイルを保存することで、Gitリポジトリにセキュアなファイルをコミットせずにアプリを構築できるようになります。
・Task groups
Task groupsはビルドパイプラインやリリースパイプラインを共通化して他のパイプラインで使用できるようにするためのものです。よく使用する手順をパターン化してTask groupsへ登録することで効率的にパイプラインが作成できるようになります。
・Deployment groups
通常のビルドパイプラインやリリースパイプラインでは、エージェントと呼ばれるAzure Pipelinesが提供するクラウド上のマシンでビルドやテストなどを行ってターゲットとなる環境へのデプロイが行われます。一方、Deployment groupsでは、ターゲットとなる環境上で直接パイプラインの実行ができるようにするための仕組みを提供します。
以降では、これらのサブメニューのうち使用頻度の高い「Builds」と「Releases」の2つについて詳しく説明していきます。
ビルドパイプラインの詳細を見てみよう
まずは、ビルドパイプラインの詳細について確認していきます。ビルドパイプラインは、「Builds」サブメニューで確認することができます。
Buildsのトップ画面
サブメニューから「Builds」を選択すると以下の図のような画面が表示されます。詳しくは後述しますが、すでにビルドの実行履歴が表示されています。これは、DevOpsプロジェクトの作成時にプロジェクトテンプレートからの作成を行うと、あらかじめ1つのAzure Reposリポジトリとビルド、リリースパイプラインのセットが作成された状態でプロジェクトが用意されるためです。
Builds画面のやや左側に表示されているのは、ビルドパイプラインの一覧です。現在は「zerokara-repos - CI」というパイプラインが1つだけ表示されています。名前の左側には最新のビルドの結果がアイコンで表示されています。
この一覧からビルドパイプラインを選択すると、画面の中央から右側にそのビルドパイプラインの実行履歴が表示されます。ここではこれまでのビルドの実行結果を確認することができます。なお、ここに表示されているメッセージは、Gitリポジトリにコミットした際に入力したコミットメッセージです。ビルドパイプラインは原則としてリポジトリの更新をきっかけに起動するものであるため、コミットメッセージを表示することでどのような変更によるビルドが実行されたのかが分かるようになっています。
ビルドパイプラインの中身
続いて、ビルドパイプラインが実際にどのように定義されているのかを確認していきます。Buildsのトップ画面の右上にある「Edit」ボタンを選択します。
この画面がビルドパイプランの編集画面です。色々なメニューが表示されていますが、まずは画面左側に表示されているリストの部分について理解ができることが大切です。このリストこそがビルドパイプラインと呼んでいるビルドの実行手順になっています。
本稿ではASP.NET CoreのプロジェクトとしてDevOpsプロジェクトを作成したため、図では.NET Coreに特化したビルドパイプラインが表示されています。パイプラインは上から順に実行されるため、ここでの並び順は非常に重要です。
ビルドパイプラインの各項目について説明していきます。まずは最上部にある「Pipeline」です。ここはこのビルドパイプライン全般に関係する情報を設定する部分です。「Pipeline」の文字付近を選択すると、右側に設定内容が表示されます。パイプラインの名前やビルドする.NETプロジェクトの情報などを設定することができます。
その中にある「Agent pool」という設定項目では、ビルドを行うマシンであるエージェントの種類を選択することができます。冒頭で説明したように、WindowsやLinux、macOSなどが選択できるようになっています。ビルドする言語やプラットフォームに合わせて選択するようにして下さい。
次に「Get sources」です。ここはビルドの対象となるコードのリポジトリに関する設定を行う部分です。以下の図の通りAzure Reposをはじめ、GitHubやBitbucketなどのGitのリポジトリサービスやSubversionなどからコードを取得できます。サービスの選択後、ビルドするリポジトリ、ブランチなどを選択していきます。
続いて「Agent job 1」と表示されている部分です。ここではエージェントマシンの振る舞いについて設定することができます。例えばビルド実行時の並列度やタイムアウト時間などを設定することができます。
「Agent job 1」の下に連なるように表示されているのが、ビルドパイプラインの各手順です。ここでは.NET Coreの手順となっていますが、他の言語やプラットフォームでも大まかな流れは同じです。まずはリポジトリからチェックアウトしたコードのクリーンや依存ライブラリのダウンロードを行ってビルドを実行し、ユニットテストの実行によってバグやデグレードの検知を行うという流れです。ここに、独自の手順を追加したい場合は、「Agent job 1」の右側にある「+」ボタンから手順を追加できます。追加できる手順(taskと呼ばれています)は多岐に渡るため、ぜひ実際に使って確かめてみて下さい。
ビルドパイプラインの一番最後にある「Publish Artifact」はAzure Pipelies独自のタスクです。これはビルドパイプラインによって作成した成果物を、続くリリースパイプラインに連携するためのものです。処理自体は単純で、指定したAzure Pipelines上のディレクトリに任意の名前(ここでは「drop」)を付与した成果物をコピーするというものです。
リリースパイプラインの詳細を見てみよう
続いてリリースパイプラインの定義を確認していきます。「Releases」サブメニューを選択します。
Releasesのトップ画面
Releasesのトップ画面はBuildsのものとほぼ同じ画面構成となっているので分かりやすいかと思います。左側にリリースパイプラインの一覧が表示されており、右側に選択したリリースパイプラインの実行履歴が表示されています。
リリースパイプラインの実行履歴にある「Stages」という項目ですが、これはデプロイ先となる環境に相当するものです。図の例では「dev」と表示されているため、開発環境へのデプロイを意味していると捉えることができます。Stagesは、開発、ステージング、本番といった運用観点での環境の分け方や、東日本リージョンと西日本リージョンといった地理的な分け方など、リリースの方式によってさまざまなパターンをとることになります。
リリースパイプラインの中身
Releasesのトップ画面の右上の「Edit」ボタンを選択してリリースパイプラインの定義画面に移動します。リリースパイプラインの定義画面は以下の図のように処理がブロックごとに分かれて表示されています。リリースパイプラインでは先程説明したStagesのようにリリース先が複数に分岐することも少なくないため、このようにグラフィカルな画面で表現がされています。なお、この画面では処理の流れが左から右へと進むように読んでいきます。
リリースパイプラインの開始点となるのは「Artifacts」という枠に囲われたブロックです。リリースパイプラインがデプロイすべき成果物をここで定義します。このブロック内にある「Drop」というコンポーネントを選択すると成果物の詳細情報を確認できます。
このうち「Source(build pipeline)」という項目がこのリリースパイプラインと連携しているビルドパイプラインを指します。ビルドパイプラインを指定し、そこで生成された成果物の名前を「Source alias」で指定します。図の例では「Drop」と記載されていますが、これは先程確認した「zerokara-repos - CI」というビルドパイプラインの最後の処理にあった「Publish Artifact」で指定した成果物の名前(drop)と一致するようにします(文字の大文字小文字は問われません)。
これでビルドパイプラインとリリースパイプラインの連携が定義されましたが、このリリースパイプラインを起動する条件であるトリガーに関しては「Drop」コンポーネントの右上の雷マークのアイコンを選択して定義していきます。この中にある「Continuous deployment trigger」のトグルが「Enabled」となっていれば、ビルドパイプラインの正常終了後に連続してリリースパイプラインの実行が開始されるようになり、「Disabled」の場合は手動でのみ実行が開始されるようになります。
続いて「Stages」のブロックを確認していきます。このブロックの中で実際にデプロイを行うためのコンポーネントであるステージを定義していきます。現在ある「dev」というステージに表示されている「1 job, 4 tasks」という部分を選択すると、ステージで定義されている処理の詳細を確認することができます。
この画面はビルドパイプラインの定義画面とほぼ同じ構成となっていることが分かるかと思います。エージェントの中で定義している各処理の種類が異なるだけだと捉えることができます。このプロジェクトでは、Azure App Serviceに対してアプリケーションをデプロイするため、まず「Azure Deployment:Create Azure App Service」という処理でApp Serviceの作成を行っています。この処理は、Azure Pipelinesが提供している「Azure resource group deployment」というタスクを使用しています。このタスクによって、ARM(Azure Resource Manager)テンプレートと呼ばれるAzureのリソース情報を定義したJSONファイルからAzureのリソースを作成する機能を使用できます。
ARMテンプレートには、リソースの名称やサイズ、作成先となるリージョンなどのリソースに関する情報を自ら定義する必要があります。このプロジェクトの例では、あらかじめApp Serviceを作成するためのARMテンプレートがAzure Reposにコミットされており、それをこのタスクから利用しています。このタスクの詳細情報のうち、「Template」という項目でARMテンプレートのパスを指定しています。
パスの先頭に記載されている「$(System.DefaultWorkingDirectory)」という環境変数は、パイプライン上の作業ディレクトリを意味しています。ビルドパイプラインの処理中にアップロードしたファイルがこのパスに配置されています。このパス配下に含まれる「windows-webapp-template.json」というファイルが実際のARMテンプレートになります。また、パスの右側にある「・・・」ボタンを選択すると、作業ディレクトリの内容を確認することのできるダイアログが表示されてファイルを探すこともできるので、パスが分からない場合などはここからファイルを選択することでパスを補完することができます。
なお、「windows-webapp-template.json」というARMテンプレートファイルは、このプロジェクトのリポジトリであるAzure Reposにコミットされています。別タブなどでAzure Reposを開き、Filesサブメニューでリポジトリの「ArmTemplates」ディレクトリを展開すると、ARMテンプレートを確認することができます。
ARMテンプレートを使用してApp Serviceを作成した後で、「Deploy Azure App Service」で成果物をApp Serviceへデプロイします。このタスクも1つ前と同様に、「Package or folder」という項目でデプロイする成果物を作業ディレクトリから選択して指定します。
ここまでのタスクでデプロイが完了します。以降の2つのタスクは、デプロイしたWebアプリケーションに対してテストを行うためのものです。単体テストとは異なり、ここでは実際のWebページにアクセスして画面の内容を確認するテストを行っています。
パイプラインを実行してみよう
ビルド・リリースパイプラインの仕組みについて理解したところで、最後にパイプラインを実行してみましょう。パイプラインの実行は手動で行うことも可能ですが、ここではコードの修正をトリガーとしてビルドパイプラインとリリースパイプランが連続して実行されていく様子を確認していきたいと思います。
ビルドパイプラインの実行確認
ここではWebアプリのトップページのタイトルを修正してみます。ブラウザの別タブでAzure ReposのFilesメニューを開き、「Application/aspnet-core-dotnet-core/Pages/Index.cshtml」というファイルを選択します。画面上部の「Edit」を選択してファイルを編集可能にし、4行目にある「Home Page」という部分を「Top Page」に修正してみます。
タイトルを変更したら、画面上部の「Commit...」を選択して修正内容をリポジトリにコミットします。ファイルのコミット後すぐにAzure PipelinesのBuildsメニューに戻ると、ビルドパイプラインの実行履歴に先程コミットしたメッセージで新しいビルドの履歴が表示されています。
このコミットメッセージを選択すると、ビルドパイプラインの実行ログを確認することができます。ビルドパイプラインの定義画面で設定した各タスクが上から順に実行されていきます。なお、ビルドが実行中の場合は以下の図のように実行中のタスクのログが画面に表示されます。
しばらく待っていると、ビルドパイプラインのすべてのタスクが終了します。以下の図のように全てのタスクにチェックマークが付いていれば、ビルドは成功となります。
リリースパイプラインの実行確認
ビルドパイプラインが成功すると、それをトリガーにリリースパイプラインが実行されるので、左側のメニューから「Releases」を選択します。すると、ビルドパイプラインと同様に新しいリリースパイプラインの実行履歴が表示されています。
新しい実行履歴の名前(図では「Release-3」)を選択します。すると現在のリリースパイプラインの進捗状況を確認することができます。以下の図では、「dev」のステージのタスクを実行中で、6つのタスクのうち3つまで完了していることが分かります。
「dev」ステージに表示されている「In progress」の部分を選択すると、ステージのさらに詳細なログを確認することができます。こちらもビルドパイプライン同様に、定義したリリースパイプラインの各タスクが上から順に実行されていきます。
しばらくするとリリースパイプラインの実行が完了します。しかし、以下の図ではステータスが「Failed」、つまりリリースパイプラインが失敗で終わってしまいました。
失敗しているタスクはNGマークで表示されている「Test Assemblies」というタスクです。このタスクは、デプロイが完了したWebアプリケーションに対してWebブラウザを経由したテストを実行するタスクです。今回のコードの修正によってテストが失敗してしまった可能性が考えられるので、Azure Reposに戻ってテストコードを確認してみましょう。
テストコードの修正
失敗してしまったテストコードは、Azure Reposにコミットされている「Application/aspnet-core-dotnet-core.FunctionalTests/SampleFunctionalTests.cs」というファイルです。テストコードの詳細については割愛しますが、このファイルの36行目から始まるテストメソッドの48行目に、Webアプリのトップページのタイトルの文字列を検証している部分があります。この部分の記述が、先程修正したタイトルの文字列と一致していないためにテストが失敗してしまったようです。そのため、このファイルの48行目の「Home Page」という部分を「Top Page」となるように修正してコミットします。
テストコードのコミットによって、また新たにビルドパイプラインとリリースパイプラインの実行が開始されます。しばらく待ってリリースパイプラインの実行まで全て成功すれば、リリースは成功となります。
ここまでで、コードの修正を起点にAzure Pipelines上でビルドとリリースが連続して行われていく様子を確認することができました。
まとめ
今回はAzure DevOpsのうちCI/CDの機能を提供するAzure Pipelinesについてご紹介しました。Azure PipelinesにはCIとCDというDevOpsにおいて非常に大きな役割を担う2つの機能が含まれており、提供されている機能も多岐に渡りため初めのうちはとっつきにくい印象をもってしまうかもしれません。しかし、今回の説明に使用したようなDevOpsのプロジェクトテンプレートなどを使用することで、ゼロベースでパイプラインを構築するのではなく、完成したパイプラインを自分の要件に合うように修正していくことでハードルを下げることができるのではないかと思います。テンプレートからうまく応用していき、徐々に理解を深めていくことがAzure Pipelinesを使いこなす近道ではないでしょうか。
次回はAzure DevOpsのラインナップのうち、パッケージ・ライブラリ管理のためのサービスであるAzure Artifactsについて紹介する予定です。
WINGSプロジェクト 秋葉龍一著/山田祥寛監修
<WINGSプロジェクトについて>テクニカル執筆プロジェクト(代表山田祥寛)。海外記事の翻訳から、主にWeb開発分野の書籍・雑誌/Web記事の執筆、講演等を幅広く手がける。一緒に執筆をできる有志を募集中