Help us understand the problem. What is going on with this article?

AzurePipelines(CI)で採番したコンテナのタグ情報をAzureReleases(CD)に渡す

前提

AKSやACSなどのコンテナソリューションを利用しているCI/CDの場合一般的には
1. CIでコンテナを作成
2. コンテナイメージレジストリに保存
3. CDでコンテナイメージレジストリの情報をAKSやACSに渡してpullを指示
みたいな感じに回すと思う。

下記の図で3~6が該当する。

image.png

その際に「AzurePipelinesで、採番するTaskとArtifactsを作成するTask間のデータの橋渡し方法」
「CIで採番したコンテナのタグ情報をCDに渡す方法」について詰まったので記録に残すことにした。
...蓋を開ければ基本すぎて誰もあえて書かないだけなんだとは思う。

要約

AzurePipelinesで、Task間のデータの橋渡しを行う

CIで採番したコンテナのタグ情報をCDに渡す

  • タグ情報をpropetiesなどのテキストファイルに書き出す
  • CIでArtifactsのTasksを設定して、テキストファイルを成果物として保存する
  • CDではArtifactsを呼び出して、成果物からテキストファイルを読み込んでタグ情報を取得する

想定するシナリオ

  • Javaで書かれたweb applicationを乗っけたコンテナをプロダクト環境に自動でデプロイするCI/CDをAzureDevOpsで構築する
  • ソースコードはAzureReposのGitで管理する
  • AzurePipelinesはコンテナを作成してACRにイメージをpushする
    • Gitのmasterブランチにソースコードがマージされてgit tagが振られたときに実行される
  • AzureReleasesは指定されたタグ情報に基づいてhelmでAKSにコンテナイメージの更新を指示する
    • AzurePipelinesが実行されたときに実行される

AzurePipelines

  • 前提として、masterブランチにyamlファイルを置くこと
  • 環境変数 TagName を作ること
    • 手動でCIを実行したくなったときにTagNameに値を渡して実行できるので便利
# Starter pipeline

trigger:
  tags:
    include:
    - v*

pool:
  vmImage: 'ubuntu-latest'

variables:
  MAVEN_CACHE_FOLDER: $(Pipeline.Workspace)/.m2/repository
  MAVEN_OPTS: '-Dmaven.repo.local=$(MAVEN_CACHE_FOLDER)'

# どこかからコピペしてきたmavenのキャッシュ保存処理
steps:
- task: CacheBeta@0
  inputs:
    key: $(Build.SourcesDirectory)/Application/ApiServer/pom.xml
    path: $(MAVEN_CACHE_FOLDER)
  displayName: Cache Maven local repo

- task: Maven@3
  displayName: 'Maven Application/ApiServer/pom.xml'
  inputs:
    mavenPomFile: '$(Build.SourcesDirectory)/Application/ApiServer/pom.xml'
    jdkVersionOption: 1.11
    mavenOptions: '-Xmx2048m $(MAVEN_OPTS)'
    checkStyleRunAnalysis: true
  timeoutInMinutes: 10

# gitコマンドで最新のタグ情報を取得して環境変数に設定する
# condition~は、手動でCIを実行したときにgitから情報を取得しないようにするために設定
- task: PowerShell@2
  inputs:
    targetType: 'inline'
    script: |
      $TagArray=git tag -l v*
      $TagName=$TagArray[$TagArray.Count – 1]
      echo $TagName
      # TagNameという環境変数に、ローカル変数のTagNameの情報を渡してあげる
      Write-Host "##vso[task.setvariable variable=TagName]"$TagName      
    workingDirectory: '$(Build.SourcesDirectory)'
  condition: and(succeeded(), startsWith(variables['Build.SourceBranch'], 'refs/tags/v'))

# ちゃんと指定された情報が入っているか一応確認
- task: PowerShell@2
  inputs:
    targetType: 'inline'
    script: |
      echo "環境変数 TagName"
      echo $(TagName)
    workingDirectory: '$(Build.SourcesDirectory)'

# コンテナイメージの作成
- task: Docker@1
  displayName: 'Build an image'
  inputs:
    containerregistrytype: 'Azure Container Registry'
    azureSubscriptionEndpoint: '<省略>'
    azureContainerRegistry: 'hoge.azurecr.io'
    command: 'build'
    dockerFile: 'Application/ApiServer/Dockerfile'
    imageName: 'hoge.azurecr.io/api-server:$(TagName)'
    includeSourceTags: false

# コンテナイメージをACRへpush
- task: Docker@1
  displayName: 'Push an image'
  inputs:
    containerregistrytype: 'Azure Container Registry'
    azureSubscriptionEndpoint: '<省略>'
    azureContainerRegistry: 'hoge.azurecr.io'
    command: 'Push an image'
    imageName: 'hoge.azurecr.io/api-server:$(TagName)'
    includeSourceTags: false

# apiserver.propertiesという成果物を作成する
# apiserver=v1.0.0 という設定値が入ったテキストファイル
# 先ほどPowershellだったのにここはBashで気持ち悪い...
- task: Bash@3
  inputs:
    targetType: 'inline'
    script: |
      echo "apiserver=$(TagName)" >> apiserver.properties
    workingDirectory: '$(Build.SourcesDirectory)'

# apiserver.propertiesをArtifact/成果物として保存する
- task: PublishPipelineArtifact@0
  displayName: Store artifact
  inputs:
    artifactName: 'DevelopBranchImageTagVersion'
    targetPath: '$(Build.SourcesDirectory)/apiserver.properties'

AzureReleases

  • 前提として環境変数imagetagversionを定義しておくこと
  • ArtifactにCIの内容を指定すること

JOBの1タスクを抜粋

#Your build pipeline references an undefined variable named ‘echo $key | tr '.' '_'’. Create or edit the build pipeline for this YAML file, define the variable on the Variables tab. See https://go.microsoft.com/fwlink/?linkid=865972
#Your build pipeline references an undefined variable named ‘echo $key | tr '.' '_'’. Create or edit the build pipeline for this YAML file, define the variable on the Variables tab. See https://go.microsoft.com/fwlink/?linkid=865972
variables:
  artifactstagingdirectory: '$(System.ArtifactsDirectory)'

steps:
- bash: |
  # CIの成果物よりapiserver.propertiesの値を読みだす
   # パスは$(artifactstagingdirectory)/CIの名前/artifactName/テキストファイル名で指定できる
   file="$(artifactstagingdirectory)/CI/DevelopBranchImageTagVersion/apiserver.properties"
   # bashでpropertiesの情報をparseする処理/SOがネタ元だったはずだが忘れた...
   if [ -f "$file" ]
   then
   #  echo "$file found."

     while IFS='=' read -r key value
     do
       key=$(echo $key | tr '.' '_')
       eval ${key}=\${value}
     done < "$file"

   #  echo "imagetag       = " ${apiserver}
   else
     echo "$file not found."
   fi

   set imagetagversion #この一行不要じゃないか?
   # ここでもimagetagversionという環境変数にapiserverの変数値を設定して次のタスクにimagetagversion情報を渡してあげる
   echo "##vso[task.setvariable variable=imagetagversion;isSecret=false;isOutput=true;]${apiserver}"
  displayName: 'Bash Script'
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした