Managing Test Websites in the Cloud with git and Amazon Web Services

Blacksmith
Blacksmith
Published in
6 min readJul 12, 2016

Developers did awesome works the last years around managing development workflows with git and also running complex architectures with cloud-based virtual machines.

However we faced in my company some months ago a new challenge that have a lot of developers, especially working on complex systems with several simultaneous branches, long marketing/end-user validation procedures and a lot of expected iterations.
The question was basic : how can we generate easily test-stages for our end-users, testers and marketing teams based on “in progress” developments.

First Solution : classic static servers

The first solution was a quick-win for us but not really efficient.
Our hosting partner mounted a couple of static servers (let’s say “test1, test2, test3, …”) that we can push our development code on. Simple but not really scalable and flexible.

But this solution was bringing new issues : management of the reservations, time-consuming manual releases and the cost was super-high because of the outsource management.

Result : it was working… but not really awesome. To be honest I think it’s a procedure that we can used in the 90’s but not today. Far from the possibilities driven by the new innovations in cloud-computing and development workflows.

Second Solution : a new way to do it

As I was not satisfied about this classic architecture, I started to think about a new way to generate test-servers on the go with the minimum of complexity for the developer and the maximum of flexibility.

Stage 1 — Machines — Cloud is awesome, and AWS rocks (really).

My first research went to the Cloud part of the solution. I knew that it was possible to manipulate virtual machines easily (especially with AWS EC2 SDK, the PHP one is so nice and easy to use…).
Options are unlimited, you can create / terminate / start / stop / modify / copy / archive, your instances with a dozen of lines of code.

I decided to create from an official AMI (pre-configured images provided by AWS to run machines) my own modified AMI that will be my model to start new servers (via the runInstance method).
It’s actually great because when we will need to add new features to the test-servers, we’ll just have to update this model machine, re-create a new AMI from it (delete the old one) and reference this brand-new image as the new model in the runInstance method. Easy stuff.

So now, I have unlimited machines that I can easily create and manipulate, as they are all copies of my models machines, the access sequences (credentials, etc..) can still be the same and so you’ll just have to target the new ip in SSH or RDP or whatever to access your new test-server and push your applications files.

Stage 2 — DNS — Fighting the dynamic IPs using Route53.

AWS is clever, static IP attribution for a machine lifetime isn’t cost efficient (expensive for them because they’ll keep the machine in a reserved slot, even you don’t use it). So they’re storing your machines in S3 snapshots hosted in the infinite cloud and will plug them to an Instance only when you’ll start and run the server.

BUT, this solution for them is a new problem for us. How can our teams access or work on this server if the IP changes every day ? Because you too, for cost-efficiency, you will stop or terminate these test-servers when nobody will access it, for example in the night or during the weekends…

As every problem has a solution, AWS has a module that can solve this issue for us : Route 53 and again the AWS SDK.
If you register a domain using Route53 you can easily add subdomains to this “hosted-zone” (don’t ask me why), so we can think about something.

Every fresh-started test-server (or instance) has a new IP, so we can just wait a couple of seconds that Amazon services will attribute a public IP to the starting machine, grab this IP and create using AWS Route53 SDK.

NOTE for Amazon guys if you read this post : it could be nice to have the attributed IP as an option in the response of the runInstance method in EC2 PHP SDK. I did the trick using a “sleep” wait in PHP however it you integrate that natively, could be nice !!

Now, I have a dynamically created server with his own domain.
Note : you can make sure that the IP is updated at every machine stop/restart just deleting the subdomain and re-creating with this method at every start the DNS entry with the updated info. It’s easier than updating the route…

Stage 3 / Bonus Level — Adding some Git magic to this.

Ok, so we have unlimited machines that we can create on the go just pressing a simple button with dedicated domains.
But the graal was to find a way to make it synchronised with our gitflow.

To understand the need, we should go back 2 min to the initial flow :
– we need a fix
– a developer create a branch
– the development team works on this branch
– we need to test it on a machine.

So why don’t we just take the branch ? We can just ask the server freshly created to grab a specified branch.

AWS has (again) a solution to this issue : the User-Data scripts. To make it simple, you can specify a bunch of code to be run at the first start of a new instance.

So we’ll pass in the User-Data runInstance parameter the order to get with git the specified {branch} when the machine will run for the first time. Our machine will be so synchronised directly to the working branch.
Btw, you can also specify the branch in the Route53 DNS entry when you create the subdomain in order to have a dynamic subdomain as well like mybranch.testdomain.com

And that’s it !

We do have now a complete automatic test-server legion triggered on-demand by our development team with no more effort than pushing a button.
Our marketing team is also happy to be able to approve the new features and the fixes without having to wait decades until the dev push the feature to a test environment.

Feel free to let me know if you have advices or questions, I’ll continue to work on this in the next weeks and find new tricks using AWS.

BTW, it’s not a sponsored post. It’s just that AWS rocks…

See ya

--

--