みち草

Azure中心にまとめる技術情報ブログ

Azure Functions で NSG を疑似的に FQDN に対応させる

はじめに

Azure IaaS を使う際にまず間違いなく使用する、 L4 ACL の NSG について、送信元や宛先 IP アドレスを指定できるものの、現状は FQDN を指定することができません。

  • 送信元または宛先 IP が変動するため FQDN で指定したい
  • NSG で FQDN が使えないから Any 宛て、だと許可範囲が広すぎる
  • FQDN のためだけに FW を入れるなどコストがかかるようなことはしたくない

そんな時に使える解決策として、 Azure Functions を用いた NSG ルール更新を実装したのでまとめます。

目次

構成

今回のポイントはタイトルのとおり、Azure Functions です。

Azure Functions で指定 FQDN の名前解決を行い、解決結果の IP アドレスを取得、それを NSG ルールの送信元または宛先 IP アドレスとして、ルールを更新します。

これをタイマー トリガー関数として定期実行させることで NSG ルールを定期的に更新し、FQDN 解決結果の変化にも対応することで、NSG を疑似的に FQDN に対応させます。

図にすると、以下のようなイメージです。 (送信ルールの場合)

Azure Functions はサーバーレス ソリューションであるため VM のデプロイや管理は不要です。

また、従量課金プランであれば実行時間 (正確には、メモリ使用量と時間) により課金され、ある程度の無料枠も提供されています。 docs.microsoft.com

今回のように 1, 2 分で完了するような処理であれば、実行頻度やリソース使用量にもよりますが、VM と比較して安価に使用することができるため、Functions の活躍できるパターンでしょう。

では実際の作り方

環境構築

NSG

まずは、更新対象の NSG と NSG ルールをデプロイしておきます。
ここでは例として、以下のような送信ルールを作成しています。

宛先 IP アドレスは後に Functions に書き換えられるので、何でもいいです。

Functions

Functions のデプロイ
試したときは PowerShell Core 7.2 がプレビューだったので、 7.0 で動作確認してます。
現在は 7.2 も GA

マネージド ID

Azure Functions から NSG ルールを操作するため、Functions のマネージド ID を有効化して、RBAC での権限を付与

ここでは前述の NSG リソースをスコープに、 "ネットワーク共同作成者" ロールを付与

アプリケーション設定

"構成" から、スクリプト中で必要な環境変数を設定

今回はパラメータをすべて環境変数として、スクリプトを編集せずに使いまわせるようにしています
追加する変数と値の例は以下

名前
NSG_NAME 対象ルールを持つ NSG 名 FQDN-NSG
NSG_RESOURCEGROUP NSG のリソース グループ名 FQDN-NSG-RG
NSG_RULE_ACCESS NSG ルールのアクション Allow
NSG_RULE_DEST_PORTRANGE NSG ルールの宛先ポート範囲 587
NSG_RULE_DIRECTION NSG ルールの通信の方向 Outbound
NSG_RULE_NAME NSG ルール名 Outbound-to-FQDN
NSG_RULE_PRIORITY ルールの優先度 100
NSG_RULE_PROTOCOL 通信のプロトコル *
NSG_RULE_SOURCE_ADDRESSPREFIX NSG ルールの発信元アドレス範囲 *
NSG_RULE_SOURCE_PORTRANGE NSG ルールの発信元ポート範囲 *
TARGET_FQDN 宛先として許可したい FQDN smtp.sendgrid.net

インストールするパッケージの指定

docs.microsoft.com

上記の Docs にも記載がありますが、Functions の初回実行時、requirements.psd1 を参照して、スクリプト中で必要なモジュールが PowerShell ギャラリー から自動的にダウンロードされます。
正確には "host.json の managedDependency が true であれば" ですが、作成時にデフォルトで有効 (true) です。

デフォルトだと以下のようになっています

requirements.psd1 の 7 行目の # (コメント) を外せば実行時に Az モジュールが必要であれば 8.x バージョンを自動でインストールしてくれるんですが、ここで 1 つ注意です。

PowerShell ギャラリーで Az モジュールを検索し、最新 8.1 の Package Details を見ると、Dependencies に大量の Az.xxx パッケージが記載されています。

デフォルトの設定だとこれらがすべてインストールされるため、Azure Functions の連続実行時間上限に引っ掛かる可能性があります。
というか、従量課金プランのデフォルト 5 分だと引っ掛かります。

対処としては以下の 2 つですが、無駄なパッケージをインストールする意味もないので、必要なものを指定するのがよいでしょう。

  1. タイムアウトを延ばす (上限あり)
  2. インストールするパッケージを指定する

タイムアウトとその変更方法については以下を参照

docs.microsoft.com

特定のパッケージを指定する場合は以下のように記述します。
今回は、(記述不要なためコード中には登場しませんが) マネージド ID でのログインに Az.Accounts が、 NSG ルールの変更に Az.Network が必要なのでその 2 つを記載

Az モジュール自体のバージョンと、その中のパッケージのバージョンは異なる、という点にも注意です。

www.powershellgallery.com

www.powershellgallery.com

関数の作成

最後に、タイマートリガーで定期実行する関数を作成します。

時間指定の方法は NCRONTAB 式というもので、6 種類のフィールドがそれぞれ秒や時間、月に対応しているものです。
ここでは "0 0 0 * * *" 、つまり毎日午前 0 時 (UTC) に設定

NCRONTAB の指定サンプルやタイムゾーンの変え方は Docs を参照

docs.microsoft.com

コードは以下の GitHub にあるので貼り付けます。

github.com

コードについて簡単に補足すると、

  • 2 行目の param は、関数自体は引数を受ける作りではないけど消すと怒られるので残すことに
  • 5 行目は、.NET のライブラリを用いた FQDN の名前解決
    PowerShell の Resolve-DnsName だと余計な出力がついてきて加工が面倒だったのでこちらを採用
  • 8 行目以降は NSG ルールのアップデート処理

これで準備は OK

動作テスト

動作テストはコード画面の上部の "テストと実行" から

Application Insights と連携していない場合は、"Filesystem ログ" に変更しないとログが見えない

"接続されました" になったら "実行"

正しくできれいれば、初回実行時のみパッケージのインストールが始まる
※パッケージインストール後、パラメータミスでエラーが出て修正、再実行したため、次の画像と繋がってません

"Executed" まで表示されれば、実行は終了
エラーがなければ、NSG ルールの宛先 IP アドレスが更新されているはず。

名前解決の結果と一致しているか、nsookup などで確認してみてください。

これで、FQDN の名前解決をし、解決結果を用いて NSG ルールを更新する関数を定期実行させることができました。

関数実行の合間に IP アドレス (名前解決の結果) が変わってしまう可能性はあるため完全に対応できるものではありませんが、 Functions の実行頻度を上げることである程度対応できるはず。
疑似的に FQDN 対応させる、という点ではあまりコストもかからず、十分かと思います。

終わりに

名前解決部分やそもそもの構想など、かなりアドバイスをいただきながら作成した初 Functions でしたが、触ってみてかなり便利だと思いました。
モジュールのインストールも Automation より簡単だし、言語の対応範囲も広いし、基本 Functions でいいかなという印象

コードそんなかけないしなぁ、と思っていたけど PowerShell が使えるならいろいろできそう

今回のは使い方としてなかなか面白かったので、他にも Functions でうまく解決できるようなことがあればいろいろ作りたいなー

Logic Apps で Azure Monitor のアラート メールをカスタマイズする

はじめに

Azure Monitor でアラートを設定すると、予め決められたフォーマットでメールが送られてきます。

補足の文章やアラート内の別の情報を入れたいと思っても、Monitor の機能のみではメールの内容を変更できないため、 Logic Apps と組み合わせることでメールの内容をカスタマイズします。

Azure サポート チームのブログでも紹介されています。

アラート通知メールのカスタマイズについて | Japan Azure Monitoring Support Blog

本記事ではメールのカスタマイズとしてまとめていますが、ほぼ同じやり方でアクションを変えれば、アラートが発砲された際に Teams などに通知することも可能です。

目次

Logic Apps 作成

仮作成

まずは Logic Apps のデプロイ。アラート メールを送るだけなのでコンサンプション プランでちゃちゃっと作成。

"ロジック アプリ デザイナー" から "HTTP 要求の受信時" を選択

"サンプルペイロードを使用してスキーマを生成する" から、カスタマイズしたいアラートの種類に合わせたペイロードのサンプルを貼り付けます。

アラートの種類に応じて連携されるデータ構造が異なるため、Activity Log アラートのカスタマイズだったら "管理" 、 Advisor アラートだったら "推奨"、サービス正常性なら "Service Health" のスキーマと、自分がカスタマイズしたいものに合わせて貼ります。

スキーマは以下の Docs からコピペでもいいのですが、ここでは別の方法を紹介します。

アクティビティ ログ アラートで使用される webhook スキーマについて理解する - Azure Monitor | Microsoft Docs

ということで、ここでは何も貼り付けずに"保存" を選択します。

アクショングループの作成、テスト

一旦 Logics Apps の作成をやめ、アラート発生時に Logic Apps を呼び出すアクション グループを作成します。

"モニター" - "アラート" の "アクション グループ" から、"作成" を選択します。

名前を付け、"アクション" タブに進みます。

"アクションの種類" でロジック アプリを選択します。

右側に別のブレードが出てくるので、先ほど作成した Logic Apps を選択し OK

"確認と作成" を選択すると、"テスト アクション グループ (プレビュー)" ボタンが表示されるため選択します。

これはプレビュー機能ですが、実際のアラートと同じペイロードを送信し、アクション グループのテストを実施できます。
カスタマイズしたいアラートの種類に応じてサンプルを選択し、テストを実行します。

この記事では、"アクティビティ ログ アラート" を選択します。

テストが成功したら "作成" を選択して、中断していたアクション グループの作成を完了させます。

本作成

Logic Apps 作成の続きを行います。

Logic Apps を見ると、先ほどのテスト実行の履歴があるため選択。

この履歴の、"HTTP 要求の受信時" を選択すると、"出力" 本文に値が入っています。
これをコピーして、一番最初の "サンプルペイロードを使用してスキーマを生成する" に貼り付けることでスキーマを指定します。

最初に挙げたように Docs でスキーマを探してコピペでもできるのですが、SubscriptionId がなかったりするので何が正解かイマイチわからず、 多少の手間はありますが "アクション グループのテスト" を用いたこの方法が確実かと思います。

コピーしたら "ロジック アプリ デザイナー" に戻り、サンプルとして貼り付けましょう。

続いてはメールのカスタマイズ部分
"新しいステップ" から、"メールの送信(v2)" を選択します。

注意点として、このアクションは Microsoft 365 と連系してメールを送信するため、M365 が使用できるアカウントでの認証が必要です。
ここで認証したアカウントを送信元としてアラート メールが送信されるため、自分からアラートメールが飛んだように見えるのが嫌な場合、アラート用のアカウント作成などが必要です。

メールの宛先、件名、本文を設定していきます。
本文中では、アラートとして送信された値を参照することができます。
ペイロードの値をそのまま参照したいのであれば "動的なコンテンツ" に対象の名前を入力してクリックするだけなので簡単です。

例として Subscription ID を参照するとこんな感じ
動的コンテンツで subscriptionid を検索して選択

本文に緑色の値が挿入されれば OK

完成版はこんな感じ

リソース名だけは動的なコンテンツとして参照できないので、"式" の方に関数を入れてアラート内の情報から取り出してくる必要があります。
ここではこんな式にしてます。

split(triggerBody()?['data']?['context']?['ActivityLog']?['resourceId'],'/')[8]

リソース ID は以下の形式なので、"/" で split してリソース名の部分を取り出してます。

/subscriptions/サブスクリプションID/resourceGroups/リソースグループ名/providers/Microsoft.Compute/virtualMachines/リソース名

関数の参考 Docs はこちら 式関数のリファレンス ガイド - Azure Logic Apps | Microsoft Docs

これで Logic Apps は完成なので保存。

アラート設定

最後は、Logic Apps を起動するアラートを設定すれば完成です。

モニターのアラート作成から、サブスクリプション対象のアラートを作成

Activity Log アラートのスキーマを使用しているので、条件は Create or Update Virtual Network (Microsoft.Network/virtualNetworks) にしてます。

アクション グループは、既に作成しテストに使用したものを選択

作成時にアラート有効化、以外は好きに設定してアラート完成

動作確認

実際に NW を作成して、アラートを発砲させてみます。

適当な VNet を作成します。

実際に届いたアラートメールがこちら

認証に使用した自分のメールアドレスから届いています。

本文中には Logic Apps で指定した内容や値が記載されており、caller には Azure AD のユーザープリンシパル名が表示されています。
split で作成したリソース名も OK です。

このようにして、カスタマイズしたアラート メールを送信することができます。

終わりに

今回はアラート メールのカスタマイズとしましたが、最初にも書いたとおりアクションを変えれば Teams に連携したり、他の処理を行ったりもできるので、Logic Apps を使えばいろいろと自動化ができます。

ここでは Microsoft 365 との連携でメール送信をしていますが、アカウント認証が必要なのが少し面倒かなぁと思います。
実際の運用では個人にするわけにはいかないので専用アカウントを作成することになると思いますが、社内的にその申請やアカウント管理が手間になることは多々あるのかなと。

その点では SendGrid などを使用して、API で連携させる方が楽でよさそう。

診断ログによる Azure Table Storage のエンティティを定期削除する

はじめに

Azure VM イベントログやパフォーマンス カウンターを診断ログとしてストレージ アカウントに保存できますが、Blob ストレージではなくテーブル ストレージに保存されるため、 ライフサイクル管理機能が使えず、古いエンティティが自動的に削除されません。

そこで、Azure Automation の Runbook を用いて定期的に削除するようにしてみました。

一部画像が荒いですが、クリックすれば綺麗に見えます。

目次

対象テーブル

対象は、診断ログにより生成されるこれらのテーブルです。
Linux の Syslog テーブルもありますが、ここでは "WAD" がついたテーブルを対象にします。

削除実行前に、古いものがいつぐらいか確認しておきます。
ストレージ エクスプローラーを使うのが簡単

削除用スクリプト

削除用に作成した、Automation 向け PowerShell スクリプトはこちら
PowerShell/Delete-TableEntity.ps1 at main · kzk839/PowerShell · GitHub

こちらの記事のスクリプトを参考にし、Az モジュール、マネージド ID を使用するようしています。 Table Storageに溜まり続けるWindowsイベントログのクリーニング - Qiita

対象のストレージ アカウント、リソース グループの指定が必須
テーブル名はの指定は任意で、指定する場合はそのテーブルのみ、指定しない場合は "WAD" がついたすべてのテーブルが対象です。

ログの保持日数は、何日以上古いエンティティを削除するかの指定です。
365 を指定した場合は、1 年以上古いエンティティを削除対象とします。

ただ、はじめは指定日数より古いエンティティすべてを対象としていたのですが、自分の環境で試した限りでは、 エンティティ数が多くなると時間がかかり過ぎ、Automation のジョブが制限時間内 (3 時間) に終わらないことがありました。

なので 70 行目にて、最大 5000 件の制限をかけています。
ここは実際に動かしてみて、状況を見て調整してください。

Automation アカウント作成

Automation アカウントを作成する際は、マネージド ID を有効にした状態で作成します。

作成されたマネージド ID に対して、対象ストレージ アカウントの "ストレージ アカウント共同作成者" ロールを付与します。

今回のスクリプトを動かすために AzTable モジュールが必要なため、それを追加します。

Runbook、スケジュール作成

Runbook に先ほどのスクリプトを登録します。

コードを貼り付けた後は、"公開" を選択することを忘れずに。

パラメータはこんな感じで指定

実行結果

あとは時間になる or 手動で実行すれば、こんな感じで各テーブルのエンティティを削除してくれます。
Target : 0 は指定日数を超えるエンティティがない場合です。

実行前に確認したテーブルを再度見ると、綺麗になってます。

終わりに

途中でも記載しましたが、エンティティ量が増えると処理に時間がかかり 3 時間以内に終わらない場合があるため、試してみて数を減らしたり、別のジョブに分けるなど調整してください。
時間がかからずいい感じにできる方法が見つけられなかったので、そこは改善の余地あり。

エンティティ削除スクリプトを作成したものの、現状はイベント ログもパフォーマンス カウンタも Log Analytics に入れてしまう方が多いと思うので、あまり役立つ機会はないかも…
料金は Log Analytics の方が高いけど、最近は Basic Logs とかアーカイブとか出始めたし、Log Analytics なら自動で削除されるし、クエリもできるし、そっちの方が使い勝手はいいと思います。

あとは単純に、エンティティが結構なスピードで増えていくのでこれだと消すのが追い付かなさそう、というのが率直な感想です。

Azure Blob Storage を NFS 3.0 で Linux VM にマウントする

はじめに

タイトルのとおり、Azure Blob Storage にコンテナーを作成して、Linux VM (RHEL) 上から NFS 3.0 でマウントを試したので、備忘的なもの。

目次

環境

構成はシンプルに、VM と同一サブネット上にプライベート エンドポイントで接続可能なストレージ アカウントを置いて、 VM からマウントする感じです。

f:id:kkkzk:20211202234720p:plain

手順は以下の Docs を参考にしてます。

NFS 3.0 プロトコルを使用して Azure Blob Storage をマウントする | Microsoft Docs

Blob ストレージの準備

ストレージ アカウントのデプロイ

Blob Storage デプロイ時の注意点は以下

  1. NFS 3.0 は Data Lake Storage Gen2 の機能であるため、階層型名前空間を有効にする
  2. LRS か ZRS しか選べない

NFS 3.0 は通常の Blob Storage ではなく、Data Lake Storage Gen2 でないと使えないため、以下のオプションを有効にします。

f:id:kkkzk:20211202234706p:plain

また、NFS 3.0 を使う場合の制限として、冗長性は LRS か ZRS しか選べません。
GRS を選んだ状態だと、こんな感じで押せません。

f:id:kkkzk:20211202235408p:plain

その他、機能制限など既知の問題ページで挙げられているため注意。

Azure Blob Storage の NFS 3.0 に関する既知の問題 | Microsoft Docs

コンテナーの作成

RHEL でマウントするための、適当なコンテナーを作成しておきます。
今回は testnfs で作成

f:id:kkkzk:20211203000025p:plain

f:id:kkkzk:20211203000033p:plain

VM からのマウント

パッケージ インストール

以下のコマンドを実行して、NFS 接続に必要なパッケージをインストール

yum install -y nfs-utils

f:id:kkkzk:20211203001536p:plain

名前解決の確認

ストレージ アカウントへプライベート エンドポイントを用いて接続できるか、nslookup で確認

以下はプライベート IP 172.21.0.5 に解決できているので OK

f:id:kkkzk:20211203001722p:plain

マウント

以下のコマンドを実行してマウント用マウントポイントを作成

mkdir -p /mnt/test

以下のコマンドの <storage-account-name> ストレージ アカウント名に、<container-name> をコンテナー名に変更したうえで実行して、 マウントポイントにコンテナーをマウント

mount -o sec=sys,vers=3,nolock,proto=tcp <storage-account-name>.blob.core.windows.net:/<storage-account-name>/<container-name>  /mnt/test

今回の例だと以下のコマンドを実行

mount -o sec=sys,vers=3,nolock,proto=tcp kknfsstorage.blob.core.windows.net:/kknfsstorage/testnfs /mnt/test

f:id:kkkzk:20211203010446p:plain

マウントできたので、いくつかファイルを作成してみる
これで Blob Storage の NFS マウントができました。

f:id:kkkzk:20211203010555p:plain

fstab

fstab はこんな感じで追記して設定できました。

kknfsstorage.blob.core.windows.net:/kknfsstorage/testnfs        /mnt/test       nfs     sec=sys,vers=3,nolock,proto=tcp 0       0

終わりに

NFS でマウントしたり、fstab を書いたりしたことがあまりないので、試してみました。

ストレージの作成時に階層構造かつ LRS or ZRS にする、ということさえわかっていれば、後はそんなに難しいところはないと思います。
(個人的には Linux に慣れてなくて、nfs のパッケージとか fstab の書き方調べるのにちょっと手間取った)

Data Lake Storage は通常のストレージよりもできることが少ない (機能が対応してない) 場合があるので、その点は注意が必要です。

Azure VM のサイズ選択を助ける、VM セレクターが登場

はじめに

今回は小ネタ的に、Azure VM の VM セレクターを紹介。

これは、Azure VM のサイズ選択を手伝ってくれる Web ツールです。

目次

Azure VM セレクター

Azure VM のスペックを選択するのがサイズですが、最近は新しいものもたくさん出てきて、どれがいいのか悩むことは多々あります。

そんなとき、必要な情報を入れていくことでお勧めサイズを教えてくれるのが VM セレクターです。

リンクはこちら

azure.microsoft.com

使ってみる

最初の選択

最初に、以下のどれから始めるかを選択し、"ここから開始" をクリックします。
ちなみにこれ、どれを選んでも最終的に入力が必要なものは同じなので、最初の問いが違うだけです。

  • ワークロードの種類で VM を検索する
  • OS とソフトウェアで VM を検索する
  • デプロイ リージョンで VM を検索する

f:id:kkkzk:20211125224626p:plain

OS とソフトウェア

今回は "OS とソフトウェアで VM を検索する" を選択してみました。
OS とソフトウェアを選ぶ画面になるので、Windows で SQL Server Enterprise を動かす体で選択。

右のほうに、現在選択した値とその結果何台が当てはまるかが表示されています。

f:id:kkkzk:20211125225119p:plain

ワークロードの種類

続いて、VM 上で稼働させるワークロードの種類を選択します。
"+" をクリックすれば例が表示されるので、それを参考に選びます。

ここでは大規模なリレーショナル DB 想定で、"メモリ集中型" にしてみます。 (この選択が実質シリーズの選択なので、ここで何を選ぶかで大体何が出てくるか決まると思います)

f:id:kkkzk:20211125225615p:plain

VM の技術仕様 (要求スペック)

続いては、VM に必要な CPU とメモリの幅を選択します。
また、追加の機能を展開すると、CPU ブランドや GPU の要否、必要なデータ ディスクの本数などを指定する枠があります。

こんな感じでざっくりと指定。

f:id:kkkzk:20211125230357p:plain

ディスク ストレージ (SKU)

次は、必要なディスクのスペック (SKU) を指定します。

今回は DB 想定なので Premium にします。
これで s のついたシリーズしか表示されないはず。

f:id:kkkzk:20211125230543p:plain

ディスク ストレージ (SKU とサイズ)

次もディスク ストレージで、今度はデータディスクの種類とサイズを指定します。

ちょっとわかり辛いのですが、左から Ultra ディスクの枠、Premium SSD の枠、Standard SSD の枠、Standard HDD の枠になってます。
なので、Premium SSD * 3 本付けても左から 2 番目の枠内にまとめられています。
(偶然にもデータ ディスクを 4 と指定していたので 4 枠あるのかと思いましたがそうではない)

図では、Premium SSD * 3、Standard HDD * 1 の計 4 本を選択しています。

f:id:kkkzk:20211125231040p:plain

リージョン

最後に、リージョンを選択して入力は完了です!

f:id:kkkzk:20211125231155p:plain

結果画面

結果はこんな感じで、推奨されたサイズは "E16s v5" でした。
指定した CPU とメモリは当然クリアしてます。

下の方には、似たようなスペックのサイズも表示してくれるようです。

デフォルトで "Azure ハイブリッド特典の価格を表示" が有効なことには注意

f:id:kkkzk:20211125231302p:plain

"詳細の表示" をクリックすると、サイズの詳細や予約の価格を教えてくれます。

f:id:kkkzk:20211125231703p:plain

"選択されたデータ ディスク" 画面はこんな感じ。

f:id:kkkzk:20211125231627p:plain

終わりに

VM のサイズが増え、どう選んだらいいのか、どこから考えればいいのか、みたいに迷うことは増えたと思うので、 どの辺りがいいのか目星をつけることができるのはよいところだと思います。

Web で使えて、お金がかかるものでもないので、気軽に使っていきましょう。

Azure Lighthouse を設定してみる

はじめに

今回は、Azure Lighthouse にて別テナントユーザーへのサブスクリプション権限の委任を設定してみました。 ポータルでテンプレートを作成することができ、思ったよりは楽にできました。

目次

Azure Lighthouse 概要

Azure Lighthouse とは - Azure Lighthouse | Microsoft Docs

ざっくり言えば Azure サブスクリプションやリソース グループの権限を別 AAD のユーザーに与えることができる、という機能であり、 AAD に招待して権限つけるのと同じじゃないの?と思いますが、Lighthouse ならではのメリットがあります。

個人的に Lighthouse のメリットだと感じたのはこの辺

  1. ユーザーだけでなくグループに対して委任を行うことができる
  2. Azure ポータルで委任された環境を管理する際、テナントの切り替えが不要

個人的メリット 1

1 点目について、例として作業を依頼したベンダーに権限を与える場合、作業メンバーを連携するから招待して権限を付与してください、と顧客に依頼し対応してもらう、 担当者の増減があればそれを伝え、また実施してもらう、というパターンが多いと思います。
この場合、依頼してから顧客側の対応を待たないといけなかったり、顧客側も度々変更依頼があると手間だったりということがあります。
※共有ユーザーを作成して招待し、複数人で使いまわすことも可能ではありますが、アクティビティログから誰がどの操作をしたのか確認できず、セキュリティ的にはよろしくないので考慮しない。

f:id:kkkzk:20211112235546p:plain

Lighthouse でグループに対して委任を行うことで、このやり取りが不要になります。

Lighthouse では前述のとおり、AAD ユーザーだけでなく AAD グループに対してもサブスクリプションやリソース グループの権限を委任することができます。
サブスクリプションやリソース グループ権限の委任ですので、AAD グループの管理自体は元々の持ち主 (先の例だと作業ベンダー) が行えます。

つまり、顧客側としては 1 回 だけ Azure Lighthouse の設定を行い、ベンダー側 AAD のグループに対して権限を委任してしまえば、 あとはベンダー側が自分たちで AAD グループのメンバー変更を行うことで、環境の権限を持つユーザーを変更する、ということができます。

f:id:kkkzk:20211112235710p:plain

これにより、管理をする側、される側の双方にとってやりやすい状態が作れるかと思います。

個人的メリット 2

2 点目について、これまでどおり招待した場合どうなるかをおさらいします。

招待されている場合、招待先の AAD およびサブスクリプションの操作を行うためには、Azure ポータルでテナントを切り替える必要があります。

右上の歯車アイコンを選択して

f:id:kkkzk:20211113002134p:plain

設定画面から見ることのできる "現在のディレクトリ"
"切り替え" ボタンで AAD を切り替えることで、そのディレクトリに紐づくサブスクリプションが見えるようになります。

f:id:kkkzk:20211113002818p:plain

別 AAD のサブスクリプションを見るときには切り替えて、ロードが発生して、終わったらまた自分のディレクトリに戻して、ロードが発生して、 というこの操作は結構面倒だと思っています。

これについても、Lighthouse を使うと解決することができます。

"現在のディレクトリ" と同じページの少し上を見てもらうと、"現在のディレクトリ + 委任されたディレクトリ" という部分があると思います。
Lighthouse で委任した場合、ここでチェックボックスにチェックを入れれば、ディレクトリを切り替えずともサブスクリプションの閲覧、リソース作成が可能になります。
リソースを閲覧するためには、 Lighthouse で委任されたディレクトリとサブスクリプションにチェックを入れます。
※kkdev が委任したもの

f:id:kkkzk:20211113004643p:plain

何かしらのリソース一覧にてフィルターを見てもらうと、別ディレクトリのサブスクリプションも選択できるようになっています。

f:id:kkkzk:20211113005543p:plain

リソース作成画面でも、別ディレクトリのサブスクリプションが選択できます。

f:id:kkkzk:20211113005759p:plain

というように、Lighthouse の委任を行うと、ディレクトリを切り替えずとも他のサブスクリプションを操作することができるようになります。
切り替えを繰り返す必要がなくなることで、利便性が上がる部分はあるかと思います。

Azure Lighthouse の構成

ここからは Azure Lighthouse の構成方法について紹介します。

サブスクリプションやリソース グループを委任してもらう側 (前述のベンダー側) と、 サブスクリプションやリソース グループを委任する側 (前述の顧客側) のそれぞれで作業が必要です。
スタートはサブスクリプションを委任してもらう側です。

委任してもらう側の作業

委任してもらう側の作業としては、Azure Lighthouse を有効にしてもらうための ARM テンプレート作成が必要です。
以下は Azure ポータルから作成する流れです。

まずは Azure Lighthouse の画面を開いて、[顧客の管理] を選択

f:id:kkkzk:20211113013034p:plain

[ARM テンプレートを作成] を選択

f:id:kkkzk:20211113013124p:plain

以下の画面では主に、委任するスコープを指定します。

サブスクリプション全体で委任してもらうのか、特定のリソース グループを委任してもらうかの選択です。
リソース グループを選択した場合は、委任してもらうリソース グループの名前を直接入力します。

今回はサブスクリプションのまま [認可の追加] へ

f:id:kkkzk:20211113014043p:plain

認可の追加画面では、誰にどんな権限を与えるか、与える際は永続か一時的か、といったことを指定します。
一時的な場合は、権限が与えられる時間、多要素認証、承認の有無が指定できます。
なお、グループに権限を委任したい場合は、[プリンシパルの種類] でグループを選択しましょう。

f:id:kkkzk:20211113015133p:plain

1 プリンシパル分の登録ができたので、複数のユーザーやグループ、サービス プリンシパルに委任してもらいたい場合は繰り返して追加しましょう。
追加できたら [テンプレートの表示] を選択します。

f:id:kkkzk:20211113020033p:plain

テンプレートが表示されるので、[ダウンロード] を選択して保存します。

f:id:kkkzk:20211113020250p:plain

これで委任してもらう側の作業は完了です。

ダウンロードしたテンプレートを顧客に渡し、以下の手順でテンプレートをデプロイしてもらいましょう。

委任する側の作業

委任する側の作業としては、前の流れで作成された ARM テンプレートを受け取りデプロイすることです。
以下は Azure ポータルからデプロイする流れです。

ポータル上部の検索ボックスに "テンプレート" と入力し、[カスタムテンプレートのデプロイ] を選択します。

f:id:kkkzk:20211114130228p:plain

[エディターで独自のテンプレートを作成する] を選択します。

f:id:kkkzk:20211114131045p:plain

[ファイルの読み込み] から先ほどの ARM テンプレートを読み込み、下部の [保存] を選択します。

f:id:kkkzk:20211114131402p:plain

そうするとパラメータ指定画面になりますが、テンプレートにデフォルト値が組み込まれているため、 委任するサブスクリプションとリージョンだけ指定して下部の [確認と作成] を選択します。
次のページで [作成] を選択します。

f:id:kkkzk:20211114131919p:plain

デプロイが完了後に反映されるまで少し時間はありますが、委任する側の作業は完了です。

f:id:kkkzk:20211114133331p:plain

委任後の管理

Azure Lighthouse の構成後、それぞれの画面ではどのように見えるかの紹介です。

委任してもらう側

委任してもらう側 (ベンダー側) は、[顧客の管理] から確認します。

f:id:kkkzk:20211114133900p:plain

[顧客] や [委任] の画面から、どこの AAD のどのサブスクリプションやリソース グループが、どう委任されているかを確認することができます。

f:id:kkkzk:20211114134609p:plain

f:id:kkkzk:20211114134719p:plain

[ロールの割り当て] に表示されている青文字を選択すると、詳細を見ることができます。

f:id:kkkzk:20211114135147p:plain

f:id:kkkzk:20211114135227p:plain

委任してもらう側でできることは特にないです。

委任する側

委任してもらう側 (顧客側) は、[サービス プロバイダー プランの表示] から確認します。

f:id:kkkzk:20211114135559p:plain

[サービス プロバイダーのオファー] や [委任] の画面から、先ほどと同様にどこの AAD のどのサブスクリプションやリソース グループが、どう委任されているかを確認することができます。
[ロールの割り当て] 下の青文字から見られる詳細情報も同じのためここでは省略します。

f:id:kkkzk:20211114140114p:plain

f:id:kkkzk:20211114140351p:plain

委任する側は、ここ以下の 2 つの操作を行うことが可能です。

  1. 委任するサブスクリプション、リソース グループの追加
  2. 委任の削除
委任の追加

[サービス プロバイダーのオファー] の右端の方に + ボタンがあり、ここから委任を追加することができます。

f:id:kkkzk:20211114140944p:plain

最初に委任した範囲から追加したいものが出てきた場合には活用しましょう。

f:id:kkkzk:20211114141107p:plain

チェックボックスを使って委任を追加すると、こんな感じで見えるようになります。

f:id:kkkzk:20211114141246p:plain

委任の削除

[サービス プロバイダーのオファー] や [委任] 画面の右端の方にゴミ箱ボタンがあり、ここから委任を削除することができます。

f:id:kkkzk:20211114141552p:plain

違いとしては、[委任] 画面ではサブスクリプションやリソース グループ単位での委任削除ができ、[サービス プロバイダーのオファー] 画面では委任丸ごとの削除ができます。

細かくコントロールしたいときは [委任] 画面から、完全に委任を削除したい場合には [サービス プロバイダーのオファー] 画面から、という使い分けです。

ちなみに、削除前には確認のポップアップが表示されます。

f:id:kkkzk:20211114142019p:plain

終わりに

今回は Azure Lighthouse での委任について紹介しました。
構築ベンダーと顧客の例で紹介しましたが、Lighthouse で委任してもらって、そこに対する監視やサポートなどのマネージドサービス的な使いかともできると思います。

また、AAD 招待の場合は条件付きアクセスでの MFA 強制や認証元 IP の制御が適用でき、Azure Lighthouse で全部 OK というものでもないと思いので、選択肢の 1 つとして抑えていただくのがいいかと思います。

コピペで使える Azure Resource Graph サンプル クエリ

はじめに

今回は、Azure のリソース検索に便利な Resource Graph のクエリについてです。
Resource Graph は特定のリソースを検出するうえで非常に便利ですが、 KQL を扱う必要があり、最初のうちはとっつきにくいところがあります。

ということで、コピペでそのまま使えるものをいくつかサンプルとして挙げてみます。
数も少なく IaaS 系ばかりですが、そのまま使用する、ちょっと手を加える、書き方を知るなど、何かしらの参考になれば幸いです。

目次

KQL リファレンス

関数の説明までは載せていないので、KQL のリファレンスを貼っておきます。
以下を参照してもらったり、コメント(先頭にダブルスラッシュでコメント化) したり、値を変えたりして。

KQL クイック リファレンス | Microsoft Docs

もしくはこっちを参照すれば大体載っていると思います。
※左の縦メニューの中に型とか演算子とかいろいろ

Kusto 照会言語 (KQL) の概要 - Azure Data Explorer | Microsoft Docs

SQL がわかる方はここを見ると KQL の理解が早いかもしれません。

SQL から Kusto へのクエリの変換 - Azure Data Explorer | Microsoft Docs

Resource Graph クエリ サンプル

OS 種類別の VM 台数

Resources
| where type =~ 'Microsoft.Compute/virtualMachines'
| summarize count() by tostring(properties.storageProfile.osDisk.osType)

実行結果

ResourceGraph1

古いスナップショットの上位 10 個

使われず置いたままのスナップショット検索に。

Resources
| where type =~ "Microsoft.Compute/snapshots"
| project name, resourceGroup,properties.timeCreated
| sort by tostring(properties_timeCreated) asc
| take 10

実行結果

ResourceGraph2

未接続の管理ディスク

使われず置いたままの管理ディスク検索に。

Resources
| where type =~ "Microsoft.Compute/disks"
| where properties.diskState == "Unattached"

実行結果

ResourceGraph3

未接続のパブリック IP アドレス

使われず置いたままのパブリック IP アドレス検索に。

Resources
| where type =~ "Microsoft.Network/publicipaddresses"
| where isnull(properties.ipConfiguration)

実行結果

ResourceGraph4

"Blob パブリック アクセスを許可" 設定が有効のストレージ アカウント

ストレージアカウント側の "パブリック アクセス許可" が有効なだけで、 実際にパブリック公開しているかどうかはコンテナー側の設定によります。

Resources
| where type =~ "Microsoft.Storage/storageaccounts"
| where properties.allowBlobPublicAccess == true

実行結果

ResourceGraph5

各ストレージ アカウントの "安全な転送が必要" と "Blob パブリックアクセスを許可"、"TLS の最小バージョン" の設定値

原因がわかりませんが、稀に設定値が空欄となり表示されないリソースがあります。
※作成時期が古いものだとなるかも?

Resources
| where type =~ "Microsoft.Storage/storageaccounts"
| project name, resourceGroup, properties.supportsHttpsTrafficOnly, properties.allowBlobPublicAccess, properties.minimumTlsVersion

実行結果

ResourceGraph6

Small もしくはインスタンスが 1 台以下の Application Gateway

Small 、もしくはインスタンスが 1 台以下の場合、Application Gateway の SLA 対象外です。

Resources
| where type =~ "Microsoft.Network/applicationgateways"
| where properties.sku.name == "Standard_Small" or properties.sku.capacity <= 1
| project name, properties.sku.name, properties.sku.capacity
| sort by tostring(properties_sku_name), tostring(properties_sku_capacity) asc

実行結果

ResourceGraph7

"高速ネットワーク" が無効なネットワーク インターフェイス

これだと NIC の設定値を見ているだけなので、どの VM かがわかりづらいです。
次に VM テーブルとの join 版を掲載しています。

Resources
| where type =~ "Microsoft.Network/NetworkInterfaces"
| where properties.enableAcceleratedNetworking == "false"
| project name, subscriptionId, properties.enableAcceleratedNetworking

実行結果

ResourceGraph8

各 VM のネットワーク インターフェイス名と "高速ネットワーク" の設定値 (join 版)

VM のテーブルと NIC のテーブルを join することで、どの VM のどの NIC かがわかりやすくなります。 ※複数 NIC の場合は考慮していません。

resources
| where type =~ "Microsoft.Compute/virtualmachines"
| project name, resourceGroup, size=tostring(properties.hardwareProfile.vmSize), subscriptionId, nic=tostring(split(properties.networkProfile.networkInterfaces[0].id, "/")[8])
| join kind = leftouter ( resources| where type =~ "Microsoft.Network/NetworkInterfaces") on $left.nic == $right.name
| project vm=name,subscriptionId, resourceGroup, nic, size, enableAcceleratedNetworking=properties.enableAcceleratedNetworking

実行結果

ResourceGraph9

VM の情報と、使用している Dedicated Host 名

Resources
| where type =~ "Microsoft.Compute/virtualmachines"
| project name, resourceGroup, subscriptionId,  dedicatedHost=split(properties.host.id,"/")[8]

実行結果

Basic ロードバランサー

Resources
| where type =~ "Microsoft.Network/Loadbalancers"
| where sku.name != "Standard"

実行結果

サイズ別 VM 台数を、降順で表示

resources
| where type =~ "Microsoft.Compute/VirtualMachines"
| summarize count() by tostring(properties.hardwareProfile.vmSize)
| sort by count_ desc 

実行結果

バックエンド プールが空の Application Gateway

使われず置いたままの Application Gateway 検索に。

resources
| where type =~ "Microsoft.Network/applicationGateways"
| where properties.backendAddressPools.properties.backendAddresses == ""

実行結果

Notification Id 毎の Azure リソースのメンテナンス情報

maintenanceresources
| extend p = parse_json(properties)
| mvexpand d = p.value
| project  notificationId=properties.value[0].notificationId, id=substring(id, 0, indexof(id, "/providers/Microsoft.Maintenance")), resourceGroup, subscriptionId, status=d.status, detail=d

実行結果
メンテナンス対象リソースがないため取れたら追加

終わりに

あっさりですが、今回はサンプルの紹介でした。
クエリについては習うより慣れろで実際に動かしてみるのが一番かと思いますので、リファレンスを見つつ実際に動かしてみてください。

関数を使いこなせればもっといろいろできて楽しそうなのですが、自分でもまだそこまで扱えておらず join をちょっと試したくらい…
同じような、使ってみたいけどよーわからん、という方の参考になれば嬉しいです。
また、今後新しいクエリを作成できたら、更新していきたいと思います。

2023 年 7 月から Azure 可用性ゾーン間のデータ転送料が発生する

はじめに

今回は Azure 利用料金について新しいことを知ったので小ネタ投稿

内容としては、データ転送について今まで課金がなかったところが課金されるようになる、というものです。

文面から読み取れる範囲で記載しているため、正確な判断は Microsoft 社へ問い合わせください。

料金ページが変更され "2021 年 7 月 1 日から課金開始" となったため修正しました。
料金ページが変更され "2022 年 7 月 1 日から課金開始" となったため修正しました。
料金ページが変更され "2023 年 7 月 1 日から課金開始" となったため修正しました。

目次

変更点

まず現状ですが、Azure のデータ通信については以下のルールがあります。

(1) 外部から Azure に対するデータ転送は無料
 インターネットやオンプレミス環境からAzure に入ってくるデータについては課金されない。
 逆に、Azure からインターネットやオンプレミスへ出ていくデータは課金される。
※VPN や ExpressRoute はそちら側での下記のためここでは記載していませんが、同様に Azure からオンプレミス方向のデータ転送に対して課金が発生します。

Az1

(2) Azure リージョン内でのデータ転送は無料、リージョン間の場合は有料
 例として、東日本リージョン ⇒ 東日本リージョンのデータ転送であれば課金されない。
 東日本リージョン ⇒ 西日本リージョンのデータ転送は課金される。

Az2

(3) Azure から Azure CDN へのデータ転送は無料

これまで、同一リージョンの可用性ゾーン (Az) 間データ転送については (2) のリージョン内データ転送になるため、課金が発生しませんでした。

しかし、2023 年 7 月 1 日より、この同一リージョン内の可用性ゾーン間データ転送について、課金されるようになります。

新たな課金対象

Microsoft の Azure 料金サイト(料金 - 帯域幅 | Microsoft Azure)によると、新たな課金対象および課金対象外は以下です。

▼課金対象

ある可用性ゾーンにデプロイされた VNet リソースから同一 VNET 内の別の可用性ゾーンにある別のリソースへのデータ転送 (イングレスとエグレス両方)

例として、VM (Az : 1 , 東日本) と、VM (Az : 2 , 東日本) があったとすると、2 つの VM 間(= データセンター間)で通信が発生する場合はそのデータ量に対して課金が発生するよ、ということです。

VNet リソースとあるので、VM であればもちろんのこと、Az 対応の Load Balancer, Application Gateway, VNet GW など他のリソースの通信でも適用されるものと思われます。

Az3

一方で、以下の場合は課金対象外です。

▼課金対象外

同一の可用性ゾーン内にある VNet リソース間のデータ転送

例として、VM (Az : 1 , 東日本) と VM (Az : 1 , 東日本) であれば課金対象外です。
これは、同じデータセンター内の通信になるから課金されない、ということになるのかと思います。

Az4

同一の Azure リージョン内にある VNet リソースとパブリック IP アドレス間のデータ転送

VM や Load Balancer, Application Gateway, VNet GW などと、パブリック IP アドレスが同一リージョンに存在していれば課金対象外のようです。

これだと、VM (Az 1, 東日本) と VM (Az 2, 東日本) の VM があり、VM 1 から VM 2 のパブリック IP アドレス通信した場合は、課金されないということなのでしょうか。
VM 1 から東日本リージョン内の PaaS への通信とかですかね?
ちょっとわかりづらいです。

可用性ゾーン間でピアリングされた VNet にある VNet リソース間のデータ転送。このデータ転送は、VNet ピアリング料金に従って課金されます。

VNet ピアリングされた VNet 間の通信の場合は、データ転送ではなくて VNet ピアリングの料金で課金するよ、ということだと思われます。

ということで、これまでは「Azure から出ていくデータ転送料とリージョン間のデータ転送料」のみだったところに、 2023 年 7 月 1 日からは「可用性ゾーン間のデータ転送料」が追加されます。

環境を作るうえで費用見積は重要かと思うので、これからはリージョン間よりもう 1 つ細かい、 データセンター間の通信料まで考慮する必要がある、ということを抑えておきましょう。

終わりに

公式の料金サイト側がいつ更新されていたのかはわかりませんが、本日知り驚いたので小ネタとしてまとめました。

金額が出ていないのでわかりませんが、Az を分散したサーバー間でレプリケーションなんかが動くとそこそこ課金されるかもしれませんね。来年コストを見積もる際は考慮漏れのないようにしたいですね。