Saturday, April 8, 2023

Deploying an ASP.NET Core 2.0 App to (AWS) Amazon ECS (EC2)

 This section describes how to use the Publish Container to AWS wizard, provided as part of the Toolkit for Visual Studio, to deploy a containerized ASP.NET Core 2.0 application targeting Linux through Amazon ECS using the EC2 launch type. Because a web application is meant run continuously, it will be deployed as a service.

Before you publish your container

Before using the Publish Container to AWS to deploy your ASP.NET Core 2.0 application:

Accessing the Publish Container to AWS wizard

To deploy an ASP.NET Core 2.0 containerized application targeting Linux, right-click the project in the Solution Explorer and select Publish Container to AWS.

You can also select Publish Container to AWS on the Visual Studio Build menu.

Publish Container to AWS Wizard

Account profile to use - Select an account profile to use.

Region - Choose a deployment region. Profile and region are used to set up your deployment environment resources and select the default Docker registry.

Configuration - Select the Docker image build configuration.

Docker Repository - Choose an existing Docker repository or type in the name of a new repository and it will be created. This is the repository the built container image is pushed to.

Tag - Select an existing tag or type in the name of a new tag. Tags can track important details like version, options or other unique configuration elements of the Docker container.

Deployment - Select Service on an ECS Cluster. Use this deployment option when your application is meant to be long-running (like an ASP.NET Core 2.0 web application).

Save settings to aws-docker-tools-defaults.json and configure project for command line deployment - Check this option if you want the flexibility of deploying from the command line. Use dotnet ecs deploy from your project directory to deploy and dotnet ecs publish the container.

Launch Configuration page

ECS Cluster - Pick the cluster that will run your Docker image. You can create an ECS cluster using the AWS Management Console.

Launch Type - Choose EC2. To use the Fargate launch type, see Deploying an ASP.NET Core 2.0 Application to Amazon ECS (Fargate).

Service Configuration page

Service - Select one of the services in the drop-down to deploy your container into an existing service. Or choose Create New to create a new service. Service names must be unique within a cluster, but you can have similarly named services in multiple clusters within a region or across multiple regions.

Number of Tasks - The number of tasks to deploy and keep running on your cluster. Each task is one instance of your container.

Minimum Healthy Percent - The percentage of tasks that must remain in RUNNING state during a deployment rounded up to the nearest integer.

Maximum Percent - The percentage of tasks that are allowed in the RUNNING or PENDING state during a deployment rounded down to the nearest integer.

Placement Templates - Select a task placement template.

When you launch a task into a cluster, Amazon ECS must determine where to place the task based on the requirements specified in the task definition, such as CPU and memory. Similarly, when you scale down the task count, Amazon ECS must determine which tasks to terminate.

The placement template controls how tasks are launched into a cluster:

  • AZ Balanced Spread - distribute tasks across Availability Zones and across container instances in the Availability Zone.

  • AZ Balanced BinPack - distribute tasks across Availability Zones and across container instances with the least available memory.

  • BinPack - distribute tasks based on the least available amount of CPU or memory.

  • One Task Per Host - place, at most, one task from the service on each container instance.

For more information, see Amazon ECS Task Placement.

Application Load Balancer page

Configure Application Load Balancer - Check to configure an application load balancer.

Select IAM role for service - Select an existing role or choose Create New and a new role will be created.

Load Balancer - Select an existing load balancer or choose Create New and type in the name for the new load balancer.

Listener Port - Select an existing listener port or choose Create New and type in a port number. The default, port 80, is appropriate for most web applications.

Target Group - By default, the load balancer sends requests to registered targets using the port and protocol that you specified for the target group. You can override this port when you register each target with the target group.

Path Pattern - The load balancer will use path-based routing. Accept the default / or provide a different pattern. The path pattern is case-sensitive, can be up to 128 characters in length, and contains a select set of characters.

Health Check Path - The ping path that is the destination on the targets for health checks. By default, it is / and is appropriate for web applications. Enter a different path if needed. If the path you enter is invalid, the health check will fail and it will be considered unhealthy.

If you deploy multiple services, and each service will be deployed to a different path or location, you might need custom check paths.

ECS Task Definition page

Task Definition - Select an existing task definition or choose Create New and type in the new task definition name.

Container - Select an existing container or choose Create New and type in the new container name.

Memory (MiB) - Provide values for Soft Limit or Hard Limit or both.

The soft limit (in MiB) of memory to reserve for the container. Docker attempts to keep the container memory under the soft limit. The container can consume more memory, up to either the hard limit specified with the memory parameter (if applicable), or all of the available memory on the container instance, whichever comes first.

The hard limit (in MiB) of memory to present to the container. If your container attempts to exceed the memory specified here, the container is killed.

Task Role - Select a task role for an IAM role that allows the container permission to call the AWS APIs that are specified in its associated policies on your behalf. This is how credentials are passed in to your application. See how to specify AWS security credentials for your application.

Port Mapping - Add, modify or delete port mappings for the container. If a load balancer is on, the host port will be default to 0 and port assignment will be dynamic.

Environment Variables - Add, modify, or delete environment variables for the container.

When you are satisfied with the configuration, click Publish to begin the deployment process.

Publishing Container to AWS

Events are displayed during deployment. The wizard is automatically closed on successful completion. You can override this by unchecking the box at the bottom of the page.

You can find the URL of your new instances in the AWS Explorer. Expand Amazon ECS and Clusters, then click on your cluster.

Deploying an ASP.NET core application with Elastic Beanstalk

 In this tutorial, you will walk through the process of building a new ASP.NET Core application and deploying it to AWS Elastic Beanstalk.

First, you will use the .NET Core SDK's dotnet command line tool to generate a basic .NET Core command line application, install dependencies, compile code, and run applications locally. Next, you will create the default Program.cs class, and add an ASP.NET Startup.cs class and configuration files to make an application that serves HTTP requests with ASP.NET and IIS.

Finally, Elastic Beanstalk uses a deployment manifest to configure deployments for .NET Core applications, custom applications, and multiple .NET Core or MSBuild applications on a single server. To deploy a .NET Core application to a Windows Server environment, you add a site archive to an application source bundle with a deployment manifest. The dotnet publish command generates compiled classes and dependencies that you can bundle with a web.config file to create a site archive. The deployment manifest tells Elastic Beanstalk the path at which the site should run and can be used to configure application pools and run multiple applications at different paths.

The application source code is available here: dotnet-core-tutorial-source.zip

The deployable source bundle is available here: dotnet-core-tutorial-bundle.zip

Prerequisites

This tutorial uses the .NET Core SDK to generate a basic .NET Core application, run it locally, and build a deployable package.

Requirements
  • .NET Core (x64) 1.0.1, 2.0.0, or later

To install the .NET core SDK
  1. Download the installer from microsoft.com/net/core. Choose Windows. Choose Download .NET SDK.

  2. Run the installer and follow the instructions.

This tutorial uses a command line ZIP utility to create a source bundle that you can deploy to Elastic Beanstalk. To use the zip command in Windows, you can install UnxUtils, a lightweight collection of useful command line utilities like zip and ls. Alternatively, you can use Windows Explorer or any other ZIP utility to create source bundle archives.

To install UnxUtils
  1. Download UnxUtils.

  2. Extract the archive to a local directory. For example, C:\Program Files (x86).

  3. Add the path to the binaries to your Windows PATH user variable. For example, C:\Program Files (x86)\UnxUtils\usr\local\wbin.

    1. Press the Windows key, and then enter environment variables.

    2. Choose Edit environment variables for your account.

    3. Choose PATH, and then choose Edit.

    4. Add paths to the Variable value field, separated by semicolons. For example: C:\item1\path;C:\item2\path

    5. Choose OK twice to apply the new settings.

    6. Close any running Command Prompt windows, and then reopen a Command Prompt window.

  4. Open a new command prompt window and run the zip command to verify that it works.

    > zip -h Copyright (C) 1990-1999 Info-ZIP Type 'zip "-L"' for software license. ...

Generate a .NET core project

Use the dotnet command line tool to generate a new C# .NET Core project and run it locally. The default .NET Core application is a command line utility that prints Hello World! and then exits.

To generate a new .NET core project
  1. Open a new command prompt window and navigate to your user folder.

    > cd %USERPROFILE%
  2. Use the dotnet new command to generate a new .NET Core project.

    C:\Users\username> dotnet new console -o dotnet-core-tutorial Content generation time: 65.0152 ms The template "Console Application" created successfully. C:\Users\username> cd dotnet-core-tutorial
  3. Use the dotnet restore command to install dependencies.

    C:\Users\username\dotnet-core-tutorial> dotnet restore Restoring packages for C:\Users\username\dotnet-core-tutorial\dotnet-core-tutorial.csproj... Generating MSBuild file C:\Users\username\dotnet-core-tutorial\obj\dotnet-core-tutorial.csproj.nuget.g.props. Generating MSBuild file C:\Users\username\dotnet-core-tutorial\obj\dotnet-core-tutorial.csproj.nuget.g.targets. Writing lock file to disk. Path: C:\Users\username\dotnet-core-tutorial\obj\project.assets.json Restore completed in 1.25 sec for C:\Users\username\dotnet-core-tutorial\dotnet-core-tutorial.csproj. NuGet Config files used: C:\Users\username\AppData\Roaming\NuGet\NuGet.Config C:\Program Files (x86)\NuGet\Config\Microsoft.VisualStudio.Offline.config Feeds used: https://api.nuget.org/v3/index.json C:\Program Files (x86)\Microsoft SDKs\NuGetPackages\
  4. Use the dotnet run command to build and run the application locally.

    C:\Users\username\dotnet-core-tutorial> dotnet run Hello World!

Launch an Elastic Beanstalk environment

Use the Elastic Beanstalk console to launch an Elastic Beanstalk environment. For this example, you will launch with a .NET platform. After you launch and configure your environment, you can deploy new source code at any time.

To launch an environment (console)
  1. Open the Elastic Beanstalk console using this preconfigured link: console.aws.amazon.com/elasticbeanstalk/home#/newApplication?applicationName=tutorials&environmentType=LoadBalanced

  2. For Platform, select the platform and platform branch that match the language used by your application.

  3. For Application code, choose Sample application.

  4. Choose Review and launch.

  5. Review the available options. Choose the available option you want to use, and when you're ready, choose Create app.

Environment creation takes about 10 minutes. During this time you can update your source code.

Update the source code

Modify the default application into a web application that uses ASP.NET and IIS.

  • ASP.NET is the website framework for .NET.

  • IIS is the web server that runs the application on the Amazon EC2 instances in your Elastic Beanstalk environment.

The source code examples to follow are available here: dotnet-core-tutorial-source.zip

Note

The following procedure shows how to convert the project code into a web application. To simplify the process, you can generate the project as a web application right from the start. In the previous section Generate a .NET core project, modify the dotnet new step's command with the following command.

C:\Users\username> dotnet new web -o dotnet-core-tutorial
To add ASP.NET and IIS support to your code
  1. Copy Program.cs to your application directory to run as a web host builder.

    Example c:\users\username\dotnet-core-tutorial\Program.cs
    using System; using Microsoft.AspNetCore.Hosting; using System.IO; namespace aspnetcoreapp { public class Program { public static void Main(string[] args) { var host = new WebHostBuilder() .UseKestrel() .UseContentRoot(Directory.GetCurrentDirectory()) .UseIISIntegration() .UseStartup<Startup>() .Build(); host.Run(); } } }
  2. Add Startup.cs to run an ASP.NET website.

    Example c:\users\username\dotnet-core-tutorial\Startup.cs
    using System; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Http; namespace aspnetcoreapp { public class Startup { public void Configure(IApplicationBuilder app) { app.Run(context => { return context.Response.WriteAsync("Hello from ASP.NET Core!"); }); } } }
  3. Add the web.config file to configure the IIS server.

    Example c:\users\username\dotnet-core-tutorial\web.config
    <?xml version="1.0" encoding="utf-8"?> <configuration> <system.webServer> <handlers> <add name="aspNetCore" path="*" verb="*" modules="AspNetCoreModule" resourceType="Unspecified" /> </handlers> <aspNetCore processPath="dotnet" arguments=".\dotnet-core-tutorial.dll" stdoutLogEnabled="false" stdoutLogFile=".\logs\stdout" forwardWindowsAuthToken="false" /> </system.webServer> </configuration>
  4. Add dotnet-core-tutorial.csproj, which includes IIS middleware and includes the web.config file from the output of dotnet publish.

    Note

    The following example was developed using .NET Core Runtime 2.2.1. You might need to modify the TargetFramework or the Version attribute values in the PackageReference elements to match the version of .NET Core Runtime that you are using in your custom projects.

    Example c:\users\username\dotnet-core-tutorial\dotnet-core-tutorial.csproj
    <Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> <OutputType>Exe</OutputType> <TargetFramework>netcoreapp2.2</TargetFramework> </PropertyGroup> <ItemGroup> <PackageReference Include="Microsoft.AspNetCore.Server.Kestrel" Version="2.2.0" /> </ItemGroup> <ItemGroup> <PackageReference Include="Microsoft.AspNetCore.Server.IISIntegration" Version="2.2.0" /> </ItemGroup> <ItemGroup> <None Include="web.config" CopyToPublishDirectory="Always" /> </ItemGroup> </Project>

Next, install the new dependencies and run the ASP.NET website locally.

To run the website locally
  1. Use the dotnet restore command to install dependencies.

  2. Use the dotnet run command to build and run the app locally.

  3. Open localhost:5000 to view the site.

To run the application on a web server, you need to bundle the compiled source code with a web.config configuration file and runtime dependencies. The dotnet tool provides a publish command that gathers these files in a directory based on the configuration in dotnet-core-tutorial.csproj.

To build your website
  • Use the dotnet publish command to output compiled code and dependencies to a folder named site.

    C:\users\username\dotnet-core-tutorial> dotnet publish -o site

To deploy the application to Elastic Beanstalk, bundle the site archive with a deployment manifest. This tells Elastic Beanstalk how to run it.

To create a source bundle
  1. Add the files in the site folder to a ZIP archive.

    Note

    If you use a different ZIP utility, be sure to add all files to the root folder of the resulting ZIP archive. This is required for a successful deployment of the application to your Elastic Beanstalk environment.

    C:\users\username\dotnet-core-tutorial> cd site C:\users\username\dotnet-core-tutorial\site> zip ../site.zip * adding: dotnet-core-tutorial.deps.json (164 bytes security) (deflated 84%) adding: dotnet-core-tutorial.dll (164 bytes security) (deflated 59%) adding: dotnet-core-tutorial.pdb (164 bytes security) (deflated 28%) adding: dotnet-core-tutorial.runtimeconfig.json (164 bytes security) (deflated 26%) adding: Microsoft.AspNetCore.Authentication.Abstractions.dll (164 bytes security) (deflated 49%) adding: Microsoft.AspNetCore.Authentication.Core.dll (164 bytes security) (deflated 57%) adding: Microsoft.AspNetCore.Connections.Abstractions.dll (164 bytes security) (deflated 51%) adding: Microsoft.AspNetCore.Hosting.Abstractions.dll (164 bytes security) (deflated 49%) adding: Microsoft.AspNetCore.Hosting.dll (164 bytes security) (deflated 60%) adding: Microsoft.AspNetCore.Hosting.Server.Abstractions.dll (164 bytes security) (deflated 44%) adding: Microsoft.AspNetCore.Http.Abstractions.dll (164 bytes security) (deflated 54%) adding: Microsoft.AspNetCore.Http.dll (164 bytes security) (deflated 55%) adding: Microsoft.AspNetCore.Http.Extensions.dll (164 bytes security) (deflated 50%) adding: Microsoft.AspNetCore.Http.Features.dll (164 bytes security) (deflated 50%) adding: Microsoft.AspNetCore.HttpOverrides.dll (164 bytes security) (deflated 49%) adding: Microsoft.AspNetCore.Server.IISIntegration.dll (164 bytes security) (deflated 46%) adding: Microsoft.AspNetCore.Server.Kestrel.Core.dll (164 bytes security) (deflated 63%) adding: Microsoft.AspNetCore.Server.Kestrel.dll (164 bytes security) (deflated 46%) adding: Microsoft.AspNetCore.Server.Kestrel.Https.dll (164 bytes security) (deflated 44%) adding: Microsoft.AspNetCore.Server.Kestrel.Transport.Abstractions.dll (164 bytes security) (deflated 56%) adding: Microsoft.AspNetCore.Server.Kestrel.Transport.Sockets.dll (164 bytes security) (deflated 51%) adding: Microsoft.AspNetCore.WebUtilities.dll (164 bytes security) (deflated 55%) adding: Microsoft.Extensions.Configuration.Abstractions.dll (164 bytes security) (deflated 48%) adding: Microsoft.Extensions.Configuration.Binder.dll (164 bytes security) (deflated 47%) adding: Microsoft.Extensions.Configuration.dll (164 bytes security) (deflated 46%) adding: Microsoft.Extensions.Configuration.EnvironmentVariables.dll (164 bytes security) (deflated 46%) adding: Microsoft.Extensions.Configuration.FileExtensions.dll (164 bytes security) (deflated 47%) adding: Microsoft.Extensions.DependencyInjection.Abstractions.dll (164 bytes security) (deflated 54%) adding: Microsoft.Extensions.DependencyInjection.dll (164 bytes security) (deflated 53%) adding: Microsoft.Extensions.FileProviders.Abstractions.dll (164 bytes security) (deflated 46%) adding: Microsoft.Extensions.FileProviders.Physical.dll (164 bytes security) (deflated 47%) adding: Microsoft.Extensions.FileSystemGlobbing.dll (164 bytes security) (deflated 49%) adding: Microsoft.Extensions.Hosting.Abstractions.dll (164 bytes security) (deflated 47%) adding: Microsoft.Extensions.Logging.Abstractions.dll (164 bytes security) (deflated 54%) adding: Microsoft.Extensions.Logging.dll (164 bytes security) (deflated 48%) adding: Microsoft.Extensions.ObjectPool.dll (164 bytes security) (deflated 45%) adding: Microsoft.Extensions.Options.dll (164 bytes security) (deflated 53%) adding: Microsoft.Extensions.Primitives.dll (164 bytes security) (deflated 50%) adding: Microsoft.Net.Http.Headers.dll (164 bytes security) (deflated 53%) adding: System.IO.Pipelines.dll (164 bytes security) (deflated 50%) adding: System.Runtime.CompilerServices.Unsafe.dll (164 bytes security) (deflated 43%) adding: System.Text.Encodings.Web.dll (164 bytes security) (deflated 57%) adding: web.config (164 bytes security) (deflated 39%) C:\users\username\dotnet-core-tutorial\site> cd ../
  2. Add a deployment manifest that points to the site archive.

    Example c:\users\username\dotnet-core-tutorial\aws-windows-deployment-manifest.json
    { "manifestVersion": 1, "deployments": { "aspNetCoreWeb": [ { "name": "test-dotnet-core", "parameters": { "appBundle": "site.zip", "iisPath": "/", "iisWebSite": "Default Web Site" } } ] } }
  3. Use the zip command to create a source bundle named dotnet-core-tutorial.zip.

    C:\users\username\dotnet-core-tutorial> zip dotnet-core-tutorial.zip site.zip aws-windows-deployment-manifest.json adding: site.zip (164 bytes security) (stored 0%) adding: aws-windows-deployment-manifest.json (164 bytes security) (deflated 50%)

Deploy your application

Deploy the source bundle to the Elastic Beanstalk environment that you created.

You can download the source bundle here: dotnet-core-tutorial-bundle.zip

To deploy a source bundle
  1. Open the Elastic Beanstalk console, and in the Regions list, select your AWS Region.

  2. In the navigation pane, choose Environments, and then choose the name of your environment from the list.

    Note

    If you have many environments, use the search bar to filter the environment list.

  3. On the environment overview page, choose Upload and deploy.

  4. Use the on-screen dialog box to upload the source bundle.

  5. Choose Deploy.

  6. When the deployment completes, you can choose the site URL to open your website in a new tab.

The application simply writes Hello from ASP.NET Core! to the response and returns.

Launching an environment creates the following resources:

  • EC2 instance – An Amazon Elastic Compute Cloud (Amazon EC2) virtual machine configured to run web apps on the platform that you choose.

    Each platform runs a specific set of software, configuration files, and scripts to support a specific language version, framework, web container, or combination of these. Most platforms use either Apache or NGINX as a reverse proxy that sits in front of your web app, forwards requests to it, serves static assets, and generates access and error logs.

  • Instance security group – An Amazon EC2 security group configured to allow inbound traffic on port 80. This resource lets HTTP traffic from the load balancer reach the EC2 instance running your web app. By default, traffic isn't allowed on other ports.

  • Load balancer – An Elastic Load Balancing load balancer configured to distribute requests to the instances running your application. A load balancer also eliminates the need to expose your instances directly to the internet.

  • Load balancer security group – An Amazon EC2 security group configured to allow inbound traffic on port 80. This resource lets HTTP traffic from the internet reach the load balancer. By default, traffic isn't allowed on other ports.

  • Auto Scaling group – An Auto Scaling group configured to replace an instance if it is terminated or becomes unavailable.

  • Amazon S3 bucket – A storage location for your source code, logs, and other artifacts that are created when you use Elastic Beanstalk.

  • Amazon CloudWatch alarms – Two CloudWatch alarms that monitor the load on the instances in your environment and that are triggered if the load is too high or too low. When an alarm is triggered, your Auto Scaling group scales up or down in response.

  • AWS CloudFormation stack – Elastic Beanstalk uses AWS CloudFormation to launch the resources in your environment and propagate configuration changes. The resources are defined in a template that you can view in the AWS CloudFormation console.

  • Domain name – A domain name that routes to your web app in the form subdomain.region.elasticbeanstalk.com.

All of these resources are managed by Elastic Beanstalk. When you terminate your environment, Elastic Beanstalk terminates all the resources that it contains.

Note

The Amazon S3 bucket that Elastic Beanstalk creates is shared between environments and isn't deleted during environment termination. For more information, see Using Elastic Beanstalk with Amazon S3.

Cleanup

When you finish working with Elastic Beanstalk, you can terminate your environment. Elastic Beanstalk terminates all AWS resources associated with your environment, such as Amazon EC2 instancesdatabase instancesload balancers, security groups, and alarms.

To terminate your Elastic Beanstalk environment
  1. Open the Elastic Beanstalk console, and in the Regions list, select your AWS Region.

  2. In the navigation pane, choose Environments, and then choose the name of your environment from the list.

    Note

    If you have many environments, use the search bar to filter the environment list.

  3. Choose Actions, and then choose Terminate environment.

  4. Use the on-screen dialog box to confirm environment termination.

With Elastic Beanstalk, you can easily create a new environment for your application at any time.

Next steps

As you continue to develop your application, you'll probably want to manage environments and deploy your application without manually creating a .zip file and uploading it to the Elastic Beanstalk console. The Elastic Beanstalk Command Line Interface (EB CLI) provides easy-to-use commands for creating, configuring, and deploying applications to Elastic Beanstalk environments from the command line.

If you use Visual Studio to develop your application, you can also use the AWS Toolkit for Visual Studio to deploy changed, manage your Elastic Beanstalk environments, and manage other AWS resources. See The AWS Toolkit for Visual Studio for more information.

For developing and testing, you might want to use the Elastic Beanstalk functionality for adding a managed DB instance directly to your environment. For instructions on setting up a database inside your environment, see Adding a database to your Elastic Beanstalk environment.

Finally, if you plan to use your application in a production environment, configure a custom domain name for your environment and enable HTTPS for secure connections.

Popular Posts