IaCとセットで出てくる技術用語としてCI/CDというものがあります。
今回は「CI/CDとは何か」「GitHub Actionsを使ったCI/CDの組み方」について解説していきます。
前提知識のおさらい
IaCとは
Infrastructure as Codeの頭文字でインフラをコードで管理することです。
コードと聞くといかにも技術のような印象がありますが、
- どういうシステムの完成系を目指しているか
- 完成系に至るまで、どのように作業していくか
- 完成系を継続的にどのように運用していくか
ということに対するGUI・CLIのような操作論・方法論の一つです。
コードでシステムの最終系を記述するので「最新の状態を維持できる」「同じ(検証)環境などを繰り返し構築できる」などのメリットがあります。
Bicepとは
宣言型の構文を利用してAzureリソースをデプロイするためのドメイン固有言語(DSL)です。
この値はこれ、このSKUはこれを使う などを宣言的に記述することでシステムの最終系を定義します。
CI/CDとは?
「継続的インテグレーション/継続的デリバリー」の頭文字をとった言葉です。
継続的インテグレーション(CI)
コードをデプロイする前に、そのコードに問題がないかを自動でチェックします。
一般的にCIフェーズでは以下のようなことを行います。
- 静的コード解析
- モジュールなどの依存関係のチェック
- 脆弱性がないかなどのセキュリティチェック
継続的デプロイ
コードのデプロイを自動で行います。
一般的にはCIでチェックし問題なければデプロイを自動実行するという段階に分けられます。
これにより、ユーザー側でコードの修正→GitHubに保存→CIにより自動チェック→CDにより自動デプロイというフローになるので、ユーザーが行うチェックやデプロイ作業が一貫したフローになります。
これは、インフラの一貫性を保つ上で非常に強力なツールです。
今回は主にCI/CDにおける自動デプロイの処理にフォーカスして、
自分がコードに加えた変更点が自動で反映される動作を体感していただきます。
Bicepを使ったCI/CD環境を構築する
Azure VMを定義しているBicepファイルを使ってCI/CDパイプラインを構築します。

構成は図の通りです。
わかりやすく、冪等性の時に確認したようなNSGのルールを変更する処理を行います。
前提条件
- GitHubアカウントがあること
- GitHubのリポジトリ内にBicepファイルが保管されていること
今回使うリポジトリを公開しています。
全体の作業フロー
1.GitHub ActionsをEntra IDにアプリ登録し、RBACを設定し認証できるようにする
2.GitHub Actionsで動作するワークフローを定義したYAMLファイルを作成する
3.コードを変更しgit pushでワークフローをトリガーさせ、デプロイを実行する
※GitHub Actions:GitHubで提供される機能の一つで、チェックやデプロイを実行するための仮想マシン
1.GitHub ActionsをEntra IDにアプリ登録し、RBACを設定し認証できるようにする
Entra IDへのアプリ登録
GitHub ActionsがAzureへ認証するために、GitHub Actionsをアプリとして登録します。

ここで、以下の3点の情報を押さえておきます。
- アプリケーション (クライアント) ID
- ディレクトリ (テナント) ID
- サブスクリプション ID
アプリケーションIDとディレクトリIDはアプリ登録後に表示されるため、その値をコピーします。
サブスクリプションIDはAzure Portalからサブスクリプションのページに飛んで確認します。
クライアントシークレットの作成
次に、このアプリが使用するパスワードを生成します。

規定ではシークレットの有効期限は180日です。必要に応じて調整してください。
追加を押すとシークレット情報が出てくるので、「値」をコピーしておきます。
登録したアプリケーションに権限を割り当て
Github Actions用のアプリは作成したので、これに対象のリソースグループに対する共同作成者権限を割り当てます。

対象のリソースグループのIAMからロールの割り当ての追加を選択し
ロールの種類:共同作成者
メンバー:登録したアプリ
で割り当てを行います。

2.GitHub Actionsで動作するワークフローを定義したYAMLファイルを作成する
GitHub シークレットの設定
アプリ登録の際に控えたシークレットの情報などをGithub側にも登録していきます。
Githubの対象のリポジトリを開いて、
Setting→Secrets and variables→Actionsを開きます。


New repository secretから事前に控えた4つの情報を使って、以下のシークレットを作成します。

Name: AZURE_CREDENTIALS
{
"clientId": "アプリケーション (クライアント) ID",
"clientSecret": "シークレットの 値 (Value)",
"subscriptionId":"サブスクリプション ID",
"tenantId": "ディレクトリ (テナント) ID"
}
また、これまでコマンドで渡していた引数もGitHub Secretsで渡します。
- Name: EXISTING_KEYVAULT_ID
- Secret: リソースID(リソースのプロパティからコピー可能)
- Name: VM_ADMIN_USERNAME
- Secret: VMのadminUser名

2.GitHub Actionsで動作するワークフローを定義したYAMLファイルを作成する
ワークフローファイルを作成
VSCodeを開き、現在開いているフォルダに「.github\workflows」というフォルダを作成します。

作成したフォルダの中に「deploy-azure-vm.yml」という以下のファイルを作成します。
# .github/workflows/deploy-azure-vm.yml
name: Deploy Azure VM Bicep (from main.bicep)
# このワークフローが実行されるトリガーを指定
on:
push:
branches:
- cicd # cicdブランチへのpushで実行
paths:
# 変更を監視するファイルを指定
- 'main.bicep'
- '**.bicep'
# GitHubのActionsタブから手動で実行できるようにする
workflow_dispatch:
jobs:
build-and-deploy:
runs-on: ubuntu-latest # 実行環境
steps:
# 1. リポジトリのコードをチェックアウト
# (main.bicep と modules/ ディレクトリを読み込むため)
- name: Checkout code
uses: actions/checkout@v4
# 2. Azure へのログイン
# (Azure Portal で作成した個別のシークレットを使用)
- name: Log in to Azure
uses: azure/login@v1
with:
# 推奨: サービスプリンシパル情報を1つのシークレット(AZURE_CREDENTIALS)にまとめて渡します。
# 内容は次の JSON(例)を GitHub Secrets に登録してください:
# {"clientId":"...","clientSecret":"...","subscriptionId":"...","tenantId":"..."}
creds: ${{ secrets.AZURE_CREDENTIALS }}
# 3. Bicep ファイルのデプロイ
- name: Deploy Bicep (main.bicep)
uses: azure/arm-deploy@v1
with:
# スコープは必須入力です。resourceGroup を指定しているため以下を追加します。
scope: 'resourcegroup'
# デプロイ先のサブスクリプションID
subscriptionId: ${{ fromJson(secrets.AZURE_CREDENTIALS).subscriptionId }}
# ★ ターゲットのリソースグループ名
resourceGroupName: 'rg-bicep-vm'
# ★ 実行するBicepファイル (main.bicep) のパス
template: './main.bicep'
# デプロイが失敗した場合にエラーとする
failOnStdErr: true
parameters: >
vmName=vm-deploy-bicep
adminUsername=${{ secrets.VM_ADMIN_USERNAME }}
adminPassword=${{ secrets.VM_ADMIN_PASSWORD }}
location=japaneast
リポジトリへpush
cicdブランチへpushします。
git add .
git commit -m "ワークフローファイルの作成"
git push origin cicd
GitHubのリポジトリに保存されていることを確認します。

git push origin cicdをトリガーに、ワークフローファイルによってGitHub Actionsが起動します。
GitHubのリポジトリから「Actions」を確認します。

緑のチェックがついていれば成功しています。
(参考)エラーが出ている場合は、ワークフローを選択するとどの部分で詰まっているかがわかります。

Azure Portalを確認すると、リソースが作成されていることがわかります。

3.コードを変更しgit pushでワークフローをトリガーさせ、デプロイを実行する
これまでの流れで、Githubへのpushをトリガーにデプロイを行う操作を確認しました。
運用ではこのコードを修正&保存(push)し環境を維持管理し、「コードベースでインフラを管理する」という本質に触れていきます。
NSGルールの変更
今回は簡単な構成のため、NSGルールを変更する処理を入れてみます。
network.bicepのNSGルールで8080ポートを*(any)→自宅のIPアドレスに変更します。
{
name: 'AllowTCP8080'
properties: {
priority: 120
protocol: 'Tcp'
access: 'Allow'
direction: 'Inbound'
sourceAddressPrefix: '133.32.181.21'
sourcePortRange: '*'
destinationAddressPrefix: 'VirtualNetwork'
destinationPortRange: '8080'
}
}
変更したらpushして完了です。
git add .
git commit -m "NSGルール変更:8080ポートを自宅からのみ許可"
git push origin cicd
GitHub Actionsが起動し、自動でデプロイを行います。

ポータルを確認すると、NSGのルールが修正されていることがわかります。

これで修正を行う操作は終了です。
毎回パスワード付きのデプロイコマンドを手動実行しなくても、GitHubへの保存をトリガーに環境が常に最新化されるため、GitHubリポジトリの中身=現在の環境という状態を維持できます。(コード修正はしたけどデプロイはしていなかったというドリフトを回避します)
まとめ
今回はワークフローファイルを使ってGitHubへのpushをトリガーにデプロイを自動化するCI/CDパイプラインについて解説しました。
簡易的な内容で解説しましたが、実際の運用環境においてはブランチ運用(チェック・承認フロー)やマージやビルド時のセキュリティチェック(静的コード解析や依存関係の可視化など)を組み合わせることで、非常にセキュアにかつ自動化を組み合わせた環境維持の実現が可能になりますので、運用環境に合わせて検討してみてください。


コメント