Bicep(バイセップ)は、Azureのリソースを宣言的に書いてデプロイするIaC(Infrastructure as Code)言語です。英語の biceps が上腕二頭筋を指すため、検索結果には筋トレの話が混ざります。この記事で扱うのはAzure向けのほうです。Bicep CLI 0.48.1(2026年10月5日公開)を前提に、インストール時につまずく仕様、.bicepparam、what-ifとデプロイメントスタック、GitHub Actionsからのデプロイまでを、Microsoft Learnとリリースノート、手元での実行結果をもとに整理します。
まとめ:Azure Bicepを使い始める前に知っておく要点
読み方は「バイセップ」です。Azure CLI 2.20.0以降なら明示的なインストールは要りません。ただしAzure CLIが入れるBicep CLIはPATHに追加されないため、コマンドはaz bicep versionの形で実行します。デプロイのたびにbicep buildを手で走らせる必要もありません。
テンプレートに無いリソースを消す完全モードは公式が非推奨としており、削除を伴う運用はデプロイメントスタックで行います。プルリクエストの検証はローカルで完結するbicep snapshot、本番直前の確認はwhat-ifという分担が手戻りの少ない形です。CI/CDはGitHub Actionsのazure/bicep-deploy@v2とOIDCの組み合わせで組めます。すでにTerraformでAzureを運用し、現在の構成に不満や未解決の要件がないなら、乗り換える必要はありません。
Bicepの読み方と、ARMテンプレート・Terraformとの関係
読み方は「バイセップ」、日本語ドキュメントの「二頭筋」
英語の bicep は biceps から逆成された語で、発音は /ˈbaɪsɛp/ です(Wiktionary)。カタカナにすると「バイセップ」で、biceps の語源はラテン語の「2つの頭を持つ」です。MicrosoftのドキュメントにはBicepのカタカナ表記も命名の由来も書かれていません。Bicep FAQにも命名の項目は無いため、ARM(Azure Resource Manager)=腕にかけた名前という説明は、公式の記述としては確認できません。
日本語の公式ドキュメント自体にも混同があります。Microsoft Learn日本語版の「Bicep とは」は機械翻訳(ms.translationtype: MT)で、コード例のタブ見出しが「二頭筋」と訳されたまま公開されています(2026年11月1日確認)。日本語で調べて意味が通らない箇所に当たったら、英語版を開いてください。
ARM JSONに変換して動く仕組みと、状態ファイルを持たない設計
Bicepで書いたコードはARMテンプレートのJSONに変換され、ARMへ送られてデプロイされます。公式FAQの説明では、Bicepは新しい言語ではなく「既存の Azure Resource Manager テンプレート (ARM テンプレート) 言語のリビジョン」です。ランタイムはARMのままなので、既存のARMテンプレート資産もそのまま動きます。
@description('ストレージアカウント名のプレフィックス')
param prefix string
param location string = resourceGroup().location
@allowed(['Standard_LRS', 'Standard_ZRS'])
param skuName string = 'Standard_LRS'
resource st 'Microsoft.Storage/storageAccounts@2024-01-01' = {
name: '${prefix}${uniqueString(resourceGroup().id)}'
location: location
sku: { name: skuName }
kind: 'StorageV2'
properties: {
minimumTlsVersion: 'TLS1_2'
allowBlobPublicAccess: false
}
}
output storageId string = st.id
以降の章では、このファイルをmain.bicepとして使います。リソース型とAPIバージョンを@でつなぎ、シンボリック名(この例ではst)で他の宣言から参照します。状態はAzure側が持つため、Terraformのtfstateのようなファイルを共有・ロックする運用は要りません。GitHubのREADMEには「Supported by Microsoft support and 100% free to use」とあり、言語とツールに料金はかかりません。ARM JSONとの書き方の違いや変換結果はARMテンプレートとBicepの違い|変換後のJSONとdecompileで移行する手順で扱っています。
Terraformから乗り換えるべきでない条件
すでにTerraformでAzureを運用し、現在の構成が要件を満たしているなら、Bicepへ移る必要はありません。Microsoft自身がFAQで「Terraform を使い慣れている場合は、切り替える理由はありません」と書いています。AWSやGoogle Cloudも同じコードで管理したい場合も同じで、FAQは「現時点では、Azure を超えて Bicep を拡張する予定はありません」としています。Terraformを続ける場合の構成はTerraformでAzureを構築する手順|azurerm 5系の認証とbackend設計にまとめました。逆に、Azureだけが対象でARM JSONを手書きしているなら、Bicepへ移る効果は大きくなります。
Bicep CLIのインストール手順と版の固定
VS Code・Azure CLI・手動の3経路と選び方
公式のインストール手順は、作業ごとに経路を分けています。
| やりたいこと | 経路 | Bicep CLIの導入 |
|---|---|---|
| Bicepファイルを書く | VS Code+Bicep拡張機能 | 拡張機能が自動で用意 |
| Azure CLIでデプロイ | Azure CLI 2.20.0以降 | 自動(PATHには入らない) |
| Azure PowerShellでデプロイ | Az 5.6.0以降 | 手動インストールが必須 |
| CLIを単体で使う | 手動インストール | PATHに追加される |
書くだけならVS CodeのBicep拡張機能を入れれば足ります。拡張機能はリソースの補完と型検証を提供します。ARM JSONにもエディターの検証支援はあるため、両者の差は構文の短さとシンボリック名による参照のほうに出ます。
az bicep installで入るCLIがPATHに入らない仕様
Azure CLIは、Bicepを必要とするコマンドを実行したときにBicep CLIを自動で導入します。明示的に入れるなら次の2行です。
az bicep install
az bicep version
導入先はLinux・macOSが$HOME/.azure/bin、Windowsが%UserProfile%/.azure/binで、公式ドキュメントは「The Azure CLI doesn’t add Bicep CLI to your PATH」と明記しています。このためaz bicep installの直後にbicep --versionを叩くと、コマンドが見つからないというエラーになります。Azure CLI経由で入れたならaz bicep ...の形で使ってください。逆に、手動で入れたPATH上のBicep CLIをAzure CLIに使わせたいときはaz config set bicep.use_binary_from_path=Trueで切り替えます。
Azure PowerShellはこの自己完結型のインスタンスを使えません。公式は「Azure PowerShell deployments fail if you haven’t manually installed the Bicep CLI」と書いており、PowerShellでデプロイするなら次の手動インストールが必要です。
手動インストールのOS別コマンドと配布ファイル名
Bicep CLIの実体はAzure/bicepのリリースページで配布されています。v0.48.1の配布ファイルはbicep-linux-x64、bicep-linux-musl-x64(Alpineなどmusl系)、bicep-linux-arm64、bicep-osx-x64、bicep-osx-arm64、bicep-win-x64.exe、bicep-win-arm64.exeと、Windowsインストーラーのbicep-setup-win-x64.exeです。
# Linux(x64)
curl -Lo bicep https://github.com/Azure/bicep/releases/latest/download/bicep-linux-x64
chmod +x ./bicep
sudo mv ./bicep /usr/local/bin/bicep
bicep --version
# macOS
brew tap azure/bicep
brew install bicep
# Windows
winget install -e --id Microsoft.Bicep
Windowsインストーラーは管理者権限なしで実行でき、ユーザーのPATHに追加されます。Rosetta 2やQEMUのようなエミュレーション環境での安定性は保証されないと公式が注記しているので、Apple SiliconやARM64のLinuxではarm64版を選んでください。
バージョンの固定とエアギャップ環境への配置
CIで毎回最新版を取ると、リンタールールの追加で警告が増えてログの差分が読みにくくなります。Bicep CLIはほぼ毎月更新されており、2026年は7月30日にv0.46.1、9月8日にv0.47.16、10月5日にv0.48.1が出ました。固定するなら次のように指定します。
az bicep list-versions
az bicep install --version v0.48.1
# ARM64環境では上の行の代わりに実行
# az bicep install --version v0.48.1 --target-platform linux-arm64
# 固定を解除して最新版へ上げるときだけ実行
# az bicep upgrade
# 手動導入で版を固定する場合(latest の代わりに版を指定)
curl -Lo bicep https://github.com/Azure/bicep/releases/download/v0.48.1/bicep-linux-x64
外部に出られないエアギャップ環境では、ダウンロードを伴うaz bicep installとaz bicep upgradeが使えません。Linux・macOSでは、別の環境でダウンロードしたバイナリに実行権限を付け、bicepという名前で$HOME/.azure/binへ置くと、Azure CLIが管理するインスタンスとして使われます。Windowsではbicep.exeを%UserProfile%/.azure/binへ置きます。
bicep buildの用途と.bicepparamによるパラメーター分離
bicep buildを手で実行する場面
az deployment group createなどのデプロイコマンドは内部で変換を行うので、bicep buildを毎回実行する必要はありません。手で走らせるのは、生成されるARM JSONをレビューしたいときと、JSONを成果物として残す運用のときです。
bicep build main.bicep
bicep build main.bicep --outfile dist/azuredeploy.json
bicep lint main.bicep
az bicep build --file main.bicep
外部レジストリのモジュールを参照しているとbuildは自動でrestoreを呼びます。オフラインで回すなら--no-restoreを付けますが、キャッシュに無いモジュールがあると失敗します。
.bicepparamの版要件とreadEnvironmentVariable
パラメーターの外出しは、ネイティブの.bicepparamと従来のJSONパラメーターファイルの2通りです。.bicepparamは、下回ると使えない版要件が機能ごとにあります。
| 機能 | Bicep CLI | Azure CLI | Azure PowerShell |
|---|---|---|---|
| .bicepparam の利用 | 0.18.4 以降 | 2.47.0 以降 | 9.7.1 以降 |
| –template-file の省略 | 0.22.X 以降 | 2.53.0 以降 | – |
| ファイル内の変数 | 0.21.X 以降 | – | – |
| using none | 0.31.0 以降 | – | – |
| extends による継承 | 0.44.1 以降 | – | – |
先頭のusingで対象のBicepファイルを指し、環境ごとに.bicepparamを分けるのが基本形です。extendsで継承できるのはパラメーター代入だけで、基底ファイルの変数やユーザー定義型は派生ファイルから見えません。extendsは1ファイルに1本までです。
using './main.bicep'
param prefix = readEnvironmentVariable('ST_PREFIX', 'stdev')
param skuName = 'Standard_ZRS'
readEnvironmentVariableは環境変数を読む関数で、第2引数は変数が無いときの既定値です。読み込みはコンパイル時に行われ、実行時には行われません。手元でbicep build-params main.bicepparam --stdoutを実行すると、環境変数が無ければprefixは"stdev"、ST_PREFIX=stprdを付ければ"stprd"がパラメーターJSONへ固定値として書き込まれました。既定値を省き環境変数も無い場合はBCP338エラーで止まります。CIでは、変換を走らせるジョブで環境変数を渡してください。
パラメーターファイルの値は平文で保存されます。パスワードなどの機密値はKey Vaultに置き、getSecret関数で取得する形にしてください。.bicepparamをリポジトリにコミットする運用では、機密値を1つも書かない前提で設計します。
az deployment group createによるデプロイと差分・削除の管理
.bicepparamを渡すデプロイコマンド
.bicepparam内のusingが対象ファイルを指しているので、--template-fileを省いて渡せます(Azure CLI 2.53.0以降・Bicep CLI 0.22.X以降)。例はBash形式で、デプロイ先のrg-demoは事前に作成しておきます。
az login
az deployment group create \
--resource-group rg-demo \
--parameters main.bicepparam \
--parameters skuName=Standard_LRS
ローカルのパラメーターファイルとインライン指定は併用でき、重複したときはインラインの値が優先されます。アプリのコードとインフラをまとめて扱うなら、テンプレート駆動のAzure Developer CLI(azd)とは?Azure CLIとの違い・インストールとazd upの使い方も選択肢になります。
what-ifによる差分確認と増分モードの挙動
本番に流す前にaz deployment group what-if --resource-group rg-demo --parameters main.bicepparamで差分を出します。Azureの現在の状態とテンプレートを突き合わせ、作成・変更・削除されるリソースとプロパティを並べるコマンドです。既定の増分モード(Incremental)では、テンプレートに書かれていない既存リソースには手を付けません。
増分モードにも落とし穴があります。テンプレートに書かなかったプロパティは「そのまま残る」のではなく、既定値へ戻されます。ポータルで変えた設定がある既存リソースを再デプロイするときは、what-ifの出力でプロパティの変更行を必ず見てください。
デプロイメントスタックによる削除管理と完全モードの非推奨化
テンプレートに無いリソースを消す完全モード(--mode Complete)は、古い記事ではIaCの前提として紹介されていることがあります。現在のデプロイモードの公式ページは「Complete mode is not recommended」とし、完全モードは「will be gradually deprecated」=段階的に非推奨化されると書いています。Azure CLIの--modeにはまだCompleteが残っていますが、新しく組む構成で選ぶ理由はありません。削除まで管理したいならデプロイメントスタックを使います。
az stack group create \
--name stack-demo \
--resource-group rg-demo \
--template-file main.bicep \
--parameters main.bicepparam \
--action-on-unmanage detachAll \
--deny-settings-mode denyDelete
--action-on-unmanageは、テンプレートから外れたリソースの扱いです。detachAll(管理対象から外すだけ)、deleteResources(リソースを削除)、deleteAll(リソースとリソースグループを削除)から選びます。--deny-settings-modeはnone・denyDelete・denyWriteAndDeleteで、管理対象リソースへの削除や変更を拒否割り当てで制限します。どちらも既定値が無く、指定しないとコマンドは通りません。ただし既知の問題として、リソースグループスコープのスタックでは親のリソースグループ自体の削除は防げず、削除すればスタックごと消えます。最初はdetachAllで始め、削除へ切り替える前にスタック専用のaz stack-whatif group createで確認します。前節の通常デプロイ用what-ifでは、スタックの管理から外れて消えるリソースは見えません。
az stack-whatif group create \
--name whatif-demo \
--resource-group rg-demo \
--stack-id <スタックのリソースID> \
--template-file main.bicep \
--parameters main.bicepparam \
--action-on-unmanage deleteResources \
--deny-settings-mode denyDelete \
--retention-interval PT3H
結果はPT1H〜PT3Hの保持期間だけ保存されます(スタックのwhat-if)。--action-on-unmanageと拒否設定は、実際に適用する値と同じものを渡してください。値が違うと結果も変わります。
snapshotとconsoleによるデプロイ前のローカル検証
bicep snapshotによる生成結果の差分検証
snapshotはv0.41.2でGAになったコマンドで、.bicepparamから最終的に生成されるリソース定義を.snapshot.jsonとして書き出します。モジュールへの切り出しのようなリファクタリングで、生成結果が変わっていないことをAzureへ接続せずに確かめられます。上のmain.bicepparamでBicep CLI 0.48.1を実行した結果です。
bicep snapshot main.bicepparam \
--subscription-id 00000000-0000-0000-0000-000000000000 \
--resource-group rg-demo --location japaneast
# main.snapshot.json(抜粋)
"name": "stdevuqhahkpg5qbky",
"sku": { "name": "Standard_ZRS" },
--subscription-idと--resource-groupを渡すと、uniqueString(resourceGroup().id)まで計算された実際のリソース名が出ます。次に.bicepparamのSKUをStandard_LRSへ変えて--mode Validateで比べると、終了コード1で止まり、変わったプロパティが表示されました。
Snapshot validation failed. Expected no changes, but found the following:
~ Microsoft.Storage/storageAccounts/stdevuqhahkpg5qbky
~ sku.name: "Standard_ZRS" => "Standard_LRS"
終了コードで判定できるので、プルリクエストのチェックにそのまま組み込めます。what-ifはAzureのライブ状態と比べるぶんAPI呼び出しと認証が要るため、本番デプロイ直前の1回に絞るのが現実的です。なお、Bicep側のCLIドキュメントには「az bicep snapshot doesn’t exist」と書かれていますが、Azure CLIリファレンスにはaz bicep snapshotがGAとして載っています。ドキュメントのほうが古い状態です。
bicep consoleによる式の評価と制約
v0.42.1以降のbicep consoleは、式や関数をその場で評価するREPLです。パイプで渡すこともでき、手元では次の結果になりました。
$ printf "split('a,b,c', ',')\ntoUpper('stdev')\n" | bicep console
[
'a'
'b'
'c'
]
'STDEV'
resourceGroup()のようにAzureのコンテキストが要る式は評価できず、セッションをまたいだ状態も残りません。az bicepのコマンド一覧にはconsoleが無いため、Bicep CLIを直接呼びます。0.48.1のヘルプにはdeploy・what-if・teardownも並んでいますが、いずれも[Experimental]の表示付きで、本番のパイプラインに組み込む段階ではありません。
GitHub ActionsによるBicepのデプロイとOIDC認証
CI/CDからのデプロイは、Microsoftが公開するazure/bicep-deployアクションで書けます。2026年10月28日時点の最新はv2.5.0で、参照はメジャー版の@v2です。認証にはazure/login@v3のOIDC(フェデレーション資格情報)を使うので、クライアントシークレットをリポジトリに置かずに済みます。前提として、サービスプリンシパルかユーザー割り当てマネージドIDにデプロイ権限とmainブランチ用のフェデレーション資格情報を設定し、クライアントID・テナントID・サブスクリプションIDをSecretsに登録しておきます。ワークフローの置き場所は.github/workflows/deploy-bicep.ymlです。
name: deploy-bicep
on:
push:
branches: [main]
permissions:
id-token: write
contents: read
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
- uses: azure/login@v3
with:
client-id: ${{ secrets.AZURE_CLIENT_ID }}
tenant-id: ${{ secrets.AZURE_TENANT_ID }}
subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
- name: What-If
uses: azure/bicep-deploy@v2
with:
type: deployment
operation: whatIf
scope: resourceGroup
subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
resource-group-name: rg-demo
template-file: ./main.bicep
parameters-file: ./main.bicepparam
- name: Deploy
uses: azure/bicep-deploy@v2
with:
type: deployment
operation: create
scope: resourceGroup
subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
resource-group-name: rg-demo
template-file: ./main.bicep
parameters-file: ./main.bicepparam
typeはdeploymentかdeploymentStackで、deploymentのoperationはcreate・validate・whatIfから選びます。deploymentStackにすれば、前章のスタックと同じくaction-on-unmanage-resourcesとdeny-settings-modeを指定できます。azure/loginのREADMEは、client-idなどに${{ github.event.* }}の値(ブランチ名やPRタイトル)を渡さず、secretsからだけ渡すよう警告しています。
この例はWhat-IfとDeployを同じジョブで続けて実行します。本番ではWhat-IfとDeployを別ジョブに分け、Deployジョブに保護されたEnvironmentを指定して、What-Ifの結果を見てから承認する構成にします。承認の設定はGitHub ActionsのEnvironments|承認ゲートと環境別シークレットの設計、シークレットからOIDCへ移る判断はGitHub ActionsのSecrets管理|置き場所の選定と漏えい経路・OIDC移行の判断、Azure DevOpsで組む場合はAzure Pipelinesの使い方|YAMLの書き方とCI/CDパイプライン作成手順を参照してください。
モジュール分割とAzure Verified Modules
公開レジストリのAVMの参照とバージョン指定
ストレージアカウントや仮想ネットワークのような定番リソースは、Microsoftが検証したAzure Verified Modules(AVM)が公開レジストリにあります。br/publicエイリアスで参照し、バージョンはモジュールごとに独立しています。ストレージアカウント用は、MCRのタグ一覧で2026年11月1日に確認した時点で0.33.1が最新でした。
module storage 'br/public:avm/res/storage/storage-account:0.33.1' = {
name: 'storageDeploy'
params: {
name: 'stexample001'
}
}
公開されるのはバージョンのタグだけで、latestのような可変タグはありません。自作する前にAVMを探し、足りない設定がある場合だけ自作に回すほうが、保守の手間は小さく済みます。
社内モジュールをACRへ発行するときの注意
組織固有のモジュールはAzure Container Registryへ発行して共有します。
az bicep publish --file storage.bicep \
--target "br:exampleregistry.azurecr.io/bicep/modules/storage:v1" \
--documentation-uri https://www.contoso.com/storage.html
既存のタグへ発行するとエラーになり、上書きには--forceが要ります。内容を変えたらタグを上げる運用にしてください。v0.47.16ではモジュールの説明をMarkdownに書き出すbicep docs generateが実験的機能として入りました。レジストリの料金と作成手順はAzure Container Registry(ACR)とは?料金プランの違いと月額・作成からpushまでの手順にまとめています。
既存Azureリソースのエクスポートと逆コンパイル
ポータルで作ったリソースをコードへ寄せるなら、リソースグループのARMテンプレートを書き出して逆コンパイルします。
az group export --name rg-demo > main.json
az bicep decompile --file main.json
公式ドキュメントはJSONからBicepへの変換を保証しておらず、出力をそのままデプロイするのは避けてください。パラメーター名のピリオドがアンダースコアに置き換わる、変換器が付けた名前が残るといった手直しが要ります。変換後に直す箇所と移行の進め方はARMテンプレートとBicepの違い|変換後のJSONとdecompileで移行する手順で詳しく解説しています。既存環境のコード化や構成の見直しを外部に頼む場合は、弊社のインフラ構築(AWS・Google Cloud・Azure)でも対応しています。
よくある質問
Bicepの読み方と意味は何ですか?
読み方は「バイセップ」です。英語の bicep は上腕二頭筋を指す biceps からできた語で、発音は /ˈbaɪsɛp/ です。Azureの文脈では、ARMテンプレートを簡潔に書くためのIaC言語を指します。Microsoftの公式ドキュメントにカタカナ表記や命名の由来の説明はありません。Azureの情報を探すときは「azure bicep」と組み合わせて検索すると、筋トレの記事を避けられます。
az bicep installを実行したのにbicepコマンドが見つからないのはなぜですか?
Azure CLIが入れるBicep CLIは$HOME/.azure/binに置かれ、PATHに追加されないためです。az bicep versionなら動きます。bicep単体で使いたい場合は、リリースページのバイナリかwinget・Homebrewで手動インストールしてください。
bicep buildは毎回実行する必要がありますか?
必要ありません。az deployment group createなどのデプロイコマンドが内部で変換します。構文の検査だけならaz bicep lint --file main.bicep、整形はaz bicep format --file main.bicepを使います。
Bicep CLIの特定のバージョンはどこからダウンロードできますか?
GitHubのAzure/bicepのリリースページです。https://github.com/Azure/bicep/releases/download/v0.48.1/bicep-linux-x64のように、版とOSを指定したURLで取得できます。Azure CLIを使う環境ならaz bicep install --version v0.48.1で同じ版を入れられます。
Bicepの利用に料金はかかりますか?
言語とツールは無料で、Microsoftのサポート対象です。料金が発生するのはデプロイしたAzureリソースだけで、状態ファイルを置くストレージも要りません。