Microsoft Workloads on AWS

Running your modern CoreWCF application on AWS

In this blog post, we will show you how to deploy a CoreWCF application on an Amazon Linux Graviton2 instance. Also, we will provide a sample application that integrates with Amazon CloudWatch. This approach of running CoreWCF applications on Linux and integration with other AWS services gives customers the ability to improve performance, increase security, and reduce license spend on Microsoft Windows Server.

Introduction

AWS has been one of the key contributors to the CoreWCF community project, which was announced in June 2019. The blog post “Supporting development of CoreWCF” provides more details about the AWS partnership with Microsoft for this initiative.

The target audience for the CoreWCF project is the customers who have been using WCF on .NET Framework and require WCF support in .NET Core to aid in modernizing their applications. The target use of CoreWCF is to simplify updating server and client applications that rely heavily on WCF and SOAP. In our previous blog post, we outlined the steps to convert an existing WCF application to CoreWCF using the Porting Assistant for .NET tool. In this post, we outline the steps to deploy the CoreWCF application on Amazon Linux and integrate it with AWS services such as CloudWatch. You may use a similar approach to integrate your application with other AWS services, such as Amazon Simple Storage Service (Amazon S3), Amazon Simple Queue Service (SQS), etc.

Prerequisites

You will need two machines, i.e. developer and deployment machines, to develop and deploy the steps outlined in the walkthrough section.

Developer machine configuration:

  • Amazon Elastic Compute Cloud (Amazon EC2) Windows instance with Visual Studio 2022 installed
  • An AWS Identity and Access Management (IAM) role with permissions to write to Amazon CloudWatch assigned to an Amazon EC2 instance
  • AWS account and profile set up
  • Sample application downloaded from AWS_Samples GitHub repo
  • WinSCP application

Deployment machine configuration:

Walkthrough

In the CoreWCF, data and service contracts are defined and implemented in the same ways as in WCF. The major difference is in the host’s definition, which is now based on ASP.NET Core, and in how to expose the CoreWCF service. The sample code is based on .NET 6, but the same steps apply to other versions of .NET.

Step 1: Verify existing service endpoints

Let us first test the WCF application using the following steps:

  1. Browse to the location where you downloaded the sample code. Open the WCFSelfHost solution file of the sample application in Visual Studio. The file is in the root folder of the sample application. The solution file contains three Visual Studio projects.
  2. Build the solution file to verify it compiles successfully.
  3. Run the WCFTCPSelfHost project to start the console application. The service will start on the following URL: http://localhost:8443 . For this sample, we define this information in the program.cs file. However, we also have an option to define the base address in the configuration file.
  4. Binding information is defined in the corewcf_ported.config file. We are using a relative path to load the configuration file, as specifying the absolute path will not work on Linux. We define the code to load the configuration file in startup.cs
<endpoint address="basicHttp" binding="basicHttpBinding" name="Basic"  contract="WcfServiceLibrary.IService,WcfServiceLibrary" /> 

Figure 1: Binding information defined in corewcf_ported.config entry

public void ConfigureServices(IServiceCollection services)
 {
    string pathToXml = @"corewcf_ported.config";
    services.AddServiceModelServices();
    services.AddServiceModelConfigurationManagerFile(pathToXml);
    services.AddServiceModelServices()
    .AddServiceModelMetadata();
  }

Figure 2: Load config file and add service metadata statements

In the sample application, we have configured Kestrel to listen to multiple addresses. This information is defined in the Program.cs file. Port number (8443) is hard-coded in the example above, but it doesn’t have to be — you can bind to an IConfiguration instead and store port information in the configuration file.

  1. Run the WcfClient It connects to the service endpoint and invokes two operations defined in the service: GetDataAsync and GetDataUsingDataContract.
  2. You can validate the Web Services Discovery Language (WSDL) by accessing the following URL locally: http://localhost:8443/basicHttp?wsdl.

Figure 3: WCFTCPSelfHost application console

Step 2: Adding Amazon CloudWatch Support

Amazon CloudWatch is a management tool in AWS that allows you to monitor resources hosted on AWS and elsewhere. In this section, we are going to look at how you can integrate the CoreWCF service with AWS services like Amazon CloudWatch. A similar approach can be used to integrate with other AWS services like Amazon S3, SQS, etc.

Open the NuGet package manager console in Visual Studio. The first step is to install the AWSSDK.CloudWatchLogs NuGet package. This will allow you to make calls to the Amazon CloudWatch service from a .NET application programmatically using an AWS-provided SDK. You can install this package using the NuGet package manager, as shown in Figure 4:

Figure 4: Install AWSSDK.CloudWatch.Logs NuGet package

You will encapsulate your logging logic in a single Logging class called CloudWatchLogger. This will make your logging logic clean and keep it out of your application code.

Step 3: Deploy CoreWCF to Amazon Linux

Amazon Linux 2 is the next-generation Amazon Linux operating system that provides modern application environment with the latest enhancements from the Linux community and offers long-term support.

In this section, you will deploy the application on Amazon Linux 2 (i.e. deployment machine).

Step 3a: Publish your .NET Core application

You need to create an application source bundle that contains your published artifacts. Perform the following steps to generate artifacts:

  1. Right-click on the WCFTcpSelfHost project in Visual Studio.
  2. Click on publish.
  3. Create a new publish profile, e.g. development, and browse to the folder where you want to publish your project dll.
  4. Click on publish so it will create your dll in the folder.

You can also use a command line, shown in Figure 5, to build a self-contained application.

dotnet publish -c Release -r linux-x64 --self-contained=true -p:PublishSingleFile=true -p:GenerateRuntimeConfigurationFiles=true -o artifacts 

Figure 5: Publish dotnet application from the command line

Now, let’s connect to your Amazon EC2 instance. You will use the WinSCP tool you installed on the developer machine in the prerequisite section. If needed, refer to the following guide that defines the steps to connect to an Amazon EC2 instance using WinSCP.

Open a new terminal window and create a new directory on the deployment Amazon EC2 instance. This directory will be used to deploy your code into. You will also need to change directory permissions to give write access.

sudo mkdir /var/dotnetexamples/corewcf chmod 777 /var/dotnetexamples/corewcf

The next step is to transfer the application artifacts package.

Figure 6: Transfer application package through WinSCP

Once the files are transferred, you can execute the following command within the published folder from the PuTTY client:

Dotnet WCFTCPSelfHost.dll

This will start the CoreWCF application on Linux.

Step 3b: Running your application as a service

To allow the application to run in background, you can use Systemd. Systemd uses service unit configuration files to configure services.

First, create a service file for your web application.

[Unit]
Description=CoreWCFApplication 

[Service]
Type=notify
ExecStart=/usr/sbin/WCFSelfHost  

[Install]
WantedBy=multi-user.target

Figure 7: Service file to run CoreWCF application in background

This file needs to exist in the /etc/systemd/system/ directory; in our example, the file would be in this location /etc/systemd/system/corewcfapp.service. Once the file exists in the directory, run the following command for systemd to load the new configuration file:

sudo systemctl daemon-reload

To start the service, run the following command:

sudo systemctl start corewcfapp.service

Step 3c: Invoke your client code

You can run the client code on your developer machine. You will need to change the service address in the client code to point to the service running on the Amazon Linux instance (i.e. deployment machine). In the sample app, we define the endpoint address in GetEndpointAddress method in the Reference.cs file. However, this information can be abstracted out and stored in a configuration file for production applications.

At this point, you can validate the application by accessing WSDL from the client machine. To execute service operations, you will need to modify the security group and open the port (e.g., 8443) to allow access from the machine that is running the CoreWCF client. You should be able to see the result on the client, as shown in Figure 9.

Figure 8: Output of WcfTcpClient project

After you execute the operations, you will see entries in the Amazon CloudWatch console. You will see a new log group (/dotnet/corewcfdemo ) created in the Amazon CloudWatch console, as shown in Figure 10.

Figure 9: CloudWatch log groups showing the log stream from CoreWCF service running on Linux

Cleanup

To avoid ongoing charges for resources you created to complete this tutorial, you should:

  • Terminate Amazon EC2 instances
  • Delete Amazon CloudWatch log group

You can use the AWS CLI, Amazon EC2, or the AWS APIs to perform the cleanup.

Conclusion

In this blog post, we demonstrated how to launch a CoreWCF application on Amazon Linux after being converted to .NET Core. We also ran the ported code on Amazon Linux Graviton instances and showed how the interaction with Amazon CloudWatch worked.

Read the .NET blog post “Supporting the community with WCF OSS projects” to learn more about the roadmap for CoreWCF projects. Refer to the CoreWCF GitHub repo for issues, discussion threads, and feature requests If you need support with modernizing your legacy WCF application using Porting Assistant for .NET, contact us at aws-porting-assistant-support@amazon.com.

Ashish Bhatia

Ashish Bhatia

Ashish Bhatia is a Senior Solutions Architect at AWS with a special focus on Microsoft technologies such as .NET and SQL Server on AWS. He is passionate about helping customers build modern software solutions using AWS cloud native services. In his 20-year professional career, he has worked with large enterprises and build software products .NET, C#, SQL Server and cloud platforms such as Azure and AWS.

Jagadeesh Chitikesi

Jagadeesh Chitikesi

Jagadeesh is a Sr. Microsoft Specialist Solutions Architect at AWS. He worked as a developer and an architect with enterprises of all sizes across healthcare, finance, retail, utility, and government for the last 20 years. He is passionate about cloud and all the innovation happening at AWS.