DevOps, Continuous Delivery, PaaS, Cloud meet Ornette Coleman

Menu

Tag Archives: Agile software development

Post navigation

As I have written here, the DevOps Platform (aka ADOP) is an integration of open source tools that is designed to provide the tooling capability required for Continuous Delivery. Through the concept of cartridges (plugins) ADOP also makes it very easy to re-use automation.

In this blog I will describe an ADOP Cartridge that I created as an easy way to experiment with Ansible. Of course there are many other ways of experimenting with Ansible such as using Vagrant. I chose to create an ADOP cartridge because ADOP is so easy to provision and predictable. If you have an ADOP instance running you will be able to experience Ansible doing various interesting things in under 15 minutes.

To anyone only loosely familiar with ADOP, Docker and Ansible, I recognise that this blog could be hard to follow so here is a quick diagram of what is going on.

The Jenkins Jobs in the Cartridge

The jobs do the following things:

As the name suggests, this job just demonstrates how to install Ansible on Centos. It installs Ansible in a Docker container in order to keep things simple and easy to clean up. Having build a Docker image with Ansible installed, it tests the image just by running inside the container.

$ ansible --version

2_Run_Example_Adhoc_Commands

This job is a lot more interesting than the previous. As the name suggests, the job is designed to run some adhoc Ansible commands (which is one of the first things you’ll do when learning Ansible).

Since the purpose of Ansible is infrastructure automation we first need to set up and environment to run commands against. My idea was to set up an environment of Docker containers pretending to be servers. In real life I don’t think we would ever want Ansible configuring running Docker containers (we normally want Docker containers to be immutable and certainly don’t want them to have ssh access enabled). However I felt it a quick way to get started and create something repeatable and disposable.

The environment created resembles the diagram above. As you can see we create two Docker containers (acting as servers) calling themselves web-node and one calling it’s self db-node. The images already contain a public key (the same one vagrant uses actually) so that they can be ssh’d to (once again not good practice with Docker containers, but needed so that we can treat them like servers and use Ansible). We then use an image which we refer to as the Ansible Control Container. We create this image by installing Ansible installation and adding a Ansible hosts file that tells Ansible how to connect to the db and web “nodes” using the same key mentioned above.

With the environment in place the job runs the following ad hoc Ansible commands:

By running the job and reading the console output you can see Ansible in action and then update the job to learn more.

3_Run_Your_Adhoc_Command

This job is identical to the job above in terms of setting up an environment to run Ansible. However instead of having the hard-coded ad hoc Ansible commands listed above, it allows you to enter your own commands when running the job. By default it pings all nodes:

ansible all -m ping

4_Run_A_Playbook

This job is identical to the job above in terms of setting up an environment to run Ansible. However instead of passing in an ad hoc Ansible command, it lets you pass in an Ansible playbook to also run against the nodes. By default the playbook that gets run installs Apache on the web nodes and PostgreSQL on the db node. Of course you can change this to run any playbook you like so long as it is set to run on a host expression that matches: web-node-1, web-node-2, and/or db-node (or “all”).

How the jobs 2-4 work

To understand exactly how jobs 2-4 work, the code is reasonably well commented and should be fairly readable. However, at a high-level the following steps are run:

Create the Ansible inventory (hosts) file that our Ansible Control Container will need so that it can connect (ssh) to our db and web “nodes” to control them.

Build the Docker image for our Ansible Control Container (install Ansible like the first Jenkins job, and then add the inventory file)

Create a Docker network for our pretend server containers and our Ansible Control container to all run on.

Create a docker-compose file for our pretend servers environment

Use docker-compose to create our pretend servers environment

Run the Ansible Control Container mounting in the Jenkins workspace if we want to run a local playbook file or if not just running the ad hoc Ansible command.

Conclusion

I hope this has been a useful read and has clarified a few things about Ansible, ADOP and Docker. If you find this useful please star the GitHub repo and or share a pull request!

In this blog I will describe integrating ADOP and the Cloud Foundry public PaaS from Pivotal. Whilst it is of course technically possible to run all of the tools found in ADOP on Cloud Foundry, that wasn’t our intention. Instead we wanted to combine the Continuous Delivery pipeline capabilities of ADOP with the industrial grade cloud first environments that Cloud Foundry offers.

Many ADOP cartridges for example the Java Petclinic one contain two Continuous Delivery pipelines:

The second to build and test the application code and deploy it to an environment built on the Platform Application.

The beauty of using a Public PaaS like Pivotal Cloud Foundry is that your platforms and environments are taken care of leaving you much more time to focus on the application code. However you do of course still need to create an account and provision your environments.

Kills the running application in environment and waits to verify that Cloud Foundry automatically restores it.

Deploys the application to a multi node Cloud Foundry environment.

Kills one of the nodes in Cloud Foundry and validates that Cloud Foundry automatically avoids sending traffic to the killed node.

The beauty of ADOP is that all of this great Continuous Delivery automation is fully portable and can be loaded time and time again into any ADOP instance running on any cloud.

There is plenty more we could have done with the cartridge to really put the PaaS through its paces such as generating load and watching auto-scaling in action. Everything is on Github, so pull requests will be warmly welcomed! If you’ve tried to follow along but got stuck at all, please comment on this blog.

Successfully delivering Enterprise IT is a complicated, probably even complex problem. What’s surprising, is that as an industry, many of us are still comfortable accepting so much of the problem as our own to manage.

Let’s consider an albeit very simplified and arguably imprecise view of The “full stack”:

When you examine this view, hopefully (irrespective of what you think about what’s included or missing and the order) it is clear that when we do “IT” we are already extremely comfortable being abstracted from detail. We are already fully ready to use things which we do not and may never understand. When we build an eCommerce Platform, an ERP, or CRM system, little thought it given to Electronic components for example.

My challenge to the industry as a whole is to recognise more openly the immense benefit of abstraction for which we are already entirely dependent and to embrace it even more urgently!

Here is my thinking:

Electrons are hard – we take them for granted

Integrated circuits are hard – so we take them for granted

Hardware devices (servers for example) are hard – so why are so many enterprises still buying and managing them?

The software that it takes to make servers useful for hosting an application is hard – so why are we still doing this by default?

For solutions that still involve writing code, the most extreme example of abstraction I’ve experienced so far is the Lambda service from AWS. Some seem to have started calling such things ServerLess computing.

With Lambda you write your software functions and upload them ready for AWS to run for you. Then you configure the triggering event that would cause your function to run. Then you sit back and pay for the privilege whilst enjoying the benefits. Obviously if the benefits outweigh the cost for the service you are making money. (Or perhaps in the world of venture capital, if the benefits are generating lots of revenue or even just active users growth, for now you don’t care…)

Let’s take a mobile example. Anyone with enough time and dedication can sit at home on a laptop and start writing mobile applications. If they write it as a purely standalone, offline application, and charge a small fee for it, theoretically they can make enough money to retire-on without even knowing how to spell server. But in practice most applications (even if they just rely on in app-adverts) require network enabled services. But for this our app developer still doesn’t need to spell server, they just need to use the API of the online add company e.g. Adwords and their app will start generating advertising revenue. Next perhaps the application relies on persisting data off the device or notifications to be pushed to it. The developer still only needs to use another API to do this, for example Parse can provide that to you all as a programming service. You just use the software development kit and are completely abstracted from servers.

So why are so many enterprises still exposing themselves to so much of the “full stack” above? I wonder how much inertia there was to integrated circuits in the 1950s and how many people argued against abstraction from transistors…

Try spinning up the DevOps Platform open source tool (which brings together a number of other great open source tools)

You could also consider attending the DevOps Enterprise Summit London (DOES). It’s the third DOES event and the first ever in Europe and is highly likely to be one of the most important professional development things you do this year. Organised by Gene Kim (co-author of The Phoenix Project) and IT Revolution, the conference is highly focused on bringing together anyone interested in DevOps and providing them as much support as humanly possible in two days. This involves presentations from some of the most advanced IT organisations in the world (aka unicorns), as well as many from those in traditional enterprises who may be on a very similar journey to you. Already confirmed are talks from:

Nearly two years ago, I started this blog series to describe the main challenges I’d experienced trying to implement Continuous Delivery. At the time, the last post in the series was about four challenges related to people. Since then I’ve observed a fifth challenge and discovered it has been studied in psychology and has a name.

Through various interactions with clients, at meetups, conferences and even with my own team, I’ve witnessed the following phenomena:

Something is done (or not done) on an engagement that makes Continuous Delivery difficult (for example the development team accepting SonarQube saying some seriously defamatory things about their unit test coverage but neglecting even to gradually address this).

When questioned:

many people already appreciate that this is very wrong.

hardly anyone can really explain or justify why this is happening.

hardly anyone seems worked up about a solution.

It gave me an impression that people had experienced good practice in the past, but having joined this particular engagement had somehow lost the inclination to do it. It’s possible that for some people, in the past when things just worked, they didn’t question it, so never really appreciated the value of particular practices. But I think most people are more analytical than that. I started to realise that people probably had gone through an experience like this:

Joined the engagement, didn’t understand why certain things were / weren’t done, but opted to observe before speaking up.

Spoke up again several times , but didn’t really ever get listened to.

Gave up and accepted things for the sorry way that they are.

I figured there must be a name for this, started googling and realised it is called Learned Helplessness, something that was first experimented in the 1960’s by some scientists we can probably assume weren’t dog lovers…

The experiments are best described here on Wikipedia but in extremely simplified form:

some dogs were given no random electric shocks,

some dogs were given shocks and also given a button to press to disable the shocks,

some dogs received shocks at the same time as group 2 dogs but had no button. Group 3 dogs were paired with Group 2 dogs and were shocked until their Group 2 pair happened to press the button (which was at a random time from the Group 3 dog’s perspective).

The learned helplessness of Group 3 was demonstrated in the second part of the experiments when dogs had the opportunity to cross over a small wall to avoid getting shocks. Whereas groups 1 and 2 quickly learned how to avoid shocks, group 3 all failed to learn and sat their accepting their fate in pain.

The similarity of the above diagram to diagrams about DevOps like this made me smile!

Subsequent experiments demonstrated the ineffectiveness of threats or even rewards on motivating group 3 to change their location. Only by physically teaching the group 3 dogs to move more than twice did they learn to overcome the helplessness. Later experiments also proved the same phenomena in humans (without electricity).

So how do we overcome this?

Here are some things I’m experimenting with:

Try some introspection – ask yourself what you’ve learnt to accept, really look around for things that are stopping your project going faster – no matter how obvious, and start to ask why, perhaps at least 5 times.

Ask others around you ideally at all levels of experience less, the same and more than you what they think is preventing learning and improvement and consider asking “5 Whys” with them.

Pay close attention to new joiners to your team – they are the only ones not yet infected by Learned Helplessness.

Be sensitive with people. No-one wants to be told they are “helpless” or hear your amateur psychobabble. Tread carefully.

If you are looking to impart a change, don’t over estimate the impact of threatening or incentivising the people who need to change – they may already be too apathetic. Instead expect to need to show them multiple times:

That the proposed change is possible. You need to demonstrate it to them (for example if it relates to Continuous Delivery something like the DevOps Platform may help make things real).

That their opinions count and they have an important voice.

How is Learned Helplessness harming your organisation and to what extent are you suffering?

As per my last post about GCE sometimes knowing something is possible just isn’t good enough. So here is how I spun up the DevOps Platform on the Microsoft Azure cloud. Warning thanks to Docker Machine, this post is very similar to this earlier one.

1. I needed an Azure account.

2. I logged into my Azure account and didn’t click “view the new Portal”.

3. On the left hand menu, I scrolled down to the bottom (it didn’t look immediately to me like it will scroll so hover) and clicked settings. Here I was able to see my subscription ID and copy it.

4. (Having previously installed Docker Toolbox, see here) I opened Git Bash (as an Administrator) and ran this command:

I was prompted to open a url in my brower, enter a confirmation code, and then login with my Azure credentials. Credit to Microsoft, this was easier than GCE for which I needed to install the gcloud commandline utility!

You will notice that this is fairly standard. I picked an Standard_A3 machine type which is roughly equivalent to what we use for AWS and GCP.

...
SUCCESS, your new ADOP instance is ready!
Run these commands in your shell:
eval\"$(docker-machine env$MACHINE_NAME)\"source env.config.sh
Navigate to http://52.160.97.159 in your browser to use your new DevOps Platform!

It has never been easier to get ‘hands-on’ with Infrastructure Coding and Containers (yes including Docker), even if your daily life is spent using a Windows work laptop. My friend Kumar and I proved this the other Saturday night in just one hour in a bar in Chennai. Here are the steps we performed on his laptop. I encourage you to do the same (with an optional side order of Kingfisher Ultra).

We installed Docker Toolbox.
It turns out this is an extremely fruitful first step as it gives you:

Git (and in particular GitBash). This allows you to use the world’s best Software Configuration Management tool Git and welcomes you into the world of being able to use and contribute to Open Source software on Git Hub. Plus it has the added bonus of turning your laptop into something which understands good wholesome Linux commands.

Virtual Box. This is a hypervisor that turns your laptop from being one machine running one Operating System (Windoze) into something capable of running multiple virtual machines with almost any Operating System you want (even UniKernels!). Suddenly you can run (and develop) local copies of servers that from a software perspective match Production.

Docker Machine. This is a command line utility that will create virtual machines for running Docker on. It can do this either locally on your shiny new Virtual Box instance or remotely in the cloud (even the Azure cloud – Linux machines of course)

Docker command line. This is the main command line utility of Docker. This will enable you to download and build Docker images, and turn them into running Docker containers. The beauty of the Docker command line is that you can run it locally (ideally in GitBash) on your local machine and have it control Docker running on a Linux machine. See diagram below.

Docker Compose. This is a utility that gives you the ability to run and associate multiple Docker containers by reading what is required from a text file.

Having completed step 1, we opened up the Docker Quickstart Terminal by clicking the entry that had appeared in the Windows start menu. This runs a shell script via GitBash that performs the following:

Creates a virtual box machine (called ‘default’) and starts it

Installs Docker on the new virtual machine

Leaves you with a GitBash window open that has the necessary environment variables set to instruct point Docker command line utility to point at your new virtual machine.

We wanted to test things out, so we ran:

$ docker ps –a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES

This showed us that our Docker command line tool was successfully talking to the Docker daemon (process) running on the ‘default’ virtual machine. And it showed us that no containers were either running or stopped on there.

We wanted to testing things a little further so ran:

$ docker run hello-world
Hello from Docker.
This message shows that your installation appears to be working correctly.
To generate this message, Docker took the following steps:
The Docker client contacted the Docker daemon.
The Docker daemon pulled the "hello-world" image from the Docker Hub.
The Docker daemon created a new container from that image which runs the
executable that produces the output you are currently reading.
The Docker daemon streamed that output to the Docker client, which sent it
to your terminal.
To try something more ambitious, you can run an Ubuntu container with:
$ docker run -it ubuntu bash
Share images, automate workflows, and more with a free Docker Hub account:
https://hub.docker.com
For more examples and ideas, visit:
https://docs.docker.com/userguide

The output is very self-explanatory. So I recommend reading it now.

We followed the instructions above to run a container from the Ubuntu image. This started for us a container running Ubuntu and we ran a command to satisfy ourselves that we were running Ubuntu. Note one slight modification, we had to prefix the command with ‘winpty’ to work around a tty-related issue in GitBash

We opened a proper web brower (Chrome) and navigated to: http://192.168.99.100:32769/ using the information above (your IP address may differ). Pleasingly we were presented with the: ‘Welcome to nginx!’ default page.

We decided to clean up some of what we’re created locally on the virtual machine, so we ran the following to:

We opened Oracle VM Virtual box from the Windows start machine so that we could observe our ‘default’ machine listed as running.

We ran the following to stop our ‘default’ machine and also observed it then stopping Virtual Box:

$ docker-machine stop default

Finally we installed Vagrant. This is essentially a much more generic version of Docker-Machine that is capable of creating not just virtual machines in Virtual Box for Docker, but for many other purposes. For example from an Infrastructure Coding perspective, you might run a virtual machine for developing Chef code.

Not bad for one hour on hotel wifi!

Kumar keenly agreed he would complete the following next steps. I hope you’ll join him on the journey and Start Infrastructure Coding Today!

Learn Git. It really only takes 10 minutes with this tutorial LINK to learn the basics.