一歩先行く Azure Computing シリーズ(全3回) 第2回 Azure VM どれを選ぶの? Azure VM 集中講座Minoru Naito
近年 Azure VM のラインナップが急速に拡大し、どれを選ぶのかわからなくなっている方もおられるのではないでしょうか。
こちらでは、Azure VM のラインナップ一つ一つを解説し、どのような用途でどのような VM を選べばよいかを解説します。
本資料は、以下のウェビナーの資料となります。こちらのウェビナーで動画も閲覧できますので、よろしければこちらもぜひどうぞ!
https://info.microsoft.com/JA-AzureINFRA-WBNR-FY19-11Nov-20-AzureVMIntensiveCourse-MCW0009132_02OnDemandRegistration-ForminBody.html
日本マイクロソフト株式会社
カスタマーサクセス事業本部 エンタープライズアーキテクト統括本部 クラウドアーキテクト技術本部 クラウドソリューションアーキテクト
牛上 貴司
AVD の導入を検討している方、または、構築に携わる方に向けて、導入する際に肝となるポイントをまとめてみました。
これらのポイントをおさえておくだけで、多くの時間を費やす事や余計なトラブルを回避できると思います。
Windows 365 の登場により、ますます活性化するクラウド VDI 市場に乗り遅れることなかれ!
【Microsoft Japan Digital Daysについて】
Microsoft Japan Digital Days は、お客様が競争力を高め、市場の変化に迅速に対応し、より多くのことを達成することを目的とした、日本マイクロソフトがお届けする最大級のデジタル イベントです。4 日間にわたる本イベントでは、一人一人の生産性や想像力を高め、クラウド時代の組織をデザインするモダンワークの最新事例や、変化の波をうまく乗り切り、企業の持続的な発展に必要なビジネスレジリエンス経営を支えるテクノロジの最新機能および、企業の競争優位性に欠かせないクラウド戦略のビジョンなどデジタル時代に必要な情報をお届けいたしました。(2021年10月11日~14日開催)
一歩先行く Azure Computing シリーズ(全3回) 第2回 Azure VM どれを選ぶの? Azure VM 集中講座Minoru Naito
近年 Azure VM のラインナップが急速に拡大し、どれを選ぶのかわからなくなっている方もおられるのではないでしょうか。
こちらでは、Azure VM のラインナップ一つ一つを解説し、どのような用途でどのような VM を選べばよいかを解説します。
本資料は、以下のウェビナーの資料となります。こちらのウェビナーで動画も閲覧できますので、よろしければこちらもぜひどうぞ!
https://info.microsoft.com/JA-AzureINFRA-WBNR-FY19-11Nov-20-AzureVMIntensiveCourse-MCW0009132_02OnDemandRegistration-ForminBody.html
日本マイクロソフト株式会社
カスタマーサクセス事業本部 エンタープライズアーキテクト統括本部 クラウドアーキテクト技術本部 クラウドソリューションアーキテクト
牛上 貴司
AVD の導入を検討している方、または、構築に携わる方に向けて、導入する際に肝となるポイントをまとめてみました。
これらのポイントをおさえておくだけで、多くの時間を費やす事や余計なトラブルを回避できると思います。
Windows 365 の登場により、ますます活性化するクラウド VDI 市場に乗り遅れることなかれ!
【Microsoft Japan Digital Daysについて】
Microsoft Japan Digital Days は、お客様が競争力を高め、市場の変化に迅速に対応し、より多くのことを達成することを目的とした、日本マイクロソフトがお届けする最大級のデジタル イベントです。4 日間にわたる本イベントでは、一人一人の生産性や想像力を高め、クラウド時代の組織をデザインするモダンワークの最新事例や、変化の波をうまく乗り切り、企業の持続的な発展に必要なビジネスレジリエンス経営を支えるテクノロジの最新機能および、企業の競争優位性に欠かせないクラウド戦略のビジョンなどデジタル時代に必要な情報をお届けいたしました。(2021年10月11日~14日開催)
Power Apps は初期状態から多種多様な SaaS サービスの API を利用するためのコネクタが用意されています。裏返せば API が提供されていない、あるいはコネクタが提供されていないサービスの利用ができません。せっかく購入した Power Apps を使い倒すために、カスタム API & コネクタが利用する方法の基礎的な部分をまとめてみました。
9. Web アプリで Azure AD 認証を構成するには
Web アプリケーション
適切なトークンを持つリクエストに応じたアクセス制御を行う
適切なトークン情報を持たない場合 Azure AD の認可エンドポイントへ誘導する
その際に必要とするアプリケーション情報を指定する
トークンを返却してもらうための URI を指定する
Azure Active Directory
アクセスしているユーザーの正当性を確認する
登録されたアプリに対してユーザーの同意を取得する
トークンを発行してアプリケーションに返却する
9
10. Azure Web App ユーザー認証の動作イメージ
Web App は Azure AD を信頼し、認証を委託する ”クライ
アント”アプリケーション
ユーザーは AAD で認証を受け、 Web App が自身の情報にアクセスすることに同意する
Web App は指定のディレクトリで発行された認可コードを持つリクエストを処理する
10
ApplicationEasy
Auth
18. Azure AD 認証の有効化
SQL Database の Active Directory 管理者を指定する
名前がややこしいが、 AD を管理する人ではなく、 SQL DB にアクセスする AAD ユー
ザーやアプリケーションを管理する人
18
19. SQL DB の AD 管理者によるアクセス
AD 管理者は自身の AAD 認証情報を使用して SQL
Database にアクセスできる
SQL Server Management Studio や Azure Data Studio など、 Azure AD 認証に
対応したクライアントツールを使用
19
20. AAD ユーザーの登録
AD 管理者は他のユーザーを SQL DB にユーザー登録、
データベースロールを割り当てることができる
この操作は SQL 認証で接続した管理者では実行できない
アクセスさせたいユーザーが多数の場合は AAD グループで登録すると良い
20
-- AAD ユーザーの登録
CREATE USER [sqluser1@tenantname.onmicrosoft.com] FROM EXTERNAL PROVIDER;
ALTER ROLE db_reader ADD MEMBER [sqluser1@tenantname.onmicrosoft.com];
-- AAD グループの登録
CREATE USER [sqlusers-group] FROM EXTERNAL PROVIDER;
ALTER ROLE db_owner ADD MEMBER [sqlusers-group];
T-SQL
21. AAD ユーザーによるアクセス
SQL DB に登録された AAD ユーザーは AD 管理者と同
様に自身の AAD 認証情報を使用してアクセスできる
複数のユーザーが 1 つの ID/Password を使い回すことなく、日常的に使用している認証
情報を使用してアクセスすることができる(多要素認証にも対応可能)
21
24. AAD アプリによるアクセス
ユーザーが介在しない場合は AAD にアプリケーションを登
録して SQL DB にアクセスする
常駐型デーモンアプリ、バッチアプリ、 Web アプリなど
接続文字列に埋め込まれた情報ではなく AAD 発行のアクセストークンを使用する
24
25. AAD アプリによるアクセス
アクセストークンを取得する方法は以下の4パターン
① 新規に作成したサービスプリンシパルのキー(または証明書)を使用する
② AAD 認証設定時に生成されたサービスプリンシパルのキーを使用する
③ システム割り当てマネージド ID を使用する
④ ユーザー割り当てマネージド ID を使用する
トークンを取得すれば SqlConnection の作成は同じ
25
using Microsoft.Data.SqlClient;
private static SqlConnection GetAadAppTokenConnection()
{
var token = GetAccessToken(); // トークンの取得方法によって実装を変える
var constr = @"Server=tcp:sqlsvrName.database.windows.net,1433;Initial Catalog=dbName;";
var connection = new SqlConnection(constr);
connection.AccessToken = token;
return connection;
}
C#
実際には環境変数等の
外部に切り出すこと
26. AAD アプリによるアクセス
前述の ①〜④ で作成されるサービスプリンシパルに対して
SQL Database に対するアクセス権を付与する
A) データベースユーザーおよびロールに登録する
B) すでにデータベースユーザーおよびロールに登録された AAD グループに追加する
26
-- A) DB 管理者による AAD アプリの登録
CREATE USER [sqlapp_sp] FROM EXTERNAL PROVIDER;
ALTER ROLE db_reader ADD MEMBER [sqlapp_sp];
T-SQL
27. ① 新規サービスプリンシパルによるアクセス
Azure AD にアプリケーション登録権限を持った管理者が下
記の情報を準備
アプリケーション名
アプリケーション ID
ディレクトリ ID
クライアント シークレット
上記の情報をもとに、前述のように
A) SQL DB のユーザーを作成するか
B) AAD グループに追加しておく
27
https://docs.microsoft.com/ja-jp/azure/active-directory/develop/howto-create-service-principal-portal
28. ① 新規サービスプリンシパルによるアクセス
アプリケーションはキーや証明書を使用して SQL Database
に対するアクセストークンを取得することができる
Azure AD にアクセス可能な環境であれば、必ずしも Azure 上で動作させる必要はなく、
オンプレミスや他社クラウドでも良い
28
using Microsoft.Identity.Client;
private static string GetAccessTokenWithServicePrincipal()
{
var directoryid = "guid-of-your-azuread-directory-id";
var applicatonid = "guid-of-your-application-id";
var clientkey = "key-secret-generated";
var scopes = new[] { "https://database.windows.net/.default" };
var app = ConfidentialClientApplicationBuilder
.Create(applicationid)
.WithAuthority(new Uri($"https://login.microsoftonline.com/{directoryid}"))
.WithClientSecret(clientkey)
.Build();
var authresult = app.AcquireTokenForClient(scopes).ExecuteAsync().Result;
return authresult.AccessToken;
}
C#
https://www.nuget.org/packages/Microsoft.Identity.Client/
実際には環境変数等の外部に切り出すこと
Azure Web App なら構成情報に記載
29. ② 認証設定のサービスプリンシパルを流用
AAD 認証を設定した Web App は既にAzure AD にアプリ
登録されている
29
Web App と同名のアプリケーションが
登録されているのでこの名前で
A) SQL DB のユーザーを作成するか
B) AAD グループに追加しておく
30. ② 認証設定のサービスプリンシパルを流用
Web App の認証設定画面の情報は環境変数から取得でき
るように設定されている
ASP.NET Core アプリケーションであれば Environment.GetEnvironmantVariable()
や Configuration で取得できる
30
using Microsoft.Identity.Client;
private static string GetAccessTokenFromAppServiceEasyAuth ()
{
var clientid = _config["WEBSITE_AUTH_CLIENT_ID"];
var secret = _config["WEBSITE_AUTH_CLIENT_SECRET"];
var guidpattern = @"([A-Fa-f0-9]{8})¥-([A-Fa-f0-9]{4})¥-([A-Fa-f0-9]{4})¥-([A-Fa-f0-9]{4})¥-([A-Fa-f0-9]{12})";
var tenantid = Regex.Match(_config["WEBSITE_AUTH_OPENID_ISSUER"], guidpattern).Groups[0].Value;
var authority = new Uri($"https://login.microsoftonline.com/{tenantid}");
var scopes = new[] { "https://database.windows.net/.default" };
var app = ConfidentialClientApplicationBuilder
.Create(clientid).WithAuthority(authority).WithClientSecret(secret).Build();
var builder = app.AcquireTokenForClient(scopes);
var authResult = await builder.ExecuteAsync();
return authResult.AccessToken;
}
C#
32. ③ システム割当マネージ ID を使用したアクセス
Web App にマネージド ID を割り当てておくと、そこで動作
するアプリがトークンを取得するエンドポイントが用意される
この場合も Web App と同じ名前のサービスプリンシパルが AAD に作成される
32
https://docs.microsoft.com/ja-jp/azure/app-service/overview-managed-identity?tabs=dotnet
Web App と同名のアプリケーションが
登録されているのでこの名前で
A) SQL DB のユーザーを作成するか
B) AAD グループに追加しておく
33. ③ システム割当マネージ ID を使用したアクセス
Web App にデプロイされたアプリは実行環境からマネージ
ド ID を使用してアクセストークンを取得することができる
アクセストークンの取得は Azure AD のトークンエンドポイントではなく、Web App 環境内に
用意されるエンドポイントを使用する
ASP.NET Core の場合は System.Net.Http や Json.NET などを使用する
33
using System.Net.Http;
using Newtonsoft.Json.Linq;
private static async Task<string> GetAccessTokenFromSystemAssignedManagedId()
{
var resourceuri = "https%3A%2F%2Fdatabase.windows.net%2F";
var msiurl = string.Format("{0}?resource={1}&api-version=2017-09-01", _config["MSI_ENDPOINT"], resourceuri);
string token = null;
using (var hc = new HttpClient())
{
hc.DefaultRequestHeaders.Add("Secret", _config["MSI_SECRET"]);
var ret = await hc.GetStringAsync(msiurl);
token = JObject.Parse(ret)["access_token"].ToString();
}
return token;
}
C#
マネージ ID 用のトークンエンドポイント URL が設定され
ている環境変数を使用して下記 URL を組み立てている
http://127.0.0.1:41631/MSI/token/
?resource=http://database.windows.net
&api-version=2017-09-01
34. ③ システム割当マネージ ID を使用したアクセス
マネージド ID を使用してアクセストークンを取得する専用の
ライブラリが提供されている場合はそちらを使うと良い
ASP.NET Core の場合は Microsoft.Azure.Services.AppAuthentication が利用で
きる
34
using Microsoft.Azure.Services.AppAuthentication;
private static async Task<string> GetAccessTokenFromSystemAssignedManagedId()
{
var provider = new AzureServiceTokenProvider();
var token = await provider.GetAccessTokenAsync("https://database.windows.net/");
return token;
}
C#
アクセストークンを取得した
い対象リソースの URI だけ
指定すれば良い
35. ④ ユーザ割当マネージ ID を利用したアクセス
ユーザー割り当てマネージ ID は柔軟な構成が可能
1つのマネージ ID を複数の WebApp や VM に割り当てて共用する
1つの Web App に対して複数のマネージ ID を割り当てアクセス先に応じて使い分けるこ
とができる
35
対象となる Web App に割り当てる
マネージ ID と同名のサービスプリンシ
パルが登録されているのでこの名前で
A) SQL DB のユーザーを作成するか
B) AAD グループに追加しておく
36. ④ ユーザ割当マネージ ID を利用したアクセス
アクセストークンの取得クライアント ID を指定する以外システ
ム割当の場合とほぼ同じ
36
using System.Net.Http;
using Newtonsoft.Json.Linq;
private static async Task<string> GetAccessTokenFromSystemAssignedManagedId()
{
string token = null;
using (var hc = new HttpClient())
{
var resourceuri = "https%3A%2F%2Fdatabase.windows.net%2F";
var msiurl = string.Format("{0}?resource={1}&api-version=2017-09-01&clientid={2}"
, _config["MSI_ENDPOINT"], resourceuri, "guid-of-clientid-for-uamid");
hc.DefaultRequestHeaders.Add("Secret", _config["MSI_SECRET"]);
var ret = await hc.GetStringAsync(msiurl);
token = JObject.Parse(ret)["access_token"].ToString();
}
return token;
}
C#
37. Tips : AAD ユーザーの確認
SQL Database に登録した AAD ユーザーやグループおよ
びデータベースロールは下記のように確認できる
37
SELECT
DP1.name AS DatabaseRoleName,
isnull (DP2.name, 'No members') AS DatabaseUserName ,
DP2.type_desc as PrincipalType,
DP2.sid
FROM sys.database_role_members AS DRM
RIGHT OUTER JOIN sys.database_principals AS DP1
ON DRM.role_principal_id = DP1.principal_id
LEFT OUTER JOIN sys.database_principals AS DP2
ON DRM.member_principal_id = DP2.principal_id
WHERE DP1.type = 'R'
ORDER BY DP1.name;
T-SQL
38. Tips:現在の SQL セッションのユーザー
SQL Database に接続できたら現在どのユーザーで接続
しているのかを確認してみると良い
38
using Microsoft.Data.SqlClient;
private static async Task OnGet()
{
var connection = GetAadAppTokenConnection();
try
{
await connection.OpenAsync();
using ( var cmd = connection.CreateCommand() )
{
cmd.CommandText = "select suser_name()";
var dbuser = cmd.ExecuteScalar().ToString();
}
}
finally
{
connection.Close();
}
}
C#
39. Tips : アプリ名の重複
Web App の以下の操作で ”同名のサービスプリンシパル”
が作成され、SQL DB への登録時に区別がつかない
AAD ユーザー認証を構成する
システム割当マネージ ID を有効にする
39
ユーザー認証(簡易モード)で作成された
サービスプリンシパル
マネージ ID で作成されたサービスプリンシパル
-- A) DB 管理者による AAD アプリの登録
CREATE USER [ainaba-aadauth-web]
FROM EXTERNAL PROVIDER;
T-SQL
41. Tips : アプリ名の重複
SQL DB への登録時に SID を使用してアプリケーションを
明示的に指定することができる
41
## アプリケーション ID から SID を生成
PS> $b = [Guid]::Parse("eb49934f-…").ToByteArray()
PS> "0x" + (($b | % {$_.ToString("X2")}) –join "")
0x4F9349EB85BD…
PowerShell
-- sid を指定することで AAD アプリとは別名をつける
CREATE USER [ainaba-aadauth-web-mi2]
with sid = 0x4F9349EB85BD…, type = E;
-- 別名のユーザーをデータベースロールに追加
ALTER ROLE db_owner ADD MEMBER [ainaba-aadauth-web-mi2];
T-SQL
42. 補足: VM でアプリが動作する場合
アプリが Azure VM 上で動作する場合も同様の実装が可能
だがいくつか差異が発生する
AAD ユーザー認証を自動構成してくれる簡易機能は提供されない
> 対応する Web アプリの認証するライブラリを利用して自力で実装する
サービスプリンシパルのキー情報などは環境変数に自動設定されない
> 自力で環境変数に設定するか、構成設定ファイルやレジストリで管理する
マネージ ID によるトークンエンドポイントが異なる
> URL が異なる程度だがコードの流用時に注意
システム割当マネージ ID は VM インスタンスごとに異なるオブジェクトになる
> ユーザー割当マネージ ID や AAD グループによる管理を検討する
詳細は下記の Blog などを参照
https://ayuina.github.io/ainaba-csa-blog/sqldb-aad-authentication/
42
45. Web App によるアクセストークンの自動取得
ユーザー認証が有効になっている Web App であれば、
SQL DB のアクセストークンも取得を任せることができる
Web App の認証時に SQL DB へのアクセストークンも発行するように構成
Microsoft.Web/sites/appName/config/authsettings/properties/additionalLoginParams
45
// ポータルでは設定できないので Resource Explorer 等で
// 認証設定のオプションを指定
additionalLoginParams : [
"response_type=code id_token",
"resource=https://database.windows.net"
]
ARM
48. アプリ側でアクセストークンを取得する
こちらの手法であれば任意のタイミングに任意のリソースに対
してアクセストークンを取得できる
48
private static async Task<string> GetAccessTokenAsUser()
{
var clientid = _config["WEBSITE_AUTH_CLIENT_ID"];
var secret = _config["WEBSITE_AUTH_CLIENT_SECRET"];
var guidpattern = @"([A-Fa-f0-9]{8})¥-([A-Fa-f0-9]{4})¥-([A-Fa-f0-9]{4})¥-([A-Fa-f0-9]{4})¥-([A-Fa-f0-9]{12})";
var tenantid = Regex.Match(_config["WEBSITE_AUTH_OPENID_ISSUER"], guidpattern).Groups[0].Value;
var authority = new Uri($"https://login.microsoftonline.com/{tenantid}");
var scopes = new[] { "https://database.windows.net/.default" };
var app = ConfidentialClientApplicationBuilder
.Create(clientid).WithAuthority(authority).WithClientSecret(secret).Build() as IByRefreshToken;
var authcode = Request.Headers["X-MS-TOKEN-AAD-REFRESH-TOKEN"][0];
var builder = app.AcquireTokenByRefreshToken(scopes, authcode);
var result = await builder.ExecuteAsync();
return result.AccessToken;
}
ARM
49. 補足:HTTP ヘッダー情報の一覧
一度 Web App で動作するアプリが受け取るリクエストヘッ
ダーを確認するアプリを作ってデプロイしてみると早い
Web App にアクセスしているユーザー情報は
X-MS-CLIENT-PRINCIPAL-XXXX で
AAD から渡されるトークン関係の情報は
X-MS-TOKEN-AAD-XXXX で取得できる
49
<div>
<h2>HTTP リクエストヘッダー</h2>
<table class="table">
<thead>
<tr> <th>Key</th> <th>Value</th> </tr>
</thead>
<tbody>
@foreach (string key in string key in Request.Headers.Keys.OfType<string>())
{
<tr>
<td><span>@key</span></td>
<td><span>@(Request.Headers[key])</span></td>
</tr>
}
</tbody>
</table>
</div>
ASP.NET Core