Deploy Angular App in AWS S3 and .Net Core API in Lambda (server-less)

Thanks to all you for sending congratulatory notes on my attainment of Azure Solutions Architect certification. Cloud is a commodity and we need not to stick to one provider though it sometimes make sense to stay with certain vendor for long. In this blog post, I would try to demo how easy it is to deploy applications in AWS cloud.

What comes first – data or application? What comes first – design or requirements? We are going to start with high level requirements and design a solution to meet the requirements. Requirements –

  • Minimize the cost where possible without sacrificing the security.
  • Deliver user interface app close users and app must follow responsive design.
  • Backend API would run in server-less compute. Pay for what you use and no need to worry about maintaining underlying infrastructure.
  • Data must be secure in transit and at rest.
  • Capture logs for monitoring and troubleshooting.

High level design:

Solution Design

AWS services and Tools used to meet our requirements-

  • Visual Studio Enterprise 2019 IDE for app development
  • Angular 9.1.12 for building responsive UI application
  • .Net Core v3.1 for building API application
  • AWS S3 + AWS CloudFront to deploy UI application
  • AWS Lambda + AWS Api Gateway + AWS CloudFront to deliver API application with support for CORS
  • GoDaddy for domain registrar (can’t use of Route 53)
  • Draw.io for creating design diagrams

Build and Deploy UI Application

We are going to use the same Angular codebase that is used to build Tools at Aspnet4you (currently deployed in Azure). We just change the api endpoint to AWS. So simple, just run “ng build –prod” and copy the output of dist folder to S3!

 $bucketName = 'whois-aws.aspnet4you.com'
 echo s3://$($bucketName)
 #Create an AWS S3 bucket
 aws s3 mb s3://$($bucketName) --region=us-east-1
 #List buckets, verify bucket is created
 aws s3api list-buckets
 #Configure AWS S3 bucket for static web hosting
 aws s3 website s3://$($bucketName) --index-document index.html --error-document index.html
# Copy angular app to S3
aws s3 sync dist/tools-aspnet4you-app s3://$($bucketName)
# Clear the cache from CloudFront if you redeploy codes in S3
aws cloudfront create-invalidation --distribution-id E1LUDLX5FXY0QM --paths "/*"

When you copy javascript files to S3, the metadata type is set to text/html! That’s problem and Angular app will not render. You must set the metadata to application/javascript for all .js files in S3. For this exercise I have done it manually but you should automate it.

S3 Object Metadata for .js files

I named the S3 bucket same as my intended domain name. Plan was to create a CNAME at GoDaddy with the bucket website endpoint. It worked but it does not support HTTPS protocol which is one of our requirements. No blame to AWS, it clearly says so – Amazon S3 website endpoints do not support HTTPS. Other problem is, you have to make the S3 bucket public (read-only) which is not a security best practice. CloudFront is our rescue, CloudFront supports CNAME, SSL Certificate, Caching, WAF, etc. and of course, S3 origin with origin access identity. Here is a sample configuration at the CloudFront –

AWS CloudFront Configuration

Now that we have CloudFront domain name, we can go back to GoDaddy to add/update the CNAME (whois-aws.aspnet4you.com => d2gssfew19hjja.cloudfront.net). That’s all and we can access our angular app with custom domain over HTTPS protocol. Try it – whois-aws.aspnet4you.com!

Build and Deploy .Net Core API

If you have been using Visual Studio to build .Net Core application, it’s so easy to port your existing API application into AWS Lambda function. Download and install AWS Toolkit for Visual Studio to get started. Julie Lerman written couple nice articles on CODE Magazine and those articles can guide you step by step –

For me, I just added a new project to existing solution and published the api app to Lambda. AWS Toolkit did the heavy lifting by packaging, templating (Cloud Formation) and publishing to AWS. While this is good for learning and development, you want to have more control on production deployment and follow CI/CD. Toolkit will take care of creating necessary components – Lambda, Api Gateway, IAM Roles, IAM Policies, etc.

Publish AWS Server-less Application from VS

Visual Studio provides status right from Cloud Formation, nice!

Deployment Status in Visual Studio

Once deployment is done, you can add custom domain and add SSL certificate in ACM at the Api Gateway console –

Custom Domain at API Gateway

Be sure to create Edge optimized endpoint which will created a managed CloudFront distribution for you. You will need to configure api mappings as well.

API Mappings

At this point API can be accessed via CloudFront domain name but we will disable it (under api settings) so api is not accessible directly. We want api to be accessible via custom domain only.

Next step is to setup a CNAME at domain registrar (whoisapi-aws.aspnet4you.com => d2riou95ufaavr.cloudfront.net).

Okay, we should have our api ready! Give it a try, here! Yep, it works. :)-

Oh, wait! Api can be invoked standalone but our angular app is complaining about cross origin access (CORS). This is very common when web site and web api are deployed in two separate domains (sub domains precisely, in our case). I thought I could simply add CORS settings at the API Gateway but it didn’t work. I kept getting error message and I gave up when I saw this on aws documentation – “When applying the above instructions to the ANY method in a proxy integration, any applicable CORS headers will not be set. Instead, your backend must return the applicable CORS headers, such as Access-Control-Allow-Origin“. Wasted so much time for no reason! Azure is nice in this case, I could add CORS headers in Azure App Service so easily. Well, I need to go back to my code and add CORS.

Add CORS at application startup

Since we changed the code, we have to redeploy to Lambda. Redeploying the code will update lambda only and it would not impact/modify our settings in api gateway.

One final test to make sure angular UI app is working and it can seamlessly talk to backend API without CORS issue. While there, we want to verify the identity of the website by inspecting the SSL certificate. All looks good, happy AWS Cloud learning!

Leave a Reply