Atsushi2022の日記

データエンジニアリングに関連する記事を投稿してます

Azure DevOps

概要

Azure DevOpsを業務で使いそうなので下記のUdemy講座を受講してみた。

重要そうなところをメモしておく。

Learn DevOps: Docker, Kubernetes, Terraform and Azure DevOps

DockerやTerraformはなんとなくわかっているので、今回は以下のセクションに取り組んだ。

  • 6 Getting started with Continuous Integration, Deployment & Delivery
  • 7 Learn Azure DevOps - Continuous Integration, Deployment & Delivery Docker
  • 8 DevOps on Azure AKS, Kubernetes Clusters - Docker, Azure DevOps & Terraform
  • 10 Learn Azure DevOps with Boards and Backlogs

自分がスキップしまくったせいかもしれないけれど、Azure DevOpsの全体感が本Udemy講座ではわかりにくかった。

Udemy視聴前に読んでおくと良い記事

いきなりUdemy講座を視聴するのではなく、まずはこちらでAzure DevOpsについて概観しましょう。

CI / CD プロセス

Continous Integration

CIのプロセスは以下の通り。

  1. Code Commit
  2. Unit Tests
  3. Code Quality
  4. Package
  5. Integration Tests

Continous Deployment

CIのプロセスに、DeployとAutomated Testsが入っている。

  1. Code Commit
  2. Unit Tests
  3. Integration Tests
  4. Package
  5. Deploy
  6. Automated Tests

Continous Delivery

Continous Deploymentのプロセスに加えて、UATチームやTestingチームが承認を行い、ステージング環境や本番環境にデプロイされる。

  1. Code Commit
  2. Unit Tests
  3. Integration Tests
  4. Package
  5. Deploy
  6. Automated Tests
  7. Testing Approval
  8. Deploy Next
  9. ...

CI/CDで利用されるツール

  • Code Commit
    • Git Hub
  • Unit Tests
    • PyTest
  • Integration Tests
  • Package
    • pip
  • Deploy
    • Jenkins, Azure DevOps
  • Automated Tests (Smoke test, Load test, Performance test)
  • Testing Approval
  • Deploy Next

Azure DevOpsでのパイプライン

https://stackoverflow.com/questions/58575016/what-is-the-difference-between-pipeline-and-release-pipeline-in-azure-devops

  • Azure DevOpsにはPipelinesの配下にPipelinesReleasesが存在する。
  • Pipelinesはビルドパイプラインのことで、ソースコードからアーティファクトを生成するのに利用する。例えば、Dockerイメージを生成したりするのに利用する。単体テスト結合テストも自動化して実施する。
  • 一方、Releasesは、ビルドパイプラインで生成したアーティファクトをあるステージに展開する。例えば、デスクトップアプリケーションならインストール作業のこと。

https://www.patrickkoch.dev/posts/post_03/#:~:text=The%20Azure%20DevOps%20Server%20provides,within%20a%20multi%2Dstaging%20system.

  • The Azure DevOps Server provides two different types of pipelines to perform build, deployment, testing and further actions.
  • A Build Pipeline is used to generate Artifacts out of Source Code.
  • A Release Pipeline consumes the Artifacts and conducts follow-up actions within a multi-staging system.

ビルドパイプライン

ビルドパイプライン作成の流れ

https://learn.microsoft.com/ja-jp/azure/devops/pipelines/create-first-pipeline?view=azure-devops&tabs=java%2Ctfs-2018-2%2Cbrowser

  1. Repositoryとして使用するGit Hubリポジトリの作成
  2. 作成したリポジトリをAzure DevOps Pipelinesで指定
  3. パイプライン定義のYAMLを作成

ビルドパイプラインの定義

https://dev.azure.com/bluenamesjp/azure-devops-k8s-terraform/_apps/hub/ms.vss-build-web.ci-designer-hub?pipelineId=1&nonce=52/HC0X2RafAUc7AUd9vQg%3D%3D&branch=main

パイプラインYAMLファイルに、CI/CD プロセスを記述する

trigger:
- main

pool:
  vmImage: ubuntu-latest

steps:
- script: echo Hello, world!
  displayName: 'Run a one-line script'

- script: |
    echo Add other tasks to build, test, and deploy your project.
    echo See https://aka.ms/yaml
  displayName: 'Run a multi-line script'

YAMLファイルには以下のような項目を定義する

ビルドパイプラインの構成

パイプラインでは以下のような階層でタスクを定義できる。

ステージ、ジョブが定義されてなくても、タスクを定義できる。

パイプライン └── ステージ └── ジョブ └── タスク(ステップ)

ジョブの定義

https://learn.microsoft.com/ja-jp/azure/devops/pipelines/process/phases?view=azure-devops&tabs=yaml

以下ではJob1とJob2というジョブを追加してみた。

Azure DevOps Pipelineで実行すると、Job1とJob2それぞれのステータスが表示される。

それぞれのジョブは異なるエージェント(VM)で実行される。ジョブ間に依存関係がない限り、各ジョブは並行して実行される。

jobs:
- job: Job1
  steps:
  - script: echo Hello, world!
  displayName: 'Run a one-line script'
  - script: |
      echo Add other tasks to build, test, and deploy your project.
      echo See https://aka.ms/yaml
  displayName: 'Run a multi-line script'

- job: Job2
  steps:
  - script: echo Hello, world!
  displayName: 'Run a one-line script'

ジョブ間の依存関係の定義

https://learn.microsoft.com/ja-jp/azure/devops/pipelines/process/phases?view=azure-devops&tabs=yaml#dependencies

dependsOn:にジョブを指定することでジョブ間の依存関係を定義できる。

複数のジョブに対して依存関係を持たせることもできる。

現実には、Terraformでインフラを構築してから、アプリをインストールしたりする。そういった場合にジョブを指定した順に実行していく。

dependsOn:にステージ名を指定することで、ステージ間に依存関係を定義することができる。

jobs:
- job: Job1
  steps:
  - script: echo Hello, world!
  displayName: 'Run a one-line script'
  - script: |
      echo Add other tasks to build, test, and deploy your project.
      echo See https://aka.ms/yaml
  displayName: 'Run a multi-line script'

- job: Job2
  dependsOn: Job1
  steps:
  - script: echo Hello, world!
  displayName: 'Run a one-line script'

- job: Job3
  dependsOn: Job1
  steps:
  - script: echo Hello, world!
  displayName: 'Run a one-line script'

- job: Job4
  dependsOn: 
  - Job2
  - job3
  steps:
  - script: echo Hello, world!
  displayName: 'Run a one-line script'

ステージの定義

https://learn.microsoft.com/ja-jp/azure/devops/pipelines/process/stages?view=azure-devops&tabs=yaml

以下のようにステージを定義することができる。

stages:
- stage: Build
  jobs:
  - job: FirstJobs
    steps:
    - bash: echo Build,FirstJob
- stage: DevDploy
<省略>
- stage: QaDevloy
<省略>
- stage: ProdDeploy
<省略>

これを実行すると、Azure DevOpsのパイプライン画面で、各ステージのステータスが表示される。

stepsの定義

https://learn.microsoft.com/ja-jp/azure/devops/pipelines/yaml-schema/steps?view=azure-pipelines#list-types

stepsにはscrip以外にも、bashpwshなど様々なタイプをサポートする。種類は↑を参照。

trigger:
- main

pool:
  vmImage: ubuntu-latest

steps:
- script: echo This runs in the default shell on any machine
- bash: |
    echo This multiline script always runs in Bash.
    echo Even on Windows machines!
- pwsh: |
    Write-Host "This multiline script always runs in PowerShell Core."
    Write-Host "Even on non-Windows machines!"

変数の定義

https://learn.microsoft.com/ja-jp/azure/devops/pipelines/process/variables?view=azure-devops&tabs=yaml%2Cbatch

コンソール上やパイプライン定義、タスクのスクリプトで変数を定義できる。

パイプライン定義内で変数を定義する

https://learn.microsoft.com/ja-jp/azure/devops/pipelines/process/set-variables-scripts?view=azure-devops&tabs=bash#set-an-output-variable-for-use-in-future-jobs

以下のようにパイプライン定義内で変数を定義することもできる。

jobs:
- job: B
  dependsOn: A
  variables:
    env: Dev

変数のスコープ

https://learn.microsoft.com/ja-jp/azure/devops/pipelines/process/variables?view=azure-devops&tabs=yaml%2Cbatch#variable-scopes

さまざまなスコープで変数を設定できます。

  • ルート レベルで、パイプライン内のすべてのジョブで使用できるようにします。
  • ステージ レベルでは、特定のステージでのみ使用できるようにします。
  • ジョブ レベルでは、特定のジョブでのみ使用できるようにします。

定義済みの変数

https://learn.microsoft.com/ja-jp/azure/devops/pipelines/build/variables?view=azure-devops&tabs=yaml

↑の通り、Azure パイプラインで定義されている変数がある。

例えば、ビルドしたパイプラインの名前をログに表示するには、Build.DefinitionName変数を使って、echoで表示させることができる。

stages:
- stage: Build
  jobs:
  - job: FirstJobs
    steps:
    - bash: echo $(Build.DefinitionName)

ログの表示

https://learn.microsoft.com/ja-jp/azure/devops/pipelines/troubleshooting/review-logs?view=azure-devops#view-and-download-logs

↑の手順で、各ステップの個々のログを表示できる。

タスクアシスタント

https://learn.microsoft.com/ja-jp/azure/devops/pipelines/get-started/yaml-pipeline-editor?view=azure-devops#use-task-assistant

使いたいタスクを簡単に追加できる。

ファイルのコピー

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

stepsにtaskとして、CopyFiles@2を定義することで、ファイルをコピーすることができる。

stages:
- stage: Build
  jobs:
  - job: FirstJobs
    steps:
    - bash: echo $(Build.DefinitionName)
    - task: CopyFiles@2
      inputs:
        SourceFolder: '$(Build.SourcesDirectory)'
        Contents: |
          **/*.yaml
          **/*.tf
        TargetFolder: '$(Build.ArtifactStagingDirectory)'

ビルド成果物の発行

https://learn.microsoft.com/ja-jp/azure/devops/pipelines/tasks/reference/publish-build-artifacts-v1?view=azure-pipelines

stage間でビルド結果を共有したいことがある。

そういった場合には、task: PublishBuildArtifacts@1を使用する。

steps:
- task: CopyFiles@2
  inputs:
    contents: '_buildOutput/**'
    targetFolder: $(Build.ArtifactStagingDirectory)
- task: PublishBuildArtifacts@1
  inputs:
    pathToPublish: $(Build.ArtifactStagingDirectory)
    artifactName: 'drop'
    publishLocation: 'Container'

ビルド成果物とは?

https://learn.microsoft.com/ja-jp/azure/devops/pipelines/artifacts/artifacts-overview?view=azure-devops&tabs=nuget

  • ビルドによって生成されたファイル
  • 例: .dllや.exeなど

ストラテジー

https://learn.microsoft.com/ja-jp/azure/devops/pipelines/yaml-schema/jobs-job-strategy?view=azure-pipelines

  • マトリックスを使用すると、それぞれ異なる入力を持つジョブのコピーが生成されます。
  • これらのコピーは、さまざまな構成またはプラットフォーム バージョンに対するテストに役立ちます。
strategy:
    matrix:
      Python35:
        PYTHON_VERSION: '3.5'
      Python36:
        PYTHON_VERSION: '3.6'
      Python37:
        PYTHON_VERSION: '3.7'
    maxParallel: 2

steps:
- script: echo Running on $(PYTHON_VERSION)  
  displayName: 'Run a one-line script'
  • このマトリックスでは、"Build Python35"、"Build Python36"、"Build Python37" の 3 つのジョブが作成されます。
  • 各ジョブ内で、PYTHON_VERSION という名前の変数を使用できます。
  • "Build Python35" では、変数は "3.5" に設定されています。 同様に、"Build Python36" では "3.6" に設定されます。
  • 同時に実行されるジョブは 2 つだけです。

デプロイジョブ

https://learn.microsoft.com/ja-jp/azure/devops/pipelines/process/deployment-jobs?view=azure-devops

  • YAML パイプラインでは、デプロイ ジョブと呼ばれる特殊な種類の ジョブ にデプロイ手順を配置することをお勧めします。
  • デプロイ ジョブは、環境に対して順番に実行される手順のコレクションです。
  • デプロイ ジョブと従来の ジョブ は、同じステージに存在できます。
stages:
- stage: DevDeploy
  jobs:
  - deployment: DeployToDevelopment  
    environment: Dev
    strategy:
      runOnce:  
        deploy:
          steps:
          - script: echo deploy
- stage: QADeploy
  jobs:
  - deployment: DeployToQA 
    environment: QA
    strategy:
      runOnce:  
        deploy:
          steps:
          - script: echo deploy

承認とチェックの定義

https://learn.microsoft.com/ja-jp/azure/devops/pipelines/process/approvals?view=azure-devops&tabs=check-pass#approvals

  • 承認チェックを使用してステージを実行するタイミングを手動で制御できます。
  • 例えば、environment(環境)に対して、「承認とチェック」を作成すると、承認されるまでステージの実行を待機させる。
  • これによって承認されたもののみデプロイするということができるようになる。

ビルドパイプラインの無効化

https://www.ntweekly.com/2022/01/25/how-to-disable-azure-devops-pipeline-temporarily/

作成したパイプラインは↑の手順で無効化できる。

サービス接続の作成と使用

DockerHubなどの外部サービスと接続するためには、「サービス接続」を作成し、パイプライン定義で使用する。

サービス接続の作成

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

サービス接続の使用

https://learn.microsoft.com/ja-jp/azure/devops/pipelines/library/service-endpoints?view=azure-devops&tabs=yaml#use-a-service-connection

Dockerをビルドしてみる

https://www.udemy.com/course/devops-with-docker-kubernetes-and-azure-devops/learn/lecture/18086393#overview

  1. DockerHubへのサービス接続を作成する
  2. パイプラインで、サービス接続を使用する
trigger:
- main

resources:
- repo: self

variables:
  tag: '$(Build.BuildId)'

stages:
- stage: Build
  displayName: Build image
  jobs:
  - job: Build
    displayName: Build
    pool:
      vmImage: ubuntu-latest
    steps:
    - task: Docker@2
      displayName: Build an image
      inputs:
        containerRegistry: 'docker-hub-test'
        repository: 'test2023'
        command: 'buildAndPush'
        Dockerfile: '**/Dockerfile'
        tags: '$(tag)'

↑の例では、DockerイメージのタグにビルドIDを指定している。

Library

ライブラリでは、変数グループとセキュアファイルを設定できる。

変数やファイルへのアクセス制御ができるため、Azureへの接続情報などを安全に保管し、パイプラインで使用できる。

変数グループやセキュアファイルにアクセスできるパイプラインを制限することができる。

Variable group

https://learn.microsoft.com/ja-jp/azure/devops/pipelines/library/variable-groups?view=azure-devops&tabs=yaml

Secure files

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

リリースパイプライン

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

リリースパイプラインでは、ビルドパイプラインで作成したアーティファクトをAzure Appサービスなどにリリースする。

例えば、次のようなリリース例がある。

  • PythonJavaのアプリケーションをAzure Appサービスにデプロイ
  • コンテナ化したアプリケーションをKubernetesクラスタにデプロイ
  • Azure Functionsへのデプロイ
  • ARMテンプレートを利用したAzureリソースの作成
  • Terraformを利用したAzureリソースの作成

Terraformを利用したAzureリソースの作成

https://learn.microsoft.com/ja-jp/azure/developer/terraform/best-practices-integration-testing

https://www.udemy.com/course/devops-with-docker-kubernetes-and-azure-devops/learn/lecture/18086321?start=180#overview

Terraformを利用したAzureリソースの作成をPipelinesを利用して実現する。

PipelinesでTerraformを実行してAzureリソースを作成するには、PipelinesでTerraform CLI(terraform initやterraform apply)を扱えるようにするためのプラグインをイネーブルする必要がある。

以下の流れでPipelinesを作成する。

  1. Terraformコードの作成
  2. Azure DevOps上でAzureへの「サービス接続」の作成
  3. Azure DevOpsプラグインのイネーブル
    1. https://marketplace.visualstudio.com/items?itemName=ms-devlabs.custom-terraform-tasks&targetId=4f030a9a-9459-478b-beae-d29469710a6d
    2. https://marketplace.visualstudio.com/items?itemName=charleszipp.azure-pipelines-tasks-terraform
  4. Pipelinesの作成

Terraform CLIを実行するのにあたって、AzureのクライアントID、クライアントシークレット、SSH公開鍵ファイルをパイプラインYAMLに渡してあげる必要がある。

クライアントID、クライアントシークレットをPipelinesに渡すのには、Azure PipelinesのLibraryVariable groupを利用する。

一方、SSH公開鍵ファイルを渡すにはAzure PipelinesのLibrarySecure filesを利用する。

terraform initを実行するパイプライン定義は以下のようになる。

以下では、.tfstateファイルをAzure Storage Account上に作成している。リソースグループやストレージアカウントも一緒に作成している。

trigger:
- main

pool:
  vmImage: ubuntu-latest

steps:
- script: echo Azure Terraform!
  displayName: 'Run a one-line script'

- task: TerraformCLI@0
  inputs:
    command: 'init'
    workingDirectory: '$(System.DefaultWorkingDirectory)/configuration'
    backendType: 'azurerm'
    backendServiceArm: 'Pay-As-You-Go (e595aee6-f9b8-450f-b9d3-73768a2fd47a)'
    ensureBackend: true
    backendAzureRmResourceGroupName: 'terraform-backend-rg'
    backendAzureRmResourceGroupLocation: 'westeurope'
    backendAzureRmStorageAccountName: 'azuredevopsterraformbackend20230311'
    backendAzureRmContainerName: 'dev'
    backendAzureRmKey: 'terraform-dev.tfstate'

- task: TerraformCLI@0
  inputs:
    command: 'apply'
    workingDirectory: '$(System.DefaultWorkingDirectory)/configuration'
    environmentServiceName: 'Pay-As-You-Go (e595aee6-f9b8-450f-b9d3-73768a2fd47a)'
    commandOptions: '-var client_id=$(client_id) -var client_secret=$(client_secret) -var ssh_public_key=$(publickey.secureFilePath)'

Azure DevOps Demo Generator

https://azuredevopsdemogenerator.azurewebsites.net/

https://qiita.com/dz_/items/736bfd7be1478d638518

Azure DevOps Demo Generatorでリファレンスプロジェクトとなるプロジェクトを作成することができる。

Azure DevOps Demo Generatorでリファレンスプロジェクトを作成すると、作成済みのDashbords, Wiki, Boards, Repos, Pipelinesのサンプルを参考にすることができる。

Boards

以下の記事を読むのがよい。

https://qiita.com/mstakaha1113/items/44458046d5a8568559b5

https://qiita.com/mstakaha1113/items/2c857e85ed6203d93028

https://qiita.com/mstakaha1113/items/9e0be0aaa5db89dd5ca9

Sprint

https://www.udemy.com/course/devops-with-docker-kubernetes-and-azure-devops/learn/lecture/18086137#overview

Query

https://www.udemy.com/course/devops-with-docker-kubernetes-and-azure-devops/learn/lecture/18086135#overview

指定した条件を満たすWork itemを探すクエリを作成できる。

作成したクエリは保存して、再度同じ条件で検索できる。

Repos

https://qiita.com/mstakaha1113/items/e2c6ef2622bc6cc0b0ef

コードリポジトリ

Test Plans

https://news.mynavi.jp/techplus/article/zeroazure-30/