Giter Club home page Giter Club logo

aws-deployment-instructions's Introduction

Deploying Your Capstones with Amazon Web Services

Table of Contents

  1. Amazon Web Services
  2. Why Deploy on AWS?
  3. Getting Started
  4. Caveat Architectus - Engineer Beware
  5. AWS Elastic Beanstalk and the AWS Elastic Beanstalk CLI
  6. Deploying Your React Application with AWS Elastic Beanstalk
  7. Deploying Your Django Application with AWS Elastic Beanstalk
  8. Deploying Your React Client Frontend and Django Server Backend with AWS Elastic Beanstalk

Amazon Web Services (AWS)

AWS, a subsidiary of Amazon, is the leading provider of on-demand cloud computing platforms and APIs. According to Canalys, AWS owns around one third of the cloud computing market and has reported revenue of $12.7 billion for Q4 2020. Its competitors include Microsoft Azure and Google Cloud Platform.

Why Deploy on AWS?

Your ability to display your capstones running on AWS servers will signal to employers your ability to work in a modern software development team, many of which are now responsible for the deployment, monitoring, and maintenance of their software stack in the cloud.

Caveat Architectus - Engineer Beware

These instructions are designed to introduce you to working with cloud computing resources. Do not use this guide to try to deploy your capstone professionally. There are other steps you must take to secure your application in production: https and an internal load balancer, for instance. Those steps are not included here because they can unnecessarily complicate a basic introduction to cloud computing, which is more important for you at this stage. Follow the steps below to acclimate yourself to AWS and to motivate yourself to take the steps to secure your application fully.

Getting Started

AWS Account

Working with AWS requires an active AWS account. Fortunately, as of March 2021 Amazon still offers an extended free-tier account that gives free access for one year to all the services you will need to deploy your application. Even still, note that setting up an AWS account requires an active credit or debit card, which will be billed if your usage exceeds the free tier limit. These instructions will teach you how to set up daily billing alerts as an additional tool to prevent excessive unwanted charges. Moreover, AWS automatically tracks your service usage and will alert you if you have reached 85% of the usage limit for one or more AWS Free Tier-eligible services. Nonetheless, prioritize security to protect your assets.

Creating and Activating Your Account

  1. Open the Amazon Web Services home page.
  2. Choose Create an AWS Account.
  3. Enter your account information. Choose a strong password, document the information securely, and then choose Continue.

You will notice that this document repeatedly mentions securing your credentials. The importance of this cannot be overstated. Your finances are now tied to your AWS credentials. In the wrong hands, an AWS account can accrue charges rapidly, even with a daily budget and AWS usage tracking. Consider using a password manager such as LastPass or 1Password, services whose yearly costs mirror the cost of one hour of the most expensive EC2 instances. Pay for basic credential management to avoid paying for someone else's unauthorized use of your account.

  1. Choose Personal.
  2. Enter your personal information.
  3. Enter your billing information.
  4. Confirm your identity with a phone number.
  5. Enter the verification code.
  6. Select the Basic Plan.

You will receive an email to confirm that your account has been created. Once that happens, you can access your account with the email address and password you used to register.

Setting Up an IAM User and Root Multi-factor Authentication

  1. Open the Amazon Web Services home page.
  2. Choose Sign In to the Console.
  3. Sign in as the Root user.
  4. Set up a virtual Multi-factor Authentication device for your AWS account root user. Setting up multi-factor authentication is another vital step toward securing your account.
  5. Navigate to IAM with the search bar at the top of the screen.
  6. Choose Users on the left navigation menu.
  7. Select Add user.
  8. Enter a User name and check both Programmatic and AWS Management Console access.
  9. Choose a Console password type and determine whether you would like to Require password reset for the user at initial sign-in.
  10. Choose Next: Permissions.
  11. Choose Create group.
  12. Enter Admin in the Group name box and select Administrator Access in the policy name menu.
  13. Choose Create group.
  14. Choose Next: Tags.
  15. Choose Next: Review.
  16. If all looks as you expect, choose Create User.

Setting Up a Budget

  1. While logged in to the AWS console as the root user, choose My Account from the account dropdown menu in the top right corner of the screen.
  2. Scroll down to IAM User and Role Access to Billing Information and select edit.
  3. Select Activate IAM Access and Update.
  4. Document all credentials securely: root user email address; root user password; IAM username; IAM password, and account number.
  5. Sign out of the Root account through the account dropdown menu in the top right corner of the screen. It is widely considered bad practice to perform tasks with the root user. The root user should only be used to create the first IAM administrative user, to open billing privileges to administrators, and to close the account. Store the credentials securely.
  6. Open the Amazon Web Services home page.
  7. Choose Sign In to the Console.
  8. Sign in as the IAM user you created above.
  9. Use the search console to find AWS Budgets.
  10. Choose Create budget.
  11. Select Cost budget.
  12. Name the budget. Choose Daily for the Period. Select Recurring budget and Fixed. Enter $0.01 as the Budgeted Amount.
  13. Choose Configure thresholds.
  14. Set threshold based on Actual cost.
  15. Set the Alert threshold to 100%. Note that you may want a different threshold if your budget is greater than $0.01.
  16. Set up notifications by entering an email address in the Email recipients box.
  17. Choose Confirm budget.

IAM Multi-factor Authentication

  1. Set up multi-factor authentication for your IAM user.
  2. Sign out of your AWS account through the account dropdown menu in the top right corner of the screen.

Congratulations! You are now ready to deploy your application with AWS.

AWS Elastic Beanstalk and the AWS Elastic Beanstalk CLI

AWS Elastic Beanstalk

AWS developed Elastic Beanstalk to facilitate the deployment of web applications with AWS managed services. It orchestrates the provisioning and monitoring of the infrastructure necessary to manage a scalable and secure web application developed with Java, .NET, PHP, Node.js, Python, Ruby, or Go.

Installing the Elastic Beanstalk CLI

While it is possible to deploy an application through the AWS Elastic Beanstalk Console, you will find working with the CLI to be more efficient. You can find installation instructions here. Note that the CLI requires Python 2.7, 3.4 or later. Since Python 2 has reached its end of life, you should be working in Python 3.

Review the Elastic Beanstalk Command Line reference material here.

Deploying Your React Application with AWS Elastic Beanstalk

AWS Elastic Beanstalk React Tutorial

Before working to deploy your application, it is worth completing a tutorial to orient yourself to the Elastic Beanstalk tools and to make sure you have configured them correctly on your machine. It should take no more than an hour, which is less time than it will take you to learn the service while fighting to deploy your application with misconfigurations.

React Deployment Prerequisites

Make certain that your application works with npm. The Elastic Beanstalk Node.js platform uses npm as a package manager by default. If you have used yarn to build your application, you can remove the node_modules folder and yarn.lock file and then reinstall the dependencies with npm install. Ensure that your application runs locally after the changes. It is easier to debug errors on your local machine than it is to dig through AWS logs. Fix errors as necessary before trying to deploy your project.

A Note About Using json-server

Many NSS frontend capstones use json-server to mock backend responses. Deploying an application to the web with such a setup presents a significant security risk. In short, it allows unknown users to access and/or manipulate your data. The intent of these instructions for deploying your frontend application is to acclimate you to working with AWS. It is not to teach you how to deploy a frontend application with proper security protocols. It is essential that you follow the security group instructions below to limit ingress to your application to your computer's IP on your home network. Failing to do so represents significant risk to your users and your AWS account, which - as noted above - is tied to your finances.

Setting Up a React Application with a JSON Server

Deploying a React application with a JSON server on Elastic Beanstalk will require you to make a few small changes to your capstone code base. Fortunately, Andy Collins has written a simple JSON server that you can incorporate your project to get it up and running in the cloud. The source code is here. Following is an abstraction to facilitate your deployment:

package.json

  1. Make sure your application includes concurrently and json-server in its package.json file, e.g.:
"dependencies": {
    "concurrently": "^5.3.0",
    "json-server": "^0.16.3",
    "react": "^16.8.3",
    "react-dom": "^16.8.3",
    "react-scripts": "^4.0.0"
  }
  1. Alter your scripts block to include the following:
    "scripts": {
    "start": "npm run build && npm run json-serve",
    "json-serve": "node server.js",
    "start:dev": "concurrently \"npm run json-serve\" \"react-scripts start\"",
    "build": "react-scripts build",
    "test": "react-scripts test",
    "eject": "react-scripts eject"
  } 

server.js

  1. Create a server.js file in your application's main directory. Configure it as follows:
const path = require('path');
const dbPath = './API/db.json';
const jsonServer = require('json-server');
const server = jsonServer.create();
const router = jsonServer.router(dbPath);
const middlewares = jsonServer.defaults({ static: "./build" });
const port = process.env.PORT || 5002;

server.use(middlewares);

server.use((req, res, next) => {
    const isApiRoute = req.originalUrl.includes('/api/');
    if (isApiRoute) {
        return next();
    }
    return res.sendFile(path.join(__dirname, './build/index.html'));
});

server.use(jsonServer.rewriter({
    '/api/*': '/$1'
}));

server.use(router);

server.listen(port, () => {
    console.log(`app running on port ${port}`);
});

API/db.json

  1. Create a folder titled API under your application's main directory.
  2. Place your db.json file under that directory.

/src/data.js

Create a data.js file under your application's src directory and configure it as follows:

const baseUrl = process.env.NODE_ENV === 'production'
  ? '/api/'
  : "http://localhost:5002/api/";

const data = {
  getPosts: () => 
    fetch(`${baseUrl}posts`).then(resp => resp.json())
};

export default data;

Congratulations! You application is now configured for development and deployment.

Initializing Elastic Beanstalk

From your application's home directory, run eb init. This sets default values for Elastic Beanstalk applications. It will ask a series of questions:

  1. If you have not set up your Elastic Beanstalk CLI with your AWS credentials, the prompts will ask you for your AWS IAM user's key and secret key. You will be able to find these credentials in the AWS console under IAM --> Users --> <your_user> --> Security credentials. If you are unable to access your credentials or failed to store them when you accessed them initially, you can create new credentials. Document them securely.
  2. Select us-east-1 as your region. The reason for this is two-fold. First, it is best practice to deploy your application closest to its user base. Amazon's us-east-1 region is based in northern Virginia. The proximity argument may lead to your wanting to select us-east-2, which is in Ohio. Nonetheless, you should still choose us-east-1 because this is the region in which AWS often deploys its newest services first. The benefit of having access to the newest services far outweighs the cost of a few hundred miles.
  3. Choose [ Create new Application ]. It will default to the the name of your application's main folder.
  4. Allow the default value for Application Name.
  5. The prompt will ask you whether you are using Node.js. Enter Y.
  6. Choose the version of Node you used locally to develop your project.
  7. Select n for CodeCommit. You do not need an AWS-managed service for source control.
  8. Set up SSH access for your EC2 instances if you would like:
    • Select a keypair.
    • Name the keypair.
    • Enter a passphrase.
    • The public key will be saved locally to /Users/<user>/.ssh/<keypair_name>.
    • Enter your passphrase to upload the public key to AWS. Store this passphrase securely. You will need it each time you use the keypair.

Creating Your Elastic Beanstalk Application

From your application's home directory, run eb create. This will generate a new Elastic Beanstalk environment and deploy your application to it.

  1. Choose an environment name or allow the default value.
  2. Enter a value for the prefix of your application's DNS Canonical Name record or allow the default value.
  3. Select an application load balancer. AWS is in the process of deprecating Classic load balancers. Network load balancers cost money, and you do not need their low level configuration options to deploy your capstone.
  4. Choose n for Spot Fleet requests. Since you are deploying a light application on the free tier, you do not need to worry about this configuration option.

From this point, the service will complete the following steps:

  1. Package and deploy your application to S3.
  2. Upload your ssh keypair to EC2 if you attached one to the environment in the steps above.
  3. Create a target group.
  4. Create security groups.
  5. Create an auto-scaling launch configuration and auto scaling group.
  6. Create an EC2 instance.
  7. Create auto scaling group policies for scaling your application's resources up and down.
  8. Create two CloudWatch alarms to support auto scaling.
  9. Create an application load balancer and load balancer listener.
  10. Deploy your application to your EC2 instance.
  11. Print the DNS CNAME of your Elastic Beanstalk environment, which will follow the pattern <DNS_CNAME_prefix>.us-east-1.elasticbeanstalk.com.

Update Your Application Code

You will need to replace all calls to localhost:<port> with <elastic_beanstalk_environment_DNS_CNAME>/api. Note the following example:

Original
return fetch(`http://localhost:5000/users?email=${email.current.value}`)
Adapted
return fetch(`http://eb_react_app.us-east-1.elasticbeanstalk.com/api/users?email=${email.current.value}`)

Deploy your changes as follows:

git add .
git commit -m "<your detailed commit message>"
eb deploy --staged

Elastic Beanstalk only updates from the HEAD commit of the main or master Git branch. Deploying with the --staged flag pulls all the changes you have staged for pushing to your main branch. This way you can confirm that your application works before committing the changes to the main branch.

Update Your Application Load Balancer's Security Group

IMPORTANT: Without this step, your application's data will be exposed to the world. Take this step seriously, and complete it from your own computer on your home router.

  1. Log in to the AWS Management Console.
  2. Go to the EC2 service. You can search for it in the search bar at the top or use the dropdown Services menu to locate it.
  3. In the left navigation bar, select Security Groups.
  4. Find the Security Group with the Name of your Elastic Beanstalk Application and the following Description:
Elastic Beanstalk created security group used when no ELB security groups are specified during ELB creation
  1. Click on its Security group ID.
  2. Select Edit inbound rules.
  3. Under Source close the box with the entry 0.0.0.0/0.
  4. In the dropdown menu that has Custom, select My IP.
  5. Select Save rules.
  6. Your application is now restricted to your home network. It will accept traffic from no other source.

Congratulations! You have now deployed your React application with AWS Elastic Beanstalk.

Reviewing the Health, Status, and Configuration of Your Elastic Beanstalk Environment

To check the health of your Elastic Beanstalk environment, you can run eb status from the command line.

To review other facts about your Elastic Beanstalk application and environment, access the Elastic Beanstalk console via the Search Bar or Services menu in the AWS Console. The logs functionality is especially helpful for debugging. To access your application's logs, go to the Elastic Beanstalk console. Select Environments on the left navigation menu. Select your environment. In the navigation pane, choose Request Logs. When Elastic Beanstalk finishes processing the logs, choose Download.

You can terminate your Elastic Beanstalk environment with eb terminate. This will tear down all the AWS resources you have deployed.

Deploying Your Django Application with AWS Elastic Beanstalk

IMPORTANT NOTE: If you are deploying a web application with a SQLite database, you will need to make several configuration changes that are not captured in these instruction. They are forthcoming.

Before trying to deploy your Django application with AWS Elastic Beanstalk, it is worth working through a tutorial. It should take no more than an hour and will save you much time when working to deploy your own application.

Before proceeding, make sure your Django application runs without a hitch on your local machine. You do not want to debug your application remotely.

Configure Your Application for Elastic Beanstalk

  1. Activate your virtual environment.
  2. Run pip freeze and save the output to a requirements.txt file in your project's main directory.
  3. Create a directory named .ebextensions.
  4. In the .ebextensions directory, create a file named django.config and configure it as follows:
option_settings:
  aws:elasticbeanstalk:container:python:
    WSGIPath: <your_application_name>.wsgi:application

Note: Replace <>your_application_name> with the name of your application.

  1. Deactivate your virtual environment.
  2. Review the Django deployment checklist and make all necessary changes to your server code. This includes, but may not be limited to, removing the SECRET_KEY from your settings.py file and setting DEBUG to False. This is a requirement to protect your deployed application. Failing to take this step seriously jeopardizes your application and your AWS account, which is tied to your finances.

Initialize Elastic Beanstalk for Your Application

  1. Run the eb init command.
  2. Select us-east-1.
  3. Select [ Create new Application ].
  4. Select the default name for the application.
  5. Select Python.
  6. Select the version of Python you used to develop your application.
  7. Select n to the CodeCommit prompt.
  8. Select Y to set up SSH.
  9. Select an existing keypair or [ Create a new KeyPair ].

Create Your Elastic Beanstalk Django Application

  1. Run eb create.
  2. Choose the default environment name.
  3. Choose the default DNS CNAME prefix.
  4. Select the application load balancer.
  5. Select N when prompted about Spot Fleet requests.

From this point, the service will complete the following steps:

  1. Package and deploy your application to S3.
  2. Upload your ssh keypair to EC2 if you attached one to the environment in the steps above.
  3. Create a target group.
  4. Create security groups.
  5. Create an auto-scaling launch configuration and auto scaling group.
  6. Create an EC2 instance.
  7. Create auto scaling group policies for scaling your application's resources up and down.
  8. Create two CloudWatch alarms to support auto scaling.
  9. Create an application load balancer and load balancer listener.
  10. Deploy your application to your EC2 instance.
  11. Print the DNS CNAME of your Elastic Beanstalk environment, which will follow the pattern <DNS_CNAME_prefix>.us-east-1.elasticbeanstalk.com.

At this point your browser will return the following error:

DisallowedHost at /

Invalid HTTP_HOST header: '<DNS_CNAME_prefix>.us-east-1.elasticbeanstalk.com'. You may need to add 
'<DNS_CNAME_prefix>.us-east-1.elasticbeanstalk.com' to ALLOWED_HOSTS.

As the error message recommends, you will need to add '<DNS_CNAME_prefix>.us-east-1.elasticbeanstalk.com' to ALLOWED_HOSTS in your settings.py file. Remember to replace <DNS_CNAME_prefix> with your DNS CNAME prefix.

Once you have made the appropriate change to your code, add and commit your changes to GitHub, and deploy your application again by running eb deploy --staged.

At this point, your application should be running in the cloud.

Secure Your Django Server in the Cloud

This is a good point to restrict http traffic to your application. It is a requirement. Follow the instructions here to limit your application's http traffic to your local network. Failing to complete this step leaves your data exposed to all internet traffic, which is a significant security risk to your server in the cloud. This is also a risk to your AWS account, which is tied to your finances.

Congratulations! Your Django application is now running in the cloud.

Serve Your Django Application's Static Files to the Cloud

Now that you have secured your server, you can attend to its visual representation. You will notice that your Admin and API pages lack the expected Django styling. This is because your Django application has not collected its static files and your Elastic Beanstalk application has not been configured to serve them.

  1. Add the following configuration to your settings.py file:
import os

PROJECT_ROOT = os.path.abspath(os.path.dirname(__name__))
STATIC_ROOT = os.path.join(PROJECT_ROOT,'static/')
STATIC_URL = '/static/'

Your settings.py file may already have STATIC_URL = '/static/' by default.

  1. From your project's main local directory (i.e., not on the cloud server), run python manage.py collectstatic. Your application's static files have now been collected under the static directory under your project's root directory.
  2. Add the following configuration to your django.config file under the .ebextensions directory:
  aws:elasticbeanstalk:environment:proxy:staticfiles:
    /static: static

Make sure the indentation of the new aws line matches the indentation of the aws line above it. Standard is two spaces from the left side.

  1. Add and commit all your changes to GitHub.
  2. Deploy them to your Elastic Beanstalk environment with eb deploy --staged.
  3. Merge your changes to your main GitHub branch.

Deploying Your React Client Frontend and Django Server Backend with AWS Elastic Beanstalk

Before proceeding, please ensure that both your client and your server run locally. You do not want to have to debug your application in the cloud.

  1. Deploy your Django application following the instructions above.
  2. To test your remote server, change all API calls in your React code from http://localhost:3000 to your Django application's Elastic Beanstalk URL, which will mirror the following: http://<DNS_CNAME_prefix>.us-east-1.elasticbeanstalk.com. At this point, your local React client should be connecting to your remote Django server. Make sure you are working from the computer and router whose IP address is allowed ingress to your Django server. Otherwise, your local client will not be allowed to communicate with your remote server.
  3. Once your local React client is communicating as expected with your remote Django server, you are ready to deploy your client remotely. Follow the instructions here. At this point, your React app should return an error: Invalid Host header.
  4. Create or modify a .env file under your application's src directory and add the following: HOST='http://<DNS_CNAME_prefix>.us-east-1.elasticbeanstalk.com'. Remember to replace <DNS_CNAME_prefix> with your application's DNS CNAME. You will also need to remove your localhost proxy entry from your package.json file. Add and commit your changes to GitHub. Deploy them with eb deploy --staged.
  5. At this point, you should see the homepage of your React application displayed from your remote client. Data from your backend server will be missing, however, because your browser will have blocked API requests due to a Access-Control-Allow-Origin header. To fix this, you will need to update your CORS_ORIGIN_WHITELIST in your Django application's settings.py file. Add your Elastic Beanstalk environment's URL to the list as follows:
    CORS_ORIGIN_WHITELIST = (
     'http://localhost:3000',
     'http://<DNS_CNAME_prefix>.us-east-1.elasticbeanstalk.com',
     )
    
    Add and commit your code to Github. Deploy your code to Elastic Beanstalk with eb deploy --staged.
  6. Add, commit, and push your code to GitHub.

There are at least two caveats of which you should be aware:

  1. This setup only allows for HTTP traffic. HTTP is an unsecured protocol.
  2. This setup routes your client and server traffic publicly. Limiting server traffic will require additional modifications to use an internal load balancer.

Without further work to configure HTTPS and an internal load balancer, you should restrict server traffic to your home network as noted above.

Congratulations! You have now deployed a full-stack application to the cloud with AWS Elastic Beanstalk. Remember to terminate it when you are finished with the resources: eb terminate.

aws-deployment-instructions's People

Contributors

jeremybakker avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.