ごった煮

色々な事を書いてます

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

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

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

期限いつでしたっけ

  • 2024年2月29日

詳しくはこちら

azure.microsoft.com

スクリプト

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

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

まとめ

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

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

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

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

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

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

やったね

www.credly.com

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

Bicep で App Configuration の接続文字列を取得する

Bicep 上で、App Configuration の接続文字列が欲しい時があったので、備忘録として残します。

やってみる

次のような Bicep を書けば取得できます。

なんでこうなるの

App Configuration を listKeys() すると、実体は次のような構造の json になっているので、filter 関数で、キーをフィルターして最初のモノを取得すると接続文字列が取得できます。

{
  "value": [
    {
      "id": "abcdefg123456789",
      "name": "Primary",
      "value": "000000000000000000000000000000000000000000000000000000",
      "connectionString": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
      "lastModified": "2023-06-06T00:00:00+00:00",
      "readOnly": false
    },
    {
      "id": "abcdefg1234567891",
      "name": "Secondary",
      "value": "000000000000000000000000000000000000000000000000000000",
      "connectionString": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
      "lastModified": "2023-06-06T00:00:00+00:00",
      "readOnly": false
    },
    {
      "id": "abcdefg1234567892",
      "name": "Primary Read Only",
      "value": "000000000000000000000000000000000000000000000000000000",
      "connectionString": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
      "lastModified": "2023-06-06T00:00:00+00:00",
      "readOnly": true
    },
    {
      "id": "abcdefg1234567893",
      "name": "Secondary Read Only",
      "value": "000000000000000000000000000000000000000000000000000000",
      "connectionString": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
      "lastModified": "2023-06-06T00:00:00+00:00",
      "readOnly": true
    }
  ]
}

注意点

取得した接続文字列を output で返そうとすると、ログに接続文字列が露出するので、絶対にやめましょう。

現在、output で secure string を扱えるように対応が進んでるはずなので、その対応が終わるまでは、絶対に output しないようにしましょう。

まとめ

接続文字列が必要な場合は、これで対応できました。

が、お遊びやミニマムなテスト環境以外で利用する場合は、普通に Managed Identity を利用しましょう。

Azure Blob Storage に配置されたファイルを SQL Database に Bulk Insert する

業務システムなどで、 Blob に CSV が配置されていて、そのファイルの内容を DB に Bulk Insert したいといった要望は、比較的あるあるかと思います。

ファイルサイズが小さければどうとでもなるのですが、それなりにサイズの大きなファイルですと、ちまちまインサートするとそれだけで日が暮れてしまうので、 SQL Database (SQL server)の機能を頑張って使って、あれこれやった備忘録を残します。

今回の動機

今まで、Azure Functions の Blob トリガーでファイルの配置を検知し、PowerShell Function から BCP コマンドを流したりして頑張っていました。

ですが、ここ半年ほど不可解な挙動をするようになり(流したいコマンドをまとめたファイルが、不定期に読み込みに失敗する等)ちょっと運用が辛い問題がありました。

そこで、そういう問題が極力減るように、SQL Server 側でファイルを読み込み、C# の Function App でトリガーだけする方式に切り替えようとしたためです。

SQL Server から Blob へアクセスできるようにする

マスターキーを作成する

まず初めに、SQL Database でデータベースマスターキーを作成していない方は、次のようにマスターキーを作成します。

CREATE MASTER KEY ENCRYPTION BY PASSWORD='{Your Password}'

データベース資格情報を作成する

次に Blob のコンテナにアクセスするための資格情報を作成します。

資格情報の作成には、SAS が必要なので、Storage Explorer なり、ポータルなりで SAS を生成してください。

SAS がある人は、次の SQL を実行します。

CREATE DATABASE SCOPED CREDENTIAL [{Your Credential Name}]
WITH IDENTITY = 'Shared Access Signature',
SECRET = '{Your SAS}'
  • Your Credential Name : 資格情報名(コンテナの URL とかにしておくと分かりやすい気がします。)
  • Your SAS : sv ~ から始まる SAS を指定します。ポータルなどでコピーしてくると先頭に ? が付いてくるかもしれないので、それは削除しましょう

この SQL が成功したら、次の SQL を実行して、実際に登録されているか確認します。

SELECT * FROM sys.[database_scoped_credentials]

name が先ほどの資格情報名のモノが出てきたら成功です。

外部ソースを設定する

最後に外部ソースとして、コンテナを登録します。

次の SQL を実行します。

CREATE EXTERNAL DATA SOURCE [{Your External Source Name}]
WITH(
    TYPE = BLOB_STORAGE,
    LOCATION = '{Your Blob Url}',
    CREDENTIAL = [Your Credential Name]
)
  • Your External Source Name : 外部ソース名です。SQL からこの外部ソースを参照する場合に指定するモノなので、分かりやすいものを付けましょう。
  • Your Blob Url : Blob ストレージの URL を指定します。(https://{ストレージアカウント名}.blob.core.windows.net)
  • Your Credential Name : 使用するデータベース資格情報名を指定します。

この SQL が成功したら、次の SQL を実行します。

name が先ほどの外部ソース名のモノが出てきたら、成功です。

SELECT * FROM sys.[external_data_sources]

実際に Bulk Insert してみる

事前に Insert したいテーブルなどは準備しておきましょう

次のような SQL で利用できます。

BULK INSERT {Your Table Name}
FROM '{Your Container Name}/{Blob Name}'
WITH 
(
    DATA_SOURCE = '{Your External Source Name}'
    , CODEPAGE = '65001'
    , FORMAT = 'CSV'
    , ROWTERMINATOR = '0x0a'
)
  • Your Table Name : Insert したいテーブル名
  • Your Container Name : 対象のコンテナ名
  • Blob Name : コンテナに配置されている Blob 名
  • Your External Source Name : 先ほど作成した外部ソース名

その他の設定としては、コードページが 65001、フォーマットが CSV、改行が 0x0a のファイルという情報を与えています。

細かいパラメータは、公式ドキュメントをご参照ください。

learn.microsoft.com

まとめ

これで、資格情報等は全て SQL Server 側に保持され、SQL さえ呼び出せれば、処理は全て SQL Server 側で行ってくれるようになります。

次回は、Azure Functions と組み合わせた例をまとめます。(気が向いたら)

bicep の新しいパラメータファイル .bicepparam について

Bicep をデプロイする際、通常では、外部から注入したいパラメータを ARM Template と同様の json ファイルを利用していますが、 今後新しく、.bicepparam という形式が利用可能になります。

恐らく、今後はこちらが主流になっていくと思われるので、簡単に概要をまとめます。

前提条件

今回は、次の環境を基に記載します。

  • Azure CLI : v2.48.1
  • Bicep : v0.17.1

事前準備

.bicepparam は、Bicep 0.17.1 では、Experimental features に該当する為、利用する場合、 bicepconfig.json が必要です。

ミニマムなファイルは次の通りです。

{
    "experimentalFeaturesEnabled": {
        "paramsFiles": true
    }
}

このファイルを main.bicep と同じフォルダに配置します。

App Service をデプロイしてみる

Bicep の準備

シンプルな App Service のデプロイで使い方を見ていきます。

App Service をデプロイする為の Bicep は、次の通りです。

param location string = resourceGroup().location

var suffix = guid('guid')

resource plan 'Microsoft.Web/serverfarms@2022-03-01' = {
  name: 'plan-demo-lab-${suffix}'
  location: location
  kind: 'app'
  sku: {
    name: 'B1'
  }
}

resource app 'Microsoft.Web/sites@2022-03-01' = {
  name: 'app-demo-lab-${suffix}'
  location: location
  kind: 'app'
  identity: {
    type: 'SystemAssigned'
  }
  properties: {
    serverFarmId: plan.id
  }
}

パラメータとして、location を受け取れるようになっています。

これを、main.bicep として保存します。

次に、パラメータファイルを作成します。

内容は、次の通りです。

using 'main.bicep'

param location = 'japaneast'

using 文に、利用したい bicep ファイルを指定します。

今回は、main.bicep です。

次に、bicep のように param {パラメータ名} = {値} として、値を渡します。

パラメータを渡す対象を using 文で読み込んでいる為、パラメータは、intellisense が利用できます。

このファイルを param.bicepparam として保存します。

デプロイする

後は、通常の Bicep と同じようにデプロイします。

az deployment group create -f main.bicep -g {リソースグループ名} -p param.bicepparam

想定通りならば、通常の json ファイルと同じようにデプロイ出来ます。

まとめ

parameter.json は、記述量も多いですし、intellisense も利用できない為、あまり使い勝手が良くありませんでしたが、今後はシンプルな方向に倒れるという事で、より使いやすくなるかと思います。

この機能は、6/1 リリース予定の bicep 0.18 で正式に搭載予定なので、今のうちに覚えておくと良いかもしれません。

dotnet コマンドの nuget ソースから特定のソースを除外したい

dotnet コマンドでリストア処理が走る際に、nuget のソースから特定のソースを除外したい場合が稀にあると思います。

例えば、普段は社内向けのクローズドな NuGet サーバをソースとして設定しているけど、今回はそのソースを参照したくないといった場合です。

nuget.config を書いてもいいんですが、わざわざファイルを用意するよりは、コマンドで済ませたいという場合もあると思います。(というかあった)

ので、備忘録として残します。

現在設定されているソースを確認する

次のコマンドで現在 dotnet コマンドが利用する NuGet サーバのソースが一覧できます。

dotnet nuget list source

出力結果に Enabled とついているものが、現在有効なソースです。

特定のソースを有効化・無効化する

無効化する

次のコマンドで、無効化が出来ます。

dotnet nuget disable source {ソース名}

nuget.org を無効化したい場合は、次のような形です。

dotnet nuget disable source nuget.org

有効化する

先ほどとは逆に有効化する場合は、次の通りです。

dotnet nuget enable source {ソース名}

nuget.org を有効化したい場合は、次のような形です。

dotnet nuget enable source nuget.org

まとめ

多分年1くらいでググるヤツ