Lab 2: .NET on Elastic Beanstalk

Author: Kirk Davis, Dean Suzuki (4/21/20)

Deploy ASP.NET MVC to AWS with Elastic Beanstalk

Purpose & Background

In this lab, you will create a simple ASP.NET 4.x MVC application and deploy it to AWS with Elastic Beanstalk. Optionally, time permitting, you can add a Web API controller to the application, and then configure Amazon API Gateway as a proxy layer in front of that API, to take advantage of caching and throttling.

Note: It’s also possible to put an API Gateway API in front of the entire ASP.NET MVC website, but this would require using a custom domain name, or alternatively editing the project’s paths for CSS and JavaScript. For simplicity, the optional API Gateway section of the lab has you add a Web API controller, and configure API Gateway proxying for just that endpoint.

Amazon API Gateway is a fully managed service that makes it easy for developers to create, publish, maintain, monitor, and secure APIs at any scale. By using API Gateway in front of your application’s API endpoints, you can apply throttling, security, monitoring and logging, and improve performance by using the service’s caching functionality, as well as handle versioning and developer documentation (including Swagger support).

Step 1: Create a new ASP.NET MVC project

Follow the steps below to create and customize an ASP.NET 4.x (.NET Framework) MVC Project in Visual Studio. AWS fully supports deploying .NET Framework applications on Microsoft Windows with Elastic Beanstalk, but for this lab, you’ll be using .NET Core.

Note: the steps below are for Visual Studio 2019. Perform the equivalent steps in your version of Visual Studio if using Visual Studio 2017.

  1. In Visual Studio, open the New Project dialog.
    • In the search box, type
    • Choose the ASP.NET Web Application (.NET Framework) template.
    • Press Next. VS2019 New Project dialog
  2. When selecting a project name, avoid using spaces in your project name as this can cause issues with Elastic Beanstalk.

  3. In the Framework dropdown, choose the most recent version of .NET Framework available. Click Create to continue.

  4. Choose the MVC project template then click Create to create the project. Ensure your application builds.

  5. Run your application locally by clicking the IIS Express to see what the default MVC website looks like. There might be a prompt if you want trust the IIS Express SSL certificate, select Yes. Press Yes again if prompted. A browser window should open with the default ASP.NET page.

The following is an optional module. If you want to skip the optional module, scroll down to Step2.

OPTIONAL: Add a Web API Controller

NOTE: Follow the below optional steps to add and configure a Web API controller, which can then be configured behind an API Gateway proxy to use throttling and caching features (covered in optional section 2.3)

  1. In Visual Studio, right-click the ‘Controllers’ folder in the Solution Explorer pane, and click ‘Add’ => ‘New Item’.

  2. In the ‘Add New Item’ dialog, type ‘web api’ in the search box (top right), then select ‘Web API Controller Class’ in the item template.

  3. Assign the name ‘ValuesController.cs’ (remove the trailing ‘1’ if present), then click ‘Add’.

  4. Locate and open the ‘Global.asax.cs’ file.

  5. Add the following class to the namespace:

    public static class WebApiConfig
    public static void Register(HttpConfiguration config)
        // Web API routes
            name: "DefaultApi",
            routeTemplate: "api/{controller}/{id}",
            defaults: new { id = RouteParameter.Optional }

Note: you will need to add the using statement, using System.Web.Http; at the top of the file.

  1. In the Application_Start() method, insert the following as the first line in the method, to configure Web API routing:


Ensure your application builds. Run the website locally, and when the browser window appears, append /api/values to the end of the URL to verify that the array of values (as XML or JSON) are displayed.

Step 2: Deploy to AWS Elastic Beanstalk using the toolkit

Follow the steps below to deploy the ASP.NET Core Web API application to an Amazon EC2 instance running Windows Server Core.

  1. Right-click your project in Solution Explorer, and select Publish to AWS Elastic Beanstalk to launch the publishing wizard. See the figure below. PublishToEB
  2. Ensure the Account profile to use drop-down and Region drop-down are set to the profile and region you are using for today’s labs.

    • Set the deployment target is set to, Create a new application environment,
    • Click Next
  3. On the next step of the wizard, select a name for the application (or leave it set to the default), and then select a name for the environment. The pre-populated list will include environments ending in -dev, -test and -prod (or you can type your own).

  4. AWS Elastic Beanstalk application environments are accessible via a public domain name (a subdomain of On the same step of the wizard, choose a subdomain for your Web API application, and check to ensure it’s available. Click Check availability. Once you have found a URL that’s available, click Next. See the figure below. ApplicationEnvironmnet

  5. On the next step of the wizard, choose the application stack (called the “container type” in Elastic Beanstalk; it is not a Docker container, however). Choose the latest version of 64 bit Windows Server Core running IIS.

  6. Choose an instance type (e.g. t2.medium). Ensure single instance environment is checked. Elastic Beanstalk can also deploy fully load-balanced applications, along with the load-balancer, but for this lab, you will deploy to a single EC2 instance. For this application, the “t2.medium” instance type is more than sufficient.

  7. If you don’t already have an EC2 key pair created (in the “Key pair” dropdown), select <Create new key pair…>, and enter a name for the key pair. When finished, click ‘Next’.

    Note: The key pair is a cryptographic pair of keys, one public and one private. Windows EC2 Administrator login credentials are encrypted with the public key, which AWS stores, and can only be decrypted with the private key, which you keep. In this case, the AWS Toolkit for Visual Studio will store the private key for you.

    Note also that you don’t need to use a key-pair at all if you don’t intend to RDP or otherwise connect to the instance, which is often the case.

8. On the next step of the wizard, you choose the permissions your application will inherit from the EC2 instance it’s running on by selecting the IAM Role that the EC2 instance itself will have. In the role dropdown, select check the box next to CloudWatch Full Access (under Role Templates) at the top of the drop-down list. This will create a new IAM role that has permissions to write to CloudWatch Logs. See the figure below. ApplicationPermissions

  1. The AWS Elastic Beanstalk service itself needs permissions in order to monitor and update your application environment. Select the role, aws-elasticbeanstalk-service-role from the Role dropdown under “Service Permissions”. Press Next.

  2. On the next step of the wizard, leave everything set to the defaults. In a production application, you would likely change the build configuration to Release, but for this lab, Debug is fine. Press Next.

  3. At the final step of the wizard, review your settings, and then click the Deploy button to begin deploying the app. After a few moments, the Elastic Beanstalk environment pane should automatically open in Visual Studio. If it doesn’t, find your new environment under the AWS Elastic Beanstalk node in the AWS Explorer pane of Visual Studio, and double-click it. If it doesn’t appear in the AWS Explorer, make sure that you are looking in the US East (N. Virigina) region.

You can view the progress of the deployment in the Output Window. The deployment is finished when a message appears in the Output window such as: Publish to AWS Elastic Beanstalk environment ‘…..’ completed successfully*. Once it has completed you are ready to move to the next part. It may take 5 - 10 minutes for the EC2 instance to be provisioned and the application to be deployed the first time. Subsequent in-place deployments are much faster.

Step 3: Test the website

Once your Elastic Beanstalk environment is deployed.

  1. Go to the AWS Explorer. Make sure that you are in the US East (N. Virigina) region.

  2. Go to the AWS Elastic Beanstalk. Expand your application and click on it.

  3. In the center area, the status should show Environment is healthy

  4. Click the URL shown at the top of the pane to launch a browser, or type in the URL you set earlier (<subdomain>.<region>

You should see the deployed version of the website that is now running on AWS Elastic Beanstalk.

Optional: Create and Configure API Gateway API and throttling

Optional: Create an API Gateway proxy for your Values API

With your ASP.NET website deployed on a t3.medium instance, your website (and it’s APIs) could be overwhelmed by heavy traffic. You could set up horizontal scaling to deal with the traffic, choose a larger instance type, or put your website and APIs behind an API Gateway façade and implement throttling and caching.

For this lab, we’ll implement the third option: throttling. Follow the steps below to configure and deploy an API Gateway REST API in front of your ASP.NET application’s ‘Values’ API.

Note: It’s also possible to put an API Gateway API in front of the entire ASP.NET MVC website, but this would require using a custom domain name, or alternatively editing the project’s paths for CSS and JavaScript. For simplicity in this lab, we will set up API Gateway proxying for just the Values API.

  1. In the AWS Management Console, navigate to the API Gateway console.

  2. Start creating a new REST API by clicking the appropriate ‘Build’ button. APIG REST API selection

  3. On the next view, under Settings, enter a name and (optional) description for the API, and leave ‘Endpoint Type’ set to ‘Regional’, then click ‘Create API’. APIG REST API create page

    When you first create a REST API, there are no resources (URLs) or methods (GET/POST/PUT/etc) created for it. API Gateway allows you to have different resources (ULRs or paths) and methods assigned to different backend APIs. For this lab, howevber, we’ll configure the API to proxy all requests to the same backend URL - the Elastic Beanstalk URL - using the proxy resource and ANY method pattern.

  4. In the center pane, in the Actions dropdown, select ‘Create resource’, and check the box to configure the new resource as a proxy resource, which will automatically populate the resource name and path (see screenshot below). Click ‘Create Resource’ to create the resource and display the method setup view. APIG New Child Resource UI

  5. In the method setup, choose ‘HTTP Proxy’ as the integration type, ‘Passthough’ as the ‘Content Handling’ type, and enter the full domain name for the your Elastic Beanstalk website, appending /{proxy} to the end (no quotes) for the endpoint URL. Your URL should look something like{proxy} See the figure below. Be sure to include the ‘http://’ at the start of the URL. APIG Method setup

  6. Click ‘Save’ to save your changes.

  7. After creating the new method, the content pane will show a graphical-like view of the full round-trip path of requests, starting with the client in a box on the left, and the backend resource in a box on the right. In the client box is a ‘Test’ link. Click that link. See screenshot below. APIG Method Execution view

  8. In the method test view, select ‘GET’ as the method, /api/values as the path, then click the ‘Test’ button. The response body (right side of the pane) should show the JSON representation of the array of two values (value1 and value2).

  9. Now deploy your API. In the center pane, click the Actions dropdown and select, ‘Deploy API’.

  10. In the Deploy API dialog window that appears, select ‘[New Stage]’ in the Deployment stage dropdown, enter ‘prod’ (no quotes) as the stage name, a description for the stage (something like, ‘My API production stage’) and a deployment description (something like, ‘initial deployment’). Then click ‘Deploy’.

    Note: The stage editor view will be displayed in the content pane, and the URL to access your API Gateway API will be shown, linked, at the top. A stage is the actual deployed API endpoint(s) that will be exposed for clients to access.

  11. You can test the REST API proxy by clicking on the linked ‘Invoke URL’, then appending /api/values to the URL in your browser. You should again see an XML or JSON serialization of the values array (value1 and value2).

Optional: Configure API Gateway throttling for your Values API

Note, if you want to perform the following optional sections, you must have done the earlier optional section. If you skipped the early optional section and want to perform these sections, then go back and perform that section and re-publish the app to Elastic Beanstalk before continuing.

In this section, you’ll apply throttling to your API.

  1. Review the API Gateway throttling documentation for more information about how throttling works. You can edit the Default Throttling by selecting ‘Stages’ in the left menu, ‘prod’ from the ‘Stages’ list, then check the box to Enable Throttling. See screenshot below. Api Stage editor

  2. Change the throttling values to 1 request/second, with a burst rate of 2 requests. We’re choosing this low value to make it easier to test without load-testing software. Save your changes.

You have now deployed an API Gateway API to proxy requests to your Web API, implemented throttling, and verified the API Gateway API is accessible.

Optional: Confirm Throttling with Load Test Script

There are several ways we can confirm that requests are now being throttled. If you’re familiar with Postman, you can run multiple iterations using the Collection Runner feature to run multiple iterations with no delay between each request. If you’re not familiar with Postman’s Collection Runner feature, you can create a simple PowerShell script by following the steps below that will demonstrate the throttling feature of the API Gateway API.

  1. Copy the below code to a text file, and save it with the extension .ps1 , making sure to replace <your-api-gateway-invoke-url> with the actual Invoke URL of your API, so that the full URL ends with /api/values

    Write-Output \"Sending GET request to your REST endpoint 10 times\"
    for (\$i = 0; \$i -lt 10; \$i++) {
       Invoke-WebRequest -Uri https://<your-api-gateway-invoke-url>/api/values -Method 'Get'
  2. Open PowerShell, and navigate to the folder where you saved the file. Run your PowerShell script by typing “.\<file-name>.ps1“ (no quotes) where <file-name> is the name you gave the file.

Depending on your network connection, and the speed at which your computer is able to execute the requests, you will see some of the requests succeed with status code 200 and the json payload, while others will fail with the response json, {“message”:“Too Many Requests”}.

If you are running the iterations in Postman, you will see that the response HTTP status code is 429 (Too Many Requests).