Azure Kubernetes Service(AKS) × Azure DevOpsでモダンなCI/CD環境を構築してみた

## はじめに  
CI/CDの定番ツールと言えば個人的にCircleCIとGitHubだと思うんですが、Azureサービスで楽々にCI/CD環境を構築したのでまとめてみました。ソースコードとか詳細な手順は掲載していないの悪しからず。  

## 目次  
- 構成図
- AKSクラスターとプライベートレジストリの構築  
- AzureDevOpsでプロジェクト作成  
- azure-pipeline.ymlにビルド・テストコマンドを記述  
- Deployの設定
- git push で動作確認  
- おわりに  

## 構成図  
構成図はこんな感じです。  
<img width="955" alt="スクリーンショット 2019-08-24 17.55.57.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286861/d403b549-a32f-2e99-4277-a6303fdb5d60.png">

## AKSクラスターとプライベートレジストリの構築  
AKSクラスタとContainer Registryを作成しAKSからregistryにアクセスできるようにします。これは以下の公式ドキュメントを参考にしました。
[AKSクラスタの作成](https://docs.microsoft.com/ja-jp/azure/aks/)
[ACRの作成](https://docs.microsoft.com/ja-jp/azure/container-registry/)
[AKSとACRの連携](https://docs.microsoft.com/ja-jp/azure/container-registry/container-registry-auth-aks)

## AzureDevOpsでプロジェクト作成  
ポータルからAzure DevOpsを検索し、プロジェクトを作成しました。Azure DevOpsをはじめて利用する場合は組織を作成する必要があります。ちなみにWEB UIはこんな感じです。
![スクリーンショット 2019-08-24 18.09.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286861/be861553-c764-1d79-b976-03bf90a3a17a.png)
この画面からパイプラインの作成やら、開発メンバーの追加が行えます。開発から本番環境まで全てAzureのサービスを使うといった場合、Azure DevOpsはおすすめです。

## azure-pipeline.ymlにビルド・テストコマンドを記述   
Azure Reposから新しいリポジトリを作成し、サンプルのソースコードをpushしました。Azure Pipilines > Buildで新しいビルドバイプラインを作成します。GitプロバイダーはAzure Repos以外にもGitHub、Bitbucket等を選択できます。ビルドのテンプレートは豊富な言語・プラットフォームから選択できます。ここではJavaのSpring Bootを使用したのでmavenを選択します。バイプラインを作成すると、ソースコードリポジトリのルートにazure-pipelines.ymlという名前のファイルが作成されます。今回はこんな感じで記述しました。  

```:azure-pipelines.yml
# Maven
# Build your Java project and run tests with Apache Maven.
# Add steps that analyze code, save build artifacts, deploy, and more:
# https://docs.microsoft.com/azure/devops/pipelines/languages/java

trigger:
- master

pool:
  vmImage: 'ubuntu-latest'

variables:
  dockerId: matsucon
  backendImageName: springapp

steps:
- script: |
    echo Starting Build
    mvn install -DskipTests=true
  displayName: 'ビルドを実行しています'
- script: |
    echo Starting UnitTest
    mvn test
  displayName: 'テストを実行しています'
- script: |
    docker build -t $(dockerId).azurecr.io/$(backendImageName) --no-cache .
    docker login -u $(dockerId) -p $(dockerLoginPassword) $(dockerId).azurecr.io
    docker push $(dockerId).azurecr.io/$(backendImageName)
  displayName: 'イメージをビルドしてレジストリにpushしています'
```
CircleCIなどのCIツール利用したことのある方はおなじみの記法だと思います。コンテナレジストリのパスワードなどの機密情報は環境変数としてWEB UIから設定できます。[公式リファレンス](https://docs.microsoft.com/en-us/azure/devops/pipelines/yaml-schema?view=azure-devops&tabs=schema)を参考にしています。

## Deployの設定 
次にデプロイの定義をしていきます。azure-pipelines.ymlにCI定義まで記述したんだからデプロイの定義も同じファイルに書かせてくれよと思ったのですが、そこは目をつむって先に進みます。
Pipelines > Releasesからデプロイの詳細を設定していきます。デプロイ設定はドキュメントがあまりなく、WEB UIをあちこちいじりながら設定していきました。うまくいくとこんな感じになります。
![スクリーンショット 2019-08-24 19.04.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286861/dad1ba38-4923-856c-73ab-ffe8596faccc.png)
ビルドの終了をトリガーにして、`kubectl apply deploy`でアプリのデプロイ、`kubectl apply service`でアプリを外部に公開しています。

## git push で動作確認  
SpringBootで書かれたpush前のコードは以下のようになっています。 

```java:Example.java
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@EnableAutoConfiguration
public class Example {

    @RequestMapping("/")
    String home() {
        return "<h1>hello World</h1> \n <h2>sample app</h2>";
    }

    static int calc(int a, int b) {
        return a + b;
    }

    public static void main(String[] args) {
        SpringApplication.run(Example.class, args);
    }

}

```  

h1タグのhello Worldをこんにちは世界に変えてpushしてみます。

Azure Pipelinesを見てみるとビルドが走っていることが確認出来ます。
![スクリーンショット 2019-08-24 19.07.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286861/79c52871-b2c4-3104-2e8c-e69539aaa053.png)

`kubectl get svc`で公開されているサービスのIPを調べてブラウザで表示してみます。
<img width="364" alt="スクリーンショット 2019-08-24 20.12.30.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286861/dec78f59-d9d0-d703-7fd0-c8a9db351eef.png">
AKSへのデプロイもうまくいってるみたいです。

## おわりに  
CI/CDパイプラインを誰でも簡単に(?)構築できてしまうAzureDevOpsですが、デプロイのところでは直感的に扱うのが難しいなというのが第一印象でした。ただ、Azureユーザーなら使いなれたサービスでCI/CDパイプラインを構築できてお手軽なので気になる方はぜひ試してみてください。