When developing applications that integrate with cloud services, I find it to be a more pleasant experience if I can raise, debug and destroy instances of these services locally as I build my application. In the case of Amazon S3, I might have a number of files I need to be moving around during development, and I don’t want to wait while transferring these files between my local machine and the cloud.
LocalStack to the rescue
LocalStack offers a number of Amazon APIs that can be brought up on your local machine. Importantly, it also comes in a container and so Amazon APIs on our local are only a
docker-composeaway. Here’s what it looks like:
docker-compose upon the above will bring the services (in this case just S3) up and if you browse to http://localhost:4566 you’ll get the following message, which means you’re ready to go:
Setting up a bucket
Now that LocalStack is running, we can use the AWS CLI tool to configure a bucket:
aws --endpoint-url=http://localhost:4566 s3 mb s3://my-bucket
aws --endpoint-url=http://localhost:4566 s3api put-bucket-acl --bucket my-bucket --acl public-read
aws --endpoint-url=http://localhost:4566 s3 cp ~/Desktop/some-image.jpg s3://my-bucket/image.jpg
The lines above create the bucket, set a
public-readACL on it so subsequently uploaded files will be accessible, and, the last line copies a file into the bucket.
At this point we can now pop http://localhost:4566/my-bucket/image.jpg into our browser and we should be able to see the image we uploaded. If we didn’t execute the second line, or, we executed it after uploading the file, browsing to that key will return HTTP Status Code 403 (Access Denied).
Integrating with .NET Core
With the service running and the bucket configured we’re ready to integrate. We can add AWSSDK.S3 to our .NET Core project with the following:
dotnet add package AWSSDK.S3
Using native dependency injection, and prior to pointing at our local, we might configure
To point this configuration instead at our LocalStack instance we’ll edit the
configobject we pass to
Amazons3Clientwith the following:
We need to set
ServiceURLto LocalStack and set
true. Additionally, we do this only for the
Developmentenvironment, meaning when we publish as
Production, we’ll point at Amazon S3 rather than LocalStack. The completed code looks like this:
Regardless of whether we are integrating with Amazon S3 or LocalStack on our local, the mechanism to transfer files remains unchanged:
Wrapping it up, I’ve used LocalStack specifically for S3 a couple of times and the points are to ignore the web UI - you don’t need it - and make sure to set
ServiceURLwhen integrating with .NET.