HAQM Web Services ブログ
AWS Amplify Hosting でサーバーサイドレンダリングのための IAM Compute Roles
今日、AWS Amplify Hosting は、AWS Amplify アプリケーションの IAM Compute Roles を導入しました。これにより、コンピュート実行時から AWS サービスへの安全なアクセスを可能にし、サーバーサイドレンダリング機能を拡張できるようになりました。IAM Compute Roles を使えば、開発者はサーバーサイドレンダリングアプリに特定の権限を付与でき、Amplify が他の AWS サービスへの承認された呼び出しを行えるようになります。この新機能により、セキュリティのベストプラクティスを維持しながら、開発プロセスを加速できます。
主な機能
IAM Compute Roles を使えば、以下のことができるようになりました。
- Next.js API ルートから AWS Secrets Manager と AWS Systems Manager Parameter Store を使用して、ランタイムで機密設定データにアクセスできます。
- SSR アプリを HAQM RDS、HAQM DynamoDB などの AWS データベースに直接接続できます。
- AWS Identity and Access Management (IAM) ポリシーを使用して、コンピューティング環境に細かい権限を定義できます。
- サーバーサイドコードから任意の AWS サービスに対して、安全な認証済みの呼び出しができます。
チュートリアル
始める前に、IAM コンピューティング ロールを作成し、それを Amplify Next.js アプリケーションに関連付ける次の手順に従ってください。
前提条件
始める前に、以下がインストールされていることを確認してください。
IAM Compute Roles の作成
Amplify Hosting の SSR コンピューティングサービスが、ロールの権限と信頼関係に基づいて、AWS リソースに安全にアクセスできるように、IAM ロールを作成しましょう。この例では、HAQM Simple Storage Service (HAQM S3) バケットに安全にアクセスします。
- AWS マネジメントコンソールにサインインし、IAM コンソールに移動します
- Access Management タブの下で、Roles を選択し、Create role を選びます
- Custom trust policy を選択し、Amplify がこのロールを引き受けることができるように、以下のポリシーを入力します:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": [
"amplify.amazonaws.com"
]
},
"Action": "sts:AssumeRole"
}
]
}
- AWS 管理の
HAQMS3ReadOnlyAccess
権限ポリシーをロールに追加し、Next を選択します - ロールに
amplify-compute-role
という名前を付け、Create Role を選択します
Amplify が他の AWS サービスに接続するために引き受けることができるコンピュートロールを正常に作成しました。
セキュリティのベストプラクティス: 最小特権の原則を実施し、特定のユースケースに必要な権限のみを付与してください。
HAQM S3 バケットの作成
Next.js アプリが IAM Compute Roles を使用して安全にアクセスできる、プライベートの HAQM S3 バケットを設定します。HAQM S3 オブジェクトを公開したり、アクセスキーを管理するのではなく、Amplify Hosting の IAM Compute Roles を使って HAQM S3 からプライベートコンテンツを安全に取得します。
- AWS マネジメントコンソールにサインインし、HAQM S3 コンソールに移動します
- Create bucket を選択し、一意のバケット名を入力します
- ACL を無効にし、Block all public access を有効にしたままにします。
- デフォルトの設定のままで、Create bucket を選択します。
- バケットへ移動し、Upload を選択します。
- 画像 (例: amplify-logo.png) をアップロードします。
セキュリティの検証: S3 バケットが完全にロックダウンされていることを確認するには、次の get-public-access-block AWS CLI コマンドを実行してください:
// Note: Replace amplify-compute-role-demo with your specific bucket name
aws s3api get-public-access-block --bucket amplify-compute-role-demo
出力結果は次のようになるはずです。
{
"PublicAccessBlockConfiguration": {
"BlockPublicAcls": true,
"IgnorePublicAcls": true,
"BlockPublicPolicy": true,
"RestrictPublicBuckets": true
}
}
これらの設定は以下を保証します。
- パブリック ACL の作成はできません
- 既存のパブリック ACL は無視されます
- パブリックバケットポリシーはブロックされます
- バケットへのパブリックアクセスが制限されます
Next.js アプリの作成
次に、API ルートを使用して HAQM S3 バケットからプライベートコンテンツの画像にセキュアにアクセスできる Next.js アプリを作成します。
- 新しい Next.js 15 アプリを TypeScript と Tailwind CSS で作成します。
npx create-next-app@latest compute-role-demo --typescript --tailwind --eslint
cd compute-role-demo
- JavaScript 用の AWS SDK の S3 Client パッケージをインストールします。
npm install @aws-sdk/client-s3
- HAQM S3 Image API のルートを作成します。Amplify Hosting へのアプリケーションのデプロイ
// app/api/image/route.ts
import { S3Client, GetObjectCommand, S3ServiceException } from "@aws-sdk/client-s3";
import { NextResponse } from 'next/server';
const s3Client = new S3Client({});
const BUCKET_NAME = 'amplify-compute-role-demo';
const IMAGE_KEY = 'amplify-logo.png';
export async function GET() {
console.log(`[S3 Image Request] Starting - Bucket: ${BUCKET_NAME}, Key: ${IMAGE_KEY}`);
try {
console.log('[S3 Image Request] Creating GetObjectCommand...');
const command = new GetObjectCommand({
Bucket: BUCKET_NAME,
Key: IMAGE_KEY
});
console.log('[S3 Image Request] Sending request to S3...');
const response = await s3Client.send(command);
console.log('[S3 Image Request] Received S3 response:', {
contentType: response.ContentType,
contentLength: response.ContentLength,
metadata: response.Metadata
});
console.log('[S3 Image Request] Converting response to byte array...');
const buffer = await response.Body?.transformToByteArray();
if (!buffer) {
console.error('[S3 Image Request] No buffer received from S3');
throw new Error('No image data received from S3');
}
console.log('[S3 Image Request] Successfully processed image:', {
bufferSize: buffer.length,
contentType: response.ContentType
});
return new NextResponse(buffer, {
headers: {
'Content-Type': response.ContentType || 'image/png',
'Cache-Control': 'public, max-age=31536000, immutable'
}
});
} catch (error) {
if (error instanceof S3ServiceException) {
console.error('[S3 Image Request] AWS S3 Error:', {
message: error.message,
code: error.name,
requestId: error.$metadata?.requestId,
statusCode: error.$metadata?.httpStatusCode
});
} else {
console.error('[S3 Image Request] Unexpected error:', error);
}
return NextResponse.json({
success: false,
error: 'Failed to load content'
}, {
status: 500
});
} finally {
console.log('[S3 Image Request] Request completed');
}
}
- クライアントコンポーネントを作成します。
// app/components/S3Component.tsx
'use client';
import { useState } from 'react';
import Image from 'next/image';
export default function S3Component() {
const [imageError, setImageError] = useState(false);
const [isRevealed, setIsRevealed] = useState(false);
return (
<div className="absolute inset-0 top-[88px] flex items-center justify-center">
<div className="w-full max-w-2xl rounded-2xl mx-4">
<div className="flex flex-col items-center justify-center min-h-[400px] p-8">
{!isRevealed ? (
<button
onClick={() => setIsRevealed(true)}
className="px-8 py-4 bg-[rgb(117,81,194)] text-white text-lg rounded-xl
hover:bg-[rgb(107,71,184)] transition-colors"
>
<span className="flex items-center gap-2">
Access Private S3 Bucket
<span className="text-xl">⚡</span>
</span>
</button>
) : (
<div className="space-y-8 w-full">
{!imageError && (
<div className="relative h-64 w-full">
<Image
src="/api/image"
alt="Amplify Logo"
fill
unoptimized
priority
onError={() => setImageError(true)}
className="object-contain"
sizes="(max-width: 768px) 100vw, (max-width: 1200px) 50vw, 33vw"
/>
</div>
)}
<div className="text-center">
<p className="text-gray-400 text-sm">
This content is securely served from S3 using an IAM Compute Role.
</p>
</div>
</div>
)}
</div>
</div>
</div>
);
}
- ホームページを更新して、クライアントコンポーネントをレンダリングします。
import S3Component from './components/S3Component';
export default function HomePage() {
return (
<div className="relative min-h-screen bg-[rgb(0,0,0)]">
<h1 className="text-2xl font-bold text-white py-8 text-center relative z-10">
Amplify Hosting Compute Role Demo
</h1>
<S3Component />
</div>
);
}
- 変更を git リポジトリにプッシュします。
- 新しい GitHub リポジトリを作成します
- 変更内容を Git ブランチに追加してコミットします
- リモート オリジンを追加し、変更内容をアップストリームにプッシュします
git add .
git commit -m "initial commit"
git remote add origin http://github.com/<OWNER>/amplify-compute-role-demo.git
git push -u origin main
Amplify Hosting へのアプリケーションのデプロイ
- AWS マネジメントコンソールにサインインし、Amplify コンソールに移動します。
- Create new app を選び、リポジトリソースとして GitHub を選択します。
- Amplify が GitHub アカウントにアクセスできるように認証します。
- 作成したリポジトリとブランチを選択します。
- アプリの設定を確認し、Next を選択します。
- 全体の設定を確認し、Save and Deploy を選択します。
IAM Compute Roles を Amplify アプリに割り当てる
- Amplify コンソールでアプリを選択し、「App settings > IAM roles」に進みます
- コンピュート ロールのセクションで Edit を選択します
- ロールメニューから
amplify-compute-role
を選択し、Save を選んでください - ブランチごとに固有のコンピュートロールを使うようにブランチ上書きを設定することもできます。これは開発、ステージング、プロダクションなど、さまざまな Git 環境間で特に役立ちます。
Next.js アプリへのアクセス
Amplify コンソールのアプリの Overview タブに移動し、ブラウザ上で Amplify が生成したデフォルトの URL を開いてください。
次に、Access Private S3 ボタンを選択してください。HAQM S3 バケットにアップロードされた画像が表示されるはずです。
ホスティングコンピューティングのログのレビュー
アプリのホームページから、[Hosting] > [Monitoring] に移動し、Hosting compute logs タブを選択してください。
HAQM CloudWatch の Log Streams URL に移動し、最新のログストリームを確認してください。ログには HAQM S3 からの画像リクエストが含まれるはずです:
おめでとうございます! Amplify Hosting の Next.js SSR アプリケーションに、IAM Compute Roles を正常に作成して割り当てました。これで、プライベート HAQM S3 バケットからコンテンツを安全に取得できるようになりました! 🚀
クリーンアップ
- AWS Amplify アプリを削除するには、[ アプリ設定 ] > [ 全般設定 ] に移動し、[ アプリの削除 ] を選択します。
- HAQM S3 バケットを削除するには、S3 コンソールから [ バケットを選択 ] > [ 削除を選択 ] > 削除を確認するためにバケット名を入力します。
- IAM ロールを削除するには、IAM コンソールから [ ロールを選択 ] > amplify-compute-role 名を探し > [ 削除を選択 ] > 削除を確認するためにロール名を入力します。
まとめ
AWS Amplify Hosting は現在、サーバーサイドレンダリング (SSR) アプリケーションの IAM Compute Roles をサポートし、AWS サービスへのセキュアなアクセスの課題を解決しています。以前は、開発者が環境変数を介して手動で認証情報を管理していました。しかし、IAM Compute Roles を使えば、開発者は SSR アプリに直接 IAM アクセス許可を割り当てられるため、サービスの統合が簡単になり、セキュリティが強化されます。
SSR アプリに IAM Compute Roles を追加するには今日、Amplify ドキュメントをご覧ください。
本記事は「IAM Compute Roles for Server-Side Rendering with AWS Amplify Hosting」を翻訳したものです。