AWS CDK For Noobs: Deploying Your First NextJS App

AWS CDK For Noobs: Deploying Your First NextJS App

As a developer, have you ever wanted to deploy your app to AWS instead of PaaS providers like Netlify or Heroku, but do not want to go through the "stress" of setting things up through the console or learning to write infrastructure-as-code?

Then, you are the target audience for AWS Cloud Development Kit (CDK).

This post is part of my commitment to Women Who Code Days of Code challenge

What is AWS CDK?

It is an AWS development framework for provisioning cloud infrastructure using programming languages familiar to software developers.

Simply put, it's a tool for software developers to deploy their apps onto AWS without manually setting up resources through the console, or writing declarative/imperative infrastructure-as-code.

In this post, I'll share all about my initial experience with CDK and how I eventually deployed the most basic NextJS app.

First Attempt

I first tried it last month by starting with the free AWS CDK Primer course on Skills Builder; however, the course mostly covered the theory basics and a broad overview of how it may be used. There was not much insights on how it could be used for practical projects e.g deploying a full-stack app (which is understandable, since it was a free primer course).

Then, I tried using the learning path on Cloud Academy but it quickly became disengaging since the contents were focused on Python (hence a different version of the API docs) and I preferred Typescript. Overall, I found myself quite lost, trying to figure out the "right" thing to do according to the docs, and if there was only one way to do it. Meanwhile, every other tutorial (even the basic ones) seemed to already know their way around navigating the necessary construct libraries.

Maybe it's just me and I'm missing the foundations, but there really needs to be a crash course on how to navigate through API docs for different AWS services👀.

Anyway, I eventually tried this tutorial to get something done (at least) and was able to deploy a basic NextJS app.

How to set up a CDK app for deploying a NextJS app to AWS Amplify

This assumes you have:

  • installed the AWS CDK toolkit

  • installed Typescript (somehow, this was my first time doing this!)

  • configured your AWS credentials

  • generated a GitHub PAT and saved to AWS secrets manager

If necessary, watch the linked tutorial for all preliminary setup.

1) Create an empty folder (e.g cdk-next-app) and set up a CDK app

cdk init app --language typescript

The 'app' template sets up a basic CDK app in language Typescript.

2) Set up your preferred environment in bin/cdk-next-app.ts

This is optional but I personally think it might be best to specify and avoid the 'environment agnostic' situation.

import * as cdk from 'aws-cdk-lib';
import { CdkNextAppStack } from '../lib/cdk-next-app-stack';

const app = new cdk.App();
new CdkNextAppStack(app, 'CdkNextAppStack', {
  env: { account: process.env.CDK_DEFAULT_ACCOUNT, region: process.env.CDK_DEFAULT_REGION },
});

This creates your CDK app and within it, a stack which will have all of the constructs needed to provision infrastructure for the Next app and deploy it to AWS Amplify.

Check out the Primer course for AWS CDK basics.

3) Set up the stack in lib/cdk-next-app-stack.ts

Note: This uses @aws-cdk/aws-amplify-alpha, which is basically the construct library with experimental features for Amplify using CDK. The current stable version does not have L2 constructs (constructs for provisioning AWS resources) yet, so the option was either the experimental library or setting everything up using L1 constructs (which I would have to look into👀).

Comments have been added to briefly explain the codes.

import * as cdk from 'aws-cdk-lib';
import { Construct } from 'constructs';
import {
  App,
  GitHubSourceCodeProvider,
  Platform,
  RedirectStatus
} from "@aws-cdk/aws-amplify-alpha";
import * as codebuild from 'aws-cdk-lib/aws-codebuild';

export class CdkNextAppStack extends cdk.Stack {
  constructor(scope: Construct, id: string, props?: cdk.StackProps) {
    super(scope, id, props);

    //create a new Amplify app
    const amplifyApp = new App(this, 'NextApp', {
      //set a code source provider for the app to be deployed e.g GitHub
      sourceCodeProvider: new GitHubSourceCodeProvider({
        //requires all three properties
        owner: 'khairahscorner',
        repository: 'sample-next-app',
        oauthToken: cdk.SecretValue.secretsManager('github-token-cdk'),
      }),
      autoBranchDeletion: true,
      platform: Platform.WEB_COMPUTE, //required for SSR apps 
      customRules: [{ //used to avoid page errors by redirecting them
        source: '/<*>',
        target: '/index.html',
        status: RedirectStatus.NOT_FOUND_REWRITE
      }],
      buildSpec: codebuild.BuildSpec.fromObjectToYaml({
          // Alternatively add a `amplify.yml` to the repo
          version: '1.0',
          frontend: {
            phases: {
              preBuild: {
                commands: ['npm ci'],
              },
              build: {
                commands: ['npm run build'],
              },
            },
            artifacts: {
              baseDirectory: '.next',
              files: ['**/*'],
            },
            // save time on npm reinstalling??
            cache: {
              paths: ['node_modules/**/*'],
            }
          }
      }),
    })

    // branch to deploy
    let branchName = 'main';
    amplifyApp.addBranch(branchName)

    //outputs the url to both your console and Outputs in the CF stack
    new cdk.CfnOutput(this, 'AmplifyAppUrl', {
      value: `https://${branchName}.${amplifyApp.appId}.amplifyapp.com`,
      description: 'Amplify App URL',
    });
    }
}

4) (Optional) Run cdk bootstrap and cdk synth

cdk bootstrap is used to setup necessary resources required to store and manage the deployment artifacts for your CDK app. Run this if it's your first time using AWS CDK, else it uses the existing setup on your AWS account.

cdk synth generates the AWS CloudFormation template version of your code, just to have a look through.

5) Deploy your app with cdk deploy

That's it!

Pitfalls to Avoid

1) Ensure you have installed and authorised the AWS Amplify GitHub App.

I previously installed and authorised it for only one repository, so I encountered a permissions error and eventually fixed it by authorising the current repository.

2) AWS Amplify seems to run with node v16 (with support up to v18.13).

However, Next14 requires a minimum of node v18.17, hence I was getting this error despite trying different fixes.

In the end, I downgraded to next13 and it worked, but do let me know if you know of a workaround for next14.

Up Next

I'll be trying more sample app deployments with CDK and maybe even explore CDK for Terraform.


Thanks for reading!