This post was going to be about System Initiative, a “Lego for deployment” service that I looked at last July and which has recently gone public. But I noticed that their demo seems to be tightly wrapped around an Amazon Web Services (AWS) API. However, I didn’t want to rejoin AWS right now, as it takes quite a lot of information and tends to produce unpredictable billing. Eventually System Initiative will have a deeper emulation with Digital Ocean or a simpler provider, but for now I wanted a local emulation of AWS.
Enter LocalStack. This service provides a drop-in replacement for AWS. LocalStack’s mission is quite simple: emulate AWS API functionality. Now, obviously AWS has countless services, but we know that only a handful are used in general.
First of all I signed up to LocalStack with my GitHub account. I asked for a “hobby license,” although later I discovered this wasn’t even necessary (more on that shortly).
I then followed the getting started link.
I’m going to be using my trusty MacBook, so I will use a brew tap for installation:
brew install localstack/tap/localstack-cli
I was then given an auth token. It was on my page, so I am assuming it was autogenerated for my account:
export LOCALSTACK_AUTH_TOKEN="ls-....947"
I was then invited to set test environment variables:
export AWS_ACCESS_KEY_ID="test" export AWS_SECRET_ACCESS_KEY="test" export AWS_DEFAULT_REGION="us-east-1"
I started up, but was then curtly reminded to turn on Docker. If the documentation doesn’t make this clear, it nevertheless should be; LocalStack functions as a local “mini-cloud” operating system that runs inside a Docker container. As it happens, there are different images that reflect the services you can use. I will use the LocalStack Community Image, which is the free offering that doesn’t need an API key. As a paying customer, you can use the LocalStack Pro image.
After I switched on Docker desktop, and updated to 4.35.1, things progressed smoothly:
OK, now we can check to see what we have, before we try to use it.
Looking inside Docker Desktop we have this image:
…and this container:
Ok, let’s try to hit it in another terminal or tab, with the example instruction:
aws s3 mb s3://my-first-bucket --endpoint-url=http://localhost:4566
That endpoint port is hopefully active in the container. The instruction is the standard one that tells an AWS service to make an S3 bucket. I think “mb” stands for… make bucket. There is an available tool (“awslocal”) which adds that lengthy endpoint reference automatically, but for clarity I’ll stick to the full command.
The LocalStack log running in the original shell more or less agrees with this result:
That’s fine. We had better check that we can place something in it.
Make a quick test file and then move it into the bucket. First we make the file:
…then toss it in the bucket:
A quick contents check reveals the file:
Note that the “27” corresponds to the “27B” response when we created the file.
Our reason for using LocalStack was to check System Initiative, so we will need to create other AWS components. Obviously a service like LocalStack is not going to give you the whole of AWS in a box. I’m not even sure Amazon could recreate AWS if it started from scratch today. So before you work with LocalStack, you need to understand what it fully emulates and what it merely responds to statically (which it refers to as CRUD) and probably with dummy data. And of course, some services are only available to Pro customers. Check out the feature coverage page.
The most relevant service to most users is obviously EC2, and you can look at how features are covered against that here. Kicking the tyres on this, I started doing some of the things we know we’d normally need to do to work on an EC2. For instance, create a key pair for access:
(To use the complete key.pem file, we would also have to change permissions on it.)
Before we start an instance, we normally have to punch holes through it so that we can get information in and out. We do that by adding rules to security groups. LocalStack only supports the default group:
The response, in JSON, confirms the ingress change:
I’ll stop my kicking there, to avoid the detail on running an EC2 instance, though I will revisit this again when looking at System Initiative.
Naturally some things operate differently. AWS works across demarcated geographical regions, for physical and legal reasons. AWS uses separate API endpoints for each region, and usually resources can only be accessed from within the same region.
On the other hand, LocalStack — the clue is in the name — operates on one API endpoint, allowing interactions with services across defined regions. This is probably a boon for most use cases, but clearly would cause failures in some security tests.
Conclusion
This is a service that had to exist just for convenient testing against a live AWS service, and fortunately it does. As a product, it should be safe from predation by Amazon, as Amazon wants to encourage the idea that using a public remote server is normal — they don’t want to associate “local” with greater convenience.
Regardless, if you use LocalStack, just make sure it emulates or reflects the methods you need — and away you go.
The post Introduction to LocalStack, a Drop-In Replacement for AWS appeared first on The New Stack.
Leave a Reply