TL;DR
- Amplify HostingでSSRする際に不足していた「実行ロール」機能が実装された。これでSSR環境下で安全にAWSリソースを利用できる
- 今までは安全にAWSリソースを制御するには、Amplify Backendか、IAMユーザーのクレデンシャルを持たせるかしか方法がなかったが、これが解決する(AWSのほかのコンピューティングと同じように使える)
Amplify Hostingの実行環境にIAMロールを設定出来るようになった
Amplify Hostingでは最近はServer-side Rendering(SSR)がサポートされていて、Node.js上でフロントエンドアプリケーションを実行してくれるようになっています。ただしこれまで、そのNode.js実行環境にIAMロールを設定することが出来ませんでした。このアップデートでIAMロールを設定出来るようになり、Node.jsから安全にAWSリソースを操作出来るようになります。
本記事では、SvelteKitを利用して、IAMロールに基づいたAWSリソースの制御をテストします。
検証
S3バケットの作成
バケットを作成してファイルを置いておく。ここではamplify-role-test
というバケットにmock.json
というファイルを配置。
{
"message": "hello amplify"
}
IAMポリシーの作成
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "VisualEditor0",
"Effect": "Allow",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::amplify-role-test/*"
}
]
}
IAMロールの作成
「カスタム信頼ポリシー」を選択して以下のポリシーを記述
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": [
"amplify.amazonaws.com"
]
},
"Action": "sts:AssumeRole"
}
]
}
SvelteKitアプリケーションの作成
SvelteKitはAmplifyで動作します。詳しくは以下の記事を参照してください。
npx sv create svelte-amplify-ssr-role
cd svelte-amplify-ssr-role
pnpm add -D @aws-sdk/client-s3 amplify-adapter
import { GetObjectCommand, S3Client } from '@aws-sdk/client-s3';
import { json } from '@sveltejs/kit';
const s3 = new S3Client({
region: 'ap-northeast-1',
});
export async function GET() {
// getobject
const params = {
Bucket: 'amplify-role-test',
Key: 'mock.json',
};
const command = new GetObjectCommand(params);
const response = await s3.send(command);
const jsonStr = await response.Body.transformToString();
const _json = JSON.parse(jsonStr);
return json(_json);
}
import type { PageServerLoad } from './$types';
import { GetObjectCommand, S3Client } from '@aws-sdk/client-s3';
const s3 = new S3Client({
region: 'ap-northeast-1',
});
export const load: PageServerLoad = async ({}) => {
// getobject
const params = {
Bucket: 'amplify-role-test',
Key: 'mock.json',
};
const command = new GetObjectCommand(params);
const response = await s3.send(command);
const jsonStr = await response.Body.transformToString();
const _json = JSON.parse(jsonStr) as { message: string };
return {
mock: _json,
};
};
<script lang="ts">
let { data } = $props();
async function fetchS3() {
const response = await fetch('/api/mock');
const json = await response.json();
alert(JSON.stringify(json, null, 2));
}
</script>
<!-- SSR -->
<p>mock.json:</p>
<pre>{JSON.stringify(data, null, 2)}</pre>
<!-- Fetch API via API Routes -->
<button onclick={fetchS3}>Fetch S3</button>
import adapter from 'amplify-adapter';
// 以下略
コードはGitHubにあげておきましょう。上記のコードは:
-
/api/mock
に対するGETリクエストの実装 -
/
で返却するページの実装
がそれぞれ含まれています。1はREST-APIのことで、Fetch APIで動作を検証しています。2はSSRのことで、/
にアクセスした際に返却されるHTMLの内容にS3の内容が含まれています。
Amplifyアプリケーションの作成
version: 1
frontend:
phases:
preBuild:
commands:
- 'npm install -g pnpm'
- 'pnpm install'
build:
commands:
- 'pnpm build'
- 'cd build/compute/default/'
- 'npm i --production'
artifacts:
baseDirectory: build
files:
- '**/*'
cache:
paths:
- 'node_modules/**/*'
コンピューティングロールの設定
「アプリケーションの設定」に「IAMロール」が追加されているので、「コンピューティングロール」に先ほど作成したIAMロールを設定します。ブランチごとに区別することも出来るようですね。
動作検証
デプロイされたアプリケーションにアクセスします。
API Routesに対するFetch APIの結果。S3にあるファイルを取得できている。
コンピューティングロールの設定を解除してみる
再度デプロイして(重要、デプロイ時にIAMロールが決定されるもよう)、アプリケーションにアクセスする
エラーが発生するようになる、ログを確認する
クレデンシャルが読めてなさそうなので、期待どおりの挙動
終わりに
全俺が待ってたアップデートゆえ取り急ぎ検証回しました
Amplify + SSRについては以下のようなトークを持ったこともありました
そこでも「実行ロール」が利用できないことには言及していました
今回のアップデートにより、Amplify Hostingの活用の幅がより広がるものと期待しています