Day 11: Santa CL::AWS

Santa’s elves are in charge of updating the e-Christmas site every year and, since that site uses WordPress, it needs a full rebuild each time to make sure that it is ready for all the kids to Post their Christmas lists without drooping under the weight of traffic.

This winter, they thought it would be cool to move their WordPress site to the CLoud by using Amazon Web Services to keep their gift wrapping area free of servers and router racks.

They looked for a tool that would help them to manage all the phases of launching a clean WordPress build:

  1. Launch a clean AWS EC2 server with Ubuntu 22.04LTS, set up security groups and elastic IP (via the awscli) and ssh into the new instance
  2. Use apt-get (on the EC2 instance Ubuntu cli) to install the minimum set of packages to run docker-compose
  3. Use git clone to get the platform docker-compose.yaml and so run clean instances of MySQL, WordPress and NGINX with ports and SSL certificates
  4. Install a predefined set of WordPress Themes and Plugins into the instances (via the WordPress cli) and populate pages and content by moving in content files

It would be some work to set all this up, but a layered approach (ssh’ing into the AWS base instance and then into the child Docker VMs) would mean that the “pattern” of the WordPress site could be standardized and repeatable. And that the layers could be extended to other cloud providers, other web applications and so on. The configuration could be stored in a layered set of .yaml files.

Authors note: I am still working on step 1 … so this is the subject matter for this post. Keep an eye on my blog for future posts about the other steps over at https://p6steve.com

Before starting Santa asked his reindeer what would be the best language for this.

Doner said “I would use Bash but that’s pretty clunky, probably need to add some awk so I can regex stuff our of the JSON results, and it lacks any sensible class / object way to model stuff, plus I would have to learn it, hmmm”

Blitzen said “perl5 – that’s everywhere and it’s fast and it has some useful CPAN modules such as AWS CLI and PAWS (oh look, there’s a WordPress CLI … would need to write a module for that) but sadly it’s missing the -Ofun and maintainability for me these days”

Rudolph said “python – well I have done some coding in python and it’s great for simple OO and has a mountain of modules and packages – but really python is a square peg to the round hole of installation and CLI scripts”

The discussion was settled by Mrs CL::AWS “we need a kitchen sink language (geddit?!) where CLI and OO and Modules are all first class citizens – why don’t we try raku?”

Here’s a snippet from version one…

use Paws:from<Perl5>;
use Paws::Credential::File:from<Perl5>;

# will open $HOME/.aws/credentials
my $paws = Paws.new(config => {
  credentials => Paws::Credential::File.new(
    file_name => 'credentials',
  ),  
  region => 'eu-west-2',
  output => 'json',
});

my $ec2 = $paws.service('EC2');

my $result = $ec2.DescribeAddresses.Addresses;
dd $result;

Look we can use awscli directly via the awesome CPAN perl5 Paws module, no need for a gift wrapper or anything.

Authors note: I link a recent discussion on Reddit where I was finally convinced that perl5 modules require no wrapper … on that point, as you can see from the snippet, raiph is right. All the same, I personally have two unrelated issues with this approach: (i) Paws is huge and quite intimidating to swallow all at once, I want to apply just the minimum set of things and (ii) this requires my director machine to have awscli and Python (awscli is written in Python!) and perl5 and cpanm and Paws installed along with raku which is quite a bunch of stuff that I really don’t want on my main dev machine with penv and all that jazz.

Hmmm – a late night on the Advocaat convinces Mrs CL::AWS to try again, but to cut things down to size all is really needed is ‘apt-get install awscli && aws configure’ and then to take the same approach as perl5 does via shell commands and backticks.

Let’s see, do I need something like this from the raku docs:

my $proc = run 'echo', 'Rudolph is Great!', :out;
$proc.out.slurp(:close).say; # OUTPUT: «Rudolph is Great!␤» 

That seems a bit less handy than perl5 backticks, surely I can do better:

my $word = "kids";
say qqx`echo "hello $word"`;  # OUTPUT: «hello kids␤»

Authors note: qqx is perfect since the double quote nature automatically interpolates variable names like ‘$word’ and it returns stdout which we need for the awscli response. One really cool things is that the delimiters , often ‘qqx{…}’ may be any character, so I use backticks for old timers` sake and to keep out of the way of {} for function calls.

So here’s some version 2.0:

use JSON::Fast;

my $image-id = 'ami-0f540e9f488cfa27d';
my $instance-type = 't2.micro';

qqx`aws ec2 run-instances --image-id $image-id --count 1 --instance-type $instance-type --key-name $key-name --security-group-ids $sg-id` andthen 

say my $instance-id = .&from-json<Instances>[0]<InstanceId>;

Some other little gifts from Raku are:

  • qqx sets the topic to the cli response,
  • andthen hands the topic from left to right
  • I can then use . to apply any method to the topic
  • the & converts the sub from-json to a method call
  • the <> autoquote to streamline the accessors into the json result

And here’s a snapshot of the whole thing (for step 1) in a gist:

As a way to channel perl5 backticks ad apply some cli magic, this gist shows how raku builds so nicely on the perl5 cli heritage and avoids burying the awscli commands in distracting boilerplate so that the intent is clear to coders / maintainers. But, this is a linear piece that is getting to the limit of procedural steps and is pretty hard to repurpose and/or extend.

We’re running out of time & space as I have to put the kettle on for Santa and the Elves. Maybe I can come back later and show how raku OO can be used to tease out the innate structure and relationships to give a deeper model which can be reasoned about.

Merry Christmas to .one and .all!

~p6steve

One thought on “Day 11: Santa CL::AWS

Leave a comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.