éçºè
ã¯ãã°ãã°ã AWS Amplify Hosting ã«ãããã€ããã Next.js ã¢ããªã±ãŒã·ã§ã³ããã Amazon Virtual Private Cloud (Amazon VPC) å
ã«ãããã€ããããªãœãŒã¹ã«ã¢ã¯ã»ã¹ããå¿
èŠããããŸãã Amazon VPC ã䜿çšãããšãã客æ§ã¯éé¢ãããä»®æ³ãããã¯ãŒã¯ã§ãªãœãŒã¹ãèµ·åã§ããŸããããããéçºè
ã¯ãè€éãªãããã¯ãŒã¯ã¢ã¯ã»ã¹å¶åŸ¡ãšã»ãã¥ãªãã£ã°ã«ãŒãã®ããã«ãAmazon VPC å
ã§ API ãšããŒã¿ããŒã¹ãåŒã³åºãããã«ããã³ããšã³ãã¢ããªã±ãŒã·ã§ã³ãæ¥ç¶ããããšãå°é£ã§ãããšæãããããããŸããã ãã®æçš¿ã§ã¯ãAWS Amplify Hosting äžã§åäœãã Next.js ãµãŒããŒãµã€ãã¬ã³ããªã³ã° (SSR) ã¢ããªã±ãŒã·ã§ã³ããã Amazon Relational Database Service (Amazon RDS) ã AWS Lambda ãªã©ã®ãªãœãŒã¹ã VPC å
ã®ãªãœãŒã¹ã«ã¢ã¯ã»ã¹ããããã®ãœãªã¥ãŒã·ã§ã³ãå®è£
ããŸãã ãœãªã¥ãŒã·ã§ã³ã®æŠèŠ ãŸãã AWS Cloud Development Kit (AWS CDK) ã䜿ã£ãŠãAmazon VPC å
ã« Lambda 颿°ããã«ãããŠãããã€ããŸãã æ¬¡ã«ãPages Router ã䜿çšãã Next.js API Routes ãéã㊠Amazon VPC å
ã®ããŒã¿ã«ã¢ã¯ã»ã¹ãã Next.js ã¢ããªãäœæããAWS Amplify Hosting äžã§ãã¹ãããã React UI ã«ã¢ã¯ã»ã¹ããŸãã AWS Systems Manager Parameter Store ãå©çšãã API ããŒããã®ä»ã®èšå®ããŒã¿ã®ãã¢ãè¡ããŸãã ãã®çµæããšã³ããŠãŒã¶ãŒã Amazon VPC å
ããããŒã¿ã衚瀺ããããã«ã¢ã¯ã»ã¹ã§ãã Next.js ã¢ããªãäœæãããŸãã åææ¡ä»¶ ãã®ãã¥ãŒããªã¢ã«ã§ã¯ä»¥äžã®ãã®ãå¿
èŠã§ãã AWS ã¢ã«ãŠã³ã NPM ã§ã€ã³ã¹ããŒã«ããã Node.js VPC ã¹ã¿ãã¯ã§ã® Lambda 颿°ã®äœæ Next.js ã¢ããªã±ãŒã·ã§ã³ãã¢ã¯ã»ã¹ã§ããä¿è·ããã Amazon VPC ãªãœãŒã¹ã説æããããã«ãLambda 颿°ãåäœãã Amazon VPC ãäœæããŸãã ãŸããAWS CDK ãã€ã³ã¹ããŒã«ããŸããåææ¡ä»¶ã®è©³çŽ°ã¯ AWS CDK ã®éå§æ¹æ³ ãåç
§ããŠãã ããã $ npm install -g aws-cdk 次ã«ãã¢ããªçšã®æ°ãããã£ã¬ã¯ããªãäœæããŸãã $ mkdir lambda-in-a-vpc $cd lambda-in-a-vpc 次ã«ã以äžã®ã³ãã³ããå®è¡ã㊠AWS CDK ã¢ããªã±ãŒã·ã§ã³ãäœæããŸãã $ cdk init app âlanguage=typescript çæãããã lib/lambda-in-a-vpc-stack.ts ã®å
容ã以äžã®ã³ãŒãã«çœ®ãæããŸãã AWS CDK Stack ã¯ããããªãã¯ããã©ã€ããŒããéé¢ããããµãããããæã€ Amazon VPCãã»ãã¥ãªãã£ã°ã«ãŒããAmazon VPC ã®éé¢ããããµããããã«é
眮ããã Lambda 颿° (Node.js) ãäœæããŸãã Lambda 颿°ãã»ãã¥ãªãã£ã°ã«ãŒãä»ãã®ãã©ã€ããŒããµããããã«é
眮ããããšã§ãAmazon VPC å
ã§é¢æ°ãåé¢ããŸãã ããã«ããããããªãã¯ã€ã³ã¿ãŒãããããåé¢ããã Lambda 颿°ã®ã»ãã¥ã¢ãªãããã¯ãŒã¯ç°å¢ãæäŸãããŸããããã©ã€ããŒããµããããå
ã®ããŒã¿ããŒã¹ã®ãã㪠Amazon VPC å
ã®ãªãœãŒã¹ã«ã¢ã¯ã»ã¹ããããšãã§ããŸãã // lib/lambda-in-a-vpc-stack.ts import { CfnOutput, Duration, Stack, StackProps, aws_ec2 as ec2, aws_lambda as lambda, } from "aws-cdk-lib"; import { NodejsFunction } from "aws-cdk-lib/aws-lambda-nodejs"; import { Construct } from "constructs"; import path = require("path"); export class LambdaInAVpcStack extends Stack { constructor(scope: Construct, id: string, props?: StackProps) { super(scope, id, props); const vpc = new ec2.Vpc(this, "LambdaVpc", { subnetConfiguration: [ { name: "Isolated", subnetType: ec2.SubnetType.PRIVATE_ISOLATED, }, { name: "Private", subnetType: ec2.SubnetType.PRIVATE_WITH_EGRESS, }, { name: "Public", subnetType: ec2.SubnetType.PUBLIC, }, ], }); // Create a security group to be used on the lambda functions const lambdaSecurityGroup = new ec2.SecurityGroup( this, "Lambda Security Group", { vpc, } ); const getDataLambda: NodejsFunction = new NodejsFunction( this, id + "-getDataLambda", { memorySize: 1024, timeout: Duration.seconds(5), runtime: lambda.Runtime.NODEJS_18_X, handler: "handler", entry: path.join(__dirname, "../lambda/getData.ts"), vpc: vpc, vpcSubnets: { subnetType: ec2.SubnetType.PRIVATE_ISOLATED }, securityGroups: [lambdaSecurityGroup], } ); new CfnOutput(this, "getDataLambdaArn", { value: getDataLambda.functionArn, exportName: "getDataLambdaArn", }); } } Lambda 颿° (Node.js) ã®å
éšã§ã¯ãAmazon RDS ã€ã³ã¹ã¿ã³ã¹ãã㪠Amazon VPC å
ã®ãªãœãŒã¹ããAmazon S3 ãã±ããããã®ä»ã®ä¿è·ããããªãœãŒã¹ããŸãã¯å€éšã®ãµãŒãããŒã㣠API ãªã©ä»»æã®ãªãœãŒã¹ããããŒã¿ãååŸããããšãã§ããŸãã æ¬¡ã«ã lambda ãã£ã¬ã¯ããªãäœæãããã®äžã« getData.ts ãäœæããŸãã 説æã®ããã«ããŒã¿ã¯ããŒãã³ãŒããããŠããŸããããã® Lambda 颿°ã¯ Amazon RDS ããã®ä»ã®ããŒã¿ãœãŒã¹ããå°çããŒã¿ãååŸãããããè¿ãåã«æ€èšŒã倿ãè¡ãããšãã§ããŸãã // lambda/getData.ts import { APIGatewayProxyResultV2 } from "aws-lambda"; const geoData = [ { name: "United States", states: [ "Alabama", "Alaska", "Arizona", //... ], }, { name: "Canada", states: [ "Alberta", "British Columbia", "Manitoba", // ... ], }, { name: "Mexico", states: [ "Jalisco", "Mexico City", "Oaxaca", // ... ], }, ]; exports.handler = async function (): Promise<APIGatewayProxyResultV2> { try { return { statusCode: 200, headers: { "Content-Type": "application/json" }, body: JSON.stringify(geoData, null, 2), }; } catch (error) { console.error("Unable to return data:", error); return { statusCode: 500, headers: { "Content-Type": "application/json" }, body: JSON.stringify(error), }; } }; cdk deploy ãå®è¡ã㊠AWS CDK ã¹ã¿ãã¯ããããã€ããæ¬¡ã®ã»ã¯ã·ã§ã³ã§ Next.js ã¢ããªã±ãŒã·ã§ã³ã§äœ¿çšããããã«è¿ãããã¢ãŠãããããã¡ã¢ããŸãã $ cdk deploy [+] Building 92.4s (14/14) FINISHED 8.4s WARNING: The requested image's platform (linux/amd64) does not match the detected host platform (linux/arm64/v8) and no specific platform was requested asset-output/index.js 831b â¡ Done in 102ms âš Synthesis time: 97.21s LambdaInAVpcStack: deploying... [1/1] LambdaInAVpcStack: creating CloudFormation changeset... â
LambdaInAVpcStack âš Deployment time: 33.99s Outputs: LambdaInAVpcStack.getDataLambdaArn = arn:aws:lambda:us-east-1:074128318641:function:LambdaInAVpcStack-LambdaInAVpcStackgetDataLambda1E-33sG563OFj2H Stack ARN: arn:aws:cloudformation:us-east-1:074128318641:stack/LambdaInAVpcStack/1fbc2790-2a57-11ee-9757-0ecf5ea19ac5 âš Total time: 131.2s LambdaInAVpcStack.getDataLambdaArn ã®æ«å°Ÿã«ãã Lambda 颿°å (ãã®å Žå㯠LambdaInAVpcStack-LambdaInAVpcStackgetDataLambda1E-33sG563OFj2H ) ã«æ³šæããŠãã ããã Next.js Amplify ã¢ããªã®äœæ 次ã«ãPages Router ã䜿ã£ãŠ Next.js ã¢ããªã±ãŒã·ã§ã³ãäœæããŸãã $ npx create-next-app@latest geo-web-app â Would you like to use TypeScript? ⊠No / `_Yes_` â Would you like to use ESLint? ⊠`_No_` / Yes â Would you like to use Tailwind CSS? ⊠No / `_Yes_` â Would you like to use `src/` directory? ⊠No / `_Yes_` â Would you like to use App Router? (recommended) ⊠`_No_` / Yes â Would you like to customize the default import alias (@/*)? ⊠`_No_` / Yes` AWS Amplify JavaScriptãAWS Amplify UI ã©ã€ãã©ãªãã€ã³ã¹ããŒã«ããŸãã ãããã®äŸåé¢ä¿ã¯ãªãã·ã§ã³ã§ãããæ¬èšäºã§ã¯ Next.js ã¢ããªã±ãŒã·ã§ã³ã® UI ãæ§ç¯ããããã«äœ¿çšããŸãã $ npm i aws-amplify @aws-amplify/ui-react 以äžã®ã€ã³ããŒãã§ pages/_app.tsx ãæŽæ°ããŠã Amplify UI ã®ã¹ã¿ã€ã«ãèšå®ããŸãã // Import Amplify UI styles import "@aws-amplify/ui-react/styles.css"; import type { AppProps } from "next/app"; export default function App({ Component, pageProps }: AppProps) { return <Component {...pageProps} />; } æŽæ°ã Git ã«ã³ãããããGit ãããã€ãã«ããã·ã¥ããŸãã Next.js ã¢ããªã® Amplify ãžã®ããã〠ã¢ããªã Git ãããã€ãã«ããã·ã¥ããããAmplify Hosting ã«ãããã€ããæºåãã§ããŸããã ãŸã Amplify ã³ã³ãœãŒã« ã«ã¢ã¯ã»ã¹ããŠãã ãããAmplify ã¢ããªãäœæããããšããªãå Žåã¯ãããŒãžãäžçªäžãŸã§ã¹ã¯ããŒã«ãã Amplify Hosting > Host your web app > Get started ãéžæããŸããã¢ããªãäœæããããšãããå Žåã¯ã New app > Host web app ãéžæããŸãã Git ãªããžããªã®ãã¹ãã£ã³ã°ãããã€ããéžæãã Continue ãéžæããŸãã Git ãããã€ããŒã«ãã£ãŠã¯ãAmplify Hosting ã«ãªããžããªãžã®ã¢ã¯ã»ã¹ãèš±å¯ããããããã³ããã衚瀺ãããŸããèªèšŒã«æåãããã Recently updated repositories ãªã¹ããããã®ã¢ããªã®ãªããžããªãéžæãã Next ãéžæããŸãã Build settings ããŒãžã§ãAmplify ã¯èªåçã«æ£ãããã«ãèšå®ãæ€åºããã®ã§ãèšå®ã倿Žããå¿
èŠã¯ãããŸãããããã©ã«ãã®ãŸãŸ Next ãéžæããŸãã Review ããŒãžã§ã Save and deploy ãéžæããŸãã ã¢ããªãäœæãããAmplify Hosting ã³ã³ãœãŒã«ã®ã¢ããªã®ããŒãžã«ç§»åããŸããAmplify Hosting ã¯ããããžã§ã¯ãçšã«åé¢ããããã«ããšãã¹ãã£ã³ã°ç°å¢ãããããžã§ãã³ã°ãããããã€ããŸãããã®ããã»ã¹ã«ã¯ 2 ~ 3 åããããŸãã以äžã®ããã«ã Provision ã Build ããŸã㯠Deploy ãªã³ã¯ãéžæããããšã§ãé²è¡ç¶æ³ã確èªã§ããŸãã ãã©ã¡ãŒã¿ã¹ãã¢ã§ã·ãŒã¯ã¬ãããæåã§äœæ Next.js ã® API Routes ã§ã¯ãAWS SDK ã Amazon VPC å
ã® Lambda 颿°ãåŒã³åºãããã«ãã·ãŒã¯ã¬ããã«ã¢ã¯ã»ã¹ããå¿
èŠããããŸãã ã·ãŒã¯ã¬ããã¯ãèšå®ããŒã¿ç®¡çãšã·ãŒã¯ã¬ãã管çã®ããã®ã»ãã¥ã¢ã§éå±€çãªã¹ãã¬ãŒãžãæäŸãã Parameter Store ã«æ ŒçŽããŸãã Amplify Hosting ã³ã³ãœãŒã«ã§ã App Settings: General ã«ç§»åãã App ARN ãååŸããŸãã æåŸã®ã¹ã©ãã·ã¥ (/) ã®åŸã®å€ã App ID ã§ãParameter Store ã«ããŒãä¿åãããšãã«äœ¿çšãããŸãã VPC ã¹ã¿ãã¯ã® CDK ã¢ãŠããããããååŸãã VPC_AWS_REGION ã VPC_LAMBDA_FUNCTION_NAME ã®ããã®ã·ãŒã¯ã¬ãããäœæããå¿
èŠããããŸãã Next.js ã® API Routes ãš Amazon VPC ã® AWS Lambda ã®éã®çµ±åãã€ã³ãã¯ãVPC Lambda 颿°ãåŒã³åºãã¢ã¯ã»ã¹æš©ãæã€ IAM ãŠãŒã¶ãŒãŸãã¯ããŒã«ã«ãã£ãŠå®çŸãããŸãã ãã®ãŠãŒã¶ãŒãŸãã¯ããŒã«ã«ã¯ã AWS_ACCESS_KEY_ID ãš AWS_SECRET_ACCESS_KEY ãããã³ VPC Lambda 颿°ãåŒã³åºãæš©éãå¿
èŠã§ãã IAM ãŠãŒã¶ãŒã®äœæ ã IAM ãŠãŒã¶ãŒã®ã¢ã¯ã»ã¹ããŒã®äœæ ãããã³ å
±æè²¬ä»»ã¢ãã« ã䜿çšããã¢ã¯ã»ã¹ã¹ã³ãŒãã®ãã¹ããã©ã¯ãã£ã¹ãåç
§ããŠãã ããã ãããã®ã·ãŒã¯ã¬ããã¯ãAWS ã³ã³ãœãŒã«ã® Parameter Store ã«ç§»åããŠæåã§èšå®ã§ããŸãã Amplify Hostingããã¥ã¡ã³ãã® ç°å¢å€æ° ã®ããŒãžã®æç€ºã«åŸã£ãŠããã©ã¡ãŒã¿åã¯ä»¥äžã®åœ¢åŒã«åŸã£ãŠãã ããã ä»åã®ã±ãŒã¹ã§ã¯ Amplify ããã¯ãšã³ããæã£ãŠããªãã®ã§ããã©ã³ãå㯠main ã«ããŸãã /amplify/{your_app_id}/{your_backend_environment_name}/{your_parameter_name} å®äºãããšãParameter Store ã§ä»¥äžã®ããã«è¡šç€ºãããŸãã ãã©ã¡ãŒã¿ã¹ãã¢ã§ã®ã·ãŒã¯ã¬ããäœæã®èªåå ãªãã·ã§ã³ãšããŠã以äžã® .env.local ãã³ãã¬ãŒããš Bash ã¹ã¯ãªãã sync-ssm-params.sh ãå©çšããŠããããžã§ã¯ãå
ã® .env.local ãã¡ã€ã«ãã Parameter Store ã«çŽæ¥ã·ãŒã¯ã¬ãããä¿åããããšãã§ããŸãã ãã®ã¹ã¯ãªããã¯ãããŒã«ã«éçºç°å¢ã« AWS CLI ãš jq ã Amplify ã¢ã㪠ID ãšäžç·ã«ã€ã³ã¹ããŒã«ãããŠããå¿
èŠããããŸãã .env.local ã« VPC_AWS_REGION ãš VPC_AWS_REGION ã VPC_LAMBDA_FUNCTION_NAME ãèšå®ãã AWS_PROFILE ã« AWS CLI ã§èšå®ãã䜿çšããããããã¡ã€ã«ãèšå®ããŸãã AWS_ACCESS_KEY_ID ãš AWS_SECRET_ACCESS_KEY ã¯ã AWS CLI ã䜿çšããŠã¹ã¯ãªãããååŸããŸãã # .env.local AWS_APP_ID=<Copy from Amplify Hosting Console> AWS_PROFILE=default VPC_AWS_REGION= VPC_LAMBDA_FUNCTION_NAME= #!/bin/bash # sync-ssm-params.sh # Allow list of parameters allowlist=( AWS_ACCESS_KEY_ID AWS_SECRET_ACCESS_KEY VPC_AWS_REGION VPC_LAMBDA_FUNCTION_NAME ) # Get the name of the current branch APP_BRANCH=$(git rev-parse --abbrev-ref HEAD) # Load .env into environment export $(cat .env.local | grep -v '^#' | xargs) # Get AWS access keys from AWS CLI profile AWS_ACCESS_KEY_ID=$(aws configure get aws_access_key_id --profile $AWS_PROFILE) AWS_SECRET_ACCESS_KEY=$(aws configure get aws_secret_access_key --profile $AWS_PROFILE) for key in "${allowlist[@]}"; do aws ssm put-parameter --name "/amplify/$AWS_APP_ID/$APP_BRANCH/$key" --value "${!key}" --type SecureString --overwrite done ã«ã¹ã¿ã ããªã·ãŒã§ Amplify Hosting ã®ãµãŒãã¹ããŒã«ã®æŽæ° Parameter Store ã«ä¿åãããã·ãŒã¯ã¬ããã«ã¢ã¯ã»ã¹ããåã«ãã¢ããªã±ãŒã·ã§ã³ã®ãããã€æã« Amplify Hosting ãäœæãã Service Role ãæŽæ°ããŠããã®ã¢ããªã±ãŒã·ã§ã³ã® Parameter Store ããã®èªã¿åãæš©éãæãããå¿
èŠããããŸãã Amplify Hosting ã³ã³ãœãŒã«ã«ç§»åããã¢ããªã±ãŒã·ã§ã³ã«ç§»åããŠã App Settings: General ã«ç§»åãã Service Role ã«æ³šç®ããŠãã ããã AWS ã³ã³ãœãŒã« ã® IAM ã«ç§»åããService Role ãæ€çŽ¢ããŸãã Add permissions > Attach policy ãéžæããŠãã€ã³ã©ã€ã³ããªã·ãŒ AllowAmplifySSMCalls ãããŒã«ã«è¿œå ããŸãã 以äžã®ããªã·ãŒã Amplify ã¢ã㪠ID ã§æŽæ°ããJSON ãšãã£ã¿ã«è²Œãä»ããŸãã { "Version": "2012-10-17", "Statement": [ { "Sid": "AllowAmplifySSMCalls", "Effect": "Allow", "Action": [ "ssm:GetParametersByPath", "ssm:GetParameters", "ssm:GetParameter" ], "Resource": [ "arn:aws:ssm:*:*:parameter/amplify/<AMPLIFY_APP_ID>/*" ] } ] } ããªã·ãŒãä¿åããããšã Permissions policies ã®äžã«ä»ã®ããªã·ãŒãšäžç·ã«è¡šç€ºãããŸãã ãã©ã¡ãŒã¿ã¹ãã¢ããã·ãŒã¯ã¬ãããããŒãããããã® Amplify ãã«ãã®ã«ã¹ã¿ãã€ãº æåŸã«ãAmplify CI ã®ãã«ãèšå®ãã¡ã€ã« amplify.yml ãæŽæ°ããŠãParameter Store ãã Next.js ããã«ãåŠçäžã«åç
§ããç°å¢ãã¡ã€ã« ( .env ) ã«ã·ãŒã¯ã¬ãããããŒãããå¿
èŠããããŸãã ãããžã§ã¯ãã« amplify.yml ãã¡ã€ã«ã远å ããŠã jq ãŠãŒãã£ãªã㣠( $secrets ã®å€ãè§£æããã®ã«å¿
èŠ) ãã€ã³ã¹ããŒã«ãããã«ãäžã« Parameter Store ããã·ãŒã¯ã¬ããã .env ã«ããŒãããããã®ä»¥äžã®ã³ãã³ãã远å ããŸãã jq ã®äœ¿çšã¯ãªãã·ã§ã³ã§ããã ç°å¢å€æ°ããµãŒããŒåŽã®ã©ã³ã¿ã€ã ããã¢ã¯ã»ã¹ã§ããããã«ããããã®ã¬ã€ãã³ã¹ ã«åŸã£ãŠ grep ãä»ã®ãŠãŒãã£ãªãã£ã䜿çšããŠãæ§ããŸããã echo $secrets | jq -r 'to_entries|map("\(.key)=\(.value)")|.[]' >> .env 以äžã¯ãå®å
šãª amplify.yml ãã¡ã€ã«ã§ãã version: 1 frontend: phases: preBuild: commands: - yum -y install jq - jq --version - npm ci build: commands: - echo $secrets | jq -r 'to_entries|map("\(.key)=\(.value)")|.[]' >> .env - npm run build artifacts: baseDirectory: .next files: - "**/*" cache: paths: - node_modules/**/* ãã¡ã€ã«ã Git ã«ã³ãããããGit ãããã€ããŒã«ããã·ã¥ããŠãããã€ãéå§ããŸãã Amazon VPC Lambda 颿°ã®ããŒã¿ã§ Next.js ã¢ããªãæŽæ° ã·ãŒã¯ã¬ããã Parameter Store ã«æ ŒçŽããããNext.js ã¢ããªãã Amazon VPC å
ã®ããŒã¿ã«ã¢ã¯ã»ã¹ã§ããããã«ãªããŸãã AWS SDK ã«äŸåããã®ã§ã次ã®ã³ãã³ãã§ã€ã³ã¹ããŒã«ããŸãã $ npm install aws-sdk page/api ã®äžã« Next.js API Routes getGeoData.ts ãäœæããAWS SDK ãåæåã㊠Amazon VPC Lambda 颿°ãåŒã³åºã次ã®ã³ãŒããèšè¿°ããŸãã // pages/api/getGeoData.ts import { Lambda } from "aws-sdk"; import { NextApiRequest, NextApiResponse } from "next"; const lambda = new Lambda({ region: process.env.VPC_AWS_REGION, accessKeyId: process.env.AWS_ACCESS_KEY_ID, secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY, }); export default async (req: NextApiRequest, res: NextApiResponse) => { lambda.invoke( { FunctionName: process.env.VPC_LAMBDA_FUNCTION_NAME!, Payload: JSON.stringify({}), }, (err, data) => { if (err) { console.log(err); res.status(500).json({ error: err }); } else { res.status(200).json({ data }); } } ); }; 次ã«ãããŒã¿ã«ã¢ã¯ã»ã¹ããããã³ããšã³ãã®ã³ãŒããèšè¿°ããŸãã pages/index.ts ãã pages/api/getGeoData ãžã® API ã³ãŒã«ãè¡ãã AWS Amplify UI ã䜿çšããŠçµæã衚ã«è¡šç€ºãã以äžã®ã³ãŒãã«çœ®ãæããŸãã // pages/index.tsx import { Heading, Table, TableBody, TableCell, TableHead, TableRow, View, } from "@aws-amplify/ui-react"; import { useEffect, useState } from "react"; type Country = { name: string; states: string[]; }; export default function Home() { const [geoData, setGeoData] = useState<Country[]>([]); useEffect(() => { fetch("/api/getGeoData") .then((res) => res.json()) .then((data) => { const payload = JSON.parse(data.data.Payload); const body = JSON.parse(payload.body); setGeoData(body); }); }, []); return ( <View padding="1rem"> <Heading level={2} marginBottom={25}> Countries and States </Heading> <br /> {geoData.length === 0 && <div>Loading...</div>} {geoData.length > 0 && ( <Table width={500}> <TableHead> <TableRow> <TableCell as="th">Country</TableCell> <TableCell as="th">States</TableCell> </TableRow> </TableHead> <TableBody> {geoData.map((country) => ( <TableRow key={country.name}> <TableCell>{country.name}</TableCell> <TableCell> {country.states.map((state) => ( <div key={state}>{state}</div> ))} </TableCell> </TableRow> ))} </TableBody> </Table> )} </View> ); } ãã¡ã€ã«ã Git ã«ã³ãããããGit ãããã€ããŒã«ããã·ã¥ããŠæçµçãªãããã€ãéå§ããŸãã ãããã€åŸããããžã§ã¯ãã® URL ã«ç§»åãããšãAmazon VPC ã® Lambda 颿°ããããŒã¿ãããŒããããŸãã ã¯ãªãŒã³ã¢ãã AWS CDK ã¹ã¿ãã¯ã®ãªãœãŒã¹ãåé€ããã«ã¯ã lambda-in-a-vpc CDK ãããžã§ã¯ãã®ã«ãŒããã cdk destroy ãå®è¡ããŸãã Next.js Amplify ã¢ããªãåé€ããã«ã¯ãAmplify Hosting ã§ã¢ããªã«ç§»åãã Actions > Delete app ãéžæããŸãã ãŸãšã æ¬èšäºã§ã¯ãAWS CDK ã䜿çšã㊠Amazon VPC å
ã§é¢æ°ãåé¢ããããã«ãã»ãã¥ãªãã£ã°ã«ãŒãä»ãã®ãã©ã€ããŒããµããããã« Lambda 颿°ãæ§ç¯ããŠãããã€ããŸããã æ¬¡ã« Next.js ã¢ããªãäœæããNext.js ã® API Routes ãéã㊠Amazon VPC å
ã®ããŒã¿ã«ã¢ã¯ã»ã¹ããAWS Amplify Hosting ã«ãã¹ããããããã€ããã React UI ã«ã¢ã¯ã»ã¹ããŸããã ãã©ã¡ãŒã¿ã¹ãã¢ã䜿çšã㊠APIããŒããã®ä»ã®èšå®ããŒã¿ãå®å
šã«ä¿åããã¢ã¯ã»ã¹ããããã®ãã¹ããã©ã¯ãã£ã¹ã玹ä»ããŸããã ã«ã¹ã¿ã ãã¡ã€ã³ ã®èšå®ãã ãã«ãªã¯ãšã¹ãçšã® Web ãã¬ãã¥ãŒ ã æ©èœãã©ã³ã (feature branch) ãªã©ãAmplify Hosting ã®æ©èœã«ã€ããŠã®è©³çްã¯ã AWS Amplify Hosting ããã¥ã¡ã³ã ãã芧ãã ããã æ¬èšäºã¯ã Accessing resources in a Amazon Virtual Private Cloud (Amazon VPC) from Next.js API Routes ãã翻蚳ãããã®ã§ãã 翻蚳è
ã«ã€ããŠ çš²ç° å€§éž AWS Japan ã§åãçãã¬ãè¶£å³ã®ãœãªã¥ãŒã·ã§ã³ã¢ãŒããã¯ããæ®æ®µã¯è£œé æ¥ã®ã客æ§ãäžå¿ã«æè¡æ¯æŽãè¡ã£ãŠããŸãã奜ã㪠AWS ãµãŒãã¹ã¯ Amazon Location Service ãš AWS Amplify ã§ãæ¥æ¬ã®ã客æ§åãã« Amazon Location Service ã®è§£èª¬ããã° ãªã©ãå·çããŠããŸãã