In this blog post, I'll guide you through deploying a Next.js 14 app to AWS Amplify using CDK.
Please note that as of writing this post, AWS Amplify does not officially support Next.js 14.
While I personally believe that Vercel is a better solution for now, I encountered challenges deploying my app to Amplify. This post aims to help others who might face similar issues.
Before we begin, ensure you have a GitHub access token obtained from the GitHub Settings Page. Store the token securely
in AWS Secrets Manager.
Let's start by creating an IAM role and a managed policy for use in the App construct of aws_amplify_alpha.
const role = new cdk.aws_iam.Role(this, 'AmplifyRole', {
assumedBy: new cdk.aws_iam.ServicePrincipal('amplify.amazonaws.com'),
description: 'CDK Amplify Role',
})
const managedPolicy = cdk.aws_iam.ManagedPolicy.fromAwsManagedPolicyName(
'AdministratorAccess',
);
role.addManagedPolicy(managedPolicy)
Now, let's create an Amplify App. Key details are explained below.
const amplifyApp = new aws_amplify_alpha.App(this, 'MyApp', {
description: 'My App',
sourceCodeProvider: new aws_amplify_alpha.GitHubSourceCodeProvider({
owner: 'ilkerdagli',
repository: 'myApp',
oauthToken: cdk.SecretValue.secretsManager('GithubAccessToken'),
}),
customRules: [
{
source: '/<*>',
target: '/index.html',
status: aws_amplify_alpha.RedirectStatus.NOT_FOUND_REWRITE,
},
],
environmentVariables: {
"AMPLIFY_MONOREPO_APP_ROOT": "frontend",
"AMPLIFY_DIFF_DEPLOY": "false",
"_CUSTOM_IMAGE": "public.ecr.aws/docker/library/node:20.11",
"NEXT_PUBLIC_AWS_AMPLIFY_REGION": "eu-central-1",
},
buildSpec: cdk.aws_codebuild.BuildSpec.fromObjectToYaml({
version: '1.0',
applications: [
{
appRoot: 'frontend',
frontend: {
phases: {
preBuild: {
commands: ['yarn install --frozen-lockfile'],
},
build: {
commands: ['env | grep -e NEXT_PUBLIC_ >> .env.production', 'yarn run build'],
},
},
artifacts: {
baseDirectory: '.next',
files: ['**/*'],
},
cache: {
paths: ['node_modules/**/*', '.next/cache/**/*'],
},
},
}
]
}),
role: role,
})
const devBranch = amplifyApp.addBranch('dev', {
description: 'dev branch',
});
My app was located in the frontend directory of my GitHub repository. Therefore, the environment variable AMPLIFY_MONOREPO_APP_ROOT_ is set to frontend,
which must match the buildSpec's applications appRoot definition.
Since Amplify's default build image doesn't support Next.js 14 due to an older node version, we use a custom image. Set the CUSTOM_IMAGE environment variable accordingly.
Additionally, we add a dev branch to the app for automatic redeployment upon each push.
To complete the setup, we need run the following commands to run the app on Amplify:
aws amplify update-app --app-id APPID --platform WEB_COMPUTE
aws amplify update-branch --app-id APPID --branch-name dev --framework 'Next.js - SSR'
However, for automation, consider using CDK custom resources as demonstrated below:
new cdk.custom_resources.AwsCustomResource(this, 'AmplifyExtraSettings', {
onUpdate: {
service: 'Amplify',
action: 'updateApp',
parameters: {
appId: amplifyApp.appId,
platform: 'WEB_COMPUTE',
},
physicalResourceId: cdk.custom_resources.PhysicalResourceId.of(Date.now().toString()),
},
policy: cdk.custom_resources.AwsCustomResourcePolicy.fromSdkCalls({
resources: [amplifyApp.arn],
}),
});
new cdk.custom_resources.AwsCustomResource(this, 'AmplifyUpdateDevBranch', {
onUpdate: {
service: 'Amplify',
action: 'updateBranch',
parameters: {
appId: amplifyApp.appId,
branchName: 'dev',
framework: 'Next.js - SSR',
},
physicalResourceId: cdk.custom_resources.PhysicalResourceId.of(Date.now().toString()),
},
policy: cdk.custom_resources.AwsCustomResourcePolicy.fromSdkCalls({
resources: [amplifyApp.arn, devBranch.arn],
}),
});
Top comments (0)