Cloud Intelligence™Cloud Intelligence™

Cloud Intelligence™

FinOps as Code:DoiT Cloud IntelligenceをTerraformで管理する

By Hannes HayashiJun 25, 202611 min read

このページはEnglishDeutschEspañolFrançaisItalianoPortuguêsでもご覧いただけます。

インフラはバージョン管理し、アプリケーションコードはプルリクエストでレビューする。では、FinOpsの設定——予算、コスト配分、アラート、分析レポート——はどう管理していますか?

多くのチームでは、これらの設定はUIの中にしかありません。誰かがウィザードを進めてしきい値を設定し、フィルターを選び、次に変更する人が意図を汲み取ってくれることを祈る。履歴もなければピアレビューもなく、環境間で同じ設定を再現する手段もありません。FinOpsの運用がインフラと同じくらい重要であるなら、同じ厳密さで扱うべきです。

そこで開発したのが DoiT Terraformプロバイダー です。クラウドリソースですでに活用している Infrastructure as Code のワークフローに、DoiT Cloud Intelligence の設定をそのまま取り込めます——17のマネージドリソース61のデータソースを備え、予算やレポートからAIアシスタントへの問い合わせ、クラウドインフラ図に至るまで幅広くカバーします。

はじめに

使い始めに必要なのは、プロバイダーブロックとAPIキーだけです:

terraform {
required_providers {
doit = {
source = "doitintl/doit"
version = "~> 1.0"
}
}
}
provider "doit" {}

環境変数に DOIT_API_TOKEN を設定すれば(APIキーは DoiT Console で発行できます)、準備完了です。追加の設定は一切不要です。

FinOpsワークフローの中核

多くのチームがまず利用するリソース——配分、予算、アラート、レポート——を順に見ていきましょう。これらを組み合わせれば一連のFinOpsパイプラインが完成し、コードで管理することで構成全体をバージョン管理・レビュー・複製できるようになります。

コスト配分

配分(Allocations)は、クラウド支出を意味のあるカテゴリに切り分ける仕組みです。本プロバイダーは、フィルター条件を組み合わせるブール式エンジン、コストを名前付きバケットに分けるグループ配分、さらにIDで他の配分を参照するネストされた配分にも対応しています。

次の例は、リージョン別にコストを分割し、どこにも該当しないものをまとめて扱うグループ配分です:

resource "doit_allocation" "by_region" {
name = "By Region"
description = "Group costs by geographic region"
unallocated_costs = "Other Regions"
rules = [
{
action = "create"
name = "US"
formula = "A"
components = [{
key = "country", mode = "is", type = "fixed", values = ["US"]
}]
},
{
action = "create"
name = "Europe"
formula = "A"
components = [{
key = "country", mode = "is", type = "fixed", values = ["DE", "FR", "GB", "NL"]
}]
}
]
}

より細かい粒度が必要な場合は、コンポーネント内で type = "allocation_rule" を指定すれば既存の配分を参照でき、配分を別の配分から組み立てられます(最大3階層までネスト可能)。また、"US""DE" のようなディメンション値をハードコードする代わりに、doit_dimension データソースを使ってAPIから有効な値を動的に取得することもできます。

予算

予算はガードレールの役割を果たします。本プロバイダーでは、複数のしきい値を持つアラートの定義、特定の配分やディメンションへのスコープ指定が可能です。さらに便利なパターンとして、組織内の全ユーザーを追加するのではなく、職種でコラボレーターを絞り込むこともできます:

data "doit_users" "all" {}
locals {
engineers = [
for u in data.doit_users.all.users : u
if u.job_title == "Software / Ops Engineer"
]
}
resource "doit_budget" "eng_budget" {
name = "Engineering Budget"
currency = "USD"
type = "recurring"
amount = 10000
time_interval = "month"
start_period = provider::time::rfc3339_parse("2026-01-01T00:00:00Z") * 1000
alerts = [
{ percentage = 50 },
{ percentage = 80 },
{ percentage = 100 }
]
collaborators = concat(
[{ email = data.doit_current_user.me.email, role = "owner" }],
[for u in local.engineers : { email = u.email, role = "viewer" }]
)
recipients = [for u in local.engineers : u.email]
scopes = [{
type = "allocation_rule"
id = "allocation_rule"
mode = "is"
values = [doit_allocation.by_region.id]
}]
}

この予算は先ほど作成したリージョン配分にスコープを限定し、職種が「Software / Ops Engineer」のユーザーにのみ通知します。予算は、月ごとに支出目標が変動する場合の seasonal_amounts もサポートしており、current_utilizationforecasted_utilization といった算出フィールドは読み取り専用の出力として参照できます。

アラート

アラートは、コストや使用量がしきい値を超えたときに通知を発火させます。真価が出るのはスコープ指定です——特定のクラウドプロバイダー、サービス、リージョン、任意のディメンションにアラートを絞り込めます。次の例では、サービスIDをハードコードする代わりに doit_products データソースを使って Compute Engine のサービスIDを動的に取得しています:

data "doit_products" "gcp" {
platform = "google_cloud_platform"
}
resource "doit_alert" "compute_cost" {
name = "GCP Compute Cost Alert"
config = {
metric = { type = "basic", value = "cost" }
time_interval = "day"
value = 500
currency = "USD"
condition = "value"
operator = "gt"
scopes = [{
type = "fixed"
id = "service_description"
mode = "is"
values = [
for p in data.doit_products.gcp.products : p.id
if p.display_name == "Compute Engine"
]
}]
}
recipients = [data.doit_current_user.me.email]
}

レポート

Cloud Analytics レポートは、本プロバイダーの中で最も機能豊富なリソースです。最大4つのメトリクスを設定し、secondary_time_range で前年同期比較を追加し、フィルターやグループ化ディメンションを適用して、レポートをフォルダーで整理できます。

resource "doit_report" "monthly_costs" {
name = "Monthly Cost Report"
description = "Tracks monthly costs across cloud providers with YoY comparison"
config = {
metrics = [
{ type = "basic", value = "cost" },
{ type = "basic", value = "usage" }
]
aggregation = "total"
time_interval = "month"
data_source = "billing"
time_range = {
mode = "last"
amount = 3
include_current = true
unit = "month"
}
secondary_time_range = {
amount = 1, unit = "year", include_current = false
}
filters = [{
id = "cloud_provider", type = "fixed", mode = "is"
values = ["amazon-web-services", "google-cloud"]
}]
group = [{ id = "cloud_provider", type = "fixed" }]
layout = "table"
display_values = "actuals_only"
currency = "USD"
}
}

フィルターやグループ化で使える有効なディメンションIDや型を調べたい場合は、doit_dimensions データソースに完全なカタログが用意されています——もう推測する必要はありません。

FinOpsの先へ

多くのチームはまず中核となるFinOpsリソースから始めますが、本プロバイダーがカバーする範囲はDoiTプラットフォームのもっと広い領域に及びます。中にはコンソールに存在することすら知らなかった機能もあるかもしれません——コードで管理することは、そうした機能を発見する絶好の入り口になります。

TerraformからAvaに尋ねる

そう、DoiTのAIアシスタント Ava には、Terraform 設定から直接質問できます。とりわけ便利なのは、プロンプトの中で他のTerraformリソースのレポートIDを参照できる点です:

data "doit_ava" "report_summary" {
question = "Can you summarize report ${doit_report.monthly_costs.id} for me?"
}
output "report_summary" {
value = data.doit_ava.report_summary.answer
}

レポートを作成し、そのまま Ava に解説を求める——すべてを同じ terraform apply の中で完結できます。「今月コストが高いクラウドサービスのトップ3は?」のような気軽な照会にも使えて、回答をTerraformのアウトプットに流し込むこともできます。

アドホックな分析クエリ

毎回レポートを保存する必要はなく、ただ質問に答えたいだけの場面もあります。doit_report_query データソースは Cloud Analytics クエリをその場で実行し、解析・変換・エクスポートできる構造化JSONを返します:

data "doit_report_query" "cost_by_provider" {
config = {
metrics = [{ type = "basic", value = "cost" }]
aggregation = "total"
time_interval = "month"
currency = "USD"
time_range = {
mode = "last", amount = 3, include_current = true, unit = "month"
}
group = [{ id = "cloud_provider", type = "fixed" }]
}
}
locals {
result = jsondecode(data.doit_report_query.cost_by_provider.result_json)
columns = [for s in local.result.schema : s.name]
}
resource "local_file" "query_csv" {
filename = "cost_by_provider.csv"
content = join("\n", concat(
[join(",", local.columns)],
[for row in local.result.rows :
join(",", [for cell in row : cell == null ? "" : tostring(cell)])]
))
}

これは CI/CD のコストゲートに特に有効です——パイプライン中でクエリを実行し、支出がしきい値を超えていればビルドを失敗させる、といった使い方ができます。doit_report_result を使えば、既存の保存済みレポートの結果を取得することもできます。

クラウド構成図をMermaidフローチャートに

本プロバイダーには Cloud Diagrams 機能向けに12のデータソースが用意されており、検索、エクスポート、関係性、スナップショット、統計をカバーします。一例として面白いのが、クラウドインフラのトポロジーから Mermaid フローチャートを生成し、READMEや Confluence ページ、インシデントレポートに直接埋め込む使い方です。

data "doit_cloud_diagrams_search" "project" {
query = "my-gcp-project"
}
data "doit_cloud_diagrams_schemes" "diagram" {
layer_ids = [data.doit_cloud_diagrams_search.project.scheme[0].ss_id]
components = true
link = true
}
locals {
ss = data.doit_cloud_diagrams_schemes.diagram.statussheet[
data.doit_cloud_diagrams_search.project.scheme[0].ss_id
]
node_lines = [
for id, n in local.ss.node :
" ${id}[\"${replace(coalesce(n.name, id), "\"", "#quot;")}\"]"
]
edge_lines = [
for id, l in local.ss.link :
l.connection_type != null
? " ${l.origin._id} -->|${l.connection_type}| ${l.destination._id}"
: " ${l.origin._id} --> ${l.destination._id}"
]
mermaid = join("\n", concat(["flowchart LR"], local.node_lines, local.edge_lines))
}
output "mermaid" {
value = local.mermaid
}

出力を mermaid.live や任意のMarkdownレンダラーに貼り付ければ、インフラの関係性を視覚的に表現できます——時系列でのトポロジー差分、コンプライアンス用のスナップショット、あるいは「何が何につながっているのか」をひと目で確認する用途にも使えます。

共有とアクセス制御

FinOpsリソースを誰が閲覧できるかという管理は、つい後回しにされがちです——問題が起きるまでは。doit_sharing リソースを使えば、レポート、予算、アラート、配分に対する権限を定義できます:

locals {
permissions = [
{ user = data.doit_current_user.me.email, role = "owner" },
{ user = "[email protected]", role = "editor" },
{ user = "[email protected]", role = "viewer" },
]
}
resource "doit_sharing" "report" {
resource_type = "reports"
resource_id = doit_report.monthly_costs.id
permissions = local.permissions
public = "viewer" # Grant org-wide read access
}

権限セットを locals に一度定義しておけば、共有するあらゆるリソースに一貫して適用できます。これを doit_user と組み合わせて新メンバーをオンボーディングし、doit_roles で利用可能なロールを把握する——すべてをTerraform設定から完結できます。

アノテーションとラベル

半年前のコストスパイクを見て、「あのとき何があったんだっけ?」と頭を抱えた経験はありませんか? アノテーションを使えば、デプロイ、移行、インシデントといったコストイベントをコストデータ上に直接記録できます:

resource "doit_label" "infrastructure" {
name = "infrastructure"
color = "blue"
}
resource "doit_annotation" "black_friday" {
content = "AWS cost spike due to Black Friday traffic"
timestamp = "2024-11-29T00:00:00Z"
reports = [doit_report.monthly_costs.id]
labels = [doit_label.infrastructure.id]
}

ラベルとラベル付けの仕組みは、リソースをまたいだタグ付けを可能にします——チーム、プロジェクト、あるいは組織にとって意味のある任意の分類軸で、レポート、アラート、アノテーションを整理できます。

フォルダーで大規模構成を整理する

Terraformで管理するFinOps設定が肥大化してくると、フォルダーが整理に役立ちます。ネストにも対応し、レポートと配分の両方で利用できます:

resource "doit_folder" "analytics" {
name = "Analytics"
description = "Cloud Analytics reports and dashboards"
}
resource "doit_folder" "cost_reports" {
name = "Cost Reports"
description = "Monthly and quarterly cost breakdowns"
parent_folder_id = doit_folder.analytics.id
}
resource "doit_report" "monthly_costs" {
name = "Monthly Cost Overview"
folder_id = doit_folder.cost_reports.id
# ... report config ...
}

カスタムテーマを使って分析画面にブランド要素を反映させることもできます——ライトモードとダークモードのカラーパレットを定義して Cloud Analytics レポートのチャートに適用すれば、ダッシュボードに洗練された統一感を持たせられます。

AWS CloudConnect のオンボーディング

AWSアカウントをDoiTに接続する手順は通常マルチステップで、IAMロールの作成、S3バケットの設定、アカウント登録が必要です。これらすべてを単一の terraform apply で完結できる 専用のTerraformモジュール を公開しました:

module "doit_cloudconnect" {
source = "doitintl/doit-cloudconnect/aws"
version = "~> 1.0"
}

このモジュールは、IAMロール、S3バケット、CloudConnect登録を一気に作成します。数十のアカウントをオンボーディングする企業であれば、アカウントリストに対して for_each と組み合わせて利用してください。より細かい制御が必要な場合は、基盤となる doit_cloudconnect_aws_account リソースを直接使用することもできます。

カスタムインサイト

自社で最適化チェックを運用している場合——未使用リソースのスキャン、ライトサイジング機会の特定、セキュリティ課題のフラグ付けなど——その結果をDoiTコンソールに直接公開できます:

resource "doit_insight" "unused_instances" {
key = "unused-ec2-instances"
title = "Unused EC2 Instances"
short_description = "EC2 instances with consistently low CPU utilization"
cloud_provider = "aws"
categories = ["FinOps"]
}

これに doit_insight_resource_results を組み合わせれば、リソース単位の検出結果を添付でき、独自の最適化エンジンの結果をDoiT組み込みのインサイトと並べて表示できます。

組み合わせ可能性のパターン

ここまでの例すべてに共通するテーマがあります。それは、データソースがすべてを結びつける接着剤だということです。ディメンションID、サービス名、ユーザーのメールアドレスをハードコードするのではなく、plan時に動的に取得します:

data "doit_dimensions" "all" {}
locals {
dimension_types = { for id, types in {
for d in data.doit_dimensions.all.dimensions : d.id => d.type...
} : id => types[0] }
}

このディメンション参照マップは、レポート、予算、アラート、配分のいずれでも再利用できます——一度書けば、あとはどこでも local.dimension_types["region"] と参照するだけです。同様に doit_current_user はメールアドレスのハードコードをなくし、doit_products は有効なサービスフィルター値を取得し、doit_platforms は組織で利用可能なクラウドプロバイダーを一覧化します。

継続開発中、そしてオープンソース

本プロバイダーは、v1.0が2026年2月にリリースされてからの4か月で5回のマイナーリリースを重ね、その都度新しいリソースとデータソースを追加してきました。直近のハイライトには、Cloud Diagrams 対応、カスタムコンソールテーマ、フォルダー管理、共有とアクセス制御、AWS CloudConnect のオンボーディング、Ava AI データソースなどがあります。

まだ v0.x 系をお使いの方、いまがアップグレードの絶好のタイミングです。v0.x はテクニカルプレビュー版であり、v1.x は本番運用に対応した安定版で、ステートの自動移行機能によりスムーズに移行できます。移行手順は v1.0.0 アップグレードガイド をご確認ください。

本プロバイダーは github.com/doitintl/terraform-provider-doit でオープンソースとして公開しています。Issue、機能リクエスト、コントリビューションをお待ちしています。すべてのリソースには実際のDoiT APIに対して動作するアクセプタンステストが用意されており、CloudConnect AWSモジュール は、プロバイダーリソースを実用的なパターンに組み合わせた上位モジュール群の第一弾です。

はじめましょう

  1. Terraform Registry からインストール
  2. APIキー を発行
  3. スキーマの詳細や追加サンプルは 公式ドキュメント を参照
  4. GitHubリポジトリ にスターを付けて、次に見たい機能をお知らせください

FinOpsの運用も、インフラと同じだけのバージョン管理、ピアレビュー、再現性に値します。ぜひ本プロバイダーを試して、Cloud Intelligence をコードで管理してみてください。