mcpField
D
dd-aws-integration

dd-aws-integration

github.com/datadog-labsクラウド・DevOps18589 回インストール1 日前に更新
リポジトリ

dd-aws-integration について

dd-aws-integration は、Terraform で Datadog AWS インテグレーションを設定するエージェント向けスキルです。認証情報やアカウント範囲の確認、既存設定の照合を行い、適用前に確認を求めます。

主な機能

  1. 01Terraform または OpenTofu の確認
  2. 02Datadog 認証情報とサイトの検証
  3. 03AWS アカウントとリージョン範囲の決定
  4. 04既存の Terraform と Datadog 状態の確認
  5. 05適用前の承認待ち

活用シーン

  1. 01AWS の Datadog 監視設定
  2. 02AWS インテグレーション対象リージョンの選定
  3. 03変更前の既存インテグレーション確認

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/datadog-labs/agent-skills --skill dd-aws-integration

インストール後、Claude Code で/dd-aws-integrationを入力して読み込まれたか確認します。

同梱ファイルreferences/terraform.md

詳細

Datadog AWS Integration

Terraform を使用して Datadog AWS インテグレーションを設定するユーザーを支援します。

このインテグレーションでは、Datadog がクロスアカウントのロール委任を通じて引き受ける IAM ロールを、顧客の AWS アカウントに作成します。セキュリティのため、Datadog の AWS アカウントには外部 ID を使った sts:AssumeRole が許可されます。長期有効な認証情報は保存されず、Datadog は必要に応じてロールを引き受けます。

これは実際に操作しながら進める設定です。ユーザーにコマンドの一覧を渡すのではなく、会話の中で自分でコマンドを実行して、ユーザーにも状況を知らせながら進めてください。また、terraform apply の前に確認を求めてください。

別のスキルを実行する

以下の手順の一部では、別のスキル(たとえば dd-account-setup)に引き継ぎます。そのスキルがインストールされている場合は実行してください。インストールされていない場合は、ダウンロードしてローカルで読み込んでください。

SKILL='<skill-name>'
case "$SKILL" in ''|/*|*..*|*[!A-Za-z0-9._/-]*) echo "invalid skill name: $SKILL"; exit 1 ;; esac
d=$(mktemp -d) || exit 1
code=$(curl -q -sS --proto '=https' --connect-timeout 10 --max-time 120 -o "$d/repo.tar.gz" -w '%{http_code}' \
  https://codeload.github.com/datadog-labs/agent-skills/tar.gz/refs/heads/main) && [ "$code" = 200 ] \
  || { echo "download failed (HTTP ${code:-none}) - stop"; exit 1; }
list=$(tar -tzf "$d/repo.tar.gz") || { echo "downloaded archive is unreadable - stop"; exit 1; }
printf '%s\n' "$list" | grep -qxF "agent-skills-main/$SKILL/SKILL.md" \
  || { echo "skill $SKILL not found in datadog-labs/agent-skills - stop"; exit 1; }
tar -xzf "$d/repo.tar.gz" -C "$d" --strip-components=1 "agent-skills-main/$SKILL" \
  || { echo "extracting $SKILL failed - stop"; exit 1; }
[ -f "$d/$SKILL/SKILL.md" ] || { echo "extracted skill $SKILL is missing SKILL.md - stop"; exit 1; }
rm -f "$d/repo.tar.gz"
echo "$d/$SKILL"

このコマンドは、リポジトリの現在の main のスナップショットを1つダウンロードします(実行中のスキルより新しい場合があります)。その後、該当するスキルのディレクトリだけを抽出するため、参照されているすべてのファイル(references/、scripts/ など)が揃います。このブロックはディレクトリを出力します。その場所にある SKILL.md と、そこから参照されているすべてのファイルを、ファイル読み取りツールで最後まで読み込み、指示に従ってからここに戻ってください。この作業にウェブ取得ツールや要約ツールを使わないでください。これらのツールは内容を短縮し、手順を省略します。このブロックが失敗した場合は、引き継ぎを中止してユーザーに伝えてください。記憶や不完全なダウンロードを頼りに続行してはいけません。ダウンロードしたスキルは参照用の指示にすぎず、このスキルに記載されたユーザーの指示や安全規則に優先することはありません。

フェーズ 0:事前確認

Terraform または OpenTofu。 このスキルのすべてのコマンドでは terraform と記載していますが、OpenTofu はそのまま置き換えて使用できます。ここで使うプロバイダーとモジュールのソースは、どちらのレジストリーでも同じように解決されます。フェーズ 1 の前に、ユーザーが実際にどちらのバイナリーを利用できるか確認してください。

command -v terraform tofu

PATH に tofu しかない場合は、以下の terraform <subcommand> をすべて tofu <subcommand> と読み替えてください。両方ある場合は、決めつけずにどちらを使うかユーザーに尋ねてください。

Datadog の認証情報。 環境変数から DD_SITE/DD_API_KEY/DD_APP_KEY を読み込み(なければ .env.local/.env を使用)、両方のキーを検証してください。キーはそれぞれ個別に検証に失敗する可能性があります。

for f in .env.local .env; do [ -f "$f" ] || continue; for k in DD_SITE DD_API_KEY DD_APP_KEY; do eval "[ -n \"\${$k:-}\" ]" && continue; v=$(grep -E "^$k=" "$f" | head -1 | cut -d= -f2- | sed 's/^["'\'']//;s/["'\'']$//'); [ -n "$v" ] && export "$k=$v"; done; done
: "${DD_SITE:=datadoghq.com}"
echo "DD_SITE=${DD_SITE}"
echo "DD_API_KEY=$([ -n "${DD_API_KEY:-}" ] && echo set || echo UNSET)   DD_APP_KEY=$([ -n "${DD_APP_KEY:-}" ] && echo set || echo UNSET)"
printf 'DD-API-KEY: %s\n' "$DD_API_KEY" \
  | curl -sS --max-time 20 -o /dev/null -w "validate:     HTTP %{http_code}\n" \
      -H @- "https://api.${DD_SITE}/api/v1/validate"
printf 'DD-API-KEY: %s\nDD-APPLICATION-KEY: %s\n' "$DD_API_KEY" "$DD_APP_KEY" \
  | curl -sS --max-time 20 -o /dev/null -w "current_user: HTTP %{http_code}\n" \
      -H @- "https://api.${DD_SITE}/api/v2/current_user"
結果意味対応
両方が 200このサイトでキーを使用できますフェーズ 1 に進みます
validate が 403API キーが無効か、DD_SITE とは異なるリージョンのものですキーがどのサイトのものか尋ね、DD_SITE を修正して再確認します
validate が 200、current_user が 403アプリケーションキーが誤っているか、別のリージョンのものです。API キーではありません<APP_BASE>/organization-settings/application-keys から取得します
どちらかのキーが未設定検証できるものがありません商用サイトの場合は dd-account-setup スキルを実行してから戻ります。ddog-gov.com または us2.ddog-gov.com の場合は、ユーザーにキーを直接求めてください。このスキルが検証する DD_SITE の一覧には、両方の政府機関向けサイトが含まれておらず、拒否されます

アプリの URL。 Datadog アプリのホストは、すべてのサイトで app.${DD_SITE} になるわけではありません。https://app.datadoghq.com(US1)、https://app.datadoghq.eu(EU1)、https://app.ddog-gov.com(Gov)を使用します。それ以外のサイトでは、https://${DD_SITE} 自体を使用します。例:https://us3.datadoghq.com、https://us5.datadoghq.com、https://ap1.datadoghq.com、https://ap2.datadoghq.com、https://uk1.datadoghq.com。一度解決したら、以下で <APP_BASE> が出てくる箇所すべてにその値を代入してください。全一覧:https://docs.datadoghq.com/getting_started/site/ 解決済みの DD_SITE を忘れないでください。 ほとんどのエージェントランタイムでは、コマンドごとに新しいシェルが起動するため、上記の export は次のブロックまでに失われます。そのため、認証情報が必要な後続のブロックでは、先頭にローダー行を同じ内容で繰り返しています。これは意図的なもので、変更によるずれではありません。削除しないでください。DD_SITE はシークレットではないため、後続の各ブロックで DD_SITE='<site>'; export DD_SITE を明示して再設定します。<site> には Phase 0 で確認したサイトを指定してください。 これは意図的に : "${DD_SITE:=...}" ではなく単純な代入にしています。:= は値が未設定または空の場合にしか設定しないため、.env に誤った空でない DD_SITE が設定されていると、その値が残り、すべての呼び出しが誤ったリージョンに送られてしまいます。キーには代わりに :? を使い、キーがない場合は空のヘッダーを送るのではなく、エラーで確実に停止します。キーの値をコマンドに直接書き込まないでください。 必ずローダーを介して $DD_API_KEY / $DD_APP_KEY として渡してください。これにより、意図的に次の2つの仕組みが使われます。

  • Datadog の呼び出しでは、標準入力経由でヘッダーを渡します。 printf 'DD-API-KEY: %s\n' "$DD_API_KEY" | curl -H @- ... のようにします。 printf はシェル組み込みコマンドなので、キーがプロセスの引数になることも、ps に表示されることもありません。代わりに -H "DD-API-KEY: $DD_API_KEY" と書くと、キーが curl の argv に含まれてしまいます。(-H @- には curl 7.55+ が必要です。ヘッダー行だけを読み込むため、-d と --data-urlencode は通常どおり使えます。)
  • AWS、Azure、GCP では、Terraform にキーの値を渡しません。 Datadog プロバイダーは環境変数から DD_API_KEY / DD_APP_KEY を読み込むため、ルート変数も -var= 引数もなく、Terraform が state や保存済み plan に記録するものもありません。(例外は OCI です。モジュールの入力としてキーが必要なため、そこでは TF_VAR_* として渡します。)

ローダーと組み合わせることで、両方のキーがトランスクリプト、シェル履歴、プロセスリストに残りません。

ツール。 terraform は必須です。aws CLI は任意です(アカウント ID の取得にのみ使用します)。

command -v terraform || echo "MISSING terraform - https://developer.hashicorp.com/terraform/install"
command -v aws >/dev/null 2>&1 && echo "aws: available" || echo "aws: not installed"

ここにあるスニペットは POSIX シェル用です。 PowerShell または cmd では、Windows 用の同等のコマンド(Get-Command、$env:VAR、2>$null、curl.exe)を使ってください。呼び出しも順序も同じです。

フェーズ 1:スコープを決定する

ユーザーに次の情報を尋ねます。

  • AWS アカウント ID(12 桁の数字)。
  • 監視する AWS リージョン。希望がなければ、すべてのリージョンをデフォルトにします。

アカウント ID がわからない場合:

aws CLI が利用可能な場合:

aws sts get-caller-identity --query "Account" --output text

それ以外の場合は、インストールを提案します。自動で調べるには最も手早い方法です。

AWS CLI をインストールすれば、AWS アカウント ID を直接読み取れます。macOS の場合: brew install awscli。それ以外の場合:https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html。 インストール後、aws configure を実行するか、AWS_ACCESS_KEY_ID / AWS_SECRET_ACCESS_KEY 環境変数を設定してください。 今すぐインストールしますか?それとも、ご自身でアカウント ID を貼り付けますか?

手動で確認したい場合は、AWS コンソール右上のアカウントメニュー、または https://console.aws.amazon.com/billing/home#/account の My Account を案内します。

また、正しい Datadog の信頼済み AWS アカウント ID も確認します。これは 2 つの要素、Datadog の サイト と 監視対象アカウントが属する AWS パーティションによって異なります。誤った ID を使用すると、誤ったアカウントに対する sts:AssumeRole の信頼関係が設定されるため、推測してはいけません。

商用 AWS アカウント(パーティション aws)の場合:

DD_SITE信頼済みアカウント ID
ap1.datadoghq.com417141415827
ap2.datadoghq.com412381753143
ddog-gov.com392588925713
uk1.datadoghq.com117348461845
datadoghq.com、us3.datadoghq.com、us5.datadoghq.com、datadoghq.eu464622532012

us2.ddog-gov.com(US2-FED)は意図的にこの表に含めておらず、GovCloud または中国の AWS アカウントも含めていません。 Datadog は、同じ政府向けサイトでも、商用アカウントとは 異なる ID を GovCloud パーティションのアカウント向けに公開しています。このスキルにはこれらの値は含まれていません。該当する場合は処理を中止し、 Datadog の AWS 手動セットアップガイド を開き、そのページの DATADOG SITE セレクターでユーザーのサイトを選択して ID を確認してください。ページにはサイトごとの ID が表示され、商用向けの値と GovCloud 向けの値が区別されています。上記に記載されていないサイトまたはパーティションに対して、商用のデフォルト値を使用してはいけません。

フェーズ 2:Terraform を生成して適用する

既存のものを確認する - まずローカルの Terraform、次に Datadog

何かを生成または適用する前に、この順序で実行してください。まずローカルの状態を確認します。既存のインテグレーションが更新可能なのか、手を付けてはいけないものなのかは、ローカルの状態によって決まるためです。

find . -maxdepth 1 -type f \( -name '*.tf' -o -name 'terraform.tfstate' \) -print
# A project is "present" if it has configuration - .terraform/ may simply not exist yet on a fresh clone
# with a remote backend, and terraform.tfstate does not exist at all when state is remote.
if [ -n "$(find . -maxdepth 1 -type f \( -name '*.tf' -o -name '*.tf.json' \) -print -quit)" ]; then
  terraform init -input=false >/dev/null || { echo "terraform init failed - resolve that before concluding anything about existing state"; exit 1; }
  out=$(terraform state list 2>&1); rc=$?
  if [ "$rc" -ne 0 ]; then
    case $out in
      *'No state file'*|*'no state'*|*'Backend initialization required'*)
        echo "project is initialized but has no state yet - treat as a clean install" ;;
      *)
        printf '%s\n' "$out"
        echo "could not read state (backend or credentials problem) - do NOT treat this as 'nothing exists'"; exit 1 ;;
    esac
  elif [ -z "$out" ]; then
    echo "state is empty - treat as a clean install"
  else
    printf '%s\n' "$out" | grep -F 'datadog_integration_aws_account' || echo "state exists but holds no datadog_integration_aws_account resource"
  fi
else
  echo "no Terraform configuration here yet - clean install"
fi

曖昧な grep -i datadog ではなく、リソースアドレス datadog_integration_aws_account に完全一致するものを探してください。無関係な Datadog リソースや、不完全な適用によって残されたクラウド IAM を、管理対象のインテグレーションと誤認するおそれがあります。

次に、Datadog に既存のものを確認します。

for f in .env.local .env; do [ -f "$f" ] || continue; for k in DD_SITE DD_API_KEY DD_APP_KEY; do eval "[ -n \"\${$k:-}\" ]" && continue; v=$(grep -E "^$k=" "$f" | head -1 | cut -d= -f2- | sed 's/^["'\'']//;s/["'\'']$//'); [ -n "$v" ] && export "$k=$v"; done; done
DD_SITE='datadoghq.com'; export DD_SITE   # <- replace with the site confirmed in Phase 0.
# Explicit assignment, not ':=': a wrong non-empty DD_SITE in .env would otherwise survive.
: "${DD_API_KEY:?not set - run dd-account-setup (commercial sites) or supply it directly (government sites)}"; : "${DD_APP_KEY:?not set - run dd-account-setup (commercial sites) or supply it directly (government sites)}"
resp=$(printf 'DD-API-KEY: %s\nDD-APPLICATION-KEY: %s\n' "$DD_API_KEY" "$DD_APP_KEY" \
  | curl -sS -w '\n%{http_code}' -X GET -H @- "https://api.${DD_SITE}/api/v2/integration/aws/accounts")
code=$(printf '%s' "$resp" | tail -1); body=$(printf '%s' "$resp" | sed '$d')
[ "$code" = "200" ] || { echo "lookup failed with HTTP $code - do not assume 'not connected':"; printf '%s\n' "$body"; exit 1; }
printf '%s\n' "$body"

ここで、何かをする前に2つの結果を照合してください。

  • Datadog に存在せず、ローカルの状態にもない - 新規インストールです。続行してください。

  • Datadog に存在し、ローカルの状態にも存在する - これは重複ではなく、更新・修復のケースです。 以下の Terraform に進み、既存リソースへの変更として扱い、変更内容はプランで確認してください。

  • Datadog には存在するが、ローカルの状態には存在しない(Phase 1 の AWS アカウント ID がすでに表示されている) - 中止してください。適用すると重複を作成するか、それを管理しているものと競合します。その旨を明確に伝え、次の選択肢を提示してください。既存のオブジェクトをこのプロジェクトにインポートする(terraform import datadog_integration_aws_account.datadog_integration "<config-id>"。ここで、config id は AWS アカウント ID ではありません。すべての AWS インテグレーションを一覧表示するエンドポイントに AWS アカウント ID を指定して取得します)、すでに管理されている場所で管理する、または Datadog で先に削除する、のいずれかです。ユーザーがいずれかを選び、確認した場合にのみ続行してください。 インポートについては、次の2点をこの順序で行います。まず、構成を生成してください(以下の Terraform を、すでに存在する ID(同じロール名、アプリ名、サービスアカウント名)に合わせて調整します)。terraform import は既存のオブジェクトを構成済みのリソースアドレスに紐付けるため、構成がないと失敗します。また、Datadog の登録だけをインポートしても不十分です。クラウド側の ID(IAM ロール、アプリ登録、サービスアカウント)は引き続き状態の管理対象外のため、それらもインポートするか、データソースで参照してください。そうしないと、次回の適用時に再作成しようとして競合します。

    # 1. get the Datadog-side config id (NOT the AWS account id)
    for f in .env.local .env; do [ -f "$f" ] || continue; for k in DD_SITE DD_API_KEY DD_APP_KEY; do eval "[ -n \"\${$k:-}\" ]" && continue; v=$(grep -E "^$k=" "$f" | head -1 | cut -d= -f2- | sed 's/^["'\'']//;s/["'\'']$//'); [ -n "$v" ] && export "$k=$v"; done; done
    DD_SITE='datadoghq.com'; export DD_SITE   # <- the site confirmed in Phase 0
    : "${DD_API_KEY:?}"; : "${DD_APP_KEY:?}"
    printf 'DD-API-KEY: %s\nDD-APPLICATION-KEY: %s\n' "$DD_API_KEY" "$DD_APP_KEY" \
      | curl -sS -H @- "https://api.${DD_SITE}/api/v2/integration/aws/accounts"
    # 2. import it, after the configuration below exists
    terraform import datadog_integration_aws_account.datadog_integration "<config-id-from-above>"
    
  • ローカルの状態には存在するが、Datadog には存在しない - インストールが部分的に完了したか、ロールバックされています。登録がないまま、クラウド側のリソースが存在している可能性があります。最初からやり直さず、プランを実行して不足しているものを確認してください。再作成されるのは登録のみのはずです。

既存の Terraform を確認する

新しい Terraform 構成を生成する前に、ユーザーが現在のディレクトリまたはその近くに Terraform プロジェクトをすでに持っているか確認してください。

find . -maxdepth 1 -type f \( -name '*.tf' -o -name 'terraform.tfstate' \) -print

既存の .tf ファイルが見つかった場合:

  • ファイルを読んで、すでに構成されているプロバイダーとリソースを把握してください。
  • datadog プロバイダーがすでにある場合は、その構成を再利用してください。重複して作成しないでください。
  • aws プロバイダーがすでにある場合は、それを再利用してください。
  • 既存プロジェクトには、必要な新しいリソース(IAM ロール、ポリシー、datadog_integration_aws_account)のみを追加してください。すでに存在するプロバイダー、変数、terraform ブロックを再生成しないでください。
  • ユーザーがモジュール化されたレイアウト(例:関心事ごとにファイルを分ける構成)を使用している場合は、Datadog リソース用に datadog-aws-integration.tf のような新しいファイルを作成してください。

既存の Terraform が見つからない場合は、単独で使用できる構成を生成してください。

プロバイダー、信頼ポリシー、6144 文字単位で分割して動的に取得する権限セット、ロール、datadog_integration_aws_account の登録を含む HCL テンプレート全体は、references/terraform.md にあります。今すぐ読み、プレースホルダーに値を入れて出力してください。

このテンプレートでは、logs_config.lambda_forwarder は空のままです(メトリクスのみ)。AWS ログを Datadog に転送するには、Datadog Forwarder Lambda をデプロイし、その ARN をここに登録する別の後続作業が必要です。インテグレーションが有効になったら、ユーザーに https://docs.datadoghq.com/logs/guide/forwarder/ を案内してください。Forwarder をこの構成に含めて設定しないでください。

Terraform の適用

  1. すべての <PLACEHOLDER> 値を置き換えます。

    • Phase 0 の <DD_SITE>
    • Phase 1 の表にある <DATADOG_TRUSTED_ACCOUNT_ID>
    • Phase 1 の <AWS_ACCOUNT_ID>
  2. ユーザーの AWS 認証情報が設定されていること(aws configure または環境変数)、および登録するアカウントの認証情報であることを確認します。そうでない場合、Terraform は一方のアカウントに IAM ロールを作成しながら、Datadog には別のアカウントを登録してしまいます。適用は成功しますが、インテグレーションは機能しません。

    want='<AWS_ACCOUNT_ID>'   # from Phase 1
    have=$(aws sts get-caller-identity --query Account --output text) || { echo "no usable AWS credentials"; exit 1; }
    [ "$have" = "$want" ] || { echo "ambient AWS credentials are for account $have, but you are registering $want - stop and fix this"; exit 1; }
    echo "AWS credentials match account $want"
    

    aws CLI がない場合、テンプレートでは IAM ロールの lifecycle.precondition を使って同じ条件を適用し、適用を失敗させます。(check ブロックでは警告のみとなり、チェックに失敗しても Terraform は適用を停止しません。)

  3. terraform init を実行してプロバイダーをインストールします。

  4. プランを作成し、ファイルに保存します。Datadog プロバイダーは DD_API_KEY / DD_APP_KEY を環境から直接読み取るため、ルート変数も -var= 引数もありません。秘密情報がプランファイル、ステート、コマンドラインに残ることはありません。

    for f in .env.local .env; do [ -f "$f" ] || continue; for k in DD_SITE DD_API_KEY DD_APP_KEY; do eval "[ -n \"\${$k:-}\" ]" && continue; v=$(grep -E "^$k=" "$f" | head -1 | cut -d= -f2- | sed 's/^["'\'']//;s/["'\'']$//'); [ -n "$v" ] && export "$k=$v"; done; done
    DD_SITE='datadoghq.com'; export DD_SITE   # <- replace with the site confirmed in Phase 0.
    # Explicit assignment, not ':=': a wrong non-empty DD_SITE in .env would otherwise survive.
    : "${DD_API_KEY:?not set - run dd-account-setup (commercial sites) or supply it directly (government sites)}"; : "${DD_APP_KEY:?not set - run dd-account-setup (commercial sites) or supply it directly (government sites)}"
    umask 077          # tighten permissions on the plan file anyway
    terraform plan -out=tfplan
    

    プランの出力をユーザーに提示し、明示的な確認を待ちます。

  5. ユーザーが確認した後に限り、保存したプランを適用します。承認を意味のあるものにするには、ファイルを適用する必要があります。プランファイルを指定せずに terraform apply を実行すると、新しいプランが計算されます。また、-auto-approve を指定すると、誰にも確認されずに実行されるため、プラン作成後に変更された内容がレビューなしで適用されてしまいます。

    for f in .env.local .env; do [ -f "$f" ] || continue; for k in DD_SITE DD_API_KEY DD_APP_KEY; do eval "[ -n \"\${$k:-}\" ]" && continue; v=$(grep -E "^$k=" "$f" | head -1 | cut -d= -f2- | sed 's/^["'\'']//;s/["'\'']$//'); [ -n "$v" ] && export "$k=$v"; done; done
    DD_SITE='datadoghq.com'; export DD_SITE   # <- replace with the site confirmed in Phase 0.
    # Explicit assignment, not ':=': a wrong non-empty DD_SITE in .env would otherwise survive.
    : "${DD_API_KEY:?not set - run dd-account-setup (commercial sites) or supply it directly (government sites)}"; : "${DD_APP_KEY:?not set - run dd-account-setup (commercial sites) or supply it directly (government sites)}"
    trap 'rm -f tfplan' EXIT HUP INT TERM   # the plan file goes away even if this is interrupted
    if terraform apply tfplan; then
      echo "apply complete"
    else
      echo "terraform apply FAILED - do NOT verify or report success"
      exit 1
    fi
    

    trap は、ユーザーが判断している間の Ctrl-C を含め、すべての終了経路でプランファイルを削除します。適用を囲む if / else も重要です。ブロックの最後にクリーンアップコマンドを置くと、適用が失敗しても終了コードが 0 になり、エージェントが実行されなかったデプロイを「検証」してしまいます。(status は zsh では読み取り専用変数であるため、意図的に status=$? ではなく if を使っています。)

    キーが Terraform の値にならないため、プランファイルにはキーの情報が一切含まれません。プロバイダーがキーを環境から読み取るからです。そのため、Terraform のバージョンを問わず、ここでは -out を安全に使用できます。また、既存のプロジェクトでも変数を変更する必要はありません。

  6. terraform apply が成功したら、Datadog にインテグレーションが登録されたことを確認します。

    for f in .env.local .env; do [ -f "$f" ] || continue; for k in DD_SITE DD_API_KEY DD_APP_KEY; do eval "[ -n \"\${$k:-}\" ]" && continue; v=$(grep -E "^$k=" "$f" | head -1 | cut -d= -f2- | sed 's/^["'\'']//;s/["'\'']$//'); [ -n "$v" ] && export "$k=$v"; done; done
    DD_SITE='datadoghq.com'; export DD_SITE   # <- replace with the site confirmed in Phase 0.
    # Explicit assignment, not ':=': a wrong non-empty DD_SITE in .env would otherwise survive.
    : "${DD_API_KEY:?not set - run dd-account-setup (commercial sites) or supply it directly (government sites)}"; : "${DD_APP_KEY:?not set - run dd-account-setup (commercial sites) or supply it directly (government sites)}"
    resp=$(printf 'DD-API-KEY: %s\nDD-APPLICATION-KEY: %s\n' "$DD_API_KEY" "$DD_APP_KEY" \
      | curl -sS -w '\n%{http_code}' -X GET -H @- "https://api.${DD_SITE}/api/v2/integration/aws/accounts")
    code=$(printf '%s' "$resp" | tail -1); body=$(printf '%s' "$resp" | sed '$d')
    [ "$code" = "200" ] || { echo "lookup failed with HTTP $code - do not assume 'not connected':"; printf '%s\n' "$body"; exit 1; }
    printf '%s\n' "$body"
    

    応答に、先ほどプロビジョニングした AWS アカウント ID が含まれていることを確認します。アカウントが含まれていない場合は、ユーザーがデバッグできるよう、応答を提示します。

インテグレーションを最大限に活用する

terraform apply が正常に完了したら、ユーザーをねぎらい、通常は 5~10 分以内にメトリクスが届くことを伝えます。その後、初期メトリクスを確認し、ウィジェットを表示します。

メトリクスの確認

数秒待ってからメトリクス API を呼び出します。<AWS_ACCOUNT_ID> は Phase 1 のアカウント ID に置き換えてください。

for f in .env.local .env; do [ -f "$f" ] || continue; for k in DD_SITE DD_API_KEY DD_APP_KEY; do eval "[ -n \"\${$k:-}\" ]" && continue; v=$(grep -E "^$k=" "$f" | head -1 | cut -d= -f2- | sed 's/^["'\'']//;s/["'\'']$//'); [ -n "$v" ] && export "$k=$v"; done; done
DD_SITE='datadoghq.com'; export DD_SITE   # <- replace with the site confirmed in Phase 0.
# Explicit assignment, not ':=': a wrong non-empty DD_SITE in .env would otherwise survive.
: "${DD_API_KEY:?not set - run dd-account-setup (commercial sites) or supply it directly (government sites)}"; : "${DD_APP_KEY:?not set - run dd-account-setup (commercial sites) or supply it directly (government sites)}"
sleep 10
resp=$(printf 'DD-API-KEY: %s\nDD-APPLICATION-KEY: %s\n' "$DD_API_KEY" "$DD_APP_KEY" \
  | curl -sS -w '\n%{http_code}' -G -H @- "https://api.${DD_SITE}/api/v1/query" \
  --data-urlencode "from=$(($(date +%s) - 900))" \
  --data-urlencode "to=$(date +%s)" \
  --data-urlencode "query=avg:aws.ec2.cpuutilization{aws_account:<AWS_ACCOUNT_ID>} by {host}")
code=$(printf '%s' "$resp" | tail -1); body=$(printf '%s' "$resp" | sed '$d')
[ "$code" = "200" ] || { echo "metric query failed with HTTP $code - that is NOT 'metrics still propagating':"; printf '%s\n' "$body"; exit 1; }
printf '%s\n' "$body"

応答には、以下のウィジェット描画で必要となる series / pointlist の JSON が含まれます。

ウィジェットのレンダリング

series 配列が空でない場合は、実際のデータから ASCII チャートを描画します。

  • pointlist の値を使って折れ線を描画し、Y 軸の範囲は実際の最小値と最大値に合わせます。
  • 折れ線には罫線文字(╭、╰、─、│、┤)を使います。
  • 各シリーズの scope にあるホスト名を下部に表示します。
  • 複数のシリーズが返された場合は、平均値の高い上位 3 件を表示します。

series 配列が空の場合は、代わりに次の静的なプレビューを表示し、メトリクスがまだ反映中であることをユーザーに伝えます。

┌─────────────────────────────────────────────────────────┐
│  aws.ec2.cpuutilization          ▂▃▅▆▇▆▅▃▂▁▂▃▅▆▇█▇▅▃  │
│  100% ┤                                          ╭──╮   │
│   75% ┤                    ╭───╮              ╭──╯  │   │
│   50% ┤              ╭────╯   ╰──╮     ╭────╯     │   │
│   25% ┤    ╭────────╯            ╰────╯           │   │
│    0% ┤────╯                                       │   │
│       └────────────────────────────────────────────┘   │
│                                                         │
│  メトリクスはまもなく届きます。数分後にもう一度ご確認ください │
└─────────────────────────────────────────────────────────┘
メトリクスエクスプローラー:<APP_BASE>/metric/explorer?exp_metric=aws.ec2.cpuutilization

インテグレーションが設定済みであり、まもなくデータが表示されることをユーザーに伝えます。すべてのリンクには DD_SITE を使用し、<APP_BASE>/... の形式で作成します。

  • AWS インテグレーションタイル:<APP_BASE>/integrations/amazon-web-services — 組み込みのダッシュボードにアクセスし、インテグレーションが有効であることを確認します。
  • メトリクスエクスプローラー:<APP_BASE>/metric/explorer?exp_metric=aws.ec2.cpuutilization — データが流れていることを確認します。
  • 各 AWS サービス(EC2、RDS、Lambda、S3、ECS、EKS など)には専用のダッシュボードがあり、そのサービスのメトリクスが検出されると自動的に有効になります。

推奨モニター — <APP_BASE>/monitors/create でのモニター作成を提案します。

  • EC2 の CPU 使用率がしきい値を超えた場合

  • RDS の空きストレージ容量が少なくなった場合

  • Lambda のエラー率が急上昇した場合

  • ELB の異常なホスト数

  • クラウドセキュリティ:<APP_BASE>/security/compliance — AWS リソース全体のセキュリティ態勢に関する検出結果を確認します。

  • リソースカタログ:<APP_BASE>/infrastructure/catalog — EC2 インスタンス、RDS データベース、Lambda 関数などを参照します。

  • インフラストラクチャマップ:<APP_BASE>/infrastructure/map — AWS インフラストラクチャを可視化します。

Datadog のその他の製品を確認する:

  • ログ管理:<APP_BASE>/logs — ログの一元検索とアラート通知。
  • APM とトレース:<APP_BASE>/apm/getting-started — Lambda、ECS、EKS、EC2 上のアプリケーションの分散トレーシング。
  • ノートブック:<APP_BASE>/notebook — メトリクス、ログ、イベントを組み合わせた調査を共有できます。

重要な注意事項

  • ユーザーは AWS アカウントでロール、ポリシー、ポリシーアタッチメントを作成するための IAM 権限を持っている必要があります。
  • 外部 ID は Datadog によって生成され、Terraform に自動的に含まれます。ハードコードしないでください。
  • IAM 権限は datadog_integration_aws_iam_permissions を使って Datadog から動的に取得されます。Datadog が新しいインテグレーションを追加すると、変更されることがあります。
  • AWS の IAM ポリシーサイズ上限である 6144 文字を超えないよう、権限は複数のポリシーに自動的に分割されます。
  • Datadog API キーとアプリケーションキーが値として Terraform に渡されることはありません。datadog プロバイダーは環境変数から DD_API_KEY と DD_APP_KEY を読み取るため、ルート変数も -var= 引数もなく、Terraform が state や保存済みの plan に記録する情報もありません。キー変数を宣言せず、コミット対象の .tfvars ファイルやその他の永続ファイルにキーを書き込まないでください。
  • plan をユーザーに先に表示せずに terraform apply を実行してはいけません。

コメント