AzureDevOpsのパイプラインで色々する備忘録

試験環境のAKSクラスタを20時で止めるとか、
本番環境のノードイメージのバージョンを試験環境と同じになりそうな時だけ更新するとか、
ingressのwhitelistに設定してるAzureの基盤側のLoadbalancerBackendとかTrraficManagerとかのIPリストのjsonに更新があった時だけ差分通知するだとか、
なんか色々したいときにAzureDevOpsだとAzure向けの認証突破するあたりの実装が簡単で便利なので最近LogicAppsやAutomationよりよくつかっている気がする備忘録です。Automationより動きが軽快で動確しやすい。あと問い合わせた場合の反応がよかったです。

### 基本的にはリポジトリにパイプラインのyaml書いてそれを使う
https://learn.microsoft.com/ja-jp/azure/devops/pipelines/create-first-pipeline?view=azure-devops&tabs=java%2Cbrowser
１．Project settings/Service connectionsからAzureDevOpsからサブスクリプションへの接続を許可するサービスプリンシパルを作成して認証の準備
※管理者かなにかの強い権限が要る模様
※ここで既にあるサービスプリンシパルを選択する場合そのサービスプリンシパルに対してリソースグループやリソースへのアクセス許可が必要
　使いたいリソース（AKS）のIAMのロールアサインメントからサービスプリンシパルと権限を確認することができる

２．Dockerレジストリへの接続を許可するコネクションを作成する
３．１と２で作成した名前をパイプラインのyamlに反映する
４．Pipelinesからパイプラインを作成
AzureReposGitを選択し既にあるパイプラインから選んで作成し、Runを押す

### 新しいリポジトリじゃなくて別ブランチにパイプラインの追加する場合の要点解説
https://learn.microsoft.com/ja-jp/azure/devops/pipelines/build/ci-build-git?view=azure-devops&tabs=yaml
要点としては、
　単独ブランチで作動するようにinclude/excludeをかく
　複数タスクにわたり使う変数はvariablesにかく
　condition条件で特定のスケジュール名と手動をor定義する
　Powershellの場合VMイメージをwindowsで定義（vmImage: 'windows-2019'）
　DisplayNameはわかりやすくする
　書いたら--orphan オプションで空ブランチを作りpushしてパイプラインを既存yamlから追加する
pushのたびに他のパイプラインが反応してしまうのを防げるのでブランチを分けたほうが無難。

 ### yamlの内容のセクションごとの参考例

- variables
```
#parameters:

variables:
  NewJsonName: "ServiceTags_Public_New.json"
  OldJsonName: "ServiceTags_Public_Old.json"
```
https://docs.microsoft.com/ja-jp/azure/devops/pipelines/scripts/cli/pipeline-variable-group-secret-nonsecret-variables?view=azure-devops
  
  変数書く。
  yaml内で使うときは"$(NewJsonName)" こういう感じ
  詳細は↑リンク先とその周辺記事をどうぞ。


- schedules
```
schedules:
- cron: "0 4 * * Mon"
  displayName: Mon-UTC4-JST13-weekly-build
  branches:
    include:
    - iprangechk
    exclude:
    - updateAksNodeImage
    - komi
    - main
  always: true
#pr: none
```
一般的な[`man 5 crontab`](https://www.man7.org/linux/man-pages/man5/crontab.5.html)とかで出てくるcronぽい感じでジョブスケジュール定義が可能
displayNameを後述のconditionで指定すると動かすスケジュール指定できる。
branchesのincludeで作動さす対象ブランチを指定、excludeで動かしたくないブランチを指定できる。
alwaysは入れとかないと動かない設定
pr: noneはプルリクで作動させない設定

https://docs.microsoft.com/ja-jp/azure/devops/pipelines/process/scheduled-triggers?view=azure-devops

- condition
```
stages:
- stage: IPrangeCheck
  displayName: 'IprangeCheck'
  condition: |
    or(
      eq(variables['Build.CronSchedule.DisplayName'], 'Mon-UTC4-JST13-weekly-build'),
      eq(variables['Build.Reason'], 'Manual')
    )
```
この書き方だと手動実行もできるのと、指定したスケジュール名のスケジュールで実行されます。（スケジュールパイプラインそのままだと手動実行ができないかんじだった）
スケジュールパイプラインじゃない場合には、通常はターゲットブランチへのプルリクがうまくいったら、かつソースブランチはターゲットブランチではないなど↓の参考例。
```
condition: and(succeeded(), eq(variables['Build.Reason'], 'PullRequest'), or(eq(variables['System.PullRequest.TargetBranch'], 'refs/heads/main'), ne(variables['Build.SourceBranch'], 'refs/heads/main')))
```
conditionに関するドキュメント↓
https://learn.microsoft.com/ja-jp/azure/devops/pipelines/process/conditions?view=azure-devops&tabs=yaml%2Cstages
式の記法↓
https://learn.microsoft.com/ja-jp/azure/devops/pipelines/process/expressions?view=azure-devops#job-status-functions

- jobs,pool
```
  jobs:
  - job: IPrangeCheck
    displayName: 'weekly ip range check' 
    pool:
      vmImage: 'windows-2019'
    steps:
      - checkout: self
        persistCredentials: true
```
poolはパイプラインを実行するOSが選べる。この時Powershell使いたかったのでWindowsにしていますが、ubunts-latestとかもよくある感じです。IP制限がある場合はSelfhostedAgentつかうとよいです。
https://jpdscore.github.io/blog/azuredevops/try-self-hosted-agent/
stepsに書いてるのは自分自身のリポジトリ更新するとストレージアカウントが要らなくなるのに必要な設定。特に外部連携もしないので。

-task copyfiles
```
      - task: CopyFiles@2
        displayName: 'get OLD iplist from repository'
        inputs:
          Contents: 'json/**' # string. Required. Contents. Default: **.
          TargetFolder: "$(System.DefaultWorkingDirectory)"
```
成果物をパイプライン動かしてるサーバに置きたいときにつかうタスク。

- task powershell
```
      - task: PowerShell@2
        displayName: 'ip range check 2'
        inputs:
          targetType: 'inline'
          pwsh: true
          script: |
            ls json/
            #～略～
```
https://learn.microsoft.com/ja-jp/azure/devops/pipelines/tasks/reference/powershell-v2?view=azure-pipelines
- task bash
```
        - task: Bash@3
          displayName: 'Install Helm'
          inputs:
            targetType: 'inline'
            script: 'wget https://get.helm.sh/helm-v3.8.0-linux-amd64.tar.gz && tar -zxvf helm-v3.8.0-linux-amd64.tar.gz && sudo mv linux-amd64/helm /usr/local/bin/helm'
```

まああとはscriptの中身に好きなことかく感じでパイプライン実行して直してを思い通り動くまでループです。