Deploying a simple Node JS application to AWS ElasticBeanstalk using AWS CloudFormation
This article will show you how to deploy a simple Node JS application to ElasticBeanstalk using CloudFormation. Most of the process is done using the template and CLI. You will need to have AWS command line installed and IAM credentials configured for your laptop.
First, you will need to login to the AWS console and create an S3 bucket to store your template.
Then, you will need to create an SSH key pair for the EC2 instance. For that, you will need to go to the EC2 service, and then go to the Key Pairs section under the NETWORK & SECURITY section on the left main menu. Then create a Key Pair choosing “pem” option. You will need to use the key name later.
Then you need to create a file called template.yml file with the following content.
---
AWSTemplateFormatVersion: '2010-09-09'
Description: 'AWS CloudFormation Sample Template ElasticBeanstalk_Nodejs_Sample: Configure
and launch the AWS Elastic Beanstalk sample application. **WARNING** This template
creates one or more Amazon EC2 instances. You will be billed for the AWS resources
used if you create a stack from this template.'
Parameters:
KeyName:
Description: Name of an existing EC2 KeyPair to enable SSH access to the AWS Elastic
Beanstalk instance
Type: AWS::EC2::KeyPair::KeyName
ConstraintDescription: must be the name of an existing EC2 KeyPair.
Mappings:
Region2Principal:
us-east-1:
EC2Principal: ec2.amazonaws.com
OpsWorksPrincipal: opsworks.amazonaws.com
us-west-2:
EC2Principal: ec2.amazonaws.com
OpsWorksPrincipal: opsworks.amazonaws.com
us-west-1:
EC2Principal: ec2.amazonaws.com
OpsWorksPrincipal: opsworks.amazonaws.com
eu-west-1:
EC2Principal: ec2.amazonaws.com
OpsWorksPrincipal: opsworks.amazonaws.com
eu-west-2:
EC2Principal: ec2.amazonaws.com
OpsWorksPrincipal: opsworks.amazonaws.com
eu-west-3:
EC2Principal: ec2.amazonaws.com
OpsWorksPrincipal: opsworks.amazonaws.com
ap-southeast-1:
EC2Principal: ec2.amazonaws.com
OpsWorksPrincipal: opsworks.amazonaws.com
ap-northeast-1:
EC2Principal: ec2.amazonaws.com
OpsWorksPrincipal: opsworks.amazonaws.com
ap-northeast-2:
EC2Principal: ec2.amazonaws.com
OpsWorksPrincipal: opsworks.amazonaws.com
ap-northeast-3:
EC2Principal: ec2.amazonaws.com
OpsWorksPrincipal: opsworks.amazonaws.com
ap-southeast-2:
EC2Principal: ec2.amazonaws.com
OpsWorksPrincipal: opsworks.amazonaws.com
ap-south-1:
EC2Principal: ec2.amazonaws.com
OpsWorksPrincipal: opsworks.amazonaws.com
us-east-2:
EC2Principal: ec2.amazonaws.com
OpsWorksPrincipal: opsworks.amazonaws.com
ca-central-1:
EC2Principal: ec2.amazonaws.com
OpsWorksPrincipal: opsworks.amazonaws.com
sa-east-1:
EC2Principal: ec2.amazonaws.com
OpsWorksPrincipal: opsworks.amazonaws.com
cn-north-1:
EC2Principal: ec2.amazonaws.com.cn
OpsWorksPrincipal: opsworks.amazonaws.com.cn
cn-northwest-1:
EC2Principal: ec2.amazonaws.com.cn
OpsWorksPrincipal: opsworks.amazonaws.com.cn
eu-central-1:
EC2Principal: ec2.amazonaws.com
OpsWorksPrincipal: opsworks.amazonaws.com
eu-north-1:
EC2Principal: ec2.amazonaws.com
OpsWorksPrincipal: opsworks.amazonaws.com
Resources:
WebServerRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Statement:
- Effect: Allow
Principal:
Service:
- Fn::FindInMap:
- Region2Principal
- Ref: AWS::Region
- EC2Principal
Action:
- sts:AssumeRole
Path: "/"
WebServerRolePolicy:
Type: AWS::IAM::Policy
Properties:
PolicyName: WebServerRole
PolicyDocument:
Statement:
- Effect: Allow
NotAction: iam:*
Resource: "*"
Roles:
- Ref: WebServerRole
WebServerInstanceProfile:
Type: AWS::IAM::InstanceProfile
Properties:
Path: "/"
Roles:
- Ref: WebServerRole
SampleApplication:
Type: AWS::ElasticBeanstalk::Application
Properties:
Description: AWS Elastic Beanstalk Sample Node.js Application
SampleApplicationVersion:
Type: AWS::ElasticBeanstalk::ApplicationVersion
Properties:
Description: Version 1.0
ApplicationName:
Ref: SampleApplication
SourceBundle:
S3Bucket:
Fn::Join:
- "-"
- - elasticbeanstalk-samples
- Ref: AWS::Region
S3Key: nodejs-sample.zip
SampleConfigurationTemplate:
Type: AWS::ElasticBeanstalk::ConfigurationTemplate
Properties:
ApplicationName:
Ref: SampleApplication
Description: SSH access to Node.JS Application
SolutionStackName: 64bit Amazon Linux 2 v5.1.0 running Node.js 12
OptionSettings:
- Namespace: aws:autoscaling:launchconfiguration
OptionName: EC2KeyName
Value:
Ref: KeyName
- Namespace: aws:autoscaling:launchconfiguration
OptionName: IamInstanceProfile
Value:
Ref: WebServerInstanceProfile
SampleEnvironment:
Type: AWS::ElasticBeanstalk::Environment
Properties:
Description: AWS Elastic Beanstalk Environment running Sample Node.js Application
ApplicationName:
Ref: SampleApplication
TemplateName:
Ref: SampleConfigurationTemplate
VersionLabel:
Ref: SampleApplicationVersion
Outputs:
URL:
Description: URL of the AWS Elastic Beanstalk Environment
Value:
Fn::Join:
- ''
- - http://
- Fn::GetAtt:
- SampleEnvironment
- EndpointURL
Then you will need to run the following command replacing the <BucketName> with your Bucket’s name with the same folder as the template.yml.
aws cloudformation package --template-file --s3-bucket <BucketName> template.yml --output-template-file template-generated.yml
Then you need to run the following command replacing the <KeyName> with the name of the SSH Key Pair you created in the beginning. For the <StackName>, you can put the name you want for your stack.
aws cloudformation deploy --template-file template-generated.yml --stack-name <StackName> --parameter-overrides KeyName=<KeyName> --capabilities CAPABILITY_IAM
That’s it. When the command was run successfully, you will see the CloudFormation template was created successfully in the console. You will also see an ElasticBeanstalk environment created for you.