仕組み
TerraProviderをテナントとパイプラインに設定する。
TerraProviderをセットアップするエンジニアが知っておくべきこと:サインインの仕組み、要求される権限、最初のプランの構成、既存テナントをコード管理下に置く方法。
- terraprovider/microsoft365wp
- Terraform and OpenTofu
- 10 ビルド
- バージョン 0.20.2
4ステップで完成する最初のプラン
他のAzureプロバイダーのセットアップとほぼ同じ手順で、サインインの仕組みも共通している。
Entra ID にアプリを登録する。
シングルテナント、リダイレクトURIは不要。アプリケーション(クライアント)IDとディレクトリ(テナント)IDを控えておく。Graph権限を付与する。
管理対象オブジェクトに必要なアプリケーション権限を追加し(下の表を参照)、管理者の同意を付与する。プロバイダーを宣言する。
ARM_TENANT_IDとARM_CLIENT_IDを設定し、初回テスト用にARM_CLIENT_SECRETも追加する。パイプラインでは、代わりにOpenID Connectを使用する(後述)。terraform { required_providers { microsoft365wp = { source = "terraprovider/microsoft365wp" } }}provider "microsoft365wp" {}
プランを実行する。
リソースを1つ(例:コンプライアンスポリシー)記述し、terraform planまたはtofu planを実行する。applyするまでテナントに変更は加わらない。resource "microsoft365wp_device_compliance_policy" "windows_defender" { display_name = "Windows - Defender for Endpoint" windows10 = { device_threat_protection_enabled = true } scheduled_actions_for_rule = [{ scheduled_action_configurations = [{ action_type = "block" grace_period_hours = 6 }] }] assignments = [{ target = { all_licensed_users = {} } }]}
サンプルデータ。
要求されるGraph権限
管理者の同意が必要なアプリケーション権限。管理対象オブジェクトに必要なものだけを付与すること。ここに記載されていないリソースの権限は、各リソースのドキュメントページに記載されている。
| 権限 | 許可される操作 |
|---|---|
| DeviceManagementConfiguration.ReadWrite.All | Intune デバイス構成とポリシー |
| DeviceManagementApps.ReadWrite.All | Intune アプリ |
| DeviceManagementServiceConfig.ReadWrite.All | Intune サービス構成(登録など) |
| Policy.ReadWrite.ConditionalAccess | 条件付きアクセスポリシー |
| Policy.Read.All | 組織のポリシーの読み取り |
| Application.ReadWrite.All | アプリケーション |
| Directory.ReadWrite.All | ディレクトリデータ |
| Group.ReadWrite.All | グループ |
| User.ReadWrite.All | ユーザーの完全なプロファイル |
| CloudPC.ReadWrite.All | Windows 365 構成 |
出典:プロバイダーガイド「Configuring a Service Principal for managing EntraID」。
azuread プロバイダーと同じサインイン設定
プロバイダーは azuread プロバイダーと同じ ARM_* 設定を読み取る。ARM_TENANT_ID と ARM_CLIENT_ID を設定したら、認証方式を選択する。
| 方式 | 適したシナリオ | 有効化方法 |
|---|---|---|
| OpenID Connect, GitHub Actions | シークレットを保存しないワークフロー | ARM_USE_OIDC=true |
| OpenID Connect, Azure DevOps | サービス接続を使用するパイプライン | ARM_USE_OIDC=trueARM_ADO_PIPELINE_SERVICE_CONNECTION_ID |
| OpenID Connect, any issuer | IDトークンを発行するその他のCIシステム | ARM_USE_OIDC=trueARM_OIDC_TOKEN / ARM_OIDC_TOKEN_FILE_PATH |
| Client certificate | 証明書を保持するランナー | ARM_CLIENT_CERTIFICATE / ARM_CLIENT_CERTIFICATE_PATH |
| Client secret | 初回テスト、ラボ環境 | ARM_CLIENT_SECRET / ARM_CLIENT_SECRET_FILE_PATH |
| Managed identity | Azure上のランナー | ARM_USE_MSI=true |
| AKS workload identity | Azure上のKubernetesで動作するランナー | ARM_USE_AKS_WORKLOAD_IDENTITY=true |
| Azure CLI | ローカルマシン | デフォルトで有効。ARM_USE_CLI=false で無効化できる |
各設定はプロバイダー引数としても指定できる(use_oidc、client_certificate_path など)。プロバイダーのOpenID Connectガイドでは、Entra ID がGitHubリポジトリを信頼するよう設定する方法を説明している。まとめると:OpenID Connect(GitHub Actions、Azure DevOps、任意のOIDCトークン)、クライアント証明書、クライアントシークレット、マネージドID、AKSワークロードID、Azure CLI。
4つのクラウド
environment または ARM_ENVIRONMENT を設定すると、プロバイダーは対応するクラウドの Microsoft Graph エンドポイントに接続する。対象はglobal、US Government L4、US Government L5(DoD)、Chinaの4つ。
環境
- global (also public)
- 商用クラウド(デフォルト)
- usgovernmentl4 (also usgovernment)
- US Government L4
- usgovernmentl5 (also dod)
- US Government L5 (DoD)
- china
- Microsoftの中国向けクラウド
- 独自エンドポイント
metadata_hostorARM_METADATA_HOSTNAME
プランが監視する対象
- 省略したコレクションはデフォルトで空になるため、追加されたメンバー、除外またはアプリは差分として表示される。
- 状態が指定されていない新しい条件付きアクセスポリシーは
enabledForReportingButNotEnforcedとして作成される。 - 各属性のデフォルト値はリソースのドキュメントページに記載されており、プロバイダーデフォルトとして明示されている。
注意点として、ポータルで有効にしてから無効に戻した設定が、未設定ではなく false として返ってくることがある。その場合、次のプランで1件の変更として表示されるが、一度 apply すれば解消される。
ポータルでの操作: 前回のapply以降、変更はありません。
microsoft365wp_conditional_access_policy.require_mfa_admins: Refreshing state... [id=2b7f9c3e-8d41-4f6a-b0e2-5c9a1d7e3f80]No changes. Your infrastructure matches the configuration.
resource "microsoft365wp_conditional_access_policy" "require_mfa_admins" { display_name = "Require MFA for admins" state = "enabled" conditions = { users = { include_roles = ["62e90394-69f5-4237-9190-012177145e10"] } applications = { include_applications = ["All"] } } grant_controls = { operator = "OR" built_in_controls = ["mfa"] }}
既存テナントを2フェーズでエクスポート・インポートする
クイックスタートリポジトリには、モジュール、GitHub Actionsワークフロー、PowerShellエクスポートを含むリファレンス構成が用意されている。ポリシーがグループやフィルターを参照するため、エクスポートは2フェーズで行う。
グループ、フィルター、通知テンプレートをエクスポートする。
クイックスタートのモジュールに書き出され、種類ごとにマッピングファイルが生成される。メール対応グループは明示的に指定しない限り除外される。インポートする。
ツールが Terraform または OpenTofu を呼び出し、エクスポートされたすべてのオブジェクトをステートにインポートする。コンプライアンスポリシーと構成ポリシーをエクスポートする。
設定カタログとエンドポイントセキュリティポリシーは構成ポリシーとして扱われる。各エクスポートには、Graphが返したデータの生JSONダンプも保存される。インポートする。
同じツールを使い、第2フェーズとして実行する。プランを実行する。
プランには残っている差分が表示される。エクスポートできない属性もあるため、最初のクリーンなプランが得られるまでに若干の修正作業が必要になる。
オブジェクト1件ずつの処理
エクスポートがカバーしていないオブジェクトについては、小さなスクリプトを使い、任意のリソースタイプのオブジェクト1件分のTerraformファイルをIDを指定して生成できる。Terraform自身のコード生成機能を利用するため、ファイルにはプロバイダーがテナントから読み取る内容がそのまま記録される。
GitHubのクイックスタートアプリ、パッケージ、割り当てを1つのリソースで管理する
microsoft365wp_mobile_app は 21 種類のアプリタイプに対応している。.intunewin, MSI, APPX/MSIX, DMG, PKG 種類のパッケージについては、プロバイダーがファイルを暗号化して Intune にアップロードする。この処理は source_sha256 が変わったときのみ再実行される。割り当ても同じリソース内に定義できる。全デバイス、ライセンス保有ユーザー全員、グループ、除外グループのいずれかを対象に、インクルードまたはエクスクルードフィルターを組み合わせて指定できる。locals { agent_package = "${path.module}/packages/contoso-agent-4.2.1.intunewin" agent_meta = provider::microsoft365wp::parse_intunewin_metadata(local.agent_package)}resource "microsoft365wp_mobile_app" "contoso_agent" { display_name = "Contoso Agent" publisher = "Contoso" win32_lob = { file_name = local.agent_meta.file_name setup_file_path = local.agent_meta.setup_file install_command_line = "setup.exe /quiet" uninstall_command_line = "setup.exe /uninstall /quiet" detection_rules = [{ filesystem = { detection_type = "exists" path = "C:\\Program Files\\Contoso\\Agent" file_or_folder_name = "agent.exe" } }] source_file = local.agent_package source_sha256 = filesha256(local.agent_package) } assignments = [{ target = { group = { group_id = "3d9b2f61-7a4e-4c18-9e05-6f2a8b1c4d93" } } settings = { win32_lob = {} } }]}
microsoft365wp_mobile_app.contoso_agent: Refreshing state... [id=5e0c8a17-2d94-4b6f-a3e1-9c7d0f2b8a46]No changes. Your infrastructure matches the configuration.
# microsoft365wp_mobile_app.contoso_agent will be updated in-place ~ resource "microsoft365wp_mobile_app" "contoso_agent" { ~ win32_lob = { ~ source_file = "./packages/contoso-agent-4.2.1.intunewin" -> "./packages/contoso-agent-4.3.0.intunewin" ~ source_sha256 = "9f2c41d0…" -> "b71e05aa…" # (6 unchanged attributes hidden) } # (4 unchanged attributes hidden) }Plan: 0 to add, 1 to change, 0 to destroy.
サンプルデータ。
Windows
Win32 (.intunewin)、MSI、APPX/MSIX、Microsoft Store(新、WinGet経由)、Microsoft Store(レガシー)、Microsoft Edge、Microsoft 365 Apps、Webリンク。
macOS
DMG、PKG、Microsoft Edge、Microsoft Defender、Microsoft 365 Apps、Webクリップ。
iOS and iPadOS
App Storeアプリ、マネージドiOSストアアプリ、Webクリップ。
Android
Google Playストアアプリ、マネージドGoogle Playアプリ、マネージドAndroidストアアプリ。
全プラットフォーム
Webリンク。
1つのリポジトリで複数テナントを管理する
tenant_id を指定したブロックを宣言し、ベースラインをモジュールとして記述してテナントごとに1回呼び出す。各ブロックは独立してサインインするため、テナントごとに独自の権限を持つサービスプリンシパルを割り当てられる。- テナント間の差異はモジュール変数として表現され、レビュー時に確認できる。
- 新しいテナントの追加は、プロバイダーブロック1つ、モジュール呼び出し1つ、プラン実行1回で完結する。
provider "microsoft365wp" { alias = "contoso" tenant_id = "8a1f3c2e-5b7d-4e90-a6c4-2d9e7f1b0c35"}provider "microsoft365wp" { alias = "fabrikam" tenant_id = "e4c27b91-0d3a-4f86-b5e2-7a1c9d0f6b48"}module "baseline_contoso" { source = "./baseline" providers = { microsoft365wp = microsoft365wp.contoso }}module "baseline_fabrikam" { source = "./baseline" providers = { microsoft365wp = microsoft365wp.fabrikam } allow_byod = true}
サンプルデータ。
Graph throttlingへの対処方法
Microsoft Graph はクライアントが送信できるリクエスト数を制限しており、大規模テナントに対するプランでは多数のリクエストが発生する。プロバイダーは自動的に待機してリトライする。
リトライ
- リクエストあたりのリトライ回数
- 最大 10 回
- リトライ間の待機時間
- 3〜60秒
- Retry-After が 0 の場合
- バックオフ時間まで延長される。GraphがRetry-After: 0を返すことは多く、即時リトライはほとんど効果がないため。
まずクイックスタートから始める。
リポジトリをクローンし、テスト用テナントに向けてプランを実行する。Community Editionは 99 ユーザー以下の組織であれば無料で利用できる。