Claude Code で AWS 公式プラグイン「deploy-on-aws」を使ってシンプルなAPIをデプロイしてみた

Claude Code で AWS 公式プラグイン「deploy-on-aws」を使ってシンプルなAPIをデプロイしてみた

2026.03.27

はじめに

みなさん Claude Code でプラグインを使っているでしょうか。

AWS が公式で提供している awslabs/agent-plugins というリポジトリにdeploy-on-aws というプラグインがあります。

https://aws.amazon.com/blogs/developer/introducing-agent-plugins-for-aws/

アーキテクチャの選定からコスト見積、CDK コード生成、デプロイまでを一気通貫でやってくれるとのことです。「本当にそこまでやってくれるのかな」と思いつつ、実際にインストールしてお試し URL 短縮サービスをデプロイしてみました。

何が嬉しいのか

5 ステップのワークフローで迷わない

deploy-on-awsAnalyze → Recommend → Estimate → Generate → Deploy という 5 ステップのワークフローで動きます。「どのサービスを使えばいいか」という判断を Claude Code が担ってくれます。

3 つの MCP サーバーがリアルタイムで知識を補完

プラグインをインストールすると、以下の 3 つの MCP サーバーが自動で設定されます。

MCP サーバー 役割
awsknowledge アーキテクチャ判断・AWS ドキュメントの参照
awspricing リアルタイムのコスト見積
awsiac IaCのベストプラクティス適用

Claude Code の学習データだけでなく、最新の AWS 情報をリアルタイムで参照しながら提案してくれるのは嬉しいですね。

セキュリティの基準が明確

プラグインに含まれるリファレンスの security.md には セキュリティのデフォルトが定義されています。

S3 のプライベート設定、HTTPS 強制、IAM 最小権限、暗号化が生成されるコードに自動で含まれる設計です。

前提条件

  • Claude Code v2.1.29 以降
  • AWS CLI が設定済み
  • Node.js(CDK 実行用)
  • uvx(awspricingawsiac MCP サーバー実行用)

インストール手順

以下の 2 コマンドでインストールできます。

 /plugin marketplace add awslabs/agent-plugins
 /plugin install deploy-on-aws@agent-plugins-for-aws

インストール後、プラグインの.mcp.json に 3 つの MCP サーバーが設定されます。

.mcp.json
{
  "mcpServers": {
    "awsiac": {
      "args": [
        "awslabs.aws-iac-mcp-server@latest"
      ],
      "command": "uvx"
    },
    "awsknowledge": {
      "type": "http",
      "url": "https://knowledge-mcp.global.api.aws"
    },
    "awspricing": {
      "args": [
        "awslabs.aws-pricing-mcp-server@latest"
      ],
      "command": "uvx",
      "disabled": false,
      "env": {
        "FASTMCP_LOG_LEVEL": "ERROR"
      },
      "timeout": 120000,
      "type": "stdio"
    }
  }
}

やってみる

実際にプラグインをインストールした状態で、URL 短縮サービスをデプロイしてみました。

プラグインを実行

以下のコマンドで作成したいものを伝えてみます。

 /deploy-on-aws:deploy URL短縮サービスを作りたい

1. 分析 & 推奨サービス

以下のように要望に応じた分析と推奨のアーキテクチャが提案されます。

レイヤー サービス 理由
API API Gateway (HTTP API) シンプルなREST API、低コスト
コンピュート Lambda (Node.js 22.x) ステートレスAPI、フレームワーク不要
データベース DynamoDB (オンデマンド) key-valueアクセスパターンに最適
IaC CDK (TypeScript) 型安全、最も表現力が高い

2. 月額コスト見積もり(dev環境、ap-northeast-1、月10,000リクエスト想定)

合わせてアーキテクチャのコスト見積もりも MCP サーバーを使って出力されます。

サービス 月額費用 内訳
API Gateway (HTTP API) ~$0.01 $1.29/100万リクエスト
Lambda ~$0.00 無料枠内(100万リクエスト/月、40万GB秒)
DynamoDB (オンデマンド) ~$0.01 $1.4269/100万WRU, $0.2854/100万RRU
合計 ~$0.02/月 無料枠適用で実質$0に近い

アーキテクチャを検討する上でコストを踏まえて確認できるのはいいですね。
今回はお試しなので、このまま進めてみます。

生成されたコード

構成の承認後、CDK プロジェクトと Lambda 関数のコードが自動生成されました。中身を見てみましょう。

CDK スタック(インフラ定義)

lib/url-shortener-stack.ts
import * as cdk from 'aws-cdk-lib';
import { Construct } from 'constructs';
import * as dynamodb from 'aws-cdk-lib/aws-dynamodb';
import * as lambda from 'aws-cdk-lib/aws-lambda';
import * as apigwv2 from 'aws-cdk-lib/aws-apigatewayv2';
import * as apigwv2Integrations from 'aws-cdk-lib/aws-apigatewayv2-integrations';
import * as path from 'path';

export class UrlShortenerStack extends cdk.Stack {
  constructor(scope: Construct, id: string, props?: cdk.StackProps) {
    super(scope, id, props);

    // DynamoDB Table - オンデマンド、暗号化有効
    const table = new dynamodb.Table(this, 'UrlTable', {
      partitionKey: { name: 'shortId', type: dynamodb.AttributeType.STRING },
      billingMode: dynamodb.BillingMode.PAY_PER_REQUEST,
      encryption: dynamodb.TableEncryption.AWS_MANAGED,
      pointInTimeRecovery: true,
      removalPolicy: cdk.RemovalPolicy.DESTROY,
    });

    // Lambda Function
    const fn = new lambda.Function(this, 'UrlShortenerFn', {
      runtime: lambda.Runtime.NODEJS_22_X,
      handler: 'index.handler',
      code: lambda.Code.fromAsset(path.join(__dirname, '..', 'lambda')),
      memorySize: 128,
      timeout: cdk.Duration.seconds(10),
      environment: {
        TABLE_NAME: table.tableName,
      },
      architecture: lambda.Architecture.ARM_64,
    });

    // 最小権限: Lambda → DynamoDB
    table.grantReadWriteData(fn);

    // HTTP API (API Gateway v2)
    const httpApi = new apigwv2.HttpApi(this, 'UrlShortenerApi', {
      apiName: 'url-shortener',
      corsPreflight: {
        allowOrigins: ['*'],
        allowMethods: [apigwv2.CorsHttpMethod.GET, apigwv2.CorsHttpMethod.POST],
      },
    });

    const integration = new apigwv2Integrations.HttpLambdaIntegration(
      'LambdaIntegration',
      fn,
    );

    // POST /shorten - URL短縮
    httpApi.addRoutes({
      path: '/shorten',
      methods: [apigwv2.HttpMethod.POST],
      integration,
    });

    // GET /{shortId} - リダイレクト
    httpApi.addRoutes({
      path: '/{shortId}',
      methods: [apigwv2.HttpMethod.GET],
      integration,
    });

    // Outputs
    new cdk.CfnOutput(this, 'ApiUrl', {
      value: httpApi.apiEndpoint,
      description: 'URL Shortener API endpoint',
    });

    new cdk.CfnOutput(this, 'TableName', {
      value: table.tableName,
      description: 'DynamoDB table name',
    });
  }
}

前半で触れた「セキュリティのデフォルト」が実際に適用されているか確認してみます。

  • DynamoDB の暗号化
    • encryption: AWS_MANAGEDとポイントインタイムリカバリが有効
  • IAM 最小権限
    • table.grantReadWriteData(fn) で Lambda に必要な権限だけを付与
  • ARM64 を選択してコスト最適化
  • REST API ではなく HTTP API(API Gateway v2) を選択し、低コスト構成

そのままデプロイできるレベルのコードが生成されました。

一点気になったのが、dynamodb.Table が使われている点です。現在の CDK では TableV2 がすべてのユースケースで推奨されており、今後プラグイン側のアップデートで最新のコンストラクトが使われることを期待したいですね。

Lambda 関数(アプリケーション)

lambda/index.mjs
import { DynamoDBClient } from '@aws-sdk/client-dynamodb';
import { DynamoDBDocumentClient, PutCommand, GetCommand } from '@aws-sdk/lib-dynamodb';
import { randomBytes } from 'crypto';

const client = new DynamoDBClient({});
const docClient = DynamoDBDocumentClient.from(client);
const TABLE_NAME = process.env.TABLE_NAME;

export const handler = async (event) => {
  const { httpMethod, path, body, pathParameters } = parseEvent(event);

  if (httpMethod === 'POST' && path === '/shorten') {
    return await shortenUrl(JSON.parse(body));
  }

  if (httpMethod === 'GET' && pathParameters?.shortId) {
    return await redirectUrl(pathParameters.shortId);
  }

  return { statusCode: 404, body: JSON.stringify({ error: 'Not found' }) };
};

async function shortenUrl({ url }) {
  if (!url) {
    return { statusCode: 400, body: JSON.stringify({ error: 'url is required' }) };
  }

  const shortId = randomBytes(4).toString('hex');

  await docClient.send(new PutCommand({
    TableName: TABLE_NAME,
    Item: { shortId, originalUrl: url, createdAt: new Date().toISOString() },
  }));

  return {
    statusCode: 200,
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ shortId, shortUrl: `/${shortId}` }),
  };
}

async function redirectUrl(shortId) {
  const result = await docClient.send(new GetCommand({
    TableName: TABLE_NAME,
    Key: { shortId },
  }));

  if (!result.Item) {
    return { statusCode: 404, body: JSON.stringify({ error: 'URL not found' }) };
  }

  return {
    statusCode: 301,
    headers: { Location: result.Item.originalUrl },
    body: '',
  };
}

function parseEvent(event) {
  return {
    httpMethod: event.requestContext?.http?.method || event.httpMethod,
    path: event.rawPath || event.path,
    body: event.body,
    pathParameters: event.pathParameters,
  };
}

Lambda のコードもシンプルで読みやすいですね。AWS SDK v3 の DynamoDBDocumentClient を使っています。shortenUrl(短縮 URL 作成)と redirectUrl(リダイレクト)の 2 つのエンドポイントを処理しています。

デプロイ

コードが作成されたら CDK をデプロイします。

 npm exec cdk deploy --profile test-account --require-approval broadening

  UrlShortenerStack

  Deployment time: 64.19s

Outputs:
UrlShortenerStack.ApiUrl = https://i3mv7mhbyg.execute-api.ap-northeast-1.amazonaws.com
UrlShortenerStack.TableName = UrlShortenerStack-UrlTable6FBD0DEA-1DN2HNO7UG7DC
Stack ARN:
arn:aws:cloudformation:ap-northeast-1:111111111111:stack/UrlShortenerStack/382b8a10-2986-11f1-a894-0e59a1265639

ApiUrl が確認できるので実行してみましょう。

 curl -s -X POST https://i3mv7mhbyg.execute-api.ap-northeast-1.amazonaws.com/shorten \
    -H 'Content-Type: application/json' \
    -d '{"url":"https://dev.classmethod.jp"}'

{"shortId":"76dddba5","shortUrl":"/76dddba5"}

shortId が返ってきたので、リダイレクトされるか確認してみます。

❯ curl -s -o /dev/null -w "%{http_code} %{redirect_url}" \
    https://i3mv7mhbyg.execute-api.ap-northeast-1.amazonaws.com/76dddba5

301 https://dev.classmethod.jp/

問題なく 301 でリダイレクトされています。
数分で API の用意からアプリケーションの動作確認までが完了しました。

まとめ

deploy-on-aws プラグインで URL 短縮サービスを実際にデプロイできました。

今回は実装規模が小さいため、非常にシンプルな構成で実装できました。
全く手直しなしで利用できるというわけではないですが、動くものをすぐに作成できます。特にプラグインの実行で意思決定する部分がはっきりしており、判断箇所が見やすいのもいいですね。

ぜひプラグインを導入して AWS のベストプラクティスに沿った開発をしていきましょう。

以上、鈴木純がお送りしました。

参考

この記事をシェアする

FacebookHatena blogX

関連記事