Azure DevOpsのPiplineを使ってみた

# はじめに
お疲れさまです。今回はMicrosoftのAzure DevOpsで提供されている機能の一つであるPiplineを使ってみる方法についてご紹介します。

流れとしては Github レポジトリと連携し、レポジトリのソースコードをビルドしたイメージをAzure Container Registryにプッシュ。そのイメージをApp ServiceにデプロイするというCDを実現することを目標にします。


# Piplineの作成
- Pipline作成のボタンを押すと、以下のようにコードの保存場所を選択する画面になります。今回は「GitHub」を選択します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3942439/9adb79b1-bb83-ade2-c3ca-7bcac8b18902.png)

- GitHubの場合、ログイン画面に遷移するのでログインします。
organizationへのSSOの認証が出た場合。利用したいリポジトリのあるorganizationを認証してください。
認証が成功すると、リポジトリ一覧が表示されるので、対象のリポジトリを選択します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3942439/7e94e53f-71de-e92f-503d-57ba42a9ff40.png)

- Configure your pipeline画面に遷移すると、Piplineのテンプレートを選択できます。今回はDockerの「Build and push an image to Azure Container Registry」を選択します。
すると、Azure Container Registryを指定するためのポップアップが表示されるため、対象となるリソースがあるAzure subscriptionとContainer Registry名、Dockerイメージ名、Dockerfileのデフォルトパスを指定してください。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3942439/91e2a48d-53d1-d74f-13ec-2e0aaecfcded.png)

- Review your pipeline YAML という画面で、問題なければ、「Save and run」ボタンで作成します。今回は実行をしないため、ボタン横のオプションからsaveをします。


# Azure Piplineのコードについて
以下がPiplineのコード例です。
- 環境変数の扱いは、Libraryという機能を用いています。 Libraryで環境変数のグループを作成し、その中にこのPiplineで使用する環境変数のname-valueペアを保存しています。`group: test-variable-group-dev`の箇所でグループを読み込んでいます。こうすることで、グループ内に設定されている環境変数を用いることができるようになります。

- Dockerイメージのビルドは「Docker@2」というタスクを用いることで可能です。今回は`command: buildAndPush`を利用しています。このコマンドを用いると、イメージのビルドとContainer Registryへのプッシュをまとめて行うことができます。この時、`repository: $(imageRepository)`にはPipline作成時に入力したDockerのイメージ名が入り、`containerRegistry: $(dockerRegistryServiceConnection)`にはPipline作成時に作られたContainer RegistryへのService Connectionの識別子が入ります。これはテンプレートの作成時に自動的に作成されます。

- App Serviceへのデプロイは「AzureWebAppContainer@1」というタスクで実現できます。`azureSubscription: $(azureServiceConnection)`の指定は必須でここでは、対象のApp Serviceにアクセス可能なAzure Resource ManagerのService Connectionを指定しています。また、`appName: $(appName)`も必須で、デプロイ先のApp Service名を指定します。`containers: $(containerRegistry)/$(imageRepository):$(tag)`では明示的にデプロイに用いるイメージを指定しています。ここでは、直前のstageでビルド＆プッシュされたイメージです。

```yaml
# Docker
# Build and push an image to Azure Container Registry
# https://docs.microsoft.com/azure/devops/pipelines/languages/docker

trigger:
  - dev

resources:
  - repo: self

variables:
  # Container registry service connection established during pipeline creation
  - group: test-variable-group-dev
  - name: tag
    value: '$(Build.BuildId)'

stages:
  - stage: BuildandPush
    displayName: Build and push stage
    jobs:
      - job: Build
        displayName: Build
        pool:
          vmImage: $(vmImageName)
        steps:
          - task: Docker@2
            displayName: Build and push an image to container registry dev
            inputs:
              command: buildAndPush
              repository: $(imageRepository)
              dockerfile: $(dockerfilePath)
              containerRegistry: $(dockerRegistryServiceConnection)
              tags: |
                $(tag)

  - stage: Deploy
    displayName: Deploy webApp
    dependsOn: BuildAndPush
    condition: succeeded()
    jobs:
      - job: deploy
        pool:
          vmImage: $(vmImageName)
        steps:
          - task: AzureWebAppContainer@1
            displayName: 'Azure Web App on Container Deploy dev'
            inputs:
              azureSubscription: $(azureServiceConnection)
              appName: $(appName)
              containers: $(containerRegistry)/$(imageRepository):$(tag)

```

上記のようなPiplineで、App serviceにアプリをデプロイするCDを実現できます。`Docker@2`や`AzureWebAppContainer@1`といったタスク（機能のパッケージのようなもの）が公式で提供されており、非常にシンプルに記述できることがわかります。

# 補講
## Service Connectionについて
Piplineの中で、Service Connectionを用いている箇所があります。Service ConnectionはPiplineと外部サービス（Azure、GitHub、Docker Hubなど）との間で安全に通信するための接続設定のことです。
例のPiplineでは、App Serviceへのデプロイの際に、そのApp Serviceが存在するリソースグループを対象としたAzure Resource ManagerタイプのConnectionを作成し、利用しています。

Service Connectionを用いることで、外部への接続に必要な情報を安全に管理し、かつ再利用やメンテナンスも容易になるというメリットがあります。

下図のようにservice Connectionの作成は、Azure DevOpsの設定画面から「Service connections」を選択します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3942439/6ab5688d-8362-2821-adbe-27e9bb5d0deb.png)

作成時には、connection typeを選択します。今回の例ではAzure Resource Managerを選択しています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3942439/5a4a05d2-37d9-9f5f-2f56-f8183d7800f7.png)

Azure Resource Managerのconnectionを作成する場合、下図のように設定を行います。Identity typeとCredentialは通常、推奨のままで問題ありません。また、設定から読み取れるように、conenctionを作成するとアプリの登録がEntraIDに作成されます。
その後、対象のリソースグループがあるSubscription、対象のResource groupを指定し、connection名を入力し作成します。

Piplineでの利用の際は、作成時に決めたconnection名を指定することで利用できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3942439/b2bfbd55-af79-0309-e1d9-91b97d8af3af.png)


# まとめ
- Azure DevOps PiplineでGitHubリポジトリからApp Serviceにアプリをデプロイする
- GitHubを用いる場合は認証が必要
- 必要に応じてService Connectionを作成する必要がある
- 環境変数はLibraryという機能で扱える
- 「Docker@2」、「AzureWebAppContainer@1」というタスクが利用でき、シンプルに記述可能

お読みいただきありがとうございました！

# 参考文献


https://learn.microsoft.com/en-us/azure/devops/pipelines/repos/github?view=azure-devops&tabs=yaml#access-to-github-repositories

https://learn.microsoft.com/ja-jp/azure/devops/pipelines/tasks/reference/docker-v2?view=azure-pipelines&tabs=yaml


https://learn.microsoft.com/ja-jp/azure/devops/pipelines/tasks/reference/azure-web-app-container-v1?view=azure-pipelines

https://learn.microsoft.com/ja-jp/azure/devops/pipelines/library/service-endpoints?view=azure-devops


https://learn.microsoft.com/ja-jp/azure/devops/pipelines/library/connect-to-azure?view=azure-devops