Last month I wrote a new post, namely: Building a simple, resilient, cheap network service with AWS. Now that AWS’ billing cycle for November is complete we can ask ourselves how cheap was that “cheap” in the article, and give an answer. The cost is not exact to the cent, due to the presence of a a stopped instance I am keeping around, but will still be good enough.
To summarise, the article described how to set up a service on spot instances, thus saving on the EC2 cost. We want to understand if we really saved money, and if there are opportunities to save even more. If you haven’t read the previous post, it’s probably a good time to do it now. If you did, let’s go and check the bill.
The service has been running from November 10th, billing 2,40-2,70 USD per day (approx). The total expense for November was 70.17 USD of which:
- 52.42 USD for EC2
- 3.70 USD for CloudWatch
- 0.01 USD for data transfer
- 14.04 USD for Value Added Tax
Notice how we haven’t spent a dime on the EFS usage, which is understandable: the amount of data we have put into it is negligible (it’s a copy of CFEngine’s masterfiles). The biggest of the cost is in EC2, so let’s break it down:
- 12.85 USD go for the ELB usage;
- 23.35 USD go for the NAT gateway;
- 6.56 USD go for the on-demand EC2 instances (reminder: we have two around: my stopped instance and the running “deployer node”; however when an instance is stopped you only pay for the storage, so this cost is just for the deployer node);
- 5.82 USD go for spot EC2 instances (we have three of them always running thanks to autoscaling);
- 3.84 USD for storage (of which 3.56 for provisioned storage, which is all we care about here).
Two facts catch my eye here. The first, three spot instances cost less than a single one on-demand. The second, the NAT gateway takes the biggest share. The third, the cost for the ELB is more than twice the cost of the spot instances. Now, are there any opportunities to save money? I’ll list a few, not without specifying that some of them are definitely not recommendable.
Option 1: replace the NAT gateway
Using AWS’ managed NAT gateway is very convenient, but also expensive. We could probably save nice bucks if we could do without it, for example configuring a NAT service on board of the deployer node. You save money, but you have the added burden of managing the service on your own: how much that’s convenient depends on the implementer.
Option 2: place the spot instances on a public network and remove the NAT gateway
This is definitely not recommended!!! You could have a public network and place the “workers” there, protecting them with security groups and/or network ACLs, so that they have direct access to the Internet and you don’t need a NAT gateway. This could turn out to be risky if you mess up with security groups and ACLs, and anyway: if something is not meant to be public, then you should not put it on a public subnet. However, if you like living on the edge or your instance don’t have any sensitive or important data on them, you may decide that the risk/benefit ratio is favourable. You choose your own poison.
Option 3: you give up on resiliency and availability, and only have one spot instance at a time, without the ELB in front
This is definitely not recommended and, in addition, defies the goal of the previous post completely, so… why? But just mentioning, in case you can afford being neither resilient nor available for some time (at least the time required by an autoscaling group to rebuild an instance for your service). The solution is then to save on both the ELB and the NAT gateway, and having a single spot instance directly exposed on the internet, using an Elastic IP to guarantee that the service doesn’t constantly change address. You may save a lot of money in your AWS bill, but you are giving up a lot of reliability. Besides, the solution itself becomes more complicated, as you’ll have to ensure the extra layer of security provided by an ELB at the front-end, and make sure that you engineer the solution so that the elastic IP is kept attached to a new instance when it replaces an old one. Again, you may be saving on one side, and making things more difficult to maintain on the other.
Option 4: do without the deployer node
With this, you’d be saving on the cost of the on-demand EC2 instance, which in this case would halve the instance costs, more or less, so it’s not that you’re saving so much in this case. This could be risky in some cases (see the previous article), but could still be OK depending on the case you have at hand. Or you can check how much it would cost to access your EFS filesystems from your on-premise systems. I haven’t run the calculations, but I suspect that it’s not going to be that cheap, unless you can leverage some scale and get rid of deployer nodes for many, many services.
As it often happens with cloud services, it’s a matter of balancing cost and convenience. The right balance depends on the case at hand and there is no recipe that is right or wrong. However, if not wrong, some of them are definitely not recommendable at all and you should think more than twice before going for them. Good luck!