Azure で IaC (ARM Template/Bicep) するなら PSRule for Azure!#2 [CI パイプライン編]
先日書いた PSRule for Azure 記事の続きです。今回は、PSRule for Azure を GitHub Actions に導入する方法と、Azure Monitor との連携について紹介したいと思います。
PSRule for Azure の概要や、ローカル環境での使い方については、前回の記事を参照してみてください。
CI パイプラインへの導入
PSRule を CI パイプラインに導入するには、次のアクションを使います。
- GitHub Actions: https://github.com/marketplace/actions/psrule
- Azure Pipelines: https://marketplace.visualstudio.com/items?itemName=bewhite.ps-rule
本記事では、個人的に使い慣れている GitHub Actions を例に取り、導入方法を簡単に説明したいと思います(といってもめちゃくちゃ簡単なので特に難しい点はありません)。
準備
パイプラインを導入するにあたり事前準備すべきことは、ディレクトリ構造の設計と、ps-rule.yaml
の配置だけです。今回想定するディレクトリ構造と ps-rule.yaml
は、以下の通りです (これは前回の記事と同じですが念のため再掲しておきます)。
.
├── .devcontainer/
├── .ps-rule/ <------------------------- 独自ルールを定義するディレクトリ
├── .vscode/
├── azure/
│ ├── deployment/
│ │ ├── project01/
│ │ │ └── main.bicep <------------ project01 の Bicep ファイル
│ │ └── project02/
│ │ └── main.bicep <------------ project02 の Bicep ファイル
│ └── modules/
│ └── my-module/
│ ├── main.bicep <------------ Bicep Module の定義ファイル
│ └── .tests/
│ └── main.tests.bicep <-- Bicep Module のテスト
└── ps-rule.yaml <---------------------- PSRule の設定
ps-rule.yaml
#
# PSRule for Azure configuration
#
# Please see the documentation for all configuration options:
# https://aka.ms/ps-rule/options
# https://aka.ms/ps-rule-azure/options
# Configure binding for local rules.
binding:
preferTargetInfo: true
targetType:
- type
- resourceType
# Require minimum versions of modules.
requires:
PSRule: "@pre >=2.2.0"
PSRule.Rules.Azure: "@pre >=1.17.1"
# Use PSRule for Azure.
include:
module:
- PSRule.Rules.Azure
output:
culture:
- "ja-JP"
input:
pathIgnore:
# Ignore other files in the repository.
- ".devcontainer/"
- ".vscode/"
- ".github/"
- "*.md"
# Exclude modules but not tests.
- "azure/modules/**/*.bicep"
- "!azure/modules/**/*.tests.bicep"
configuration:
# Enable automatic expansion of Azure parameter files.
AZURE_PARAMETER_FILE_EXPANSION: true
# Enable automatic expansion of Azure Bicep source files.
AZURE_BICEP_FILE_EXPANSION: true
# Configures the number of seconds to wait for build Bicep files.
AZURE_BICEP_FILE_EXPANSION_TIMEOUT: 10
Action の定義
以下のような情報を参考にしながら、.github/workflows/test-azure-infra-code.yaml
にアクションを定義しました。Pull Request を発行した時に Bicep / ARM Template の検証を実行するアクションです。
- https://github.com/marketplace/actions/psrule
- https://github.com/Azure/PSRule.Rules.Azure-quickstart/blob/main/.github/workflows/azure-analyze.yaml
name: Test Azure Infra code with PSRule
on:
pull_request:
branches:
- main
paths:
- ".github/workflows/*"
- "azure/**.bicep"
- "azure/**.json"
permissions:
contents: read
jobs:
psrule_for_azure:
name: Analyze templates
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Analyze Azure template files
uses: microsoft/ps-rule@main
with:
modules: "PSRule.Rules.Azure"
microsoft/ps-rule@main
に関する躓きポイントを一つ。なぜか (with.path
で明示的に指定しても) PSRule の config ファイル ps-rule.yaml
読み取って実行してくれないみたいで、with.modules
で利用するモジュール (PSRule.Rules.Azure
) を明示的に指定しない限り、プリセットルールなしで実行されてしまいます。ちょっと解せない動作ですが、PSRule for Azure を動かすだけならこの設定で特に問題はないのでこのまま進めます。
Pull Request 時の動作確認
GitHub Action の設定が完了したところで、動作確認してみましょう。適当なブランチに以下の Bicep ファイルをつっこんで、Pull Request を発行してみます。
動作確認に使った bicep コード
@description('Location for all resources.')
param location string = resourceGroup().location
var vnetName = 'vnet-test'
resource vnet 'Microsoft.Network/virtualNetworks@2021-05-01' = {
name: vnetName
location: location
properties: {
addressSpace: {
addressPrefixes: [
'10.0.0.0/16'
]
}
subnets: [
{
name: 'default'
properties: {
addressPrefix: '10.0.2.0/24'
}
}
]
}
}
期待通り (?) テストがこけてくれました。
ログを見てみると、サブネットに NSG を関連付けていないことと、タグが付いてないことで怒られているようですね。
公式ドキュメント 内でルール ID (たとえば AZR-000263
) を検索すると、ルールの詳細ページに飛ぶことができます。エラーが発生したルールを修正する際に役立ててください。
応用: Azure Monitor との連携
PSRule には、検証結果を Azure Monitor (Log Analytics Workspace) に出力するためのモジュール PSRule.Monitor
が用意されています。ここからは、CI パイプラインのテスト結果を、Log Analytics Workspace にログ出力する機能を試していきたいと思います。
手順 1. Log Analytics Workspcae を作成する
まずは Log Analytics Workspace を作成します。
作成できたら、連携のために利用する Workspace ID とアクセスキー (Primary/Secondary どちらでも可) を控えておきます。これらの値は、Azure Portal のエージェント管理ページから確認できます。
手順 2. モジュール PSRule.Monitor を追加する
公式ドキュメントのガイド通り GitHub Actions の設定を編集します。具体的には、microsoft/ps-rule
に PSRule.Monitor
を読み込ませつつ、環境変数に Workspace ID とアクセスキーを設定します。
psrule_for_azure:
name: Analyze templates
runs-on: ubuntu-latest
+ environment: psrule-for-azure
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Analyze Azure template files
uses: microsoft/ps-rule@main
with:
- modules: "PSRule.Rules.Azure"
+ modules: PSRule.Rules.Azure,PSRule.Monitor
+ conventions: Monitor.LogAnalytics.Import
+ env:
+ PSRULE_CONFIGURATION_MONITOR_WORKSPACE_ID: ${{ secrets.MONITOR_WORKSPACE_ID }}
+ PSRULE_CONFIGURATION_MONITOR_WORKSPACE_KEY: ${{ secrets.MONITOR_WORKSPACE_KEY }}
手順 3. シークレットを作成する
最後に、WorkspaceID とアクセスキーをシークレットに保存すれば設定完了です。GitHub レポジトリの設定画面から追加します (今回の場合、Environment 名は psrule-for-azure
にしてます)。
GitHub シークレット名 | 設定する値 |
---|---|
MONITOR_WORKSPACE_ID | Log Analytics Workspace の Workspace ID |
MONITOR_WORKSPACE_KEY | Log Analytics Workspace の アクセスキー |
ログの出力を確認する
以上の手順を完了すれば、新たに GitHub 上でパイプラインを走らせる度に、自動的に結果が Azure Monitor 側にログが出力されるようになります。
体感だと 5 分くらいデータインジェスト レイテンシがあるので、少し時間をおいて確認すると良いでしょう。Log Analytics Workspace の [Logs] ページから、PSRule_CL
テーブルのログを検索してみてください。
- テーブル名:
PSRule_CL
- スキーマ
カラム名 | 説明 | 例 |
---|---|---|
TimeGenerated | データが生成された時刻 | 9/8/2022, 5:35:49.822 AM (UTC) |
RuleId_s | ルールの正式な ID。PSRule for Azure の場合 PSRule.Rules.Azure\... となる |
PSRule.Rules.Azure\Azure.VNET.UseNSGs |
RuleName_s | ルール名 | Azure.VNET.UseNSGs |
DisplayName_s | ルールのユーザーフレンドリー名。ルール名と変わらん気がする | Azure.VNET.UseNSGs |
TargetName_s | 検証対象リソースの名前 | vnet-test |
TargetType_s | 検証対象リソースのリソース種別 | Microsoft.Network/virtualNetworks |
Outcome_s | 検証結果。Pass または Fail | Fail |
Duration_d | 実行時間 (ms) | 1 |
RunId_s | 実行時の ID。GitHub Actions から実行すると <username>/<repo-name>/<unique-id> となる |
OpenJNY/psrule-demo/3012702015 |
CorrelationId | 実行時の ID と同義の UUID | aa1cb324-d815-4f1b-b86a-d0bfc922eb56 |
たとえば、リソースごとに Pass した割合と失敗ルールの一覧を表示したければ、次のクエリを実行すれば良いです。
let repo = "OpenJNY/psrule-demo";
//
PSRule_CL
| where RunId_s startswith repo
| summarize
TimeGenerated = min(TimeGenerated),
PassRate = 100 * sum(iff(Outcome_s == "Pass", 1, 0)) / count(),
FailedRules = make_set_if(RuleName_s, Outcome_s != "Pass")
by RunId_s, TargetType_s, TargetName_s
| project TimeGenerated, RunId_s, TargetType_s, TargetName_s, PassRate, FailedRules
| sort by TimeGenerated asc, TargetType_s asc, TargetName_s asc
実行結果
まとめ
ということで、以上が GitHub Actions を使う場合の PSRule for Azure 導入方法でした。
前回の記事とあわせて PSRule for Azure の使い方を簡単にさらってみましたが、容易に導入できたのが非常に印象的でした。もし Azure ARM Template や Bicep の自動テストをどうしようか悩んでいる方がいれば、ぜひテイスティングだけでもしてみてください。
また、Azure でガバナンス確保に使える機能/製品には、IAM、リソースロック、Azure Policy、Azure Blueprints などなど、様々なものがあります。以下の MSLearn でざっと把握することが出来るので、ぜひデザートとしてご賞味ください🍰
参考文献
Discussion