19. March 2017 12:57
by Aaron Medacco
0 Comments

Renaming Your SQL Server Databases on AWS RDS

19. March 2017 12:57 by Aaron Medacco | 0 Comments

Last night, I was converting the data source for this blog from using local files to using databases managed in AWS RDS. Somewhere along the way I decided I wanted to rename one of the databases, but found I couldn't just right click and rename it thru SQL Server Management Studio. Running the sp_renamedb system stored procedure or the ALTER DATABASE command didn't work either. 

Rename RDS Database

After doing some investigation, it looks like RDS went several years without allowing you to do this. And while you still can't use any of these methods to do a database rename, they have since added a way with a custom stored procedure:

EXEC rdsadmin.dbo.rds_modify_db_name N'<OldName>', N'<NewName>'

There are some additional steps required if you are using Multi-AZ with Mirroring Deployment. You can find Amazon's documentation for this here.

Typically, I feel the AWS documentation is pretty clear and thorough, but I think a lot of users will end up on this page, scroll down to "Limits for Microsoft SQL Server DB Instances", read:

You can't rename databases on a DB instance in a SQL Server Multi-AZ with Mirroring deployment.

and conclude that they are in fact, screwed, when this isn't the case. Just took a little more digging than usual.

Cheers!

13. March 2017 01:01
by Aaron Medacco
1 Comments

What Happens When Your Lambda Functions Execute in an Infinite Loop?

13. March 2017 01:01 by Aaron Medacco | 1 Comments

Amazon Web Services' serverless compute product, Lambda, is an event-driven service that executes code without requiring the customer to manage servers. It can be triggered in response to a variety of different events or manually triggered via the AWS CLI, Shell tools, SDKs, and web console. Lambda functions can do just about anything within your AWS environment, given the appropriately configured IAM role.

So what happens if you architect (or misarchitect) a solution where your Lambda functions execute more than you anticipated? What if your Lambda functions are written so that they call themselves or other Lambda functions where, given a limitless infrastructure to facilitate, execution should logically never stop?

While the AWS platform is not actually limitless, you certainly can rack up a massive amount of compute if you're not careful. Given the pricing model of Lambda, that massive compute will become a massive bill that punching the developer who wrote the functions won't pay for.

Note: There are cases where recursive Lambda invocations are intentional and do solve problems. This post addresses concern where infinite looping is unintentional.

AWS Lambda Infinite Loop

For new and old AWS accounts that have never requested a limit increase, the maximum number of concurrent executions across all your Lambda functions in a region is restricted to 100. Apparently, Amazon has thought of this scenario, and implemented some safety rules to prevent customers from coding themselves into a real problem.

"The default limit is a safety limit that protects you from costs due to potential runaway or recursive functions during initial development and testing."

You can find Amazon's documentation on Concurrent Exections w/ Lambda here.

However, I decided to try it out myself, anyways. I did this by writing a small Lambda function which invoked itself:

var AWS = require("aws-sdk");

exports.handler = (event, context, callback) => {
    var lambda = new AWS.Lambda();
    var params = {
        FunctionName: "Infinite_Lambda_Loop",
        InvocationType: "Event",
    };
    lambda.invoke(params, function(err, data){
        if (err) {
            console.log(err, err.stack);
        }
        else {
            console.log(data);
        }
    })
};

I used a timeout of 3 seconds and the minumum value for memory (128 MB) in all of my trials. I ran each trial in a separate region to get a clean graphing dashboard from Lambda. Therefore, I am assuming that Lambda performs similarly across all regions.

Here are my Lambda statistics as seen in my dashboard after running my function in Ohio after 60 seconds:

Lambda Invocations

In Northern California for 120 seconds (separate trial):

Lambda Invocations 2

In Oregon for 300 seconds (separate trial):

Lambda Invocations 3

I found that the only way to end the madness was to delete the function. If anybody else knows a different way, leave a comment.

After validating the values in my graphs with those found in CloudWatch, my data is as follows:

Region Seconds Invocations Duration (ms) Memory / Execution (MB)
Ohio 60 573 41,731 128
N. California 120 1,523 68,907 128
Oregon 300 3,021 190,985 128

Curiously, the count of invocations and duration change was not exactly linear, but from this data we can estimate that about 3,000 executions take place during 5 minutes of a very simple Lambda function executing itself forever. Again, this assumes that Lambda performance is uniform across regions. If we calculate our estimated cost for this, we get:

3,000 * $0.0000002 / request = $0.00006 Lambda cost for requests.

Price per 100ms with 128 MB = $0.000000208, so 1,910 * $0.000000208 = $0.00039728 Lambda cost for duration.

$0.00006 + $0.00039728 = $0.00045728 cost for my infinite loop executing for 5 minutes.

$0.00045728 * 288 ~ $0.13 cost for my infinite loop executing for 1 day.

$0.13 * 7 ~ $0.91 cost for my infinite loop executing for 1 week.

$0.13 * 30 ~ $3.90 cost for my infinite loop executing for 1 month.

These costs do not reflect any savings gained by Lambda free tier discounts. Information about reducing costs per the free tier can be found here.

Therefore, I think it's safe to say you won't kill the budget with an accidental infinite loop (assuming your concurrency limit is the default 100).

Keep in mind I've made assumptions in my analysis of this data. Additionally, the pricing of AWS products changes frequently, and cost estimation for this scenario was done using Lambda pricing at the time of writing.

Cheers!

11. March 2017 12:45
by Aaron Medacco
0 Comments

Hosting a Serverless Website on Amazon Web Services

11. March 2017 12:45 by Aaron Medacco | 0 Comments

As cloud providers such as AWS keep growing their customer base and offering new services, there has been a rising interest in adopting serverless code execution models. Make no mistake, "serverless" isn't just a buzzword. The benefits of adopting such a model are real and substantial implemented under the appropriate circumstances. 

In this post, I'll provide a simple architecture available on Amazon Web Services that is both serverless and fulfills a common need: hosting a website. Below, you can see the bird's eye view of how Amazon's services can come together to deliver this.

Understand that I may use "website" and "web application" interchangeably in this post.

AWS Serverless Website

A traditional web application can be broken down into the following components: front-end (styling, behavior and structure of the interface), back-end (business logic and object management), and data (the database, it's schema, the indexes, etc.) These segments of what comprise a web application are easily mapped to the services used to create a serverless website on Amazon Web Services.

Hosting a Static Site in S3 (Front-End)

This is where you serve the files that make up your website's front-end. HTML, CSS, and Javascript among just about anything else can be stored and served from S3. You simply create a bucket with the name of your domain, upload your static files, enable public access, and flip the switch to enable static website hosting. When updates need to be made, you can manage the bucket contents like you would a file structure.

Writing Your Code with Lambda (Back-End)

Since were not deploying push packages to servers or virtual machines, we'll manage our code with Lambda.

With AWS Lambda, you can write code in one of a variety of different languages and perform the same operations and business logic a traditional back-end would. There are a number of benefits that come as a result of this.

First, no management. You no longer need to manage the servers where the code is living. No installing operating systems, performing updates, setting up drives, etc.

Second, scalability. As your website receives more traffic, you don't need to bother provisioning additional infrastructure to service the increasing number of requests. Lambda will use Amazon's infrastrucutre (which is a lot) to handle your load. While there are soft limits to the number of Lambda functions that can run concurrently on an AWS account, this number can be increased as needed by contacting AWS support.

Third, high availability. Your serverless Lambda code does indeed still run on servers, but not those you might otherwise provision yourself. Lambda might execute from any machine living in any one of several data centers maintained by Amazon. Therefore, your code will continue running as long as the Lambda service is online and won't go down when a bonehead developer elects to shutdown an instance rather than disconnecting.

Fourth, cost. The pricing model for Lambda, like most AWS services, is based on usage. You are charged for the number of requests made to each Lambda function plus the time and memory your code allocates to complete it's execution. The detailed pricing model can be found here. Obviously, there are going to be cases when Lambda is not cheaper than hosting an application on EC2 instances. However, there are also situations where usage for the month will be below the free tier, in which case your serverless compute is completely free. 

Storing Your Data with RDS or DynamoDB (Data)

You have options when it comes to storing your website's data on AWS. For an website expecting to perform several OLTP operations and where join operations will be common, RDS is the obvious choice. For sites that require lookups but don't require joins or SQL querying, DynamoDB provides an alternative. Regardless, both services are managed for you. And while RDS does involve choosing a class of server to run your database, Amazon takes over the server ops. Both services can be configured to be scalable and highly available.

You could also manage your own database on an EC2 instance, which is appropriate in some cases, but not a serverless solution to storing your data.

Exposing Your Functionality via API Gateway

API Gateway is the glue that connects the interface of your application with the code you write in Lambda. The functions you write with Lambda can serve as the backing to endpoints you define in API Gateway. Therefore, AJAX functionality served from the Javascript files in your website's S3 bucket can make calls to your API's endpoints to perform back-end functions handled by your Lambda code. 

Conclusion

It's worth mentioning that all the available options for implementing a cloud-based solution should be considered before marrying yourself to any one path. Just because serverless is the new Kool-Aid, does not mean it is the best route in all cases. Very often it's the case that both traditional and serverless computing are combined to arrive at the best result.

Additionally, many websites require additional features such as data transformation, sending notifications, etc. which I haven't included for brevity. Lambda in conjunction with other services provided by Amazon can be combined to achieve these, too.

Cheers!

9. March 2017 17:42
by Aaron Medacco
0 Comments

Attaching AWS IAM Roles to Existing EC2 Instances

9. March 2017 17:42 by Aaron Medacco | 0 Comments

Amazon recently announced functionality that would allow IAM roles to be attached to existing EC2 instances. IAM roles grant access to instances or services by allowing them to interact with resources in your AWS environment.

Previous to this announcement, if you wanted to assign permissions via an IAM role to an EC2 instance, you needed to attach that role to the instance during creation. Adding roles to existing EC2 instances was not possible. You could, however, create an image (AMI) of the existing instance, provision another instance using the AMI, and assign the role to the copy instance in order to achieve the effect.

Attach IAM Role Existing EC2

I won't include a tutorial for how to attach roles to existing instances since Amazon has already done so utilizing both the AWS CLI (here) and using the web console (here).

The announcement doesn't surprise me since not having this flexibility affected a lot of cloud users and AWS constantly reinforces that the features they prioritize are those asked for most by their customers. Exciting to see what else is in store this year.

Cheers!

5. March 2017 16:01
by Aaron Medacco
0 Comments

Configuring AWS to Send Monthly Invoices to Another Email

5. March 2017 16:01 by Aaron Medacco | 0 Comments

Sometimes you want to be able to have your Amazon Web Services invoices sent to somebody else to manage. This might be a personal assistant, your accounting department, etc. After all, nobody wants to keep forwarding emails all the time to the appropriate people.

You could create a user for your accountant and grant them access to the billing side of AWS. However, if all they need to do is see the bills, it's more secure to just have invoices sent to their email. If their email gets compromised, the damage that can be done is less than that of a compromised AWS user. Plus, you can always re-configure your account to stop the invoice emails or modify the email they're sent to.

AWS Invoices By Email

Setting this up on AWS it's not as obvious as it could be. For something relatively simple, it's actually split into two settings within account management in the web console.

Assuming you are already logged in with the account owner, here are the steps:

Enabling invoice by email:

  1. Navigate to "My Account" via the top toolbar.
  2. Select "Preferences" in the sidebar.
  3. Check the box to "Receive PDF Invoice By Email".
    Invoice By Email 1
  4. Click "Save preferences".

Selecting another email to receive invoices:

  1. Navigate back to the index page of My Account via the top toolbar.
  2. Scroll down to "Alternate Contacts".
    Invoice By Email 2
  3. Click "Edit" and fill in the information for who will receive the invoice under the Billing section.
  4. Click "Update".

At the time of this writing, I'm unaware of a method for sending invoices to multiple separate emails. However, you could setup an email group and set the billing contact to the email group to achieve that.

Cheers!

Copyright © 2016-2017 Aaron Medacco