Azure Automation を使って変則的なスケジュール実行を Azure CLI で設定してみた

例えば Azure Logic Apps のスケジュールトリガーを使って毎時実行するワークフローがあったとします。要件が追加され、夜間だけ毎時ではなく、数時間おきに実行するようにしたい場合、Azure Logic Apps の中で特定の時間帯はスキップする処理を入れる事を考えると思います。ところが、Azure Logic Apps でスキップ判定をしてスキップ処理をするアクションを追加すると、アクション数が増え課金も増加します。そこで、Azure Automation から Azure Logic Apps を呼び出すようにして、変則的なスケジュールは Azure Automation 側に任せるのがシンプルで課金も増えずに対応できるのではないかとアイデアを膨らませ、実際にやってみることにしました。いつもの事ながら、再利用可能なように Azure CLI での手順です。なお、Azure Logic Apps 自体の手順は含まれておりません。

## Azure Automation の検証環境を用意

```bash:bash
# 環境変数をセットします
prefix=mnrama
region=japaneast

# リソースグループを作成します
az group create \
  --name ${prefix}-rg \
  --location $region

# Automation アカウントを作成します
az automation account create \
  --automation-account-name ${prefix} \
  --resource-group ${prefix}-rg \
  --sku Free

# マネージド ID を有効化します
az resource update \
  --ids $(az automation account show \
  --automation-account-name ${prefix} \
  --resource-group ${prefix}-rg \
  --query id \
  --output tsv) \
  --set "identity.type=systemassigned"

# マネージド ID をリソースグループに共同作成者ロールで設定します
az role assignment create \
  --assignee $(az automation account show \
  --automation-account-name ${prefix} \
  --resource-group ${prefix}-rg \
  --query identity.principalId \
  --output tsv) \
  --scope $(az group show \
  --name ${prefix}-rg \
  --query id \
  --output tsv) \
  --role "Contributor"

# Runbook を作成します
az automation runbook create \
  --automation-account-name ${prefix} \
  --resource-group ${prefix}-rg \
  --name helloworld \
  --type PowerShell

# マネージド ID でサインインしてリソースグルーヴを取得する PowerShell を書きます
cat <<"EOF" > helloworld.ps1
Connect-AzAccount -Identity
Get-AzResourceGroup
EOF

# PowerShell を Runbook に登録します
az automation runbook replace-content \
  --automation-account-name ${prefix} \
  --resource-group ${prefix}-rg \
  --name helloworld \
  --content @helloworld.ps1

# Runbook を公開します
az automation runbook publish \
  --automation-account-name ${prefix} \
  --resource-group ${prefix}-rg \
  --name helloworld

# Runbook を実行します
az automation runbook start \
  --automation-account-name ${prefix} \
  --resource-group ${prefix}-rg \
  --name helloworld
```

## スケジュール作成と Runbook への紐付け

```bash:bash
# 変則的なスケジュールを配列にします
dailytimes=(00:00 03:00 06:00 09:00 10:00 11:00 12:00 13:00 14:00 15:00 16:00 17:00 18:00 21:00)

# スケジュールを登録します
for time in ${dailytimes[@]}; do
  name=${time//:/}
  az automation schedule create \
    --automation-account-name ${prefix} \
    --resource-group ${prefix}-rg \
    --name Daily$name \
    --frequency Day \
    --interval 1 \
    --start-time 2023-08-12 $time:00 \
    --time-zone "Asia/Tokyo"
done

# （もしスケジュールを削除したい場合は下記のようにします）
for time in ${dailytimes[@]}; do
  name=${time//:/}
  az automation schedule delete \
    --automation-account-name ${prefix} \
    --resource-group ${prefix}-rg \
    --name Daily$name \
    --yes
done

# Azure Automation の ID を取得します
amaid=$(az automation account show \
  --automation-account-name ${prefix} \
  --resource-group ${prefix}-rg \
  --query id \
  --output tsv)

# 全てのスケジュールを Runbook に紐付けます
for time in ${dailytimes[@]}; do
  name=${time//:/}
  az rest \
    --method put \
    --url "$amaid/jobSchedules/$(uuidgen)?api-version=2019-06-01" \
    --body '{
      "properties": {
        "schedule": {
          "name": "Daily'$name'"
        },
        "runbook": {
          "name": "helloworld"
        },
        "parameters": {}
      }
    }'
done
```

## 検証環境の後片付け

```bash:bash
az group delete \
  --name ${prefix}-rg \
  --yes
```

## 参考

https://learn.microsoft.com/ja-jp/cli/azure/automation/schedule?view=azure-cli-latest#az-automation-schedule-create

https://learn.microsoft.com/ja-jp/rest/api/automation/job-schedule/create?tabs=HTTP