cloudflare-vpc-services について
Cloudflare WorkersからVPCトンネル経由でプライベートAPIやサービスへ接続するためのスキルです。設定テンプレート、スクリプト、リクエスト例を使って構築やトラブルシューティングを進められます。
主な機能
- 01VPCトンネルの設定ガイド
- 02Wranglerバインディング設定
- 03プライベートAPIのリクエスト例
- 04トンネルのトラブルシューティング
- 05設定テンプレートとスクリプト
活用シーン
- 01Workerから内部APIへの接続
- 02VPC接続エラーの診断
- 03プライベートサービスへのリクエスト振り分け
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ nodnarbnitram/ claude-code-extensions --skill cloudflare-vpc-servicesインストール後、Claude Code で/cloudflare-vpc-servicesを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
README.mdreferences/api-patterns.mdREADME.mdscripts/list-vpc-services.shREADME.mdset-api-token.shtail-worker.shtemplates/vpc-service-hostname.jsonvpc-service-ip.jsonwrangler-vpc.jsonc詳細
Cloudflare VPC サービス
Workers が、パブリックインターネットに公開せず、暗号化トンネルを通じてプライベート API やサービスに安全にアクセスできるようにします。
⚠️ 開始する前に
このスキルを使うと、よくあるエラーを 5 つ防ぎ、トークンを約 60%節約できます。
| 指標 | スキルなし | スキルあり |
|---|---|---|
| セットアップ時間 | 45 分以上 | 10 分 |
| よくあるエラー | 5 | 0 |
| トークン使用量 | 約 8000 | 約 3000 |
このスキルで防げる既知の問題
- 古い cloudflared バージョンまたは誤ったプロトコルによる
dns_error - 内部ホスト名ではなくパブリックホスト名を使用したため、リクエストが VPC の外に送信される
- ポートの不一致 — fetch() のポートは無視され、サービス設定のポートが使用される
- fetch() 呼び出しで絶対 URL が指定されていない
- トンネル ID またはサービスバインディングの設定が誤っている
クイックスタート
ステップ 1:トンネルの要件を確認する
# Check cloudflared version on remote infrastructure (K8s, EC2, etc.)
# Must be 2025.7.0 or later
cloudflared --version
# Verify QUIC protocol is configured (not http2)
# Check tunnel config or Cloudflare dashboard
重要な理由: Workers VPC では、QUIC プロトコルを使用する cloudflared 2025.7.0 以降が必要です。古いバージョンや http2 プロトコルでは dns_error が発生します。
ステップ 2:VPC サービスを作成する
# Use Cloudflare API or dashboard to create VPC service
# See templates/vpc-service-ip.json or templates/vpc-service-hostname.json
重要な理由: VPC サービスは、トンネルがルーティングする実際のターゲット(IP/ホスト名)を定義します。fetch() の URL は Host ヘッダーと SNI のみを設定します。
ステップ 3:Wrangler バインディングを設定する
// wrangler.jsonc
{
"vpc_services": [
{
"binding": "PRIVATE_API",
"service_id": "<YOUR_SERVICE_ID>",
"remote": true
}
]
}
重要な理由: バインディング名は、Worker コードで使用される環境変数になります:env.PRIVATE_API.fetch()。
重要なルール
✅ 必ず行うこと
- ✅ fetch() では、プロトコル、ホスト、パスを含む絶対 URL を使用する
- ✅ パブリックエンドポイントではなく、内部 VPC ホスト名を使用する
- ✅ cloudflared が 2025.7.0 以降で、QUIC プロトコルを使用していることを確認する
- ✅ QUIC 接続用に、アウトバウンド UDP ポート 7844 を許可する
❌ 絶対に行わないこと
- ❌ fetch() の URL にポート番号を指定する(無視されます)
- ❌ VPC 内のサービスにパブリックホスト名を使用する
- ❌ http2 プロトコルが動作すると想定する(QUIC のみサポートされています)
- ❌ fetch() で相対 URL を使用する
よくある間違い
❌ 誤り:
// Port is ignored, relative URL fails
const response = await env.VPC_SERVICE.fetch("/api/users:8080");
✅ 正しい例:
// Absolute URL, port configured in VPC service
const response = await env.VPC_SERVICE.fetch("https://internal-api.company.local/api/users");
理由: 実際のルーティングは VPC サービスの設定によって決まります。fetch() の URL は Host ヘッダーと SNI の値のみを設定します。
既知の問題の予防
| 問題 | 根本原因 | 解決策 |
|---|---|---|
dns_error | cloudflared < 2025.7.0、または http2 プロトコル | cloudflared を更新し、QUIC を設定して、UDP 7844 を許可する |
| リクエストがパブリックインターネットに送信される | fetch() でパブリックホスト名を使用している | 内部 VPC ホスト名を使用する |
| 接続が拒否される | VPC サービス設定のポートが誤っている | サービスで正しい http_port/https_port を設定する |
| タイムアウト | トンネルが稼働していない、または tunnel_id が誤っている | トンネルの状態を確認し、tunnel_id を確認する |
| 404 エラー | パスのルーティングが正しくない | 内部サービスのパスが fetch() のパスと一致することを確認する |
設定リファレンス
wrangler.jsonc
{
"name": "my-worker",
"main": "src/index.ts",
"compatibility_date": "2024-01-01",
"vpc_services": [
{
"binding": "PRIVATE_API",
"service_id": "daf43e8c-a81a-4242-9912-4a2ebe4fdd79",
"remote": true
},
{
"binding": "PRIVATE_DATABASE",
"service_id": "453b6067-1327-420d-89b3-2b6ad16e6551",
"remote": true
}
]
}
主な設定:
binding:サービスへのアクセスに使用する環境変数名service_id:VPC サービスの作成時に発行された UUIDremote:VPC サービスではtrueにする必要があります
よくあるパターン
基本的な GET リクエスト
export default {
async fetch(request, env) {
const response = await env.PRIVATE_API.fetch(
"https://internal-api.company.local/users"
);
return response;
}
};
認証付き POST
const response = await env.PRIVATE_API.fetch(
"https://internal-api.company.local/users",
{
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${env.API_TOKEN}`
},
body: JSON.stringify({ name: "John", email: "[email protected]" })
}
);
パスルーティングを使用する API ゲートウェイ
export default {
async fetch(request, env) {
const url = new URL(request.url);
if (url.pathname.startsWith('/api/users')) {
return env.USER_SERVICE.fetch(
`https://user-api.internal${url.pathname}`
);
} else if (url.pathname.startsWith('/api/orders')) {
return env.ORDER_SERVICE.fetch(
`https://orders-api.internal${url.pathname}`
);
}
return new Response('Not Found', { status: 404 });
}
};
同梱リソース
テンプレート
templates/ にあります:
wrangler-vpc.jsonc- VPC バインディングを設定済みの、すぐに使える Wrangler 設定vpc-service-ip.json- IP ベースの VPC サービス API ペイロードvpc-service-hostname.json- ホスト名ベースの VPC サービス API ペイロード
実装の出発点として、これらのテンプレートをコピーして使用してください。
スクリプト
scripts/ にあります:
list-vpc-services.sh- Cloudflare API 経由で VPC サービスを一覧表示するtail-worker.sh- ライブログで VPC 接続をデバッグするset-api-token.sh- プライベート API 認証用のシークレットを設定する
リファレンス
references/ にあります:
api-patterns.md- fetch() の包括的なパターンと例
依存関係
必須
| パッケージ | バージョン | 目的 |
|---|---|---|
| wrangler | latest | VPC バインディングを使用して Workers をデプロイします |
| cloudflared | 2025.7.0+ | トンネルデーモン(リモートインフラストラクチャ上) |
任意
| パッケージ | バージョン | 目的 |
|---|---|---|
| @cloudflare/workers-types | latest | Workers 用の TypeScript 型 |
公式ドキュメント
トラブルシューティング
VPC サービスの呼び出し時に発生する dns_error
症状: env.VPC_SERVICE.fetch() の呼び出し時に Worker が dns_error を返します。
解決策:
- リモートインフラストラクチャ上の cloudflared を 2025.7.0+ に更新します
- QUIC プロトコルを設定します(http2 ではなく)
- アウトバウンドの UDP ポート 7844 を許可します
リクエストがパブリックインターネットに送信される
症状: ログに、内部エンドポイントではなくパブリックエンドポイントへのリクエストが記録されます。
解決策:
// Use internal hostname
const response = await env.VPC_SERVICE.fetch(
"https://internal-api.vpc.local/endpoint" // Internal
// NOT "https://api.company.com/endpoint" // Public
);
接続タイムアウト
症状: リクエストが停止し、最終的にタイムアウトします。
解決策:
- トンネルが稼働していることを確認します:cloudflared のログを確認します
- VPC サービスの設定で tunnel_id が一致していることを確認します
- トンネルからターゲットへのネットワーク接続を確認します
セットアップチェックリスト
このスキルを使用する前に、次の項目を確認してください。
- cloudflared 2025.7.0+ がリモートインフラストラクチャにデプロイされている
- QUIC プロトコルが設定されている(http2 ではなく)
- アウトバウンドの UDP ポート 7844 が許可されている
- 正しい tunnel_id で VPC サービスが作成されている
- wrangler.jsonc に vpc_services バインディングがある
- 内部ホスト名を使用している(パブリックエンドポイントではなく)
- fetch() 呼び出しで絶対 URL を使用している