しばやん雑記

Azure Serverless とメイドさんが大好きなフリーランスのプログラマーのブログ

Azure Pipelines に追加された特定の Service Connection で承認を必須にする機能が便利

Azure DevOps の Sprint 158 Update で紹介されていた割に全然公開されていなかった Service Connection に対する承認機能が、最近になって自分のテナントでも使えるようになってました。

Sprint 158 Update は 9 月なので内容を既に忘れている人も居そうです。

紹介されているようなインターフェースとは異なっていて、Edit の横の「…」ボタンを選ぶと Approvals and Checks の項目が出てきます。機能としては Environments のものと同じです。

f:id:shiba-yan:20191217182255p:plain

何が嬉しいかというと、本番向けの Azure Subscription など気軽に弄られたら困るような Service Connection に対して、ここで設定をしておけば Task で使われた場合に自動的に承認が必須になるという点です。

これまでは Environments を使うしかなかったので、必要な処理は Deployment job にまとめて実行する必要がありましたが、もっとシンプルに承認機能を使えるようになりました。

f:id:shiba-yan:20191217182305p:plain

設定方法などは完全に Environments と同じなので、既に使ったことがある人は簡単に設定できるはずです。この辺りも徐々に改善されていて、今後もオプションの追加も予定されているとか。

Environments や Deployment job は今後 Kubernetes 以外のリソースへの対応や、Deployment strategy も追加予定なのでアプリケーションのデプロイ向けには便利ですが、それ以外の IaC などの用途では Service Connection を使った方が簡単に実現できるのでお勧めです。

色々と試しているうちに、複数の Task で Service Connection を使っている場合に、どのような挙動になるのかが気になったので思いついたパターンを検証してみました。

Stage が順番に動く場合

恐らく一番単純な、承認が必要な Stage が順番に動いていくパターンです。サンプルとして App Service へのデプロイを行っていますが、ここは Service Connection を使う Task なら何でも良いです。

- stage: Deploy_to_Dev
  jobs:
  - job: Deploy_to_Dev
    pool:
      vmImage: 'windows-latest'
    steps:
    - download: current
    - task: AzureWebApp@1
      inputs:
        azureSubscription: 'Azure Sponsorship'
        appType: 'webApp'
        appName: 'approvalstest'
        package: '$(Pipeline.Workspace)/**/WebApplication1.zip'
        deploymentMethod: 'auto'

- stage: Deploy_to_Prd
  jobs:
  - job: Deploy_to_Prd
    pool:
      vmImage: 'windows-latest'
    steps:
    - download: current
    - task: AzureWebApp@1
      inputs:
        azureSubscription: 'Azure Sponsorship'
        appType: 'webApp'
        appName: 'approvalstest'
        package: '$(Pipeline.Workspace)/**/WebApplication1.zip'
        deploymentMethod: 'auto'

dependsOn で依存関係を定義していないので、書かれた順に実行されていきます。動かすと 1 つめの Stage に差し掛かったタイミングで承認待ちの状態に入りました。

f:id:shiba-yan:20191217182117p:plain

承認するかどうか選択する画面では、対象の Service Connection が表示されるので分かりやすいです。この辺りの UI は大きくは変わっていないように感じます。

f:id:shiba-yan:20191217182125p:plain

ここで承認すると、現在の Stage の実行完了後に後続の Stage でも承認待ち状態になりました。

f:id:shiba-yan:20191217182138p:plain

承認待ちは Stage 単位で毎回走るようです。1 度の承認で同じ Service Connection を使っている Stage が実行されても困るので、この挙動は安心しました。

Stage が同時に動く場合

次は dependsOn を設定して、2 つの Stage が同時に動く場合にどうなるかを試してみました。

- stage: Deploy_to_Dev
  dependsOn: Publish
  jobs:
  - job: Deploy_to_Dev
    pool:
      vmImage: 'windows-latest'
    steps:
    - download: current
    - task: AzureWebApp@1
      inputs:
        azureSubscription: 'Azure Sponsorship'
        appType: 'webApp'
        appName: 'approvalstest'
        package: '$(Pipeline.Workspace)/**/WebApplication1.zip'
        deploymentMethod: 'auto'

- stage: Deploy_to_Prd
  dependsOn: Publish
  jobs:
  - job: Deploy_to_Prd
    pool:
      vmImage: 'windows-latest'
    steps:
    - download: current
    - task: AzureWebApp@1
      inputs:
        azureSubscription: 'Azure Sponsorship'
        appType: 'webApp'
        appName: 'approvalstest'
        package: '$(Pipeline.Workspace)/**/WebApplication1.zip'
        deploymentMethod: 'auto'

同時に同じリソースにデプロイしてるのはテストなので気にしないでください。

実行してみると、この場合は 2 つの Stage が両方とも同時に承認待ち状態になりました。

f:id:shiba-yan:20191218015608p:plain

そして承認するかどうかの画面には 2 つ表示されました。それぞれの Stage 毎に個別に承認・非承認を行えるようになっているみたいです。

f:id:shiba-yan:20191217182106p:plain

なので片方だけ承認しないということが簡単に行えました。Stage の設計が重要になりそうです。

f:id:shiba-yan:20191219003446p:plain

ちなみに承認しなかった Stage に表示されている Rerun failed jobs ボタンを押すと、もう一度承認待ちからやり直しになります。間違った時のリカバリーに使えます。

複数の承認待ちを扱えることは知らなかったので、興味深い結果でした。何 Stage まで同時に待てるのか気になりますが、検証が結構面倒なので確認まではしないでおきます。

1 つの Stage 内で 2 つの Job が動く場合

最後はこれまで使った 2 つの Stage を 1 つにまとめた場合です。具体的には Job を複数にします。

- stage: Deploy
  jobs:
  - job: Deploy_to_Dev
    pool:
      vmImage: 'windows-latest'
    steps:
    - download: current
    - task: AzureWebApp@1
      inputs:
        azureSubscription: 'Azure Sponsorship'
        appType: 'webApp'
        appName: 'approvalstest'
        package: '$(Pipeline.Workspace)/**/WebApplication1.zip'
        deploymentMethod: 'auto'

  - job: Deploy_to_Prd
    pool:
      vmImage: 'windows-latest'
    steps:
    - download: current
    - task: AzureWebApp@1
      inputs:
        azureSubscription: 'Azure Sponsorship'
        appType: 'webApp'
        appName: 'approvalstest'
        package: '$(Pipeline.Workspace)/**/WebApplication1.zip'
        deploymentMethod: 'auto'

これも実行してみると Stage の実行前に承認待ち状態になりました。Stage 単位でしか承認待ちは行えないので、1 つだけ表示されています。

f:id:shiba-yan:20191218014202p:plain

この状態で承認すると 2 つの Job がそれぞれ同時に動き出しました。

f:id:shiba-yan:20191218015145p:plain

従って Service Connection を 1 つだけ利用する場合は、適当に使っていても問題ないケースが多そうです。

しかし Azure Subscription などリソースグループ単位で権限が与えられるような場合は、複数の Service Connection を用意することもあると思います。その場合には Stage を分けておくのが安全です。