mcpField
A
aws

aws

github.com/vercel-labsテスト・品質2.0k225 回インストール6 日前に更新
リポジトリ

aws について

aws はアプリケーションのテスト向けに、AWS API をインメモリで模擬します。S3、SQS、Cognito、IAM、STS を扱い、AWS SDK クライアント向けのリクエスト形式に対応します。

主な機能

  1. 01S3、SQS、Cognito、IAM、STS の模擬
  2. 02AWS SDK のリクエスト形式に対応
  3. 03サービス状態をメモリ内に保持
  4. 04シード設定からデータを初期化
  5. 05状態インスペクターを提供

活用シーン

  1. 01S3 のアップロードとダウンロードのテスト
  2. 02SQS メッセージ処理の検証
  3. 03Cognito の登録と認証のテスト
  4. 04IAM と STS API 連携の確認

インストール

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

$npx skills add https://github.com/vercel-labs/emulate --skill aws

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

詳細

AWS Emulator

S3、SQS、Cognito、IAM、STS のエミュレーションを提供し、AWS SDK と互換性のある S3 パスを使用します。S3 のアップロードとダウンロードでは、生のバイト長や ETag を含む任意のバイナリペイロードが保持されます。SQS は AWS JSON 1.0 プロトコルと XML Query プロトコルに対応し、IAM と STS は XML Query を使用します。すべての状態はメモリ内に保持されます。

起動

ローカルリスナーは、デフォルトで 127.0.0.1 にバインドします。コンテナーやほかのマシンからアクセスするには、CLI に --host 0.0.0.0 を渡すか、createEmulator に hostname: '0.0.0.0' を渡してください。クライアントから到達可能な URL を通知するには、--base-url または baseUrl を設定してください。

# AWS only
npx emulate --service aws

# Default port (when run alone)
# http://localhost:4000

または、プログラムから起動します。

import { createEmulator } from 'emulate'

const aws = await createEmulator({ service: 'aws', port: 4006 })
// aws.url === 'http://localhost:4006'

認証

トークンは Authorization: Bearer <token> として渡します。スコープ付き権限では、s3:*、sqs:*、iam:*、sts:* のパターンを使用します。

curl http://localhost:4006/ \
  -H "Authorization: Bearer test_token_admin"

アプリをエミュレーターに接続する

環境変数
AWS_EMULATOR_URL=http://localhost:4006
AWS SDK v3
import { S3Client } from '@aws-sdk/client-s3'

const s3 = new S3Client({
  endpoint: process.env.AWS_EMULATOR_URL,
  region: 'us-east-1',
  credentials: {
    accessKeyId: 'AKIAIOSFODNN7EXAMPLE',
    secretAccessKey: 'wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY',
  },
  forcePathStyle: true,
})
import { SQSClient } from '@aws-sdk/client-sqs'

const sqs = new SQSClient({
  endpoint: `${process.env.AWS_EMULATOR_URL}/sqs`,
  region: 'us-east-1',
  credentials: {
    accessKeyId: 'AKIAIOSFODNN7EXAMPLE',
    secretAccessKey: 'wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY',
  },
})
import { IAMClient } from '@aws-sdk/client-iam'

const iam = new IAMClient({
  endpoint: `${process.env.AWS_EMULATOR_URL}/iam`,
  region: 'us-east-1',
  credentials: {
    accessKeyId: 'AKIAIOSFODNN7EXAMPLE',
    secretAccessKey: 'wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY',
  },
})

シード設定

aws:
  region: us-east-1
  s3:
    buckets:
      - name: my-app-bucket
      - name: my-app-uploads
        region: eu-west-1
  sqs:
    queues:
      - name: my-app-events
      - name: my-app-dlq
        visibility_timeout: 60
      - name: my-app-orders.fifo
        fifo: true
  iam:
    users:
      - user_name: developer
        create_access_key: true
      - user_name: readonly-user
    roles:
      - role_name: lambda-execution-role
        description: Role for Lambda function execution
        assume_role_policy: '{"Version":"2012-10-17","Statement":[{"Effect":"Allow","Principal":{"Service":"lambda.amazonaws.com"},"Action":"sts:AssumeRole"}]}'

デフォルトのシード(常に作成されます):S3 バケット emulate-default、SQS キュー emulate-default-queue、アクセスキーのペア(AKIAIOSFODNN7EXAMPLE / wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY)を持つ IAM ユーザー admin。

API エンドポイント

S3

S3 のルートでは、実際の AWS S3 ワイヤーフォーマットに一致するルートパスを使用します。従来の /s3/ 付きパスにも対応しています。

# List all buckets
curl http://localhost:4006/ \
  -H "Authorization: Bearer $TOKEN"

# Create bucket
curl -X PUT http://localhost:4006/my-bucket \
  -H "Authorization: Bearer $TOKEN"

# Delete bucket (must be empty)
curl -X DELETE http://localhost:4006/my-bucket \
  -H "Authorization: Bearer $TOKEN"

# Head bucket (check existence, get region)
curl -I http://localhost:4006/my-bucket \
  -H "Authorization: Bearer $TOKEN"

# List objects (with prefix, delimiter, pagination)
curl "http://localhost:4006/my-bucket?prefix=uploads/&delimiter=/&max-keys=100" \
  -H "Authorization: Bearer $TOKEN"

# Put object
curl -X PUT http://localhost:4006/my-bucket/path/to/file.txt \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: text/plain" \
  -H "x-amz-meta-author: test" \
  --data-binary "file contents"

# Get object
curl http://localhost:4006/my-bucket/path/to/file.txt \
  -H "Authorization: Bearer $TOKEN"

# Head object (metadata only)
curl -I http://localhost:4006/my-bucket/path/to/file.txt \
  -H "Authorization: Bearer $TOKEN"

# Delete object
curl -X DELETE http://localhost:4006/my-bucket/path/to/file.txt \
  -H "Authorization: Bearer $TOKEN"

# Copy object
curl -X PUT http://localhost:4006/dest-bucket/copy.txt \
  -H "Authorization: Bearer $TOKEN" \
  -H "x-amz-copy-source: /source-bucket/original.txt"
SQS

現在の AWS SDK クライアントでは、上記に示す /sqs エンドポイントを使用します。SQS は、Content-Type: application/x-amz-json-1.0 と X-Amz-Target: AmazonSQS.<Action> を指定した POST /sqs/ への AWS JSON 1.0 リクエストを受け付け、JSON 形式の結果とエラーを返します。Action フォームパラメーターを含む XML Query リクエストにも引き続き対応しています。キュー操作では、返された QueueUrl をエンドポイントとして使用することもできます。

# List queues using AWS JSON 1.0
curl -X POST http://localhost:4006/sqs/ \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/x-amz-json-1.0" \
  -H "X-Amz-Target: AmazonSQS.ListQueues" \
  -d '{}'
# Create queue
curl -X POST http://localhost:4006/sqs/ \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "Action=CreateQueue&QueueName=my-queue"

# Create queue with attributes
curl -X POST http://localhost:4006/sqs/ \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "Action=CreateQueue&QueueName=my-queue&Attribute.1.Name=VisibilityTimeout&Attribute.1.Value=30"

# List queues
curl -X POST http://localhost:4006/sqs/ \
  -H "Authorization: Bearer $TOKEN" \
  -d "Action=ListQueues"

# List queues with prefix filter
curl -X POST http://localhost:4006/sqs/ \
  -H "Authorization: Bearer $TOKEN" \
  -d "Action=ListQueues&QueueNamePrefix=my-"

# Get queue URL
curl -X POST http://localhost:4006/sqs/ \
  -H "Authorization: Bearer $TOKEN" \
  -d "Action=GetQueueUrl&QueueName=my-queue"

# Get queue attributes
curl -X POST http://localhost:4006/sqs/ \
  -H "Authorization: Bearer $TOKEN" \
  -d "Action=GetQueueAttributes&QueueUrl=<queue_url>"

# Send message
curl -X POST http://localhost:4006/sqs/ \
  -H "Authorization: Bearer $TOKEN" \
  -d "Action=SendMessage&QueueUrl=<queue_url>&MessageBody=Hello+World"

# Send message with attributes
curl -X POST http://localhost:4006/sqs/ \
  -H "Authorization: Bearer $TOKEN" \
  -d "Action=SendMessage&QueueUrl=<queue_url>&MessageBody=Hello&MessageAttribute.1.Name=type&MessageAttribute.1.Value.DataType=String&MessageAttribute.1.Value.StringValue=greeting"

# Receive messages
curl -X POST http://localhost:4006/sqs/ \
  -H "Authorization: Bearer $TOKEN" \
  -d "Action=ReceiveMessage&QueueUrl=<queue_url>&MaxNumberOfMessages=5"

# Delete message
curl -X POST http://localhost:4006/sqs/ \
  -H "Authorization: Bearer $TOKEN" \
  -d "Action=DeleteMessage&QueueUrl=<queue_url>&ReceiptHandle=<receipt_handle>"

# Purge queue
curl -X POST http://localhost:4006/sqs/ \
  -H "Authorization: Bearer $TOKEN" \
  -d "Action=PurgeQueue&QueueUrl=<queue_url>"

# Delete queue
curl -X POST http://localhost:4006/sqs/ \
  -H "Authorization: Bearer $TOKEN" \
  -d "Action=DeleteQueue&QueueUrl=<queue_url>"
IAM

IAM のすべての操作では、Action を form-urlencoded パラメーターとして指定して POST /iam/ を使用します。

# Create user
curl -X POST http://localhost:4006/iam/ \
  -H "Authorization: Bearer $TOKEN" \
  -d "Action=CreateUser&UserName=new-user"

# Get user
curl -X POST http://localhost:4006/iam/ \
  -H "Authorization: Bearer $TOKEN" \
  -d "Action=GetUser&UserName=new-user"

# List users
curl -X POST http://localhost:4006/iam/ \
  -H "Authorization: Bearer $TOKEN" \
  -d "Action=ListUsers"

# Delete user
curl -X POST http://localhost:4006/iam/ \
  -H "Authorization: Bearer $TOKEN" \
  -d "Action=DeleteUser&UserName=new-user"

# Create access key
curl -X POST http://localhost:4006/iam/ \
  -H "Authorization: Bearer $TOKEN" \
  -d "Action=CreateAccessKey&UserName=developer"

# List access keys
curl -X POST http://localhost:4006/iam/ \
  -H "Authorization: Bearer $TOKEN" \
  -d "Action=ListAccessKeys&UserName=developer"

# Delete access key
curl -X POST http://localhost:4006/iam/ \
  -H "Authorization: Bearer $TOKEN" \
  -d "Action=DeleteAccessKey&UserName=developer&AccessKeyId=AKIA..."

# Create role
curl -X POST http://localhost:4006/iam/ \
  -H "Authorization: Bearer $TOKEN" \
  -d "Action=CreateRole&RoleName=my-role&AssumeRolePolicyDocument={}"

# Get role
curl -X POST http://localhost:4006/iam/ \
  -H "Authorization: Bearer $TOKEN" \
  -d "Action=GetRole&RoleName=my-role"

# List roles
curl -X POST http://localhost:4006/iam/ \
  -H "Authorization: Bearer $TOKEN" \
  -d "Action=ListRoles"

# Delete role
curl -X POST http://localhost:4006/iam/ \
  -H "Authorization: Bearer $TOKEN" \
  -d "Action=DeleteRole&RoleName=my-role"
Cognito

エンドポイント /cognito-idp では CognitoIdentityProviderClient を、/cognito-identity では CognitoIdentityClient を使用します。どちらも AWS JSON 1.1 を受け付け、公式 AWS SDK v3 で動作します。

import { CognitoIdentityProviderClient, InitiateAuthCommand } from "@aws-sdk/client-cognito-identity-provider";

const cognito = new CognitoIdentityProviderClient({
  endpoint: "http://localhost:4007/cognito-idp",
  region: "us-east-1",
  credentials: { accessKeyId: "local-access-key", secretAccessKey: "local-secret" },
});
const result = await cognito.send(new InitiateAuthCommand({
  ClientId: "emulateclient",
  AuthFlow: "USER_PASSWORD_AUTH",
  AuthParameters: { USERNAME: "developer", PASSWORD: "LocalPass123!" },
}));

デフォルトのユーザープール us-east-1_emulate、パブリックアプリクライアント emulateclient、アイデンティティプール us-east-1:00000000-0000-4000-8000-000000000001 が、ユーザーなしで作成されます。上記の例で使う、確認済みアカウントをシードします。

aws:
  cognito:
    user_pools:
      - id: us-east-1_emulate
        confirmation_code: "123456"
        users:
          - username: developer
            password: LocalPass123!
            attributes:
              email: [email protected]
              email_verified: "true"
              name: Developer

ユーザープールでは、name と、client_id、省略可能な client_secret、完全一致する redirect_uris、許可する scopes を含む clients も指定できます。ユーザーでは、status(CONFIRMED、UNCONFIRMED、FORCE_CHANGE_PASSWORD のいずれか)と enabled を指定できます。パスワードは8文字以上である必要があり、ソルト付きハッシュとして保存されます。機密クライアントでは、SDK フローで Cognito の HMAC SecretHash または SECRET_HASH が必要です。

  • SignUp、ConfirmSignUp、ResendConfirmationCode、ForgotPassword、ConfirmForgotPassword は、アカウントの確認と復旧をシミュレートします。コードの有効期限は10分で、プールの confirmation_code フィクスチャを使用します。デフォルトは 123456 です。メールや SMS は送信されません。有効なコードは /_inspector?tab=cognito で確認できます。シードされた未確認ユーザーは、ResendConfirmationCode でコードを要求できます。
  • InitiateAuth は USER_PASSWORD_AUTH、REFRESH_TOKEN_AUTH、REFRESH_TOKEN をサポートします。AdminInitiateAuth は ADMIN_USER_PASSWORD_AUTH もサポートします。管理者が作成した一時パスワードでは NEW_PASSWORD_REQUIRED が返され、RespondToAuthChallenge または AdminRespondToAuthChallenge で完了します。チャレンジセッションの有効期限は3分で、ユーザーとクライアントに紐付けられます。
  • GetUser、ChangePassword、GlobalSignOut、RevokeToken は発行済みトークンを使用します。AdminCreateUser(TemporaryPassword を指定)、AdminGetUser、AdminConfirmSignUp、AdminSetUserPassword、AdminEnableUser、AdminDisableUser、AdminDeleteUser、ページネーション付きの ListUsers は、テストのセットアップと管理に対応しています。

トークンは Cognito の token_use クレームを含む RS256 JWT です。ID トークンではアプリクライアントを aud で識別し、アクセストークンでは client_id を使用します。ID トークンとアクセストークンの有効期限は1時間、リフレッシュトークンの有効期限は30日です。サインアウト、失効、無効化、削除、パスワードのリセットを行うと、影響を受けるセッションは無効になります。ユーザー、セッション、アイデンティティ、署名鍵はスナップショット、復元、リセットの対象です。

ローカルの発行者は http://localhost:4007/cognito-idp/USER_POOL_ID です。ディスカバリー情報と公開鍵は ISSUER/.well-known/openid-configuration および ISSUER/.well-known/jwks.json で提供されます。トークン検証器には、このローカルの発行者と JWKS を設定してください。ISSUER/oauth2/authorize ではローカルユーザー選択画面が表示され、ISSUER/oauth2/token では認可コードまたはリフレッシュトークンを交換し、ISSUER/oauth2/userInfo ではスコープで指定されたプロフィールクレームを返します。認可コードの有効期限は5分で、1回のみ使用でき、クライアント、完全一致するリダイレクト URI、省略可能な S256 PKCE チャレンジに紐付けられます。クライアント認証では client_secret_basic または client_secret_post を使用できます。デフォルトのクライアントでは http://localhost:3000/callback が許可されています。

Identity Pool は GetId と GetCredentialsForIdentity をサポートします。Logins に、cognito-idp.REGION.amazonaws.com/USER_POOL_ID をキーとして ID トークンを指定します。デフォルトの Identity Pool は、デフォルトの User Pool とアプリクライアントを受け付けます。カスタム aws.cognito.identity_pools エントリでは、id、省略可能な name、providers: [{ user_pool_id, client_id }]、allow_unauthenticated_identities(デフォルトは false)を指定します。同じ認証済みサブジェクトには、常に同じアイデンティティが割り当てられます。認証情報の有効期限は1時間です。ログイン署名、有効期限、オーディエンス、アイデンティティの所有権が検証されます。

SRP、MFA、外部アイデンティティプロバイダー、Lambda トリガー、プール/クライアント管理 API、ListUsers のフィルター、Identity Pool のロール選択はシミュレートされません。管理者リクエストでは、AWS エミュレーターの寛容な認証情報の動作が適用されます。SigV4 署名と IAM ポリシーは評価されません。Identity Pool の認証情報はテスト用に生成され、ロールやポリシーの評価は行われません。

STS

STS のすべての操作では、Action を form-urlencoded パラメーターとして指定し、POST /sts/ を使用します。

# Get caller identity
curl -X POST http://localhost:4006/sts/ \
  -H "Authorization: Bearer $TOKEN" \
  -d "Action=GetCallerIdentity"

# Assume role
curl -X POST http://localhost:4006/sts/ \
  -H "Authorization: Bearer $TOKEN" \
  -d "Action=AssumeRole&RoleArn=arn:aws:iam::123456789012:role/my-role&RoleSessionName=my-session"
Inspector
# HTML dashboard (shows S3, SQS, IAM state)
curl http://localhost:4006/_inspector?tab=s3
curl http://localhost:4006/_inspector?tab=sqs
curl http://localhost:4006/_inspector?tab=iam

共通パターン

オブジェクトのアップロードと取得
TOKEN="test_token_admin"
BASE="http://localhost:4006"

# Create bucket
curl -X PUT $BASE/my-data \
  -H "Authorization: Bearer $TOKEN"

# Upload file
curl -X PUT $BASE/my-data/config.json \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  --data-binary '{"key": "value"}'

# Download file
curl $BASE/my-data/config.json \
  -H "Authorization: Bearer $TOKEN"
SQS メッセージの送受信
TOKEN="test_token_admin"
BASE="http://localhost:4006"

# Get queue URL
QUEUE_URL=$(curl -s -X POST $BASE/sqs/ \
  -H "Authorization: Bearer $TOKEN" \
  -d "Action=GetQueueUrl&QueueName=emulate-default-queue" | grep -oP '<QueueUrl>\K[^<]+')

# Send message
curl -X POST $BASE/sqs/ \
  -H "Authorization: Bearer $TOKEN" \
  -d "Action=SendMessage&QueueUrl=$QUEUE_URL&MessageBody=Hello+from+emulate"

# Receive messages
curl -X POST $BASE/sqs/ \
  -H "Authorization: Bearer $TOKEN" \
  -d "Action=ReceiveMessage&QueueUrl=$QUEUE_URL&MaxNumberOfMessages=1"
アクセスキー付き IAM ユーザーの作成
TOKEN="test_token_admin"
BASE="http://localhost:4006"

# Create user
curl -X POST $BASE/iam/ \
  -H "Authorization: Bearer $TOKEN" \
  -d "Action=CreateUser&UserName=ci-user"

# Generate access key
curl -X POST $BASE/iam/ \
  -H "Authorization: Bearer $TOKEN" \
  -d "Action=CreateAccessKey&UserName=ci-user"

組み込みエミュレーターと並行して使用するカスタムエミュレーター

npx emulate init --custom inventory を使用して、サードパーティ API エミュレーターをスキャフォールドし、テストします。emulate の defineConfig を使って、{ emulator: "aws" } などの組み込みエントリと並べて、emulate.config.ts に登録します。npx emulate start --watch を実行すると、インポートが再読み込みされ、表示された /_emulate URL でカスタム状態を確認できます。再読み込みが成功すると、実行状態はシードにリセットされます。既存のフラットなシード設定も引き続き使用できます。--config で明示的なファイルを指定します。サードパーティ API エミュレーターの作成とテストについては、https://emulate.dev/docs/custom-emulators をご覧ください。

コメント