たいちの何か

趣味を中心に車・クラウド・サーバーなどの話を勝手気ままに書いています

Azure - サービスプリンシパルを使ってPoweshellスクリプトでAzureに自動ログインする その2

会社のPMP(Project Management Professional)の研修の準備と、研修でバタバタしてBlog更新ができませんでした(言い訳)
さて、今日は実際に証明書を使ってサービスプリンシパルを作成し、Azureに自動ログインしてみたいと思います。
自動ログインを実現する方法には、大きく2通りありますが、今回はよりセキュアな方法ということで 証明書 を使った方法を試そうと思います。

以前の記事はこちらから
edge.hateblo.jp

目次

Powershellを用意する

今回はAzureADに自動ログインさせるために、Azure Resouce Manager用のPowershellモジュール(以下AzureRM)が必要になります。
AzureRMのインストールは以下のリンクを参照してください。

docs.microsoft.com

証明書の確認

今回は証明書を新たに用意するのが面倒だったので、既存の証明書を使用するので、証明書の場所を確認します!*1

Powershellを実行するコンピューターでMMCを起動し、証明書(コンピューター)を開きます。ここに幾つか証明書があるので、今回は、証明書の個人ストアにある一番下のクライアント証明書を使ってサービスプリンシパルを作ってみようと思います。 *2

証明書を使ってサービスプリンシパルを作成する

  • まずPowershellを起動し、AzureRMモジュールを読み込みます。
Import-module Azurerm
  • 読み込みが完了したら、以下のコマンドを実行し、AzureADにログインをします。  
** #AzureADにログインする(ポップアップがでます) **
Login-AzureRmAccount
  • ローカルコンピューターの証明書ストアから、<<証明書のSubject名を入れる>>にマッチする証明書を抽出し変数に代入します。
$cert =  $Thumbprint = (Get-ChildItem cert:LocalMachine\My\ | Where-Object {$_.Subject -match "<<証明書のSubject名を入れる>>" })  
  • 取得した証明書情報のフォーマットを変換します。
$keyValue = [System.Convert]::ToBase64String($cert.GetRawCertData())  
  • AzureADにサービスプリンシパルを作成する。-DisplayNameには任意の名称をつけます。この時、CertValueオプションとEnddate/Startdateオプションを使い証明書情報をAzureに送信します。
$sp = New-AzureRMADServicePrincipal -DisplayName "Powerhsell_Auto_logon" -CertValue $keyValue -EndDate $cert.NotAfter -StartDate  cert.NotBefore  
  • 最後にアサインメントをして完了です
New-AzureRmRoleAssignment -RoleDefinitionName Contributor -ServicePrincipalName $sp.ApplicationId
  • Azureポータルを確認すると、Powershell_Auto_logonというサービスプリンシパルが作成されていることが確認できました。    f:id:taitioooo:20170902232614p:plain

Powershellを使って自動ログインを試す

次にPowershellを使ってAzureVMの一覧を取得してみようと思います。
サービスプリンシパルがきちんと作成できていれば、パスワードを聞かれることなくAzureVMの一覧が入手できるはずですが、そう簡単にはイカないようです。
自動ログインしてコマンドを実行するには、証明書情報をAzureに教えて上げる必要があります。
そのおまじないが以下の構文です。

注意:今回コンピューター証明書を使ってサービスプリンシパルを作っているので、powershellは管理者として実行させてください

$Thumbprint = (Get-ChildItem cert:\CurrentUser\My\ | Where-Object {$_.Subject -match "<<サービスプリンシパル作成時に使った証明書のSubject名を入れる>>" }).Thumbprint
Login-AzureRmAccount -ServicePrincipal -CertificateThumbprint $Thumbprint -ApplicationId "<<作成したサービスプリンシパルのアプリケーションIDを入れる>>" -TenantId "AzureポータルのテナントIDを入れる"

上記コマンド実行後に Get-AzurermVM を実行するとAzure上の仮想マシン一覧を取得できます。 パスワードの入力画面はありませんでしたね。

最後に

いかがでしょうか。この方法を使うことで、Powershell内部にパスワードやアカウント情報を記載しなくて良いので、人の異動などにも影響されず、もしスクリプトが盗まれた場合でも、証明書も一緒に盗まれない限り、他の場所からのログインもできません。
PowershellでAzureを管理したいと考えている皆さん、一度試してみてはいかがでしょうか。

次回は何をするの?

次回は、Office365に同様の方法でログインする方法を紹介したいと思います。 (Office365の自動ログイン方法をググってみたら、証明書を使った方法が全くヒットしなかったため。殆どの記事はパスワードを埋め込む方式でした…)

*1:本来はサービスプリンシパル用の証明書を内部CAから発行するほうがよいですが、今回はテストなので…

*2:証明書(ユーザー)でも大丈夫ですが、Powershellの実行アカウントを気にする必要があるので、今回はコンピューターを使いました。

Copyright © 2014 - taitioooo. All Rights Reserved.