【認証を自動化!】証明書認証でAzure PowerShellを完全自動実行する

この記事の内容

  • サービスプリンシパルを使ってAzure PowerShellの認証を完全自動化する方法を紹介します
  • ユーザーID・パスワードではなく、証明書認証を使うことで安全な無人実行を実現します
  • 自己署名証明書の作成から、サービスプリンシパルの登録、ロール割り当て、スクリプト実行までを網羅します
  • クライアントシークレット(文字列)を使う方法は危険であり、証明書認証が推奨される理由を解説します
  • 一度設定すれば、スクリプトを叩くだけで認証不要にAzure操作が可能になります

なぜ認証を自動化したいのか

VMを定時に自動シャットダウンして、使うときだけ起動したい——そういった用途は多くの方が経験されていると思います。しかし「使うたびにポータルへログインして、サブスクリプションを選んで、VMを探して起動する」という操作は非常に手間がかかります。

PowerShellスクリプトで自動化しようにも、Connect-AzAccount による対話的な認証が毎回必要になり、真の意味での無人実行ができません。

この問題を解決するのが、サービスプリンシパル+証明書認証の組み合わせです。


サービスプリンシパルとは

通常のAzure操作は「ユーザープリンシパル」——つまり人間のアカウント——で行います。これに対してサービスプリンシパルは、スクリプトやアプリケーションが使うためのアカウント(昔でいうサービスアカウント)です。

サービスプリンシパルに必要な権限を付与しておけば、スクリプトがそのサービスプリンシパルとして認証・実行できるようになります。


なぜ証明書認証なのか

サービスプリンシパルの認証方式には大きく2種類あります。

方式概要安全性
クライアントシークレット文字列(パスワード)での認証低い
証明書認証秘密鍵を使った証明書ベースの認証高い

クライアントシークレットはスクリプトに文字列を埋め込む必要があり、スクリプトを他者に見られた場合にサービスプリンシパルを乗っ取られるリスクがあります。

証明書認証では、秘密鍵がローカルのWindowsの証明書ストアにのみ保存されます。Azureに登録されるのは公開鍵のみです。そのため、このPCの現在のユーザーでしか認証できない構造になっており、スクリプト自体をGitリポジトリなどに公開しても安全です。


事前準備:Azure PowerShellのインストール

Azure PowerShellモジュール(Az)がインストールされていない場合は、管理者権限のPowerShellで以下を実行します。

# 既存の AzureRM モジュールを削除(競合防止)
Uninstall-Module AzureRM -AllVersions

# Az モジュールをインストール
Install-Module Az -AllowClobber -Scope AllUsers

インストール済みのモジュール一覧は以下で確認できます。

Get-InstalledModule

手順1:自己署名証明書の作成

まずローカルのWindowsに自己署名証明書を作成します。この証明書の秘密鍵はこのPCにのみ保存されます。

$cert = New-SelfSignedCertificate `
    -CertStoreLocation "Cert:\CurrentUser\My" `
    -Subject "CN=youtube-example" `
    -KeySpec KeyExchange
  • CertStoreLocation:現在のユーザーの証明書ストアに保存します
  • Subject:証明書の識別名(任意の名前でOK)

作成後、MMC(mmc.exe)→「スナップインの追加と削除」→「証明書」→「現在のユーザー」で、個人フォルダに証明書が作成されていることを確認できます。「この証明書に対応する秘密キーを持っています」と表示されていれば正しく作成されています。


手順2:サービスプリンシパルの作成

次に、作成した証明書の情報をもとにAzure ADへサービスプリンシパルを登録します。

まず一時的に対話認証でAzureへログインします(サービスプリンシパル作成のための一回限りの操作です)。

Connect-AzAccount

続けて証明書をBase64文字列に変換し、サービスプリンシパルを作成します。

$keyValue = [System.Convert]::ToBase64String($cert.GetRawCertData())

$sp = New-AzADServicePrincipal `
    -DisplayName "youtube-example" `
    -CertValue $keyValue `
    -EndDate $cert.NotAfter `
    -StartDate $cert.NotBefore

作成後、Azureポータルの「Azure Active Directory」→「アプリの登録」→「すべてのアプリケーション」に「youtube-example」が表示されます。「証明書とシークレット」タブを確認すると、証明書のみが登録され、クライアントシークレットは存在しないことがわかります。


手順3:サブスクリプションへのロール割り当て

作成したサービスプリンシパルにAzureリソースを操作するための権限を付与します。Azureポータルから行う場合は次の手順です。

  1. 対象のサブスクリプションを開く
  2. 「アクセス制御 (IAM)」→「ロールの割り当ての追加」
  3. ロール:「共同作成者」(用途に応じて調整)
  4. メンバー:「ユーザー、グループ、またはサービスプリンシパル」を選択し、youtube-example を指定

PowerShellで実行する場合は以下のようになります。

New-AzRoleAssignment `
    -ApplicationId $sp.AppId `
    -RoleDefinitionName "Contributor" `
    -Scope "/subscriptions/<サブスクリプションID>"

手順4:自動認証スクリプトの作成

ここまでで準備は完了です。以下のスクリプトを作成することで、対話認証なしにAzureへ接続できます。

# 必要な情報を定義
$tenantId       = "<テナントID>"
$applicationId  = "<アプリケーション(クライアント)ID>"
$thumbprint     = "<証明書のサムプリント>"

# 証明書を取得
$cert = Get-ChildItem Cert:\CurrentUser\My\$thumbprint

# サービスプリンシパルとして認証
Connect-AzAccount `
    -ServicePrincipal `
    -TenantId $tenantId `
    -ApplicationId $applicationId `
    -CertificateThumbprint $thumbprint

# ここからAzure操作を記述
Get-AzSubscription
# Get-AzVM など、必要な処理を追加

各パラメーターの確認方法

パラメーター確認場所
テナントIDAzureポータル → Azure Active Directory → 「概要」
アプリケーションIDAzure Active Directory → アプリの登録 → 対象アプリ → 「概要」
証明書のサムプリントアプリの「証明書とシークレット」タブ、またはMMCの証明書プロパティ

動作確認

スクリプトを保存し、PowerShellで実行します(Set-ExecutionPolicy の設定が必要な場合があります)。

# 実行ポリシーの確認・変更(必要な場合)
Set-ExecutionPolicy RemoteSigned -Scope CurrentUser

# スクリプト実行
.\automation-script.ps1

認証プロンプトが表示されず、そのままAzureへ接続されれば成功です。Get-AzVMStart-AzVM など、サービスプリンシパルに付与した権限の範囲で各種操作が実行できます。


まとめ

Azure PowerShellの認証を完全自動化するには、以下の手順でサービスプリンシパルと証明書認証を組み合わせます。

  1. 自己署名証明書を作成して、ローカルの証明書ストアに秘密鍵を保存する
  2. サービスプリンシパルを作成し、証明書の公開鍵をAzure ADに登録する
  3. ロールを割り当てて、サービスプリンシパルに必要な権限を付与する
  4. スクリプトに接続情報を記述し、Connect-AzAccount -ServicePrincipal で無人認証する

この方法であれば、スクリプト自体にパスワードや秘密鍵を埋め込む必要がなく、Gitリポジトリなどにコードをアップしてもセキュリティリスクを最小限に抑えられます。VMの起動・停止やリソース管理など、定期的なAzure操作の自動化にぜひ活用してみてください。