
【こんなお悩み、ありませんか?(Problem Statement)】
-
タグ乱立:部門ごとに命名・大文字小文字・言語がバラバラ。自由記述で集計不能。
-
コスト割当の失敗:Cost Management でタグ粒度の配賦ができず、部門/案件別の正確なショー/チャージバックが不可能。
-
証跡欠落:規程・契約(DPA/SCC/越境規制)とリソースの突合キーがなく、監査のたびに手作業紐付け。
-
例外管理の不透明:POCや緊急対応が標準を侵食し、準拠率が恒常的に低下。
結論:タグは技術資産であり証跡であり法務リスク管理の根幹。
ARG × Policy × IaC で “最初から最後まで” を制御します。
【当社のソリューション(Principles × 実装の骨格)】
1) 標準化(タクソノミ)
-
キー名・値集合・必須/任意・命名規則・表記・言語を先に固定。
-
ルール:キーは PascalCase、値は小文字の列挙(またはコード)、フリーテキストは Notes に隔離。秘密情報はタグに置かない。
2) 強制力(Policy as Code)
-
Deny / Append / Modify / Audit を段階適用:未然防止 → 自動補正 → 例外の“明示”。
-
例外は必ず Exemption に記録(根拠・期限・承認者)。期限切れの自動失効運用をルール化。
3) 即時可視化(ARG)
-
タグカバレッジ、逸脱、列挙外値、RG継承の不一致を1秒集計。
-
月次KPIに直結する定期エクスポート基盤を整備。
4) デプロイ点制御(IaC)
-
Bicep/Terraform でデプロイ時点に標準タグ付与。
-
CI/CD に what-if と Policy準拠率ゲートを実装し、非準拠をデプロイ前に遮断。
5) 証跡主義(法務・監査の主キー統合)
-
CostCenter/ProjectId/OwnerUpn を変更管理・アクセス証跡と名寄せ。
-
DpaId/Residency/RetentionClass/DataClass で DPA/SCC/越境/保持 の台帳突合を自動化。
【タグ標準(タクソノミ)設計:推奨キーセット】
必須(列挙/形式検証含む)
-
CostCenter(部門コード/会計科目)※列挙
-
ProjectId(案件/製品ID、工数・コスト突合キー)
-
OwnerUpn(責任者UPN)※形式検証
-
Environment(prod/stg/dev/sbx)※列挙
-
AppName(サービス/アプリ名)
-
DataClass(public/internal/confidential/restricted)※列挙
任意(業務により必須化)
-
BCPTier(Tier1/2/3)
-
Residency(jp/eu/us/... 等の短コード)
-
DpaId(委託/契約管理ID)
-
RetentionClass(保持 30/180/365d/7y など)
判断基準:会計・配賦に直結するものは必須。監査・法務突合に必要な識別子は対象業務で必須化。
列挙は小文字短コードで表記ブレを排除。
【Policy as Code(代表ポリシー抜粋)】
必須タグ(Deny)
{ "properties": { "displayName": "Require tags: CostCenter, ProjectId, OwnerUpn, Environment, AppName, DataClass", "policyRule": { "if": { "anyOf": [ { "field": "tags['CostCenter']", "exists": "false" }, { "field": "tags['ProjectId']", "exists": "false" }, { "field": "tags['OwnerUpn']", "exists": "false" }, { "field": "tags['Environment']", "exists": "false" }, { "field": "tags['AppName']", "exists": "false" }, { "field": "tags['DataClass']", "exists": "false" } ] }, "then": { "effect": "deny" } } } }
既定値の付与(Append)
{ "properties": { "displayName": "Append default Environment=dev when missing", "parameters": { "tagName": { "type": "String", "defaultValue": "Environment" }, "tagValue": { "type": "String", "defaultValue": "dev" } }, "policyRule": { "if": { "field": "[concat('tags[', parameters('tagName'), ']')]", "exists": "false" }, "then": { "effect": "append", "details": { "field": "[concat('tags[', parameters('tagName'), ']')]", "value": "[parameters('tagValue')]" } } } } }
RG継承(Modify)
{ "properties": { "displayName": "Inherit CostCenter from resource group", "policyRule": { "if": { "allOf": [ { "field": "type", "notEquals": "Microsoft.Resources/subscriptions/resourceGroups" }, { "value": "[resourceGroup().tags['CostCenter']]", "notEquals": "" } ] }, "then": { "effect": "modify", "details": { "operations": [{ "operation": "addOrReplace", "field": "tags['CostCenter']", "value": "[resourceGroup().tags['CostCenter']]" }] } } } } }
例外運用:Exemption に根拠・期限・承認者を必ず記録。期限切れ検知を運用に組み込み、恒久化を防止。
【ARG(Azure Resource Graph)で即時可視化:運用で回すクエリ例】
5.1 必須タグのカバレッジ
Resources | extend costCenter = tostring(tags['CostCenter']), projectId = tostring(tags['ProjectId']), owner = tostring(tags['OwnerUpn']), env = tolower(tostring(tags['Environment'])), app = tostring(tags['AppName']), dataClass = tostring(tags['DataClass']) | extend missing = iff( isempty(costCenter) or isempty(projectId) or isempty(owner) or isempty(env) or isempty(app) or isempty(dataClass), 1, 0) | summarize total=count(), missing=sum(missing), coverage=100.0*(total-missing)/total by subscriptionId | order by coverage asc
5.2 RG継承ドリフト(不一致検出)
let rgTags = ResourceContainers | where type == 'microsoft.resources/subscriptions/resourcegroups' | project subscriptionId, resourceGroup=name, rgCostCenter=tostring(tags['CostCenter']); Resources | project subscriptionId, resourceGroup, id, name, resCostCenter=tostring(tags['CostCenter']) | join kind=leftouter rgTags on subscriptionId, resourceGroup | where isnotempty(resCostCenter) and isnotempty(rgCostCenter) and tolower(resCostCenter) != tolower(rgCostCenter) | project subscriptionId, resourceGroup, name, id, resCostCenter, rgCostCenter
5.3 列挙外値の検出
let ValidEnv = dynamic(["prod","stg","dev","sbx"]); let ValidData = dynamic(["public","internal","confidential","restricted"]); Resources | extend env = tolower(tostring(tags['Environment'])), dataClass = tolower(tostring(tags['DataClass'])) | where (isnotempty(env) and env !in (ValidEnv)) or (isnotempty(dataClass) and dataClass !in (ValidData)) | project name, type, resourceGroup, env, dataClass
5.4 “責任者なし” の是正リスト
Resources | extend owner = tostring(tags['OwnerUpn']) | where isempty(owner) | summarize count() by type | order by count_ desc
運用:クエリを定期エクスポートし、準拠率・列挙外率・ドリフト件数を月次KPIで公表。是正SLAを数値化。
【IaC 統合(Bicep / Terraform)】
Bicep:標準タグの強制付与(例)
param costCenter string param projectId string param ownerUpn string param environment string { allowed: [ 'prod' 'stg' 'dev' 'sbx' ] } param appName string param dataClass string { allowed: [ 'public' 'internal' 'confidential' 'restricted' ] } resource sa 'Microsoft.Storage/storageAccounts@2023-01-01' = { name: 'st${uniqueString(resourceGroup().id, appName)}' location: resourceGroup().location kind: 'StorageV2' sku: { name: 'Standard_LRS' } tags: { CostCenter: costCenter ProjectId: projectId OwnerUpn: ownerUpn Environment: environment AppName: appName DataClass: dataClass } }
Terraform:タグ標準化と Policy アサイン(例)
variable "tags" { type = map(string) default = { CostCenter = "fin-1001" ProjectId = "prj-xyz" OwnerUpn = "owner@contoso.com" Environment = "dev" AppName = "order-api" DataClass = "internal" } } resource "azurerm_resource_group" "rg" { name = "rg-order-api-dev" location = "japaneast" tags = var.tags } resource "azurerm_storage_account" "sa" { name = "st${substr(md5(azurerm_resource_group.rg.id),0,18)}" resource_group_name = azurerm_resource_group.rg.name location = azurerm_resource_group.rg.location account_tier = "Standard" account_replication_type = "LRS" tags = var.tags } resource "azurerm_policy_definition" "req_tags" { name = "require-standard-tags" policy_type = "Custom" mode = "Indexed" display_name = "Require standard tags" policy_rule = file("${path.module}/policies/require-tags.json") } resource "azurerm_policy_assignment" "req_tags_rg" { name = "enforce-standard-tags" display_name = "Enforce standard tags" policy_definition_id = azurerm_policy_definition.req_tags.id scope = azurerm_resource_group.rg.id enforcement_mode = true }
デプロイ前ガードレール:CI/CD に what-if と Policy 準拠率ゲートを設定し、非準拠を出荷前で遮断。
【FinOps・監査・法務との接続(アウトカム)】
-
FinOps:Cost Management を部門/案件/環境/重要度タグで切り出し、月次ショー/チャージバックに直結。
-
監査:タグ=証跡の主キー。CostCenter/ProjectId/OwnerUpn を変更管理・アクセス証跡と紐付け、提出エビデンスを自動生成。
-
法務:DpaId/Residency/RetentionClass/DataClass を用い、DPA/SCC/越境/保持 の台帳突合を自動化。例外は Exemption と運用稼働票で根拠化。
【運用KPI & ダッシュボード(定量化の指標)】
-
Tag Coverage:必須タグ充足率(目標 98%+)
-
Enum Hygiene:列挙外値率(目標 0%)
-
Drift:RG継承不一致(月次0 目標)
-
例外健全性:Exemption 期限切れ0件
-
修復リードタイム:欠損検知 → 是正完了(中央値 < 3 営業日)
KPIは月次レポートで経営層へ提出。改善計画とコスト削減額・統制レベルを併記。
【導入ロードマップ(90日モデル)】
-
週1–2:タグ標準策定(キー/列挙/必須/命名)、Policy設計、ARGタグ一括是正計画
-
週3–4:PoC(Policy as Code・ARG 可視化・IaC 統合)
-
週5–8:段階展開(管理グループ → 重要RG)。例外運用・是正フロー確立
-
週9–12:FinOps 月次レポート/監査エビデンス自動化/KPI 公開
【よくある落とし穴(Anti‑Patterns)】
-
フリーテキスト地獄:列挙定義なし → 分析不能
-
RGだけタグ:子リソースに継承されず、実態と乖離
-
表記ブレ:大文字/日本語/半角全角混在で集計崩壊
-
例外の恒久化:Exemption 期限なし → 実質無秩序
-
タグに秘密情報:キー・資格情報・個人情報をタグ化 → 監査指摘
【サービス(弊所の提供価値)】
私たちができること
-
クラウド法務 × 技術実装 × FinOps を同一チームで支援
-
タグ標準 × Policy × ARG × IaC を**“運用で回る仕組み”**として設計
-
規程・契約・RoPA と タグ/Evidence を同一キーで名寄せし、監査・取引先審査の提示を即時化
-
月次ショー/チャージバック・Exemption 管理・KPI レビューまで伴走し、削減効果と統制の両立を実現
代表メニュー(例)
-
タグ標準&Policy 設計パッケージ(ワークショップ+標準案+PoC)
-
ARG ダッシュボード&エクスポート設計(KPI 定義・運用手順)
-
IaC 統合レビュー(Bicep/Terraform)(テンプレート化・CI/CD ゲート)
-
監査エビデンス自動化支援(台帳突合・提出パック化)
-
FinOps 運用伴走(月次レポート/ショー・チャージバック運用)
価格は環境規模・対象RG数・既存統制レベルにより個別見積。
CTA:導入可否と概算見積を相談する
【FAQ】
Q1. 既にタグはあります。乱立状態からのスタートでも大丈夫?
A. ARG で現状可視化 → 収束ポリシー(Append/Modify) → 準拠率ゲートの順で無停止の是正を設計します。既存値はマッピング表で段階的に正規化します。
Q2. Cost Management 側の配賦はどの粒度で切れますか?
A. CostCenter/ProjectId/Environment/DataClass 等の組合せタグで切り出します。月次エクスポートとの連携で会計・稟議に直結させます。
Q3. 法務や監査との突合キーは何を使いますか?
A. 基本は CostCenter/ProjectId/OwnerUpn。越境や保持が絡む場合は DpaId/Residency/RetentionClass/DataClass を合わせて台帳と自動照合します。
Q4. 例外(Exemption)はどこまで許容しますか?
A. 根拠・期限・承認者を必須にし、期限切れ検知を運用へ組み込みます。“恒久例外”は禁止です。
Q5. セキュリティ上、タグに機微情報を入れてもいいですか?
A. 禁止です。キーや資格情報、個人情報は別管理し、タグは識別子とコードに限定します。
【お問い合わせ/CTAセクション】
見える化と統制を、90日で運用に乗せる。
-
まずは**無料オンライン相談(30–45分)**で現状とゴールを整理します。
-
相談後、現状診断レポートの骨子と概算スケジュールを共有。
下記を問い合わせ時に共有いただけると幸いです。
-
会社名 / 部門名
-
お名前 / 役職 / 連絡先(メール・電話)
-
Azure サブスクリプションの概数 / リソース群の概数
-
現状の課題(自由記述)
-
期待するアウトカム(コスト削減/監査対応/越境・契約突合/その他)
【参考リンク(一次情報)】
-
Azure Resource Graph 概要
https://learn.microsoft.com/azure/governance/resource-graph/overview -
Resource Graph クエリのはじめかた(ポータル)
https://learn.microsoft.com/azure/governance/resource-graph/first-query-portal -
Azure Policy 概要/効果(Deny/Append/Modify/Audit)
https://learn.microsoft.com/azure/governance/policy/overview
https://learn.microsoft.com/azure/governance/policy/concepts/effects -
タグの使用(リソース/リソース グループ/サブスク)
https://learn.microsoft.com/azure/azure-resource-manager/management/tag-resources -
組み込みポリシー(タグ関連:必須/既定値/継承)
https://learn.microsoft.com/azure/governance/policy/samples/built-in-policies#tags -
Policy Exemption(例外管理)
https://learn.microsoft.com/azure/governance/policy/concepts/exemption-structure -
Cost Management とタグ(コストのグループ化/配賦)
https://learn.microsoft.com/azure/cost-management-billing/costs/using-tags -
Cost Management エクスポート
https://learn.microsoft.com/azure/cost-management-billing/costs/cost-management-exports -
Bicep でのタグ付与
https://learn.microsoft.com/azure/azure-resource-manager/bicep/tags -
Terraform(AzureRM)でのタグ/Policy アサイン
https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs#tags
https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/policy_assignment -
Policy as Code(GitHub / Azure DevOps)
https://learn.microsoft.com/azure/governance/policy/concepts/policy-as-code -
FinOps タグ戦略(参考)
https://www.finops.org/framework/tags/


