Azureのスクリプトやツールを使用してタスクを自動化する必要がある場合、サービスアカウントまたはAzureサービスプリンシパルを使用することを検討しますか?一部の人々は、新しいサービスアカウントを作成し、必要なすべての管理者ロールを付与し、MFAの除外対象としますが、これは珍しいことではありません。
I know what you’re thinking – “that is a horrible idea”. Of course, it is! And for sure, your IT Sec will give you a lot of grief if you did all that.
しかし、代替案はありますか?MFAの除外が必要ない制限されたスコープを持つ特権資格情報を使用する方法はありますか?この記事では、幸運なことに、それについて学ぶことができます。
この記事では、Azureサービスプリンシパルについて学びます。パスワード、シークレットキー、証明書など、さまざまなタイプの資格情報を使用してサービスプリンシパルを作成する方法について学びます。
Azureサービスプリンシパルを作成するための多くのツールがあります。これには、Azureポータル、Azure Active Directory管理センター、Azure AD PowerShell、Azure CLI、およびAzure PowerShellが含まれます。この記事の焦点となるツールは、Azure PowerShellです。
まだ興味がありますか?読み続けて始めましょう!
要件
これは学習中に行う記事なので、一緒に進めるためのいくつかの前提条件を紹介します。
- Azureのサブスクリプションへのアクセスが必要です。テストテナントで作業すると最適です。持っていない場合は、無料トライアルに登録してください。
- PowerShell 5.1を実行しているWindows 10のコンピュータへのアクセスが必要です。
- Azure PowerShellモジュールがインストールされている必要があります。
Azure Service Principal vs. Service Account
自動化ツールやスクリプトでは、管理者や特権アクセスが必要なことがよくあります。たとえば、ストレージアカウントのプロビジョニングやスケジュールに基づいた仮想マシンの起動と停止などです。そして、ほとんどの管理者は、スクリプトの認証要件を設定するために完全特権のユーザーアカウント(サービスアカウントと呼ばれる)を使用するでしょう。
A service account is essentially a privileged user account used to authenticate using a username and password. And, if used with automation, a service account is most likely excluded from any conditional access policies or multi-factor authentication.
一方、Azureのサービスプリンシパルは、ユーザー名とパスワードまたは証明書を使用して設定することができます。ユーザーではなく、アプリケーションのためのアイデンティティと考えてください。
Azureのサービスプリンシパルは、特定の単一のAzureリソースに対して必要最小限のアクセス権限を割り当てることができます。たとえば、Azureのサービスプリンシパルを作成して、サブスクリプション全体または単一のAzure仮想マシンにロールベースのアクセスを持たせることができます。
Azureサービスプリンシパルを作成する際の主な考慮事項
Azureサービスプリンシパルを作成する前に、計画するために必要な基本的な詳細を把握しておく必要があります。これらの詳細はシンプルに見えるかもしれませんが、効率的かつ簡単にAzureサービスプリンシパルを作成するために役立ちます。
表示名。名前から始まり、Azureサービスプリンシパルには名前が必要です。ルールはありませんが、組織によっては指定された命名規則があるかもしれません。
- 使用する資格情報の種類。パスワードまたは証明書を使用するAzureサービスプリンシパルを作成することができます。これは、1つだけを選択する必要があるという意味ではありません。両方を使用することもできます。
サービスプリンシパルの場合、ユーザー名とパスワードは応用プログラムIDとシークレットキーとしてより適切に参照されます。
- 資格情報の有効期間。パスワードまたは証明書の資格情報を割り当てる場合、その有効期間の開始日と終了日を定義する必要があります。資格情報の有効期間は、通常、証明書とパスワードをどれくらいの頻度でローテーション/更新するかによって異なります。
- アクセスの範囲。Azureサービスプリンシパルがサブスクリプション、リソースグループ、または選択したリソースにアクセスするかどうかを定義する必要があります。
- 役割。いくつかの役割が利用可能です。例えば、Contributor、Reader、Ownerなどです。どの役割がサービスプリンシパルにとって適切かを定義する必要があります。
自動割り当てされたシークレットキーを使用してAzureのサービスプリンシパルを作成する
新しいAzureのサービスプリンシパルを作成するための中心となるのは、New-AzAdServicePrincipal
コマンドレットです。この例では、以下の値を持つ新しいサービスプリンシパルが作成されます:
表示名: AzVM_Reader
スコープ: AzVM1 (仮想マシン)
ロール: Reader
パスワード: <自動割り当て>
資格情報の有効期間:1年
ターゲットスコープ(仮想マシン)のIDを取得する
上記の例では、この新しいサービスプリンシパルのスコープはAzVM1という名前の仮想マシンに限定されています。ただし、-Scope
パラメータは単に名前を受け付けるのではなく、リソースの全体のIDを必要とします。したがって、この例では、最初にAzVM1仮想マシンのIDを取得する必要があります。以下のコードを使用してそれを行います。
上記のコードをPowerShellで実行すると、以下のスクリーンショットと似たようなVMの名前とIDのリストが表示されるはずです。

シークレットキーを持つAzureのサービスプリンシパルを作成する
これで、ターゲットスコープであるAzVM1仮想マシンのIDを取得したので、以下のコマンドを使用して、readerロールを持つ新しいサービスプリンシパルを作成できます。新しいサービスプリンシパルのプロパティは$sp
変数に保存されます。
上記のコマンドの結果、以下の値を持つサービスプリンシパルが作成されました。

シークレットキーの復号化
今、ApplicationIDとSecret、つまりサービスプリンシパルのユーザー名とパスワードを持っています。ただし、Secretの値はSystem.Security.SecureStringと表示されています。この秘密が何であるか知りたい場合は、次のコマンドを使用して秘密を平文に変換します。
上記のコマンドは、$sp.Secret
のセキュア文字列の値を平文に変換します。参考までに、以下のイメージをご覧ください。

Azureサービスプリンシパルのロール割り当ての確認
これが機能したかどうかをどのように確認しますか?Azureポータルを使用してリソースのアクセス制御リストを確認できます。たとえば、下の画像では、AzVM_ReaderサービスプリンシパルがReaderアクセス権をAzVM1仮想マシンに持っていることがわかります。

また、Get-AzRoleAssignment -ObjectID $sp.id
コマンドを使用して、Azureサービスプリンシパルのロール割り当てを取得することもできます。以下はスクリーンショットの例です。

パスワードを使用したAzureサービスプリンシパルの作成
Azureサービスプリンシパルに割り当てられるパスワードまたはシークレットキーをより細かく制御したい場合は、サービスプリンシパルの作成時に-PasswordCredential
パラメータを使用します。これは、パスワードが複雑な要件を満たす必要がある場合に特に便利です。
この例では、新しいAzureサービスプリンシパルが次の値で作成されます:
表示名: ATA_RG_Contributor
スコープ: ATA (リソースグループ)
役割: 貢献者
パスワード: 20文字で6つの非英数字の文字を含む
資格の有効期限: 5年
対象スコープ(リソースグループ)のIDを取得
この新しいサービスプリンシパルのスコープは、ATAという名前のリソースグループ全体をカバーします。最初に取得するのは、ATAリソースグループのIDです。以下のコードを使用して、-Name
パラメータの値をリソースグループの名前に変更してください。
次に、リソースグループのResourceID
が$Scope
変数に格納されていることが表示されます。

パスワード文字列の生成
次のステップは、20文字で6つの非英数字の文字を含む複雑さに従うパスワードを生成することです。そのために、.NETの静的メソッドGeneratePassword()
を利用することができます。
上記のコードGeneratePassword(20, 6)
では、最初の値はパスワードの長さを意味し、2番目の値は含まれる非英数字の文字数を意味します。結果は以下のスクリーンショットに表示されます。

GeneratePassword()
static methodパスワード資格情報オブジェクトの作成
パスワード文字列を取得したら、次のステップはMicrosoft.Azure.Commands.ActiveDirectory.PSADPasswordCredential
オブジェクトを作成することです。このオブジェクトには、$password
変数に格納されたパスワード文字列と有効期間が5年の情報が含まれます。以下のコードをコピーしてAzure PowerShellセッションで実行してください。
上記のコードをPowerShellで実行すると、クレデンシャルオブジェクトが$PasswordCredential
変数に格納されます。期待される結果は以下の例と似ています。

パスワードを使用してサービスプリンシパルを作成する
必要なパラメータの値を用意したので、Azureのサービスプリンシパルを作成しましょう。以下のコードは、表示名をATA_RG_Contributorとし、パスワードを$PasswordCredential
変数に格納します。
コードを実行すると、新しいサービスプリンシパルが作成され、プロパティが$sp
変数に格納されます。以下は例の結果です。

ロールとスコープの割り当て
前のセクションでAzureのサービスプリンシパルを作成しましたが、RoleとScopeはありませんでした。これは-Role
と-Scope
パラメータを-PasswordCredential
パラメータと同時に使用できないためです。つまり、サービスプリンシパルにロールとスコープを割り当てるために追加の手順が必要です。
以下のコードでは、New-AzRoleAssignment
コマンドレットを使用して、Azureサービスプリンシパルのスコープと役割を割り当てます。
以下のスクリーンショットは、役割とスコープがAzureサービスプリンシパルに割り当てられた後の期待される結果を示しています。

サービスプリンシパルのパスワードを保存しておくことは常に重要です。保存できなかったり、忘れてしまった場合には回復する方法はありません。
サービスプリンシパルパスワードを使用してAzureに接続する
さて、サービスプリンシパルを使用します。ユーザーアカウントを使用してAzure PowerShellにログインする代わりに、以下のコードではサービスプリンシパルの資格情報を使用します。
上記のコードを実行した後、ATA_RG_Contributorサービスプリンシパルとパスワード認証情報を使用してAzure PowerShellにログインする必要があります。

証明書を使用したAzureサービスプリンシパルの作成
パスワード認証情報以外にも、Azureサービスプリンシパルには証明書ベースの認証情報を持つこともあります。関連する証明書は、証明書機関によって発行されたものまたは自己署名のものである場合があります。
この例では、新しいAzureサービスプリンシパルは以下の値で作成されます:
表示名: VSE3_SUB_OWNER
スコープ: VSE3 (サブスクリプション)
ロール: 所有者
証明書の有効期間: 2年
ターゲットスコープ(サブスクリプション)のIDを取得する
この新しいサービスプリンシパルのスコープはVSE3という名前のAzureサブスクリプションをカバーします。最初に取得するのはVSE3サブスクリプションのIDです。以下のコードを使用して取得しますが、-SubscriptionName
パラメータの値をリソースグループ名に変更してください。
次に、作成する新しいAzureサービスプリンシパルと自己署名証明書の名前を指定します。
自己署名証明書の作成
以下のコードは、名前がCN=VSE3_SUB_OWNERで個人証明書ストアにセルフサインされたパスワードを作成します。証明書の有効期間は2年に設定されています。証明書のプロパティは$cert
変数に保存されます。
以下のスクリーンショットは、証明書が作成されたことを示しています。

もし新しい証明書をより馴染みのあるビュー(GUI)で見たい場合は、証明書コンソール(certmgr.mmc)で見つけることができます。以下の画像は、証明書を示しています。

次は、セルフサイン証明書のBase64エンコードされた値を取得し、$keyValue
変数に保存することです。
サービスプリンシパルの証明書作成
証明書が作成されたので、次のステップは、セルフサイン証明書を資格情報として使用するAzureサービスプリンシパルを作成することです。資格情報の有効期間は証明書の有効期間と一致します。
以下のコードを実行すると、以下の画像と同様の出力が得られます。

ロールとスコープの割り当て
Azureサービスプリンシパルは作成されましたが、まだロールとスコープが割り当てられていません。サービスプリンシパルにロールとスコープを割り当てるためには、さらなる手順が必要です。
以下のコードは、New-AzRoleAssignment
コマンドレットを使用して、サービスプリンシパルのVSE3サブスクリプションに所有者ロールを割り当てます。
コードを実行すると、以下のスクリーンショットによって、ロールの割り当てが完了したことが確認されます。

サービスプリンシパル証明書を使用してAzureに接続する
これで、証明書ベースの資格情報を使用してサービスプリンシパルが作成されました。これにより、パスワードを使用せずにAzureに接続することができます。代わりに、コンピュータに利用可能な証明書を認証方法として使用します。
この例では、サービスプリンシパルの表示名はVSE3_SUB_OWNERであり、証明書名はCN=VSE3_SUB_OWNERです。以下のコードでは、パーソナル証明書ストアから証明書のサムプリントを取得し、それをログイン資格情報として使用します。
以下のスクリーンショットは、上記のコードを使用して、Azure PowerShellへのログインが成功したことを示しています。ログインにはApplicationID、Tenant、およびCertificate ThumbPrintのみが使用されました。

結論
Azureサービスプリンシパルは、Azureリソースにアクセスする自動化タスクとツールの資格情報を作成する際に考慮する必要があるセキュリティプリンシパルです。適用するスコープとロールは、「ちょうど十分な」アクセス許可を与えるために選択できます。
この記事では、PowerShellを使用してAzure Service Principalsを作成する方法を学びました。Azure Service Principalsにはパスワード、シークレットキー、または証明書ベースの資格情報が付与されます。それぞれの資格情報の種類には利点と適用可能な使用シナリオがあります。
パスワードまたはシークレットキーの資格情報を持つサービスプリンシパルはより携帯性がありますが、資格情報は平文として共有されるため、セキュリティが低いと考えられています。一方、証明書ベースの資格情報はより安全なオプションですが、少し手間がかかります。
この記事で学んだ技術は、自動化にAzureサービスプリンシパルを使用するための基本的な内容に限定されています。資格情報の追加、削除、リセットなど、Azureサービスプリンシパルの設定方法は他にもたくさんあります。これらは進んで探索していくことができます。
お読みいただきありがとうございました!
追加の学習リソース
以下は、この記事と一緒に役立つと思われるリソースです。
Source:
https://adamtheautomator.com/azure-service-principal/