KENTEM TechBlog

建設業のDXを実現するKENTEMの技術ブログです。

Azure PowerShellでAzure Batchのタスクから環境変数を取得する

こんにちは、KENTEMのまつです。
担当している製品のデータを集計しようとしたところ、データ構造的にトレースできないデータがありました。
Azure Batchのタスクに設定された環境変数にデータがあったので、CSVなどにしてダウンロードできないか調査しました。

取得方法の選択肢

今回は時間もあまり無かったためPowerShellでささっと環境変数を取得できないか検討しました。
PowerShellだけでも以下のような選択肢がありました。

  • Azure PowerShell
  • Azure CLI
  • REST API
  • .NET SDK

折角なので専用で用意されているAzure PowerShellを使います。

モジュールのインストール

Azure PowerShellを利用するにはModuleのインストールが必要です。
まずは以下コマンドでAz.AccountsとAz.BatchのModuleがインストールされているか確認します。

Get-Command -Module Az.Accounts | Select-String "Connect-AzAccount"
Get-Command -Module Az.Batch | Select-String "Get-AzBatchAccount|Get-AzBatchTask"

以下のようにコマンドが出力されればOKです。

モジュール確認

出力されない場合はコマンドのインストールが必要です。
管理者権限で以下コマンドを実行します。

Install-Module Az.Accounts
Install-Module Az.Batch

認証の解決

モジュールが準備できたので、次は認証です。
Azure PowerShellにはConnect-AzAccountを使用した複数の認証方法が用意されています。

分類認証方法
対話型認証Webアカウントマネージャー
対話型認証ブラウザベースのログイン
対話型認証デバイスコード認証
非対話型認証マネージドIDを使用したログイン
非対話型認証サービスプリンシパルを使用したログイン

今回はささっと済ませたいのでWebアカウントマネージャーを選択します。
以下コマンドでログイン可能か確認します。

Connect-AzAccount -Subscription "{your subscription id}"

コマンド実行すると以下が表示されますので、アカウントを選択または入力してログインしてください。
※たまにWindowが行方不明になるので注意

WAMアカウント選択

以下のような出力になれば認証OKです。

Connect-AzAccount認証OK

コマンドベースでの確認

認証が通ったのでコマンドを打ちつつ環境変数が取得できるか確認していきます。
以下コマンドでAzureBatchのタスク一覧を取得します。
※全件取得は時間がかかります。必要に応じて-MaxCountを変更してください。

$context = Get-AzBatchAccount -AccountName "{your batch account name}"
$maxCount = [int]::MaxValue
$tasks = Get-AzBatchTask -BatchContext $context -MaxCount $maxCount -JobId "{your job id}"

タスク取得コマンド実行

実行終了したら以下コマンドで取得件数を確認します。

$tasks.length

タスク件数確認

ちゃんと取得出来ていることを確認したので、次は中身を確認します。

$tasks[0]

中身の確認

EnvironmentSettingsが今回取得したい環境変数のプロパティになります。
以下コマンドを実行するとオブジェクトとして取得出来ることが確認できます。

$tasks[0].EnvironmentSettings

ツール化

コマンドベースで環境変数を取得できることを確認したので、最後はツール化をします。
このツールは使用頻度も低く、変更もされないことを想定しているので、最低限の処理で作成しました。

$azAccountsCmd = Get-Command -Module Az.Accounts
if ($azAccountsCmd -eq $null) {
    Write-Output "Az.Accountsモジュールがインストールされていません。インストールを開始します..."
    Write-Output "管理者権限でPowerShellを実行していることを確認してください。"
    Install-Module -Name Az.Accounts
}
$azBatchCmd = Get-Command -Module Az.Batch
if ($azBatchCmd -eq $null) {
    Write-Output "Az.Batchモジュールがインストールされていません。インストールを開始します..."
    Write-Output "管理者権限でPowerShellを実行していることを確認してください。"
    Install-Module -Name Az.Batch
}
$subscriptionId = Read-Host "接続するサブスクリプションのIDを指定してください。"
$accountId = Read-Host "接続するアカウントID(メールアドレス)を指定してください。"

try {
    Connect-AzAccount -Subscription $subscriptionId -AccountId $accountId
    do {
        $batchAccountName = Read-Host "Batchアカウント名を指定してください。"
        $context = Get-AzBatchAccount -AccountName $batchAccountName
        $jobId = Read-Host "タスクを取得するジョブIDを指定してください。"
        $maxCount = [int]::MaxValue
        $tasks = Get-AzBatchTask -JobId $jobId -MaxCount $maxCount -BatchContext $context
        Add-Type -AssemblyName System.Windows.Forms
        $outputFileName = "BatchTaskEnvironments_$(Get-Date -Format 'yyyyMMdd_HHmmss').csv"
        $dialog = New-Object Windows.Forms.SaveFileDialog
        $dialog.Title = "タスク環境設定リストファイルの保存"
        $dialog.Filter = "CSVファイル (*.csv)|*.csv|すべてのファイル (*.*)|*.*"
        $dialog.InitialDirectory = Get-Location
        $dialog.FileName = $outputFileName
        $dialogResult = $dialog.ShowDialog()
        if ($dialogResult -eq [Windows.Forms.DialogResult]::OK) {
            $outputFilePath = $dialog.FileName
            $headerStr = """TaskId"",""ApplicationId"",""Version"",""CreationTime"",""State"",""StateTransitionTime"","
            $envKeys = $tasks[0].EnvironmentSettings.Keys
            foreach ($task in $tasks) {
                if ($envKeys.Count -lt $task.EnvironmentSettings.Keys.Count) {
                    $envKeys = $task.EnvironmentSettings.Keys
                }
            }
            foreach ($name in $envKeys) {
                $headerStr += """$($name)"","
            }
            $headerStr = $headerStr.TrimEnd(',')
            Set-Content -Path $outputFilePath -Value $headerStr
            foreach ($task in $tasks) {
                $output = """$($task.Id)"",""$($task.ApplicationPackageReferences.ApplicationId)"",""$($task.ApplicationPackageReferences.Version)"","
                $output += """$($task.CreationTime.ToString("yyyy-MM-dd HH:mm:ss"))"",""$($task.State)"",""$($task.StateTransitionTime.ToString("yyyy-MM-dd HH:mm:ss"))"","
                foreach ($key in $envKeys) {
                    if ($task.EnvironmentSettings.ContainsKey($key)) {
                        $output += """$($task.EnvironmentSettings[$key])"","
                    } else {
                        $output += " ,"
                    }
                }
                $output = $output.TrimEnd(',')
                Add-Content -Path $outputFilePath -Value $output
            }
            Write-Output "タスク環境設定リストがファイルに保存されました: $outputFilePath"
        } else {
            Write-Output "ファイル保存がキャンセルされました。"
        }
        $continueChoice = Read-Host "別のジョブのタスク環境設定を取得しますか? (y/n)"
        if ($continueChoice.ToLower() -ne 'y') {
            break
        }
    } while ($true)
}
finally {
    DisConnect-AzAccount
}

実行すると以下のような感じです。

認証~取得まで
保存先の指定
連続した取得の確認

毎回認証するのも面倒なのでサブスクリプション内のジョブであれば連続して指定できるようにしました。
これで今後もさらっと環境設定が取得できるようになりました。

振り返り

 今回はささっと環境変数を取得できるを目的にしており、わずか3コマンドで取得出来ているので目的は達成できているのかなと思います。
 Azure PowerShellはARMを経由しているため、BatchAccountを取得したり、Jobを取得したり、それこそAz.Batch以外のModuleをインストールして他のサービスの情報を取得することも可能です。
 ツールの入力を減らしたり、他のサービスからデータ取得したりと簡単に作成できそうでした。

おわりに

KENTEMでは、様々な拠点でエンジニアを大募集しています! 建設×ITにご興味頂いた方は、是非下記のリンクからご応募ください。 recruit.kentem.jp career.kentem.jp