【実務・中級編】Pulumiコンソールと外部オブザーバビリティツールの連携:DatadogやNew Relicへのインフラメトリクス・ログ統合監視手法 – インフラ構成管理(IaC)活用バイブル

Pulumi CloudとDatadogの完全融合:インフラ変更とメトリクスを同期させ、障害を「秒速」で駆逐するオブザーバビリティ戦略

テックリードの君なら、こんな修羅場をくぐってきたはずだ。

本番環境で突然レイテンシが跳ね上がり、エラーレートが閾値を超える。慌ててDatadogのダッシュボードを開くが、そこにあるのは「何かが壊れている」という冷酷な事実だけだ。「一体、誰が、どのリソースの何をいじったんだ?」――Gitの履歴を漁り、CI/CDのログを突き合わせ、プルリクエストのレビューコメントを遡る。この「インフラの変更事実」と「オブザーバビリティのメトリクス」の間のタイムラグこそが、復旧を遅らせる最大の癌(がん)だ。

Infrastructure as Code(IaC)の究極形は、コードを書いてデプロイすることではない。「インフラの状態変化と、システム全体の挙動を不可分の時系列データとして完全同期させること」にある。

今回は、Pulumi Cloud(旧Pulumi Service)のWebhookと監査ログをDatadogに完全統合し、インフラの変更イベントをメトリクスと同一タイムライン上にマッピングする、実戦投入済みのアーキテクチャを解説する。

—

1. なぜPulumi CloudのWebhookなのか?(設計思想)

Terraform CloudのNotificationも悪くはない。しかし、Pulumi Cloudが優れているのは、「プレビュー(Preview)段階の差分情報」から「アップデートの成否、スタックの出力値(Outputs)」までを構造化されたJSONペイロードとしてリアルタイムにフックできる点にある。

これをDatadogのEvents APIやLog Managementに流し込むことで、Datadogのタイムライン上に「誰が・どのスタックに・何を適用したか」の垂直線(Marker)を立てることができる。

全体アーキテクチャ

[Pulumi Developer] -> (pulumi up) -> [Pulumi Cloud]
│
(Webhook / Audit)
▼
[AWS API Gateway / Lambda]
│
(Datadog API)
▼
[Datadog Dashboard]
(APM Metrics vs Infra Changes)

—

2. 実践:Pulumi WebhookからDatadogへのイベント転送パイプライン

Pulumi CloudのWebhookは、スタックのライフサイクルイベント(`stack.update.succeeded`, `stack.update.failed` など)をトリガーにHTTP POSTを飛ばす。これをセキュアに受け取り、DatadogのEvents APIのフォーマットに変換して流し込むAWS Lambda(TypeScript)のベストプラクティスコードだ。

サーバーレス転送プロキシ(TypeScript)

このコードは、Pulumiのシグネチャを検証し、DatadogのEventとして美しくマッピングする。

import { Context, APIGatewayProxyEvent, APIGatewayProxyResult } from ‘aws-lambda’;
import as crypto from ‘crypto’;
import axios from ‘axios’;

// 秘匿情報は環境変数から厳格に取得(BOMや余計な空白は排除)
const DD_API_KEY = process.env.DD_API_KEY!;
const PULUMI_WEBHOOK_SECRET = process.env.PULUMI_WEBHOOK_SECRET!;

export const handler = async (event: APIGatewayProxyEvent, context: Context): Promise => {
const signature = event.headers[‘X-Pulumi-Signature’] || event.headers[‘x-pulumi-signature’];
const body = event.body || ”;

// 1. Webhookの署名検証(セキュリティの基本:偽装リクエストの完全排除)
if (!verifyPulumiSignature(body, signature, PULUMI_WEBHOOK_SECRET)) {
console.warn(‘Invalid Pulumi Webhook Signature’);
return { statusCode: 401, body: ‘Unauthorized’ };
}

const pulumiEvent = JSON.parse(body);
const { stackName, organization, type, user, timestamp, url } = pulumiEvent;

// 2. イベントタイプに応じたDatadogペイロードの構築
let title = `Pulumi Stack Update: ${organization}/${stackName}`;
let text = `User: ${user.name}\nAction: \`${type}\`\n[View Stack in Pulumi](${url})`;
let alertType = ‘info’;

if (type === ‘stack.update.failed’) {
title = `🔥 Pulumi Update FAILED: ${organization}/${stackName}`;
alertType = ‘error’;
} else if (type === ‘stack.update.succeeded’) {
title = `✅ Pulumi Update Succeeded: ${organization}/${stackName}`;
alertType = ‘success’;
}

const datadogPayload = {
title: title,
text: text,
priority: alertType === ‘error’ ? ‘high’ : ‘normal’,
tags: [
`pulumi:org:${organization}`,
`pulumi:stack:${stackName}`,
`pulumi:user:${user.githubLogin || user.name}`,
`env:${stackName.includes(‘prod’) ? ‘production’ : ‘staging’}`
],
alert_type: alertType,
source_type_name: ‘Pulumi’,
date_happened: Math.floor(new Date(timestamp).getTime() / 1000)
};

try {
// 3. Datadog Events APIへ送信
await axios.post(‘https://api.datadoghq.com/api/v1/events’, datadogPayload, {
headers: {
‘DD-API-KEY’: DD_API_KEY,
‘Content-Type’: ‘application/json’
}
});

return { statusCode: 200, body: JSON.stringify({ status: ‘success’ }) };
} catch (error: any) {
console.error(‘Failed to send event to Datadog:’, error.response?.data || error.message);
return { statusCode: 500, body: ‘Internal Server Error’ };
}
};

/
5. HMAC-SHA256による署名検証
/
function verifyPulumiSignature(payload: string, signature: string | undefined, secret: string): boolean {
if (!signature) return false;
const hmac = crypto.createHmac(‘sha256’, secret);
const digest = `sha256=${hmac.update(payload).digest(‘hex’)}`;
return crypto.timingSafeEqual(Buffer.from(digest), Buffer.from(signature));
}

—

3. チーム開発の生産性を極限まで高める:Pulumi設定共有化ルール

チームでPulumiを運用する際、散らかりがちな設定やスタックの管理を統制するための「プロダクション・グレードのディレクトリ構成と設定ファイル」のベストプラクティスを提示する。

ディレクトリ構成案(Monorepo構成)

.
├── Pulumi.yaml # プロジェクト全体のメタデータ
├── Pulumi.dev.yaml # 開発環境向け設定(暗号化済みシークレット含む)
├── Pulumi.prod.yaml # 本番環境向け設定
├── package.json
├── tsconfig.json
└── src/
├── index.ts # エントリーポイント
├── networking/ # VPC, Subnetなどの基盤レイヤー
│ └── vpc.ts
└── database/ # RDS, ElastiCacheなどのステートフルレイヤー
└── rds.ts

`Pulumi.yaml` のベストプラクティス構成

name: core-infrastructure
runtime:
name: nodejs
options:
typescript: true
description: Production-grade AWS infrastructure managed by Pulumi with Datadog integration.
config:
pulumi:tags:
value:
team: SRE
cost-center: “1042”
compliance: pci-dss

チーム開発の鉄則:暗号化設定(Passphrase vs KMS)

シークレット管理には、デフォルトのPulumiサービスバックエンド暗号化(Passphrase)ではなく、AWS KMSやVaultをプロバイダとして指定する。これにより、CI/CD環境や開発者のローカル環境で強固なシークレット分離が担保される。

`Pulumi.prod.yaml` の例:

encrypter: awskms
encryptkey: arn:aws:kms:ap-northeast-1:123456789012:key/your-kms-key-uuid
config:
aws:region: ap-northeast-1
core-infrastructure:instanceType: t3.medium
core-infrastructure:dbPassword:
secure: AAABAHv… (KMSにより暗号化された密文)

—

4. プロの隠し技:開発スピードを加速するキーボードショートカット&プラグイン

日々の開発でマウスに手を伸ばしているうちは、真のエンジニアとは言えない。CLIの操作を極限まで効率化する。

1. 開発スピードを爆上げする Pulumi CLI ショートカット

シェル(`.zshrc` や `.bashrc`)に以下のエイリアスを仕込め。これだけで毎日のキーストロークが半分になる。

スタックの高速切り替えとプレビュー
alias pp=”pulumi preview”
alias pu=”pulumi up –skip-preview” # 緊急時の即時適用(※レビュー済みの前提)
alias pr=”pulumi refresh”
alias ps=”pulumi stack”
alias pl=”pulumi logs –follow” # リアルタイムログストリーム

2. 絶対に入れるべき神プラグイン(VS Code)

VS Codeを使用しているなら、以下の拡張機能の組み合わせが最強のインフラ開発環境を作る。

  • Pulumi (Official): リソースの補完、ホバー時のドキュメント表示、スタック情報の可視化に必須。
  • Error Lens: インフラコードのエラーや型ミスをコード行内にインライン表示させ、コンパイルエラーを未然に防ぐ。
  • GitLens: コードの各行が「誰によって、いつ、どのプルリクエストで書かれたか」を即座に特定。インフラの変更理由を秒速で追跡できる。

—

5. 障害発生時の「秒速ロールバック」を支えるDatadogダッシュボード構築

前述のWebhookによって、Datadogのタイムライン上にはPulumiのアップデートイベントが刻まれている。ここからが本題だ。

ダッシュボードのレイアウト設計

1. Top Row (Events Stream):

  • Widget: Event Stream
  • Query: `sources:pulumi`
  • 意味: インフラがいつ変更されたかが一目でわかる「垂直線」を全グラフと同期させる。

2. Middle Row (APM Performance):

  • Widget: Timeseries
  • Metric: `trace.http.request.hits`, `trace.http.request.errors`, `trace.rack.request.duration.by.service`
  • 意味: アプリケーションのスループットとレイテンシ。

3. Bottom Row (Infrastructure Metrics):

  • Widget: Timeseries
  • Metric: `aws.ec2.cpuutilization`, `aws.rds.database_connections`
  • 意味: 基盤レイヤーのリソース枯渇状況。

究極の判断基準:ロールバックの自動判定フロー

Datadog上で `pulumi.update.succeeded` のイベントがプロットされた直後(例: 2分以内)に以下の条件が検知された場合、Slack等へのアラート発報と共に、自動的に緊急ロールバック(直前の安定コミットでの `pulumi up`)を走らせるCI/CDパイプラインを組む。

  • `trace.http.request.errors` が直前平均の 300% 以上に跳ね上がった場合
  • HTTP 5xx レスポンスコードの割合が 5% を突破した場合

インフラの変更履歴とアプリのメトリクスが同一の時軸で相関しているため、「このプルリクエストのデータベースインデックス追加が、コネクションプールの枯渇を招いた」という因果関係を、障害発生からわずか数分で特定できる。

—

テックリードからのメッセージ

ツールを導入しただけでは、組織の生産性は1ミリも上がらない。
「コードを書く -> デプロイされる -> 監視される -> 戻す」というフィードバックループの摩擦(フリクション)を極限まで削ぎ落とすこと。それがSREであり、インフラエンジニアのプライドだ。

Pulumi CloudとDatadogを結合したこの仕組みをチームに導入し、アラートに怯える夜を終わらせよう。君のコードとインフラストラクチャに、強靭な同期あれ。

タイトルとURLをコピーしました