Automating AWS with cloud-init

East 17, the bad boys of boy bands.Famously named after the picturesque part of London known as Walthamstow. This tourist favourite is also famous for it’s dog racing track and locals can often be heard to say “we’re going to the dogs”. Something not going to the dogs is Amazon Web Services. They have however followed East 17’s lead and named one of the core components after an area of London, EC2 (Eastern Central).

And that’s not all, the London influence goes further. As many of you probably know, Londoners speak a dialect of English known as cockney. Many words get shortened, for example, “isn’t it” is shortened to “init”. And so cloud-init is actually cockney short hand for “it’s the cloud isn’t it”.

But we must leave behind this fascinating backgound and get to the subject of this blog, automating AWS with cloud-init.

Last year the business I work for started to use cloud. AWS ownership was given to the nix team and as a member of the team, I has a lot to learn. Fortunately I like to learn new stuff. Like most RedHat shops, we used kickstart to build servers in our datacentre. When VMWare came along, the procedure stayed pretty much the same as with a physical server. Once the VM was set up, kickstart could be used to install the OS, customise the packages installed, register with Satellite and puppet, etc. Things were different with AWS.

In case you’ve never used Amazon Web Services, here’s a very brief overview of how you launch a VM (an instance in AWS speak). When you start an instance, it is created from an Amazon Machine Image (AMI). An AMI is a kind of golden image, a bit like Windows admins used to build servers from (and may well still for all I know!). It contains the OS image and any customisations you may have added when you built the AMI. When you launch your instance, you point to the AMI you want to use and specify stuff like size of the VM, disk space required, network details, etc. The instance is then up and running in a few minutes.

However, there’s still some problems to resolve like how to build your AMI initially or how to customise the instance when it launches so that it has a meaningful hostname (a random one is given by default) and other customisations you may want (like register with satellite and puppet).

This wiki entry details the procedure we followed to create an AMI and customise an instance on launch. An overview of the technique follows.

To create our AMI, first we built a fairly generic VM in VMWare using our standard build procedure. . A couple of extra things at this point will make the image cloud friendly. First off install cloud-init . This provides the framework to customise instances on launch. Initially developed by Ubuntu, it is available and packaged in RedHat. Once that’s installed, you can update some templates that are added.In our case we updated the /etc/cloud/templates/hosts.redhat.tmpl so that it included entries pointing to our puppet and satellite servers. When an instance is launched, this template replaces the existing /etc/hosts entry.

Now you have your cloud ready VM, create a VMDK from it by exporting it as an OVF template. This VMDK needs to be copied to the Amazon cloud. There’s a number of ways to do that but we used the AWS linux CLI that can be downloaded from AWS. This can also be used to launch instances and lots of other stuff. Anyway, using the aws cli, we copied the VMDK to an AWS S3 bucket we had already set up. From this, the AMI can be built.

Now you have your standard AMI, you can use it to launch instance. This is where cloud-init comes in. By creating a cloud-init cloud-config file, the actions specified in you cloud-config file will be carried out as the instance launches so that once it is up and running, it will be fully customised.

The cloud-config file is a YAML style file. If your not sure what YAML means (and to be honest, I wasn’t), here’s how the official web page describes it: YAML is a human friendly data serialization standard for all programming languages. So YAML files are human friendly, a shame the description isn’t! In summary the layout of the file defines an entries function.Data structure hierarchy is maintained by outline indentation. Here’s an example (borrowed from the very useful YAML wikipedia page):

items:
– part_no: A4786
descrip: Water Bucket (Filled)
price: 1.47
quantity: 4

– part_no: E1628
descrip: High Heeled “Ruby” Slippers
size: 8
price: 133.7
quantity: 1

Top level key is items, the indented lines are associated with the items key. Two list items are associated with the items keys, signified by the – , part_no A4786
and E1628 with their associated items (descip, size. price and quantity)

The YAML reference card is here. A YAML Syntax checker can be found here

Here’s the cloud-config file we created

#cloud-config
# == Hostname management (via /etc/hostname) ==
hostname: jss01
fqdn: jss01.justsomestuff.co.uk
manage_etc_hosts: True
# == Regenerate ssh host keys, register with satellite and make sure pupet up to date ==
runcmd:
– rm -f /etc/ssh/ssh_host_rsa_key
– rm -f /etc/ssh/ssh_host_dsa_key
– ssh-keygen -f /etc/ssh/ssh_host_rsa_key -N ” -t rsa
– ssh-keygen -f /etc/ssh/ssh_host_dsa_key -N ” -t dsa
– rm -f /root/.bash_history
– cd /var/tmp && wget http://10.44.173.76/post/satellite_register.sh && sed -i -e ‘s/\. ${POST_RUN}/\# \. ${POST_RUN}/’ satellite_register.sh && sh satellite_register.sh
– puppetd –test

When we launch an instance, we supply this cloud-config file as part of the user-data you can specify. This can either be done by cutting and pasting the cloud-config into the user-data box on the console when you launch an instance or via the CLI, e.g.

aws ec2 run-instances –image-id ami-1234d1e2 –user-data file:///var/tmp/cloud-init –count 1 –instance-type t2.micro –key-name JustSomeStuff –security-group-ids sg-1a2b3c4d –subnet-id subnet-1a2b3c4d

So what do the cloud-config entries mean? hostname & fqdn , as you may have deduced, set the hostname and fully qualified hostname for the instance. It uses some some inbuilt cloud-init functionality to do this. manage_etc_hosts true means that cloud-init will overlay the existing /etc/hosts file with one from /etc/cloud/templates/hosts.redhat.tmpl (that we set up earlier). The rest, under runcmd, are commands that will get run when the instance launches. In our case, create new ssh host keys, remove and pre-existing bash history, register the instance with satellite by uploading and running a script and finally, ensuring the puppet controlled files are copied.

Of course you can run pretty much run any command you fancy and there’s a lot or existing cloud-init modules you can run. Documentation of the modules can be found here . The full details of how we implemented cloud-init are in the wiki.

Whilst we’re on the subject of cloud, I thought I’d add my two pennies worth (I hear your groans!). I got to say that there was a period of time a while back when I was sick of hearing the word. For my first job in IT I worked for a company that had a few mainframes. These mainframes were divided into a number of virtual machines. On those VMs, they ran other companies work. In those days it was called bureau services. Now it’s called cloud. That was back in the fffing 1980s! So of course, my initial opinion of cloud was that it was a load of over hyped crap that had been around for years.

However, now I’ve used cloud I have changed my mind. It was hyped to a ridiculous and irritating level but, the tech is really cool and interesting to use. Cloud is driving all kinds of innovations in the tech area, from the OS to the container, from the development of apps to their deployment and also new IT practices like devops. Even Microsoft is getting Linux friendly these days and it has to because people want to run Linux on Azure.

Most companies are looking at the cloud to save money. It often looks good on paper but whether it will end up cheaper in the long run, it remains to be seen. It’s so easy to launch instances, will companies and up running more than expected, for example? I would say it makes absolute sense for a start up but if you’ve already invested heavily in a datacentre, does it make sense to migrate it to the cloud? Maybe some or new applications but it may not be practical to move everything.

If you haven’t had in any involvement with cloud yet, get involved. Amazon offer a free start point (and I’m sure other cloud providers must too) which is well worth a try.

One thing I don’t understand though, why name you initial cloud storage product after a suburb of Sheffield? And when it comes to boy bands, personally I prefer the laid back vibe of Blue.

It’s the cloud isn’t it….

As already mentioned, the wiki has more practical details on using cloud-init. Next time we’ll be taking a look at puppet. Bye!


Leave a Reply