Azureの小ネタ (改)

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

Azure Batch に NET 4.7.1をインストールする

Azure Batch にNET 4.7.1を仕込む備忘録。

NET4.7.1を仕込むには、まずインストーラを取得する必要がありますが、既定の状態だとCMDベースでCURLとかが使えないとかちょっと不自由。

Application Package

ただ、Azure Batchには、Application Packageと呼ばれるアプリケーションを仕込んでおく仕組みがあって、そこにNET4.7.1のパッケージを配置しておきます。

NET4.7.1のオフラインインストーラーは以下から取得します。

https://docs.microsoft.com/ja-jp/dotnet/framework/deployment/deployment-guide-for-developers

New Application から、EXEをZIP化してUploadしておくと所定のストレージに格納されます。

f:id:StateMachine:20180315105822p:plain

いちどタスクにApplication Packageを紐づけて環境変数を参照すると以下のように展開されています。

AZ_BATCH_APP_PACKAGE_netfx=D:\batch\tasks\apppackages\netfx4712018-03-15-01-59
AZ_BATCH_APP_PACKAGE_netfx#471=D:\batch\tasks\apppackages\netfx4712018-03-15-01-59

DIRすると

 Directory of D:\batch\tasks\apppackages\netfx4712018-03-15-01-59

03/15/2018  02:02 AM    <DIR>          .
03/15/2018  02:02 AM    <DIR>          ..
03/15/2018  02:02 AM        68,742,112 NDP471-KB4033342-x86-x64-AllOS-ENU.exe
               1 File(s)     68,742,112 bytes
               2 Dir(s)  18,570,358,784 bytes free

こうなります。Docsでは以下のあたりを参照のこと。

コンピューティング ノードへのアプリケーション パッケージのインストール - Azure Batch | Microsoft Docs

Pool

PoolにApplication Packageを紐づけて、ノードをリブートします。

f:id:StateMachine:20180315111241p:plain

Start Task

Start Taskでインストーラーを起動します。

f:id:StateMachine:20180315111549p:plain

最初、/norestartをつかたら、3010でエラーになりました。Rebootが必要なのに、/norestart指定したからっぽいです。

MsiExec.exe and InstMsi.exe Error Messages (Windows)

今回使っているBatchノードはVMなので、不完全ながらインストールされてしまうと再度テストできないので、ノード数を 1->0->1 のように変更してさいどセットアップされるようにしてみます。

最終的には以下のコマンドライン。

cmd /c "%AZ_BATCH_APP_PACKAGE_netfx%\NDP471-KB4033342-x86-x64-AllOS-ENU.exe /q"

最後、RDPでのぞいて KB4033393が入っていればOK。

f:id:StateMachine:20180315124655p:plain

これで、ノードをスケールアップ、ダウンさせても各ノードにNET4.7.1が展開されるでしょう。

余談

DocsのAzure BatchサンプルのPortalは日本語なのに、現時点で英語になってたよくわからない。

構成ファイルから透過的にKey Vaultへアクセス

前回、前々回では

管理対象サービスID で簡単にKeyValutにアクセスする - Azureの小ネタ (改)

開発環境から簡単にKeyValutにアクセスする - Azureの小ネタ (改)

コードベースでKey Vaultにアクセスしましたが、以下のパッケージを使うと構成ファイルから透過的にKey Vaultにアクセスできます。

ただしキーではなくシークレット(SQLの接続文字列なんかを格納)のみです。

設定

こちらもまだPreviewですけど以下をインストールします。

NuGet Gallery | Microsoft.Configuration.ConfigurationBuilders.Azure 1.0.0-preview2

記事を書くときにちょうど2H前に、Preview2がリリースされているという状態でした。にしてもDownload数が少ない。

f:id:StateMachine:20180310115624p:plain

たまたま、NET4.7.1 じゃないプロジェクト使ってたらとインストールエラーが出たので注意。BaseのほうがNET4.7.1しばりなのかもしれない。Dependencyはないけど。

インストールすると、App.Configが書き換わります。valueName属性をKey Vault名に書き換えます。またappSettingsセクションに適当な定義を行っておきます。

<?xml version="1.0" encoding="utf-8"?>
<configuration>
    <configSections>
        <section name="configBuilders"
            type="System.Configuration.ConfigurationBuildersSection, System.Configuration, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"
            restartOnExternalChanges="false" requirePermission="false"/>
    </configSections>
    <configBuilders>
        <builders>
            <add name="AzureKeyVault" vaultName="[VaultName]"
                type="Microsoft.Configuration.ConfigurationBuilders.AzureKeyVaultConfigBuilder, Microsoft.Configuration.ConfigurationBuilders.Azure, Version=1.0.0.0, Culture=neutral"/>
        </builders>
    </configBuilders>
    <startup> 
        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.7.1"/>
    </startup>
  <appSettings configBuilders="AzureKeyVault">
    <add key="hogesecret" value="FuaFuga" />
  </appSettings>
</configuration>

シークレット設定

Key Vaultの設定から適当にhogesecret 設定しておきます。

f:id:StateMachine:20180310121320p:plain

アプリ側

もう普通にConfigurationManagerからとってくるだけで、勝手にKey Vaultへアクセスしています。

  var s = ConfigurationManager.AppSettings["hogesecret"];
  Debug.WriteLine(s);

上記例は、AppSettingsですが、ConfigurationManager.ConnectionStrings などでも大丈夫です。デバッグなどの立ち上がりで一瞬引っかかりを感じ(アクセスなどで)ますが、面倒なコード書かなくて済むのは良い感じです。

ちなみに、Key Vault側へのアクセス件はREAD ONLYで問題ないはずですが、ListできないとNGだったきがします。

.NET CoreのHttpClientで無効な証明書を無視する

下書きに埋もれてたので発掘。よくある自己署名的なサーバーにHttpClientでアクセスする際、無視する話です。

.NET Frameworkでは、ServicePointManager.ServerCertificateValidationCallback を使っていたんですけど、.NET Coreでは効かないです。

以下のstackoverflowの回答にあるとおり、HttpClientHandler を使えばよいみたいですね。

stackoverflow.com

コードはこんな感じになります。

using (var httpClientHandler = new HttpClientHandler())
{
   httpClientHandler.ServerCertificateCustomValidationCallback = (message, cert, chain, errors) => { return true; };
   using (var client = new HttpClient(httpClientHandler))
   {
       // Make your request...
   }
}