AWS IAMロールからAzureの権限を取得する(terraform / azure cli)

AzureのWorkload Identity フェデレーションを使って、AWS IAMロールからAzureの操作権限を取得してみる。

まず、outbound-web-identity-federationを有効にする。

aws iam enable-outbound-web-identity-federation
{
    "IssuerIdentifier": "https://xxx.tokens.sts.global.api.aws"
}

※terraform: https://registry.terraform.io/providers/-/aws/latest/docs/resources/iam_outbound_web_identity_federation

次にAzureADのエンタープライズアプリケーションを定義する。

provider "azurerm" {
  resource_provider_registrations = "none"
  features {}
}

data "azurerm_subscription" "current" {
}

resource "azuread_application" "aws_federation" {
  display_name = "aws-iam-role-federation-app"
}

resource "azuread_service_principal" "aws_federation_sp" {
  client_id = azuread_application.aws_federation.client_id
}

resource "azuread_application_federated_identity_credential" "aws_link" {
  application_id = azuread_application.aws_federation.id
  display_name   = "aws-iam-role-link"
  description    = "AWS IAM ロールからのアクセスを許可"

  issuer = "https://xxx.tokens.sts.global.api.aws" # IssuerIdentifier

  # 信頼する AWS IAM ロールの ARN
  subject = "arn:aws:iam::123456789012:role/MyRole"

  audiences = ["api://AzureADTokenExchange"]
}

# aws_federation_spに適当な権限を付与
resource "azurerm_role_assignment" "example" {
  scope                = data.azurerm_subscription.current.id
  role_definition_name = "Reader"
  principal_id         = azuread_service_principal.aws_federation_sp.object_id
}

AWS側でget-web-identity-tokenを使って取得したトークンでazログインする

#!/bin/bash
set -e

TENANT_ID="xxx"
CLIENT_ID="yyy" # aws-iam-role-federation-appのApplication (client) ID

AWS_TOKEN=$(aws sts get-web-identity-token \
  --audience "api://AzureADTokenExchange" \
  --signing-algorithm RS256 \
  --query "WebIdentityToken" \
  --output text)

az login --service-principal \
  -u "$CLIENT_ID" \
  -t "$TENANT_ID" \
  --allow-no-subscriptions \
  --federated-token "$AWS_TOKEN"
$ ./az-login.sh
$ az account show
{
  "environmentName": "AzureCloud",
  "homeTenantId": "xxx"
  "id": "yyy",
  "isDefault": true,
  "managedByTenants": [],
  "name": "...",
  "state": "Enabled",
  "tenantId": "xxx",
  "user": {
    "name": "zzz"
    "type": "servicePrincipal"
  }
}

参考