ごった煮

色々な事を書いてます

ASP.NET MVC に Application Insights を導入すると、App Service 上で動かない時がある

ASP.NET MVC (not dotnet core) に Application Insights を NuGet から入れた際にハマったので、備忘録を残します。

何が起きたのか

下記のステップで既存の ASP.NET MVC アプリに Application Insights を入れてみました。

  1. NuGet から Microsoft.ApplicationInsights.DependencyCollector をインストール
  2. NuGet から Microsoft.ApplicationInsights.Web をインストール

1 の状態では、App Service 上でも動きました。

問題は、2の状態で発生しました。

発生したエラー

An ASP.NET setting has been detected that does not apply in Integrated managed pipeline mode.

This application defines configuration in the system.web/httpModules section.

はてさて

なぜこんなエラーが起きたのか

NuGet から、 Microsoft.ApplicationInsights.Web をインストールした際、Web.config の system.web/httpModules のセクションに下記の設定が自動で差し込まれていました。

    <httpModules>
      <add name="TelemetryCorrelationHttpModule" type="Microsoft.AspNet.TelemetryCorrelation.TelemetryCorrelationHttpModule, Microsoft.AspNet.TelemetryCorrelation" />
      <add name="ApplicationInsightsWebTracking" type="Microsoft.ApplicationInsights.Web.ApplicationInsightsHttpModule, Microsoft.AI.Web" />
    </httpModules>

使っていた App Service は Managed pipeline versionIntegrated だった為、system.web/httpModules のセクションが使えず、エラーになっていました。

Managed pipeline version を、Classic に変更すれば、該当の Web.config でも問題なく動作します。

まとめ

App Service の初期設定は、Integrated なので、注意が必要です。

今は、.NET Framework で新規のコードを書くことは減ったかもしれませんが、既存のコードに導入するといったことは往々にしてあるかと思います。 その際はご注意を

AWS から Azure の KeyVault を利用する

Azure と AWS でそれぞれアプリケーションが稼働していて、外部の API に対して利用するクライアント Id、シークレットを同じものを使いたいという状況はそれなりにあると思います。(要出典

ですが、KeyVault は、Entra 認証が必要なため、Azure 内のシステムからでないと少しアクセス方法がややこしいです。

ということで、連携方法をまとめます。

今回の仕組み

今回構築する仕組みは、Workload Identity Federation の仕組みを利用して、Cognito と User assigned managed Identity を federate して実現します。

実際にやってみる

ステップ01

User assigned managed identity を作成します

とりあえずポータルからポチポチでも何でも良いので、適当に作成します。

ステップ02

Key Vault を作成します。

こちらも、ポータルからポチポチでも何でも良いので、適当に作成します。

作成した Managed Identity に Key Vault の権限を付与する

とりあえず下記3つを IAM で付与します。

  • Key Vault Certificate User
  • Key Vault Secrets User
  • Key Vault Crypto Service Encryption User

Cognito を作ったりするように AWS に IAM ユーザを作る

Root ユーザは怖いので、IAM ユーザを作りましょう

次の2つの権限を割り当てた IAM ユーザがあれば OK です

  • AmazonCognitoPowerUser
  • AWSCloudShellFullAccess

iam:create-role が無いと、Cognito 作成時にエラーが出ますが、今回はあくまで Azure と Federate するだけで、 AWS 内で何かする権限は必要ないので、このままで OK です。

ステップ03

Cognito を作る

ID プールを作る

分かりづらいですが、プルダウンから、 AWS のサービスへのアクセス権を付与する選択して、ID プールを作成を選択します。

ID プールの信頼設定

下記の設定で次へを選択します。

  • ユーザアクセス : 認証されたアクセス
  • 認証された ID ソース : カスタムデベロッパープロバイダー

許可を設定

下記の設定で次へを選択します。 ※ IAM ロールを作成する権限が無いはずなので、あとでエラーになります。

  • IAM ロール : 新しい IAM ロールを作成
  • IAM ロール名に適当な名前を入れる

ID プロバイダーを接続する

下記の設定で次へを選択します。

  • デベロッパープロバイダー名に適当な名前を入れる(今回は、azure-access にします。)

プロパティを設定する

ID プール名に適当な名前を入れて次へを選択します。

確認と作成

確認画面で、問題が無さそうなら、ID プールを作成を選択します。

ステップ04

Cognito の設定をする

Identity プールに Identity を作成する

ここからコマンドを流す必要があります。

AWS CLI が必要なので、CloudSehll を使いましょう

CloudShell で下記のコマンドを流します。

aws cognito-identity get-open-id-token-for-developer-identity \
--identity-pool-id {ID プールの id} \
--logins {デベロッパープロバイダー名}={適当なテキスト(managed id の client id とか)}

コマンドを流すと下記のような json が取れるので、Token の値を jwt デコーダでデコードします。

{
    "Token": "{jwt トークン}",
    "IdentityId": "{登録した Identity の Id}"
}

ステップ05

Managed Identity と Cognito を federate する

Azure CLI を使うので、Azure CLI が使える環境をご用意ください

下記のコマンドを流します。(PowerShell 前提になっているので、他のシェルを使う場合は、改行の調整をしてください)

az identity federated-credential create `
--name {Managed Identity の Federated credentials として登録する名前} `
--identity-name {managed identity の名前} `
--resource-group {resource group の名前} `
--issuer {jwt から取得した iss} `
--subject {jwt から取得した sub} `
--audience {jwt から取得した aud}

ステップ06

Cognito のトークンを使って Azure にログインする

まず、Cognito からトークンを取得します。

ステップ04 で流したコマンドをもう一度流して、トークンを取得します。

下記のコマンドで Azure CLI からログインします。

az login --federated-token {cognito から取得したトークン(jwt)} `
--tenant {Entra のテナント Id} `
--service-principal -u {managed identity の client id}

ステップ07

KeyVault へアクセスできるかをチェックする

とりあえず Secrets を取得してみましょう

az keyvault secret list --vault-name {key vault の名前}

エラーが出なければ、成功です。

ステップ07

REST API を使って、Key Vault にアクセスする

Azure へのアクセストークンを取得する

下記の設定で API を呼びます。(Postman 等を使いましょう)

リクエスト Body

Key Value
client_id {Managed Identity の Client Id}
grant_type client_credentials
scope {必要な scope 設定。Key Vault の場合は、https://vault.azure.net/.default}
client_assertion {Cognito のトークン}
client_assertion_type urn:ietf:params:oauth:client-assertion-type:jwt-bearer

下記のレスポンスが返ってきます。

{
  "token_type": "Bearer",
  "expires_in": {有効期限(秒)},
  "access_token": "{アクセストークン}"
}

Key Vault を呼び出す

認証

Bearer {取得したアクセストークン}

Secrets を取得する

  • Endpoint : {KeyVault エンドポイント}/secrets?maxresults=1&api-version=7.4
  • メソッド : GET

まとめ

これで、AWS の環境から KeyVault にアクセスできるようになりました。

Managed Identity で接続できるサービスは、権限を調整すればこれで接続できるはずです。

世の中にある大抵のシステムは、パブリッククラウドを跨いで何かするということは無いと思いますが、いざというときに使えると便利です。

SDK を使った方法については気が向いたらまとめようと思います。

Windows 11 で Documents フォルダが移動できない場合の対処法

新しいマシンを買って、Windows 11 をクリーンインストールしたところ、Documents フォルダが OneDrive の配下に勝手に作られたので、場所を移動しようとしたら色々ややこしかったので備忘録に残します。

何が起きたのか

通常でしたら、Documents フォルダのプロパティ > Location から普通に場所を移動できるはずなのですが、下記のエラーが出ました。

Can't move the folder because there is a folder in the same location that can't be redirected.
Access is denied.

対処法

レジストリを直接書き換えて強引に Documents フォルダの向き先を差し替えます。

マジかよと思いますがマジです。

対象のレジストリは、

HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\User Shell Folders\Personal

OneDrive 配下だと、Data が下記のようになっているはずです。

C:\Users\{username}\OneDrive\ドキュメント

なので、Data に任意のフォルダパスを入れます。

今回は、Users 配下の Documents に移したいので、下記のパスを入れます。

%USERPROFILE%\Documents

変更したらマシンを再起動しましょう。

再起動が完了すると、フォルダが変更されているはずです。

その後、OneDrive のフォルダから必要なファイルを移すなりしましょう。

まとめ

この仕様はちょっと不親切

PowerShell でファイルエンコーディングを変更する

ファイルのエンコーディングを変更する時は、大体 VSCode を使うんですが、ファイルが大きすぎて VSCode だとどうにもならないことがあったので、PowerShell でやる方法を備忘録として残します。

前提

環境

やってみる

$sjis = [System.Text.Encoding]::GetEncoding(932)
$file = Get-Content -Path {変換したいファイルのパス} -Encoding $sjis
Set-Content {出力先のファイルパス} -Value $file -Encoding UTF8

まとめ

これにて解決

Application Insights が Workspace 版への移行対象かどうかを抽出する

Application Insights のクラシックモデルの廃止が近づいてきました。

自分は結構な量が Workspace 版への移行対象だったので、どれが移行対象なのか抽出するスクリプトを作りました。

期限いつでしたっけ

  • 2024年2月29日

詳しくはこちら

azure.microsoft.com

スクリプト

Azure CLI でデフォルトに設定されているサブスクリプションのモノを全て抜き出すので、管理している全てのサブスクリプションを横断したい場合は、az group listサブスクリプション id を渡してあげてください

IsClassicTrue のモノが、移行対象のはずです。

まとめ

ギリギリで対処しないで早めに移行しちゃいましょう

az コマンドでリソースグループの名前だけ抽出した

az コマンドでリソースグループ一覧の名前だけ抽出したいといった場合は、まぁ結構あるよねってことで備忘録

やってみる

まとめ

PowerShell いつも使い方忘れるのでメモ

Microsoft MVP for Microsoft Azure を受賞しました。

今年も Microsoft MVP を受賞させていただきました。

2016年から足掛け8年になります。

今年はコロナ禍が落ち着いたという事で、リアル勉強会に顔を出していきたいなと思いつつ、春先に子供が産まれて絶賛大忙しなので、 細々と自分の出来る活動をして行ければなと思っています。

今年はこんなバッジが貰えました。

やったね

www.credly.com

今年も一年よろしくお願いします。