Welcome back! It’s been a week or two since my last post on this subject, but here it is! Today, I’m going to talk about how to interact with AWS EC2 using the amazonka and amazonka-ec2 packages. EC2, like Lambda, is a more involved service than some of the others. Furthermore, because the APIs I’ll talk about in this post are used to start and stop real, live, actual virtual machines, some of the APIs take longer to run and consume more AWS resources. Fortunately, the AWS free tier provides sufficient juice to learn how to use the APIs.
There are many moving parts to EC2. Consequently, the EC2 API is big. If you don’t believe me, then feel free to check out the number of types in amazonka-ec2. I have managed to pare down the APIs required to produce a minimally useful demo that demonstrates the following:
The end result is a program that will start an EC2 instance and provide enough information for users to connect to the instance via SSH. The resulting example program will run a single instance of one of the standard Amazon Linux AMIs. It will assume that you have a private-public key pair in the standard locations, i.e.
$HOME/.ssh/id_rsa.pub, on your system. To grab the key pairs from a different location, please edit the program as necessary. Windows users will need to generate an
ssh-keygen-style key pair using PuTTY or similar and edit the program as appropriate. The program will import the public portion of your key pair in order to allow remote access to your newly created EC2 instance.
Since my previous instalments, the shared code has undergone some more refactoring. I’ve simplified some of the names and also introduced an AWS-specific prelude in the form of
This imports the most commonly used amazonka functions and types in order to slim down the import lists in each Haskell sample. This is the best approach I have devised so far to deal with “Haskell import hell”. Similarly, I have extracted all the amazonka-ec2 imports for this program in the form of
To run this example code, you’ll need access to EC2. The most obvious way is to use the AWS free tier. This code will assume that you set up an appropriate account. Unfortunately, I have not yet found a local-only test environment for this kind of thing. localstack does not, yet, provide emulation of EC2.
We have a pretty standard set of dependencies:
You’ll notice that we do not require a direct dependency on
amazonka. This is handled by the re-exports provided by
We generate type-safe wrappers for the EC2 service using
This generates the following items:
newtypewrappers for function arguments
We declare a number of
newtype wrappers around the
Text type. These are intended to prevent the developer from passing one type of
Text when a function expects another
Aside: amazonka, like many frameworks, is somewhat “stringly-typed” and this is my attempt to impose some order on some of its functions which take multiple
Text arguments. In fact, there is concrete example of a bug resulting from stringly-typeness and code generation where the order of multiple
Text arguments have been changed between version 1.4.5 and 1.5.0. This results in unfortunately runtime bugs in the code.
newtype wrappers for my sample functions here should minimize the chance of this happening at least at the level of these new functions.
_DuplicateKeyPair: many of the other amazonka subpackages provide custom error matchers which is not the case for amazonka-ec2, presumably because the number of errors that are routinely encountered in EC2 land is large: fortunately, it’s straightforward to implement custom matchers for the kinds of errors we’ll encounter in our simple example
Here is the code:
So, this should be enough to provision all the resources required to run an instance and to provide an
ssh command line to connect to it.
Don’t forget to terminate the EC2 instance after you’re done!
All content © 2019 Richard Cook. All rights reserved.