ツナ缶雑記

ぐうたらSEのブログです。主にマイクロソフト系技術を中心に扱います。

Azure PipelinesでYAMLを使って仮想マシンにアプリケーションをデプロイする

Azure Pipelinesには、アプリケーションをデプロイするためのリリースパイプラインを、GUIで作る機能がありました。 この機能は大変便利なのですが、既に「Classic」と表現されていて、徐々に消えていく運命にあります。 今からやるなら、ビルド/リリースパイプラインの定義をYAMLで作り、ソースリポジトリと一緒に管理していくのがよい、とされています。 Azure PipelinesにもYAMLを使ったビルドパイプラインを作る機能があるのですが、悲しいかな仮想マシンに対してアプリケーションをデプロイすることが、標準的な方法では準備されていませんでした。

しかし、2019年末のSprint 162で、Azure Pipelinesから仮想マシンにデプロイするための機能が入りましたので、その中身を軽く確認してみようと思います。 Classicなリリースパイプラインで使っていた「Deployment group」と比較しながら、何が違うのかも確認していきます。

なお本稿ではMulti stage pipelineについて詳しく解説しません。 またDeployment Groupについても知っている前提で書きますのでその辺ご容赦ください。

大変お恥ずかしいのですが、画面キャプチャ内に大量のTypoがあります。 意味はかろうじて分かると思うので、修正していません。

Environmentを追加する

まずは、アプリケーションをデプロイする論理的なグループをAzure Pipelinesに作成します。 Azure DevOpsでプロジェクトに入り、 [Pipelines] → [Environments] メニューを選択します。

f:id:masatsuna:20200116225446p:plain
Environmentの作成 その1

新しいEnvironmentの作成ダイアログが出るので、登録するVMの論理的な名前を付けます。 例えばWebアプリケーションを実行する「WebServers」とか、バッチ処理を行う「BatchServers」とか、そういった名前がよいと思います*1。 今回はVMを登録するので、リソースから [Virtual machines] を選択して [Next] ボタンを押下します。

f:id:masatsuna:20200116225607p:plain
Environmentの作成 その2

続いて仮想マシンを登録するためのPowerShellスクリプトを取得するための画面が出てきます。 今回はWindowsVMを使うので、以下の通り設定して、 [Registration script] の横にあるコピーボタンを押下して、コピーします。 このタイミングで、Azure DevOpsにVMを登録するために使用するPersonal Access Token(PAT)が発行されます*2。 自分でPATを発行する必要がないので非常に便利ですね。

f:id:masatsuna:20200116225956p:plain
Environmentの作成 その3

仮想マシンをEnvironmentに追加する

続いて作成したEnvironmentに対して、VMを登録していきます。 VMを登録するためには、先ほどの手順でコピーしたPowerShellスクリプトを、 登録するVM内で管理者権限で実行するだけです*3。 このスクリプトを実行すると、Environmentに登録すためのエージェントをダウンロードし、適当な場所に展開して、Windowsサービスとして登録するところまでやってくれます。

f:id:masatsuna:20200116231117p:plain
エージェントの登録

うまく登録が完了すると、このようにAzure DevOps側で、登録したVMが見えるようになります。

f:id:masatsuna:20200116231339p:plain
登録したVMの一覧

Deployment Groupと何が違うのか

実は、Deployment GroupとEnvironmentで、エージェントのアプリケーションは全く同一です。 コピーしたPowerShellスクリプトをよく見てみると、Deployment Groupの登録で使ったconfig.cmdを実行していることがわかります。 唯一異なるのは、config.cmdに渡している以下のオプション引数のみです。

Environemtに登録する場合

.\config.cmd --environment --environmentname "WebServers"

Deployment Groupに登録する場合

.\config.cmd --deploymentgroup --deploymentgroupname "WebServers"

ですので、プロキシサーバー内にあるVMをEnvironmentに登録することも、Deployment Groupの時と同じやり方で実現できます。 以下の記事で解説した通り、 --proxyurl オプションを指定してあげれば、プロキシの壁を越えられます。

tsuna-can.hateblo.jp

YAMLを使ったビルド/リリースパイプラインを作成する

ここまででデプロイ先のVMがAzure DevOpsとつながったので、ビルド/リリースパイプラインを作ってアプリケーションをデプロイできるようにしていきます。 アプリケーションをデプロイするStageに対して「deployment」という特殊なJobを追加して、デプロイ先のEnvironmentの設定を行います。 nameは作成したEnvironmentの名前を指定します。 resourceTypeはVMなので「VirtualMachine」を指定します。

# 前略
jobs:
  - deployment: 'DeployWebApplication'
    environment:
      name: WebServers
      resourceType: VirtualMachine
# 後略

続いてデプロイ戦略を設定します。 VMへのデプロイの場合、「RunOnce」と「Rolling」の2つからデプロイ戦略を選択することができます。 どちらの戦略でデプロイするかを決めたら、その設定を行います。

jobs:
  - deployment: 'DeployWebApplication'
    environment:
      name: WebServers
      resourceType: VirtualMachine
    strategy:
      runOnce:
        preDeploy:
          steps:
          - download: none
          - task: DownloadPipelineArtifact@2
            inputs:
              buildType: 'current'
              artifactName: 'WebApplications'
              targetPath: '$(modulePath)'
        deploy:
          steps:
          - download: none
          - task: IISWebAppDeploymentOnMachineGroup@0
            displayName: 'Deploy application to Website'
            inputs:
              WebSiteName: 'Default Web Site'
              VirtualApplication: 'VmEnvironmentSample'
              Package: '$(modulePath)/*.zip'
              RemoveAdditionalFilesFlag: true

この例ではRunOnceのデプロイ戦略を使って、アプリケーションのデプロイを行っています。 デプロイ戦略はdeploymentのJobにぶら下げる形で定義します。 preDeployにはアプリケーションを配置する直前に行う処理、deployにはアプリケーションを配置する処理を書いていきます。

通常preDeployでは、アプリケーションをビルドするStageで作成したPipeline Artifactsをダウンロードします。 この例では [WebApplications] という名前のPipeline ArtifactsをビルドするStageで作成しているため、このような形で定義しています*4

そしてdeployで、preDeployでダウンロードしたモジュール一式を、IISのアプリケーションに対して配置します。 配置先のWebサイト名、アプリケーション名などは環境にあわせて設定しましょう。

この例ではIISにWebアプリケーションを配置していますが、ここにPowerShellなどのタスクを置くことで、かなり柔軟にデプロイを実行することができます。 コンソールアプリケーションを配置する場合は、ZIPファイルの展開タスクやファイルコピータスクなどを駆使して、配置ロジックをくみ上げるのがよいかもしれません。

*1:例えばWebサーバーが複数台いる場合、ここで作成したWebServersというEnvironmentに、複数台のVMを登録することができます。

*2:ここで作成したPATは、その日限り有効になるよう設定されているようです。

*3:私の環境では、一部のダブルクォーテーションが全角でコピーされてしまうため、毎回半角に打ち直す手間が発生しています。理由は追跡していません。

*4:downloadの方を使ってもいいのですが、初学者にはわかりにくいと社内から言われるので、個人的にDownload Pipeline Artifactのtaskを使って書くようにしています。