Oct 15, 2019 11:07AM
Welcome back to my lift and shift series. This is part two of a series started here documenting my personal journey lifting an
ASP.Net application to the AWS cloud via Elastic Beanstalk. This post will focus on preparing the legacy application for deployment in an AWS based environment.
Let’s set the stage, we are looking to prove viability of lifting this solution to the cloud. We are not looking to correct sins of the past or refactor major portions of the application. Again the minimum viable solution is what we are seeking. Here is a collection of problems and solutions we had to address (your application will obviously vary):
1) Configuration of secrets
I have never personally been a fan of the
web.configformat used by IIS for configuring application secrets. Environment variables are better, however there is still a very real risk of secrets being compromised on the application server. So what do we do to protect our secrets from malicious actors and ultimately to keep these values out of source control? There are a few potential solutions to this problem in AWS such as AWS Secrets Manager and SSM Parameter Store which can both be backed by AWS KMS for encryption. So how does one choose what service to go with? It comes down to two factors features and cost. AWS Secrets Manager supports more robust use cases than SSM Parameter Store including the following:
- Password generation
- Secrets rotation
- Cross account access
Not surprisingly with these added capabilities cost is the second factor. As of writing it costs approximately $0.40 USD per secret stored each month. In addition, an additional $0.05 USD per month is charged for each batch of 10,000 API calls to interact with the secrets. SSM Parameter store incurs no additional charages for standard parameters and $0.05 USD per advanced parameters stored in a month. API interactions are billed at no additional charge for standard and $0.05 USD per 10,000 API interactions in higher throughput scenarios. Advanced parameters regardless of throughput are billed at the same rate as standard API high throughput interactions are.
Solution: SSM Parameter Store, it is cheaper and a lot of our dependencies for the application will remain on-premises. Therefore, a lot of secrets cannot be rotated/generated for these resources. This did require some code updates but they were fairly minimal.
2) Security/Sign-in Concerns
Our application will exist in a hybrid state between the cloud and on-premises. At this time it does not make sense to lift and shift our application database or any other internal API dependencies. So luckily/unluckily the application will be able to utilize AWS Direct Connect to reach into our organization’s network and connect to these dependencies, including the forms authentication user store for sign-in.
AWS Direct Connect setup is beyond the scope of this article and is not typically managed by the development team, so we will assume availability of this connection by using an already “wired-up” VPC. DNS routing was also an issue for us and had to be setup with Unbounded DNS to resolve our database and internal URLs (with fully-qualified names), however it was replaced with a managed offering through the course of this effort AWS Route 53 Resolver. With this networking activity out of the way, we ran into our first road block Microsoft Active Directory (AD).
Some of our internal APIs were secured via Windows Authentication and called via AppPool usernames in IIS. While it is certainly possible to extend your AD environment into the cloud with AWS Directory Service and the AD Connector, it is not the most cost-effective approach. In addition, the general recommendations from Microsoft are not to use this method for securing APIs, so there was little motivation to continue the bad practices moving forward. We also had integrated authentication using AD users for SQL server sign-in, so this had to be addressed.
Solution: Update APIs (code changes) to Open ID Connect client-credentials security. Not only is this a more universally accepted security method for APIs, it is supported by a lot of different vendors including Auth0, Azure AD and in AWS Amazon Cognito. Luckily in
ASP.Net there are standard middleware components and nuget pacakges available to make this job easy as pie. We also transitioned from integrated SQL Server authentication to SQL Server users, and thus broke the AD dependency.
3) Update Packaged Dependencies (Nuget/NPM etc.) (Optional, but highly advisable!)
Spend some time updating your nuget packages and NPM dependencies. You are lifting this application to a public cloud platform (albeit with restrictions to accessibility), we want to ensure known security vulnerabilities are taken care of.
Solution: Just do it, seriously!
This seems like a great place to end this particular post. With all this initial legwork out of the way, and hopefully some analysis you did in part one from the hello world example, we can begin to make rubber meet the road and start setting up our application in AWS. As a teaser, we will talk about HIPAA compliance, which affects my current employer and how to make a seemingly non-HIPAA compliant service, compliant. Stay tuned!