Skip to content

Instantly share code, notes, and snippets.

@kkamegawa
Last active February 18, 2024 05:40
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kkamegawa/c004514c4147ef3f65bd6aa54246d544 to your computer and use it in GitHub Desktop.
Save kkamegawa/c004514c4147ef3f65bd6aa54246d544 to your computer and use it in GitHub Desktop.

Azure Resource Managaerサービス接続におけるWorkload identity federationの一般提供を開始しました - Sprint 234

In this article

Workload ID federationがAzure Pipelinesで一般的に利用可能になったことをお知らせします!Azureサービス接続でシークレットや証明書を管理する必要がなく、合理化されたエクスペリエンスを楽しむことができます。

今回のアップデートでは、GitHubとAzure Boardsの統合強化の一環として、新機能もプレビューしています。GitHubのpull requestやコミットに直接リンクできるようになりました。ウィンドウを切り替えたり、コピー&ペーストしたりする必要はもうありません。必要なリポジトリを選択し、必要なpull requestやコミットを見つけてリンクするだけです!

これらの機能の詳細については、リリースノートをご覧ください。

代替クレデンシャルは2020年3月に正式に廃止されましたが、一部の既存ユーザーは、既存の代替クレデンシャル(alternate credentials)を継続して使用することで、グランドファザーリング(訳注:免除などの意味があるそうです)されました。潜在的な混乱を避けるために、個人アクセストークンやManaged Identityなど、当社が提供する利用可能な認証メカニズムのいずれかに切り替えてください。

Azure DevOps APIを利用するためには5年ごとに、Azure DevOps OAuthアプリのクライアントシークレットを更新して、アクセスとリフレッシュトークンを生成する必要があります。クライアントシークレットの有効期限が近づくと、新しいクライアントシークレットを独自に生成できるようになり、カスタマーサポートに頼らずにチームで自由に管理できるようになります。シークレットのローテーションを柔軟にスケジューリングすることで、有効期限が切れたシークレットによる交換を待つ顧客の潜在的な停止時間を最小限に抑えることができます。

Screenshot of Select a geography.

この新機能は、あなたのプロフィールページにあるAzure DevOpsアプリの各ページで確認できます。この新しいステップの詳細については、Azure DevOps OAuthガイドをご覧ください。

コードスキャンとシークレットスキャンのアラートの詳細ページに、アラートが発生したコードの1行以上を示すコードスニペットが表示されるようになりました。Azure DevOpsリポジトリ内の元のファイルに移動するには、コードスニペットの上にあるファイル名をクリックします。

Screenshot of case-sensitive middleware path.

検出されたシークレットの最後の6文字を切り捨てて、シークレットアラートの概要画面に表示するようになりました。この機能は、同じシークレットタイプのシークレットが複数公開されている場合に便利で、特定のシークレットがどこにあるかを素早く特定できます。

Screenshot of secret alerts list.

CodeQL品質クエリからのアラート結果に対して、Error, Warning, Noteといった新しいアラート重大度が発生するようになりました。各品質アラートの重大度には、重大度のスケーリングを示す独自のバッジと色があります。また、セキュリティアラートの低重度から重要度の尺度と同様に、これらの各重度のフィルタリングも可能です。

Screenshot of code scanning alerts list and severity filter.

以前、AzureサブスクリプションをリンクすることなくAzure DevOps organizationのリポジトリに対してAdvanced Securityを有効にした場合、それらのリポジトリで Advanced Security が自動的に無効になっていることに気づかれると思います。Advanced Securityを再度有効にするには、課金対象とするAzureサブスクリプションをorganizationに追加します。サブスクリプションを追加または変更する方法の詳細については、Change Azure Subscriptionを参照してください。

最近リリースされたAdvanced Security APIの様々なアップデートを紹介します。

  • GET Alerts APIは、アラートの増分リストを返し、この日付以降に変更されたアラートのみを返す新しいパラメータModifiedSinceをサポートするようになりました。詳細については、Alerts - Listを参照してください。
  • GET SARIFs APIは、SARIFアップロードの失敗のトラブルシューティングに役立つ特定のアップロードエラーを返すようになりました。詳細については、SARIFsを参照してください。
  • OrganizationまたはProjectのAdvanced Security有効化ステータスを取得または更新するための新しいエンドポイントが2つあります。どちらのエンドポイントも、Advanced Security が有効になっているリポジトリのリストを返します。詳細については、Org - EnablementまたはProject - Enablementを参照してください。
  • 組織またはプロジェクトのアクティブなコミッター数の推定値を取得し、Advanced Security メーターの推定使用量を反映するための新しいエンドポイントが2つあります。詳細については、Org Meter Usage EstimateまたはProject Meter Usage Estimateを参照してください。

以前は、Advanced Securityが有効になっている場合のみ、3つのAdvanced Security権限ビットがリポジトリごとに割り当て可能な権限として存在していました。現在では、これらのパーミッションはデフォルトでRepositories > Securityパーミッションペインで利用可能であり、Advanced Securityが有効でなくても割り当て可能です。

Screenshot of Advanced Security permissions.

ワークアイテムと GitHub のpull requestやコミットを結びつけるには、ふたつの方法があります。pull requestでAB#構文を使うか、作業項目から直接リンクするかです。現在では、GitHubのpull requestのURLをコピーして、リンクを追加するときに貼り付けるという手順になっています。そのため、複数のウィンドウを開いてGitHubとAzure DevOpsを切り替える必要があります。

今回のスプリントでは、GitHubのpull requestやコミットへのリンク時に検索機能を有効にすることで、より優れたエクスペリエンスを提供できるようになりました。検索して目的のリポジトリを選択し、ドリルダウンして特定のpull requestやコミットを見つけてリンクします。複数のウィンドウを変更したり、もうコピー&ペーストしたりする必要はありません(そのオプションはまだありますが)。

Gif to demo add link.

注意事項

この機能はNew Boards Hub previewを有効にする必要があります。

この機能へのアクセスにご興味がある方は、組織名(dev.azure.com/{organization name})を添えて直接メールをお送りください。

今回のリリースでは、アクセシビリティとページリフローを中心に、New Boards Hubプレビューに様々な機能強化を導入しました。

以下は、400%ズームまで適応するページリフローの変更の例です。

Gif to demo new boards hub improvements.

さらに、ワークアイテムフォーム、ボード、バックログページ全体のパフォーマンス強化を展開しました。これらの変更により、新しいBoardは以前のBoardとそん色ないパフォーマンスが期待できます。

プロジェクトの設定に応じて、DevelopmentをコントロールするDeploymentコントロールをワークアイテムから削除します。例えば、プロジェクトの設定でReposやPipelinesをオフにすることもできます。

Screenshots of DevOps services.

ワークアイテムに移動すると、対応するDevelopmentとDeploymentのコントロールがフォームから非表示になります。

Screenshots of related work.

GitHubリポジトリをAzure Boardsに接続することにすると、GitHubリポジトリ用の開発コントロールが表示されます。

Screenshots of development control .

9月にシークレットを使用せずにAzureサービス接続を構成する機能を発表しました。それ以来、多くのお客様がこの機能を採用し、この機能が一般的に利用できるようになったことを発表できることを嬉しく思います。

まだWorkload ID federationを使用していない場合は、以下の方法で有効期限の切れたシークレットを使用して失敗する心配のないAzureサービス接続を利用が可能です。

Workload ID federationを使用して新しい Azure サービス接続を作成するには、Azure サービス接続作成エクスペリエンスでWorkload ID federation(Automatic)を選択します:

Screenshot of Workload identity federation (automatic).

以前に作成した Azure サービス接続を変換するには、接続を選択した後に"Convert"アクションを選択します:

Screenshot of Convert action.

複数のサービス接続を変換するには、このPowerShellスクリプトなどの自動化を使用できます。

#!/usr/bin/env pwsh
<# 
.SYNOPSIS 
    Convert multiple Azure Resource Manager service connection(s) to use Workload identity federation

.LINK
    https://aka.ms/azdo-rm-workload-identity-conversion

.EXAMPLE
    ./convert_azurerm_service_connection_to_oidc_simple.ps1 -Project <project> -OrganizationUrl https://dev.azure.com/<organization>
#> 
#Requires -Version 7.3

param ( 
    [parameter(Mandatory=$true,HelpMessage="Name of the Azure DevOps Project")]
    [string]
    [ValidateNotNullOrEmpty()]
    $Project,

    [parameter(Mandatory=$true,HelpMessage="Url of the Azure DevOps Organization")]
    [uri]
    [ValidateNotNullOrEmpty()]
    $OrganizationUrl
) 
$apiVersion = "7.1"
$PSNativeCommandArgumentPassing = "Standard" 

#-----------------------------------------------------------
# Log in to Azure
$azdoResource = "499b84ac-1321-427f-aa17-267ca6975798"
az login --allow-no-subscriptions --scope ${azdoResource}/.default
$OrganizationUrl = $OrganizationUrl.ToString().Trim('/')

#-----------------------------------------------------------
# Retrieve the service connection
$getApiUrl = "${OrganizationUrl}/${Project}/_apis/serviceendpoint/endpoints?authSchemes=ServicePrincipal&type=azurerm&includeFailed=false&includeDetails=true&api-version=${apiVersion}"
az rest --resource $azdoResource -u "${getApiUrl} " -m GET --query "sort_by(value[?authorization.scheme=='ServicePrincipal' && data.creationMode=='Automatic' && !(isShared && serviceEndpointProjectReferences[0].projectReference.name!='${Project}')],&name)" -o json `
        | Tee-Object -Variable rawResponse | ConvertFrom-Json | Tee-Object -Variable serviceEndpoints | Format-List | Out-String | Write-Debug
if (!$serviceEndpoints -or ($serviceEndpoints.count-eq 0)) {
    Write-Warning "No convertible service connections found"
    exit 1
}

foreach ($serviceEndpoint in $serviceEndpoints) {
    # Prompt user to confirm conversion
    $choices = @(
        [System.Management.Automation.Host.ChoiceDescription]::new("&Convert", "Converting service connection '$($serviceEndpoint.name)'...")
        [System.Management.Automation.Host.ChoiceDescription]::new("&Skip", "Skipping service connection '$($serviceEndpoint.name)'...")
        [System.Management.Automation.Host.ChoiceDescription]::new("&Exit", "Exit script")
    )
    $prompt = $serviceEndpoint.isShared ? "Convert shared service connection '$($serviceEndpoint.name)'?" : "Convert service connection '$($serviceEndpoint.name)'?"
    $decision = $Host.UI.PromptForChoice([string]::Empty, $prompt, $choices, $serviceEndpoint.isShared ? 1 : 0)

    if ($decision -eq 0) {

        Write-Host "$($choices[$decision].HelpMessage)"
    } elseif ($decision -eq 1) {
        Write-Host "$($PSStyle.Formatting.Warning)$($choices[$decision].HelpMessage)$($PSStyle.Reset)"
        continue 
    } elseif ($decision -ge 2) {
        Write-Host "$($PSStyle.Formatting.Warning)$($choices[$decision].HelpMessage)$($PSStyle.Reset)"
        exit 
    }

    # Prepare request body
    $serviceEndpoint.authorization.scheme = "WorkloadIdentityFederation"
    $serviceEndpoint.data.PSObject.Properties.Remove('revertSchemeDeadline')
    $serviceEndpoint | ConvertTo-Json -Depth 4 | Write-Debug
    $serviceEndpoint | ConvertTo-Json -Depth 4 -Compress | Set-Variable serviceEndpointRequest
    $putApiUrl = "${OrganizationUrl}/${Project}/_apis/serviceendpoint/endpoints/$($serviceEndpoint.id)?operation=ConvertAuthenticationScheme&api-version=${apiVersion}"
    # Convert service connection
    az rest -u "${putApiUrl} " -m PUT -b $serviceEndpointRequest --headers content-type=application/json --resource $azdoResource -o json `
            | ConvertFrom-Json | Set-Variable updatedServiceEndpoint
    
    $updatedServiceEndpoint | ConvertTo-Json -Depth 4 | Write-Debug
    if (!$updatedServiceEndpoint) {
        Write-Debug "Empty response"
        Write-Error "Failed to convert service connection '$($serviceEndpoint.name)'"
        exit 1
    }
    Write-Host "Successfully converted service connection '$($serviceEndpoint.name)'"
}

詳細はドキュメントをご覧ください。

昨年10月、Pipelinesエージェントのメモリとディスクの使用量を追跡する機能が追加されました。

メモリやディスク容量の制限などのリソース制約がエージェントにあることをお客様に認識していただくために、リソース制約をより見やすくしました。

Screenshot of Limited memory and disk space warning.

上記のメッセージが表示された場合、タスクがエージェントの既定容量以上のリソースを使用しているため、エージェントが応答せず、パイプラインジョブが失敗する可能性があります。

"We stopped hearing from the agent"

このような場合、verbose logsを有効にして、より詳細なリソース利用メッセージを取得し、エージェントがどこでリソース不足になったかを追跡してください。セルフホストエージェントを使用している場合、エージェントに十分なリソースがあることを確認してください。

Azure Pipelinesは、ふたつのバージョンのエージェントパッケージを提供します。

  • vsts-agent-* パッケージは、Node 6を使用して実行するタスクをサポートします。
  • pipelines-agent-* パッケージは、実行に Node 6を使用するタスクをサポートしません。

Self-hostedエージェントを作成するお客様は、Pipeline エージェントrelease pageからダウンロードできます。エージェントに含まれる Node のバージョンはタスクの実行に使用されます。Node runner versionsを参照してください。

エージェント登録後、pipelines-agent-*パッケージからインストールされたエージェントは、エージェントに含まれておらず、organization設定の'Task restrictions'でブロックされていないNodeバージョンをダウンロードするようになります。これにより、顧客はpipelines-agent-*エージェントパッケージを使用し、organization設定の`Task restrictions'で Node 6 のインストールを制御できます。

Approvalsは、配備にsign off(訳注:最終承認)するために使用できます。しかし、承認された時刻と配備を開始する時刻が一致しない場合があります。たとえば、あなたがレビューした特定のデプロイメントについて、あなたはそれが境界外のものであることを知っています。すぐに展開することはできず、夜間に展開する必要があるとします。

このようなシナリオをカバーするために、YAMLパイプラインの承認を延期するオプションを追加しました。パイプラインの実行を承認し、いつ承認を有効にするかを指定できるようになりました。

Screenshot of approve a pipeline run.

Defer approvalを選択すると、承認が有効になる時間を設定できます。

Screenshot of Defer approval.

Screenshot of after_approval_deferred.

承認はチェックパネルで延期と表示されます。延期された時間が経過すると、承認は有効になります。

Screenshot of  approval is effective.

このスプリントでは、承認とチェックの実行順序を指定できます。

Approval and checksにより、本番環境へのデプロイを制御できます。たとえば、リポジトリのmainブランチ上で実行されるパイプラインだけが、本番環境のARMサービス接続を使用できるように指定できます。さらに、人間による承認と、システムがパフォーマンス チェックに合格することを要求できます。

今日まで、排他ロック以外のすべての承認とチェックは並行して実行されていました。つまり、デプロイプロセスで、手動で承認する前にパフォーマンスチェックに合格する必要がある場合、Azure Pipelinesでこれを強制することはできませんでした。承認指示や内部プロセスのドキュメントに頼らざるを得ませんでした。

今回のスプリントでは、Approvals and Checksにシーケンス機能を導入しました。Approvals and Checksには5つのカテゴリがあります:

  1. 静的チェック: Branch control, Required template, Evaluate artifact
  2. 事前動的チェック Approval
  3. 動的チェック:Approval, Invoke Azure Function, Invoke REST API, Business Hours, Query Azure Monitor alerts
  4. 事後動的チェック Approval
  5. Exclusive lock

Screenshot of add check.

注文はApprovals and checksタブにも表示されます。

Screenshot of approvals and checks tab.

各カテゴリ内では、チェックは並行して実行されます。つまり、Invoke Azure Function チェックと Business hours チェックがある場合、これらは同時に実行されます。

Screenshot of checks for deploy.

チェックカテゴリはひとつずつ実行され、ひとつが失敗すると残りのチェックは実行されません。つまり、Branch controlのチェックとApprovalがある場合、Branchコントロールが失敗すると、Approvalも失敗します。そのため、無駄なメールが送信されることはありません。

Screenshot of checks for deploy fail.

すべての動的チェックが実行された後、post-dynamic checks Approvalを使用してデプロイにsign offすることも、pre-dynamic checks Approvalを使用して動的チェックに進む前に手動で検証を行うこともできます。

間違ったYAMLパイプラインは時間と労力の無駄につながります。パイプラインの編集の生産性を向上させるために、エディタの保存ボタンを押したときにYAMLのバリデーションも行うように変更します。

Screenshot of  new button.

Screenshot of validate and save.

もし、パイプラインにエラーがあっても保存できます。

Screenshot of errors detected.

Screenshot of errors list.

また、Validateのエクスペリエンスも改善され、エラーが一覧でわかりやすく表示されるようになりました。

権限のないユーザーがパイプラインをビルドポリシーとして設定できないようにしました。

以前は、新しいビルドポリシーを追加するとき、ドロップダウンリストから任意のパイプラインを実行するように設定できました(Queue buildsの権限がないパイプラインも含む)。同様に、既存のビルドポリシーを編集して、Queue builds権限のないパイプラインを実行するように設定することもできました。

今回の更新で、ユーザーが任意のパイプライン実行できないようにしています。ユーザーが指定したパイプラインのQueue buildsパーミッションを拒否された場合、新しいビルドポリシーを追加する際に、そのパイプラインはドロップダウンで無効(グレーアウト)状態として表示されます。

以下の画像は"Sandbox"という名前のパイプラインで、Queue builds権限が拒否されている状態を示しています。

Screenshot of permissions for Sandbox.

以下の画像は、Queue builds権限が拒否されたユーザーが新しいビルドポリシーを追加しようとすると、ドロップダウンで "Sandbox"という名前のパイプラインが無効になる(グレーアウトする)ことを示しています。

Screenshot of add build policy.

"Sandbox"という名前のパイプラインを実行するように設定されたビルドポリシーがすでに存在する場合、Queue builds権限を持たないユーザーは、ビルドポリシーを編集したり表示したりできません。このケースを以下の画像に示します。

Screenshot of build validation.

このようなポリシーを削除しようとすると、削除の確認を求めるポップアップダイアログが表示されます。

Screenshot of confirm deletion.

これらの変更は、ビルドポリシーの作成または編集を行うAPI呼び出しにも適用されます。これらのアクションのいずれかが、Queue builds権限を持たないユーザーIDを使用して実行された場合、呼び出しは失敗し、「TFS.WebApi.Exception: TF401027:このアクションを実行するには、このパイプラインのQueueBuild権限が必要です」というエラーコードとエラーメッセージが表示されます。

Queue builds権限を持たないuser identityを使用してAPI経由でビルドポリシーを削除すると、削除は成功し、警告も防止も行われません(API経由の削除の動作に変更はありません)。

2024年2月16日より、Azure ArtifactsでのRust Cratesが一般提供開始され、サポートされます。他のサポートされるプロトコルと同じ価格モデルを使用して、課金メーターが有効になります。

Azure Artifactsが npm auditおよびnpm audit fixコマンドをサポートするようになった。この機能により、ユーザーは安全でないパッケージのバージョンを自動的に更新することで、プロジェクトの脆弱性を分析し、修正できます。詳細については、 Use npm audit to detect and fix package vulnerabilitiesをご覧ください.

注意事項

ここで議論されている機能は今後二~三週にわたって順次展開されます。

Azure DevOpsサービスを体験してみてください。

これらの機能についてどう思っているかお聞きしたいと思います。 フィードバックメニューを使用して問題を報告するか、提案を提出してください。

Make a suggestion

アドバイスや回答を必要とする質問がある場合、Stack Overflowコミュニティで聞いてください。

ありがとうございました。

Dan Hellem

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment