Intro
Azure には、Bicep という Infrastructure as Code (IaC) の DSL があります。(カタカナ読み方は "バイセップ"、日本語訳は "上腕二頭筋"、ARM に対して・・・という由来だと思われます)ARM テンプレートの後継として登場してきました。2021/06 時点では v0.4 プレビュー版です。どんどん機能が追加されているところですが、中心となる機能群はすでに揃っていて、充分使い始めることができるレベルかと思います。
この記事は、その Bicep で記述した設定ファイルを GitHub Actions で自動的に Azure に反映してみる、という内容です。
Why Bicep & GitHub Actions?
従来の ARM テンプレートは、JSON 形式ということに加え、どうしてもリソース定義以外の本質的ではない記述が多かったです。つまり、可読性が良くなかった、ということです。これは、担当者が定義ファイルを書く、誰かにプルリクエストをする、レビュアーは間違っていないかじっくり読む、といった、**頻繁に繰り返される 書く&読む プロセスにおいて、致命的なネックになります。**レビュアーも「正しいかどうかは実行してみないとわからん」「どこ見ていいかわからん」状態になってしまうと、コードレビューの本来の役割が機能しません。BicepとARM Templateのシンタックスの比較にもあるように、記述はシンプルになり、レビューするほうもこれでやっとまともな指摘ができるようになった感があります。
ということで、GitHub Actions を使って以下のプロセスをぐるぐる高速にまわす準備をさくっと済ませてしまいましょう。
- リソース定義をコードで記述する(IaC)
- プルリクエストを中心としたレビューを行う
- マージされたら環境への反映は自動的に行われる
コードを見たほうが早い、というかたは以下リポジトリに Template リポジトリを用意したので、あわせてご参考ください。"Use this template" していただければ、ご自身のリポジトリでもすぐに試せます。
https://github.com/hoisjp/vscode-remote-try-bicep
Bicep 用 devcontainer リポジトリ (https://github.com/Azure/vscode-remote-try-bicep) からフォークして、GitHub Actions のサンプルを追加しています。
手順
テンプレートからご自身のリポジトリへ
https://github.com/hoisjp/vscode-remote-try-bicep
Use this template
して、ご自身のリポジトリにひな型を作ります。Private リポジトリでもOKです。
利用手段は2種類あります。
-
ローカルの Docker 環境で VS Code リモート開発機能を使う
VS Code のリモートコンテナ機能についての説明は割愛します。このあたり のドキュメントをご参考ください。必要な準備は、ローカルのDocker環境と、VS Codeの拡張機能 だけです。 -
GitHub Codespaces を使う
まだ Private Beta 状態ですが、すでに使えるかたは、リポジトリから Codespaces を起動した環境でも可能です。
https://docs.github.com/en/codespaces/about-codespaces
いずれも Bicep 環境はコンテナビルド直後に仕上がっています。便利ですね。複数人で使っていても全く同じ環境で作業ができるわけです。
$ bicep -v
Bicep CLI version 0.4.63 (7ebed03284)
$ az version
{
"azure-cli": "2.24.2",
"azure-cli-core": "2.24.2",
"azure-cli-telemetry": "1.0.6",
"extensions": {}
}
GitHub Actions 有効化
外部のリポジトリから fork した場合や、template 生成した場合は、GitHub Actions が無効になっています。悪意のある Actions が自身のリポジトリで実行されてしまうのを回避するため、セーフティガードが働いています。
GitHub リポジトリの Actions タブメニューから、Enable workflow
ボタンで有効化します。
準備 GitHub -> Azure の認証
GitHub Actions を実行する GitHub リポジトリを用意したらば、そのリポジトリが Azure に対して操作する権限を与える必要があります。Azure サービスプリンシパルを GitHub のシークレットに追加します。間接的な準備ですが、Azure 公式ドキュメントの接続手順に従って進めてOKです。少し補足しながら以下に同じことを書きます。
Step 1. サービスプリンシパルを作ります。
Cloud Shell が手軽でしょう。Azure ポータルの右上部分のシェルアイコンから開くか、https://shell.azure.com をブラウザで開いてもよいです。
まずはサービスプリンシパルを作るアプリケーションの作成から始めます。
appName="myApp"
az ad app create \
--display-name $appName \
--homepage "http://localhost/$appName" \
--identifier-uris http://localhost/$appName
この appName="myApp"
は、組織全体の Azure AD に登録されることになるので、区別されやすい名前を与えるのがよいでしょう。またこのサービスプリンシパルは、GitHub Actions から利用するためだけに使われて、あちらこちらで流用されることはないと思うので、そんなキーワードを入れておくとよさそうです。 e.g. SampleAppGitHubActions
Step 2. 新規サービスプリンシパル作成
公式ドキュメントでは以下のように、このサービスプリンシパルが有効なスコープを、特定のリソースグループに限定しています。
--scopes
スコープ:リソースグループ
az ad sp create-for-rbac --name $appName --role contributor \
--scopes /subscriptions/{subscription-id}/resourceGroups/{resource-group} \
--sdk-auth
リソースグループをひとつに限定できる場合は上記でも構いませんが、複数のリソースグループを使って構成する場合も多いです。そのような場合は、以下のようにスコープをサブスクリプションに広げることで、そのサブスクリプションの下ならば操作ができるようになります。
--scopes
スコープ:サブスクリプション
az ad sp create-for-rbac --name $appName --role contributor \
--scopes /subscriptions/{subscription-id}/ \
--sdk-auth
このコマンドの結果JSONを後続のシークレットに使います。
Step 3. GitHub シークレット追加
GitHub リポジトリメニューの Setting
から、左メニュー Secrets
を開きます__
右上の New repository secret
ボタンからシークレット登録画面へ移動します。
AZURE_CREDENTIALS
という名前で、上記手順2のサービスプリンシパルJSON結果をコピー&ペーストします。
{
"clientId": "<GUID>",
"clientSecret": "<GUID>",
"subscriptionId": "<GUID>",
"tenantId": "<GUID>",
// (...)
}
補足:JSONの結果はプロパティがもう少し多くずらっと出力されます。そのままペーストしても問題ありませんが、最低限、上記4つのプロパティがあれば十分です。
Bicep ファイル
これはフォーク元のサンプルファイルをそのままです。Storage Account を作成するものですね。ロケーションは東日本リージョンに変更しておきました。
resource stg 'Microsoft.Storage/storageAccounts@2021-02-01' = {
name: uniqueString(resourceGroup().id)
location: 'japaneast'
kind: 'Storage'
sku: {
name: 'Standard_LRS'
}
}
GitHub Actions ワークフローファイル
前置きが長くなりましたが、ここが記事のメインコンテンツです。
長いですが、いったん全て貼り付けます。GitHub リポジトリ上ではこちらです。ファイルパス&ファイル名を以下のように作成すれば、GitHub Actionsと認識されます。
コードコメントで補足説明を追記しました。
.github/workflows/bicep-deploy-azcli.yml
name: 'BicepDeploy with Azure CLI'
# トリガーはお好きなように
# docs も参考に > https://docs.github.com/ja/actions/reference/events-that-trigger-workflows
# Web UI から直接トリガーできるように、"workflow_dispatch" も追加
on:
push:
branches:
- main
pull_request:
workflow_dispatch:
jobs:
BicepDeployAzCLI:
name: 'BicepDeploy with Azure CLI'
runs-on: ubuntu-latest
# リソースグループ名やロケーションは env で指定
env:
ResourceGroupName: rg-bicep-samples
ResourceGroupLocation: "japaneast"
environment: production
steps:
- uses: actions/checkout@v2
# GitHub Secrets に追加したクレデンシャルを参照して Azure にログインする。
- uses: azure/login@v1
with:
creds: ${{ secrets.AZURE_CREDENTIALS }}
# ビルドする。ARM テンプレートのJSONファイルが生成される。
- name: Azure Bicep Build
run: |
az bicep build --file ./main.bicep
# リソースグループを作成する。
- name: Az CLI Create Resource Group
uses: Azure/CLI@v1
with:
inlineScript: |
#!/bin/bash
az group create --name ${{ env.ResourceGroupName }} --location ${{ env.ResourceGroupLocation }}
# what-if コマンドで実際の環境と diff をプレビューする。
- name: Preview Azure Bicep
uses: Azure/CLI@v1
with:
inlineScript: |
#!/bin/bash
az deployment group what-if -f ./main.json -g ${{ env.ResourceGroupName }} --name ${{ env.ResourceGroupName }}
# Azure へ反映する。
- name: Deploy Azure Bicep
uses: Azure/CLI@v1
with:
inlineScript: |
#!/bin/bash
az deployment group create --mode Complete -f ./main.json -g ${{ env.ResourceGroupName }} --name ${{ env.ResourceGroupName }}
要点をまとめておきます。
- Azure Login は GitHub Secrets に登録した
${{ secrets.AZURE_CREDENTIALS }}
を参照します。GitHub Actions 実行時に認証エラーが出た場合はこのあたりを確認するとよいです。 - Azure Bicep Build 部分
Bicep v0.3 から、以下のように、ARM Template の JSON ファイルを経由せずとも、直接 Bicep ファイルを引数に渡せるようになりました。ここでは作成された ARM Template の JSON ファイルを確認したいので、あえてaz bicep build
コマンドで .bicep => .json の変換をしています。
az deployment group create -f ./main.bicep ...
- Preview Azure Bicep 部分 (
az deployment group what-if ...
)
何を作るのか、何を削除するのか、確認するために、ARM Template の機能のひとつである What-if 機能を使います。
ここではそこまで作りこんでいませんが、プルリクエストではこのプレビューで止めておき、マージしたときに後続の反映を行うのも有効だと思います。 - Deploy Azure Bicep 部分 (
az deployment group create --mode Complete ...
)
--mode Complete
: これはデプロイモードのオプションで、テンプレートに定義のないリソースは削除されます。
参照:Azure Resource Manager のデプロイ モード
--mode Incremental
: もうひとつのデプロイモードは増分モード(Incremental mode)というものです。このモードでは、リソースの削除までは実行されません。実環境に存在しないリソースを追加するだけです。IaC の文脈では、前者の Complete モードを想像されるかたが多いのではないでしょうか。
GitHub Actions 実行
あとは、プッシュするなり、プルリクエストするなり、トリガーに応じてワークフローが実行されます。
実行が完了したら、リソース定義が正しく Azure に反映されているか確認してみてください。
おまけ - リソース全削除
terraform をお使いのかたは、bicep destroy
はサポートされていないの?と思われるかもしれません。開発環境など使い終わったらきれいさっぱり削除したいケースもあるでしょう。残念ながら Bicep ではまだサポートされていませんが、GitHub Discussion ですでに議論されています。
将来、"Deployment Stacks" と呼ばれるライフサイクル管理の仕組み が提供されるようですね。いかにも CI/CD と相性がよさそうで楽しみです。
いざ全削除する際は、リソースグループごと削除してしまうのもよいですが、前述の --mode Complete
の仕組みに乗って、リソース削除が可能です。空の empty.bicep ファイルを与えることで、リソースグループの中身が空である、という定義に従って実行されます。
この方法だと、空のリソースグループが残ってしまうのですが、what-if
の何を削除するかというdiffの結果を GitHub Actions のログに残せる点は便利です。
.github/workflows/bicep-empty.yml
az deployment group create --mode Complete -f ./empty.bicep -n ... -g ...
次のステップへ、役に立つ Tips
- ひととおりのテクニックを学ぶためには Microsoft Learn の Bicep ラーニングパスがおすすめです。
https://docs.microsoft.com/ja-jp/learn/paths/bicep-deploy/
(まだ英語版のみですが、じきに日本語版も提供されるでしょう。) - VS Code の拡張機能についているスニペット機能を使うと便利です。リソース名を一部タイプしたところで補完機能を使えば、VS Codeがリソースの必須入力部分だけを出力してくれるので、あとは必要な値を埋めていくだけです。
Quickstart: Create Bicep files with Visual Studio Code
(画像出典 公式docsより) - いろいろと組み立て始めると、サンプルコードが欲しくなります。Bicep のサンプルコードはリポジトリの以下に集約されています。まずはここに実現したいものがないか探してみるのもおすすめです。かなり多くのケースがカバーされています。
https://github.com/Azure/bicep/tree/main/docs/examples- 101: リソース単体ごとのサンプルコード
- 201: リソースを複数組み合わせた、よくある構成を集めたもの
- 301: より発展的で特定のユースケースをカバーするもの
Feedback welcome!
ささいなことでも構いませんので フィードバックをいただけると とても喜びます。
- GitHub リポジトリ - https://github.com/hoisjp/vscode-remote-try-bicep
- Twitter - https://twitter.com/hoisjp
Enjoy Bicep and Azure!