Deploy a Web App on AWS Elastic Beanstalk

GETTING STARTED GUIDE

Module 2: Create Infrastructure using AWS CDK

In this module, you will create a CDK application that will create all the necesary infrastructure to deploy the NodeJS web app using Elastic Beanstalk.

Introduction

In this module you will create a CDK application that will create all the necessary infrastructure to deploy the NodeJS web app using AWS Elastic Beanstalk.

What You Will Learn

  • Create a simple CDK application
  • Upload a package to S3 using S3 Assets
  • Create a Elastic Beanstalk CDK app, app version, and environment

 Time to Complete

15 minutes

 Module Prereqs

  • AWS Account with administrator-level access**
  • Recommended browser: The latest version of Chrome or Firefox

[**]Accounts created within the past 24 hours might not yet have access to the services required for this tutorial.

Implementation

Create the CDK app

Make sure that you have the latest CDK version.

npm install -g cdk

Create a new directory and get into it.

mkdir cdk-eb-infra
cd cdk-eb-infra

Initialize the CDK application that you will use to do the infrastructure.

cdk init app --language typescript

Create the code for the resource stack

Go to the file /lib/cdk-eb-infra-stack.ts, there you will write the code for the resource stack you are going to create. 

A resource stack is a set of cloud infrastructure resources - in your particular case they will be all AWS resources - that will be provisioned into a specific account. The account where these resources are getting provisioned is the stack that you configured in the prerequisite steps. In this resource stack you are going to create these resources:

  • S3 Assets: this will be helping you to upload your zipped application into S3 and it will provide the CDK application a way to get the object location.
  • Elastic Beanstalk App: this is a logical collection of Elastic Beanstalk components, including environments, versions, and environment configurations.
  • Elastic Beanstalk App Version: It refers to a specific, labeled iteration of deployable code for a web application. An application version points to an Amazon Simple Storage Service (Amazon S3) object that contains the deployable code, in your case the zip file that you will be uploading to S3 using the S3 Assets. Applications can have many versions and each application version is unique.
  • Instance profile and role: It is a container for an AWS Identity and Access Management (IAM) role that you can use to pass role information to an Amazon EC2 instance when the instance starts.
  • Elastic Beanstalk Environment: It is a collection of AWS resources running an application version. Each environment runs only one application version at a time.

Upload the app to S3 automatically

For deploying your web app, you need to package it and upload it to Amazon Simple Storage Service (S3) in order for Elastic Beanstalk to deploy that application in the environment.

We will do the packaging of the application in Module 3 of this guide, but for now we will focus on uploading it to S3. For doing that you will be using a CDK constructor called S3Assets. This module will upload local files and directory to S3.

For doing that in our CDK application you need first to install the aws-s3-assets module.

npm i @aws-cdk/aws-s3-assets

And then in your lib/cdk-eb-infra-stack.ts file add the dependency to the top of the file.

import s3assets = require('@aws-cdk/aws-s3-assets');

Inside the stack, under the commented line that says "The code that defines your stack goes here" add the following code.

 // Construct an S3 asset from the ZIP located from directory up.
const webAppZipArchive = new s3assets.Asset(this, 'WebAppZip', {
      path: `${__dirname}/../app.zip`,
});

This code uses the s3 Assets module and takes the zip file of the web app located in the root of the CDK app, and uploads it to S3. When ever you update the zip file and you deploy this stack, the file will get updated in S3.

Add the Elastic Beanstalk CDK dependencies

Lets create the Elastic Beanstalk Application, Application Version and Environment, so you can deploy the web app that you just uploaded to S3 using the S3 Assets.

First you need to install the Elastic Beanstalk module for CDK.

npm i @aws-cdk/aws-elasticbeanstalk

Then add the dependency to the top of the /lib/cdk-eb-infra-stack.ts file.

import elasticbeanstalk = require('@aws-cdk/aws-elasticbeanstalk');

Create the Elastic Beanstalk application

Now you can create the Elastic Beanstalk app. As mentioned before, an Elastic Beanstalk application is a logical collection of Elastic Beanstalk components, like a folder.

Put this code under the code of the S3Assets. This code will create the application with the name MyWebApp in Elastic Beanstalk.

// Create a ElasticBeanStalk app.
const appName = 'MyWebApp';
const app = new elasticbeanstalk.CfnApplication(this, 'Application', {
    applicationName: appName,
});

Create Elastic Beanstalk application version

Now you need to create a application version from the S3 asset that you created earlier. This piece of code will create the app version using the S3 bucket name and S3 object key that S3 Assets and CDK will provide to this method.

// Create an app version from the S3 asset defined earlier
const appVersionProps = new elasticbeanstalk.CfnApplicationVersion(this, 'AppVersion', {
    applicationName: appName,
    sourceBundle: {
        s3Bucket: webAppZipArchive.s3BucketName,
        s3Key: webAppZipArchive.s3ObjectKey,
    },
});

Before moving on you want to make sure that the Elastic Beanstalk application exists before creating the app version, this is something really easy to do with CDK.

// Make sure that Elastic Beanstalk app exists before creating an app version
appVersionProps.addDependsOn(app);

Create the instance profile

For creating your Elastic Beanstalk environment, you will need to provide an exisiting instance profile name.

An instance profile is a container for an AWS Identity and Access Management (IAM) role that you can use to pass role information to an Amazon EC2 instance when the instance starts.

In your case the role will have attached the managed policy - AWSElasticBeanstalkWebTier. This policy grants permissions to the application to upload logs to Amazon S3 and debugging information to AWS X-Ray.

The first thing you need to do is install the IAM module in your CDK app.

npm i @aws-cdk/aws-iam

Then import the dependency in the CDK stack we have been working on:

import iam = require('@aws-cdk/aws-iam');

After the code to create the application version, you can add this code:

// Create role and instance profile
const myRole = new iam.Role(this, `${appName}-aws-elasticbeanstalk-ec2-role`, {
    assumedBy: new iam.ServicePrincipal('ec2.amazonaws.com'),
});

const managedPolicy = iam.ManagedPolicy.fromAwsManagedPolicyName('AWSElasticBeanstalkWebTier')
myRole.addManagedPolicy(managedPolicy);

const myProfileName = `${appName}-InstanceProfile`

const instanceProfile = new iam.CfnInstanceProfile(this, myProfileName, {
    instanceProfileName: myProfileName,
    roles: [
        myRole.roleName
    ]
});

The first thing the code does is to create a new IAM role (myRole).

To allow the EC2 instances in your environment to assume the role, the instance profile specifies Amazon EC2 as a trusted entity in the trust relationship policy.

To that role then we add the managed policy AWSElasticBeanstalkWebTier and then with that role and the profile name we create the instance profile.

Create Elastic Beanstalk environment

The last part you need to create is the Elastic Beanstalk Enviroment. The enviroment is a collection of AWS resources running an application version. For the environment we will need to give some infrastructure information.

Let start by creating the environment. When creating the environment you need to give it a name that will appear in the Elastic Beanstalk console - in this case we are naming the environment MyWebAppEnvironment.

Then you need to give the application name, that you will get from the Elastic Beanstalk application definition earlier.

The solution stack name is the name of the managed platform that Elastic Beanstalk provides for running web applications. Using the right solution name Elastic Beanstalk will provision the right resources for your application, for example the Amazon Elastic Compute Cloud (Amazon EC2) instances. You should choose the right software stack depending on the framework and platform you choose to develop your web app. For this particular case you are going to put this string '64bit Amazon Linux 2 v5.4.4 running Node.js 14'. At the end of this module there is more information about solution stack names if you are interested where this string came from.

The option settings attribute allow you to configure the Elastic Beanstalk environment to your needs:

  • IamInstanceProfile: Here you will reference to the instance profile created in the previous steps.
  • MinSize, MaxSize and InstanceTypes: These are configurations for your instances and the autoscaling group that Elastic Beanstalk generates for you. These are optional parameters, if you don't set them up Elastic Beanstalk will pick the instance type and the min and max sizes of the autoscaling group according to the platform definition. You are defining them so you can stay within the AWS free tier.

More information about Configuration options for Elastic Beanstalk

For defining all these configuration options, add the following lines of code:

// Example of some options which can be configured
const optionSettingProperties: elasticbeanstalk.CfnEnvironment.OptionSettingProperty[] = [
    {
        namespace: 'aws:autoscaling:launchconfiguration',
        optionName: 'IamInstanceProfile',
        value: myProfileName,
    },
    {
        namespace: 'aws:autoscaling:asg',
        optionName: 'MinSize',
        value: '1',
    },
    {
        namespace: 'aws:autoscaling:asg',
        optionName: 'MaxSize',
        value: '1',
    },
    {
        namespace: 'aws:ec2:instances',
        optionName: 'InstanceTypes',
        value: 't2.micro',
    },
];

Finally we have the version label. This is an important attribute as it need to be a reference to the application version that we just created.

With all these information now you can create your Elastic Beanstalk enviroment.

Paste this code in your stack definition file.

// Create an Elastic Beanstalk environment to run the application
const elbEnv = new elasticbeanstalk.CfnEnvironment(this, 'Environment', {
    environmentName: 'MyWebAppEnvironment',
    applicationName: app.applicationName || appName,
    solutionStackName: '64bit Amazon Linux 2 v5.4.4 running Node.js 14',
    optionSettings: optionSettingProperties,
    versionLabel: appVersionProps.ref,
});

Common Mistakes

Using multiple versions of the CDK libraries

One common error you might get when using CDK is that when you import a library and start using it in your application, the word "this" gets highlighted and you can see a compilation issue.

gsg_build_elb_1

This might happen because you are using CDK module with a different version than the CDK core library. CDK updates very often so it's a quite common error.

For fixing this you need to update all the cdk packages to the same version. You can see the version of your CDK packages in the package.json file in your CDK application.

gsg_build_elb_2

More information

More info about Elastic Beanstalk solution stack name

In the documentation you can read about all the supported platforms for Elastic Beanstalk. This page keeps updating as newer platforms are added and older platforms get retired.

If you are curious on how to get the right platform name - eg. 64bit Amazon Linux 2 v5.4.4 running Node.js 14. You can use the AWS CLI and get a list of all the supported plaftorms.

aws elasticbeanstalk list-available-solution-stacks

This returns a long list of supported platforms strings that you can use in your CDK application.

Conclusion

In this Module you learned how to create all the necesary resources of Elastic Beanstalk to deploy your application automatically. In the next module you are going to learn how to deploy this to the cloud and how you can update your app when there are changes.

Up Next: Deploy Application

Let us know how we did.

Thank you for your feedback
We're glad this page helped you. Would you like to share additional details to help us continue to improve?
Close
Thank you for your feedback
We're sorry this page didn't help you. Would you like to share additional details to help us continue to improve?
Close