Azureの小ネタ (改)

~Azureネタを中心に、色々とその他の技術的なことなどを~

KeyVaultへ透過的にアクセスする(証明書編)

以前、 構成ファイルから透過的にKey Vaultへアクセス - Azureの小ネタ (改) という記事を書いたのですが、そのときは Azure リソースのマネージド ID | Microsoft Docs (旧MSI)を使った方法しか使えないと思っていましたが、最近証明書ベースでもアクセスできることがわかったのでその備忘録。

WebAppsとか、Azure VMとか、Azure リソースのマネージド ID を使える場合は特に問題ないのですが、Azure BatchとかAzure BatchとかAzure Batchでは、Azure リソースのマネージド IDが使えないので、KeyVaultへのアクセスに難儀しておりましたが、この方法を使えば透過的にいけると思います。

とはいえ、証明書作ってADにアプリ登録して、KeyVaultへのアクセス許可して、Batchに証明書登録してとうの煩雑な作業は省略できません。

ここを参照するとわかるのですが、@connectionString="connection string が指定できることがわかります。

github.com

この中身は、こちらで解説されております。

docs.microsoft.com

アプリIDとテナントIDと証明書の拇印および、ストア場所を指定できます。これで証明書ベースでKeyVaultにアクセスできるということです。

RunAs=App;AppId={AppId};TenantId={TenantId};CertificateThumbprint={Thumbprint};CertificateStoreLocation={LocalMachine or CurrentUser}

いつのまにかPreviewも取れ、ドキュメントが整備されてなくてよくわからなかった仕様も分かるようになってきてますね。

TransformXmlとコンフリクトしてアセンブリリダイレクトが有効にならない

Consoleプロジェクトで最終的なConfigファイルにアセンブリリダイレクトが自動生成されなくて悩んでいたんだけどその覚え書き。

github.com

Issueとしてはいくつか上がっているのだけれど、この中で、

https://github.com/Microsoft/msbuild/issues/1310#issuecomment-429878218 のコメントで、TransformXml使ってるとApp.Configファイルがコンフリクトしてうまくいかないよと言及が。

よくよく自分のProjectみるとApp.configファァイルの切り替えに、以下の拡張(もしくはそれに類似したcsprojの手動修正)を使っていたですが、どうもそれが原因です。

marketplace.visualstudio.com

動作順序としては、

  1. GenerateBindingRedirects (App.Config -> Hoge.exe.Configへ生成)
  2. TransformXml (App.Config -> Hoge.exe.Config へ生成)

という形なので、間にファイルコピーを挟めばうまくいくかなと言うことで以下。前者のTargetでいったんHoge.exe.bind.config と名前を変えてCopyして、後続のTransformXmlでは、それを入力ファイルとすることで回避。

  <Target Name="App_config_Preprocess" AfterTargets="GenerateBindingRedirects">
    <Copy SourceFiles="$(IntermediateOutputPath)$(TargetFileName).config" DestinationFiles="$(IntermediateOutputPath)$(TargetFileName).bind.config" />
  </Target>

  <Target Name="App_config_AfterCompile" AfterTargets="AfterCompile" Condition="Exists('App.$(Configuration).config')">
    <!--Generate transformed app config in the intermediate directory-->
    <TransformXml Source="$(IntermediateOutputPath)$(TargetFileName).bind.config" Destination="$(IntermediateOutputPath)$(TargetFileName).config" Transform="App.$(Configuration).config" />
    <!--Force build process to use the transformed configuration file from now on.-->
    <ItemGroup>
      <AppConfigWithTargetPath Remove="$(IntermediateOutputPath)$(TargetFileName).bind.config" />
      <AppConfigWithTargetPath Include="$(IntermediateOutputPath)$(TargetFileName).config">
        <TargetPath>$(TargetFileName).config</TargetPath>
      </AppConfigWithTargetPath>
    </ItemGroup>
  </Target>

とりあえずアドホックな対処だけどちゃんと生成されているぽいので様子見。

Microsoft.Extensions.Logging の覚え書き

お手軽なんで、Microsoft.Extensions.Logging のコンソール出力を使ってたら、Obsoleteになってたので解決方法のメモ。

元ソースは以下ですが、これが警告になりました。

ILoggerFactory loggerFactory = new LoggerFactory().AddConsole()
ILogger<Program> logger = loggerFactory.CreateLogger<Program>();

ConsoleLoggerExtensions.AddConsole Method (Microsoft.Extensions.Logging) | Microsoft Docs をみても 廃止予定とかいてあります。

代わりに、AddConsole(ILoggingBuilder) を使えとあったのですが、ILoggingBuilderはどこから取ってくるんだろうと思って調べたら、stackoverflowにありました。

stackoverflow.com

2.x 系では、DI使えと。

IServiceCollection serviceCollection = new ServiceCollection();
serviceCollection.AddLogging(builder => builder
    .AddConsole()
    .AddFilter(level => level >= LogLevel.Information)
);
var loggerFactory = serviceCollection.BuildServiceProvider().GetService<ILoggerFactory>();

3.0 系では、

var loggerFactory = LoggerFactory.Create(builder => {
        builder.AddFilter("Microsoft", LogLevel.Warning)
               .AddFilter("System", LogLevel.Warning)
               .AddFilter("SampleApp.Program", LogLevel.Debug)
               .AddConsole();
    }
);

と、LogFactory.Createメソッドができるとか。stackoverflowの回答では、それぞれ .NET Core ではと書いてあったけど普通に .NET 4.7系とかからも使えるから、Loggerのバージョンの話じゃないですかね。3.0は現時点でPreviewです。

www.nuget.org