Book Report: “Continuous Delivery” – Automate Everything!

About four years ago, I remember seeing Continuous Delivery by Jez Humble & David Farley sitting on a colleague’s desk. I remember thinking how awful it looked. Like a textbook from college, blech!

Then, I heard about it a lot. A LOT. Developer after developer, blog post after blog post. The book’s central idea is to automate (almost) everything in your software development processes. By doing this, the theory goes, you can deliver value to your software customers faster, with less risk.

There were many potential uses for these ideas coming up in my day-to-day work, so I finally decided to read the book to see what the hype was about. It was definitely a worthwhile read, and as a way to help me remember some key points from this book, I decided to write up this post. I thought it might spark some interest in others to read it as well.

Why read this book?

If you’re involved with software in any way: a developer, a sysadmin or a manager, you really should know this stuff.

Reading it cover to cover may not be necessary, which I’ll explain below, but you should at least be familiar with the concepts and techniques talked about in this book.

Even if you think you know the concepts, you should still read it. Admittedly, some of it is simply becoming standard knowledge and some of the tools it refers to are dated. But, the details in many of the chapters matter and will be really valuable for you.

Before you start reading…

Plan on reading about a chapter or less at a time, then stopping to digest it for a day or so. Because it’s written so well, it’s almost deceiving how dense the material is.

As I alluded to before, don’t feel like you need to read the whole book. This is mentioned in the book’s introduction. There are a few essential parts I’ll outline below, but otherwise, pick and choose as you see fit. The authors specifically mention that each chapter should stand on its own.

Essential Parts

Here are the parts I consider must reads:

The Preface

This sets the stage for why the book was written and the best way to read it (in the author’s opinion).

Chapter 1 – “The Problem of Delivering Software’

This chapter addresses fundamental problems the book sets out to solve and general principles it follows. It also will define certain key terminology that you’ll need to be familiar with throughout the book.

Again, this an especially important read for managers who may have been away from code for a while, or (gasp!) managers who have never coded before. It will help you understand how manual processes are fraught with errors, cause your developers to tear their hair out and generally make them (and by proxy: you) miserable.

Chapter 2 – “Configuration Management”

This was a standout chapter for me. Humble and Farley present why it’s important to be able to automate the creation of your software environments completely. Most of this stuff I was already familiar with, but the way this information is laid out is the best I’ve seen: Step by step, introducing the problems and high-level solutions. It helped me solidify my existing understanding and give more depth to what I already knew.

This is the type of information you need to convince others that automation of your environments is of utmost importance and also tell them that “Yes! It’s possible!”

If you’re less technical, let your eyes glaze over anything that you might not understand. You’ll still come away from the chapter with plenty of new ideas. Just be careful about how you present them to your developers if they’re not already on board :)

Stand out areas

Infrastructure Management (Chapter 11)

This was probably my favorite chapter in the whole book.

For a large, dense textbook, I found myself on the edge of my seat in this chapter. I could not get enough of the ideas that the book presented to solve common issues with software environments getting out of sync and how to prevent them. I lost count of how many times I thought:

“Wow, this would have helped with [insert huge, time draining issue here].”

There are also some important tips in this chapter regarding keeping your environments maintainable. Things like logging, change management and monitoring.

You could almost consider this chapter a crash course in good system administration. And it applies whether you’re running in the cloud, your own datacenter, with one server or thousands.

Source Control

A key theme throughout the book is that you should use source control. I knew source control was important, but after reading the book, I realize how crucial it is to everything in software. Now, I want to Git all the things!!!

I do disagree with the authors’ assessment of using feature branches with Git.

They make it clear they are not fans because feature branches deviate from the main line of code and thus stifle Continuous Integration across developers. I can see their argument, but having used feature branches very effectively, I have to wonder if their opinion has this changed since 2008 when the book was written. Things like pre-flight builds help with these sort of issues.

Testing

One of my key takeaways from the book (from Chapter 8) was that to effectively run Automated Acceptance Tests, you should build a test API layer into your application. This layer captures important use cases which you can use as building blocks for real tests. This is lightyears more maintainable that using UI driven tests, which the authors say should be used, but as little as possible.

This was eye opening and a very useful idea I hope to implement someday soon.

Also, they give good guidelines for how to categorize testing and when it makes sense to automate a test and when it doesn’t.

Chapter 12 – “Managing Data” also gives some really great tips on how to manage test data.

My Only Criticism: Not enough advice on where to start

My only criticism of this book was that it preached about the ideal state of Continuous Delivery a lot and didn’t spend enough time on how to get started if you’re in a rut already. Which I’m sure is where most readers are at.

I’m sure I’m not alone in that I desperately want to reach the God-like software state these guys describe, but I have some harsh realities of a large organization I need deal with before I can get there.

Outstanding questions

What follows is a list of some of the questions the book raised for me, but didn’t answer. My intent here is not to answer these questions, but to highlight some areas know I need to get more information on, and that you might, too.

I would love to hear your comments about any of these:

Differing levels of enthusiasm

If you work in a medium to large sized organization developing software, I’m sure you have to deal with a range of enthusiasm for the job. This ranges from older people who are completely content to run a deployment from a Word document, to overly enthusiastic cowboy developers who do what they want when they want, without the faintest whiff of a plan.

How do you herd these cats and get them drinking the automation Kool-Aid? How do you get people who aren’t excited, excited? And how do you contain the people that want to go crazy shaving yaks without a good, solid vision and plan to get there?

This is something I’ve been thinking about a lot since I read the book and have tried a few things out, but that’s for another post.

Politics

With individual contributors moving your digital widgets, a lack of enthusiasm is one thing. But if you have a lack of enthusiasm in management (especially upper management) this can present a serious roadblock to making progress towards these ideas. Or even worse: What if they’re opposed to the costs of implementing automation?

I’m still trying to find good ideas for convincing upper management to back these ideas (Without telling them to read a textbook…). Management wants numbers, and numbers for this stuff are hard to come by. It seems as though storytelling is more effective, but not everybody buys stories…

Furthermore, what about dealing with upper management who pushes too hard on these concepts without really understanding them? You know, the type who reads about DevOps in an in-flight magazine then lands and puts “Must implement DevOps by June” on your yearly objectives…

DevOps

The book mentions, or alludes to, DevOps a fair bit.

The authors recommend having a unified team with development, operations and QA all working together in harmony. That’s great – at a startup or an organization supporting one large application.

But, what if you work in a large, siloed organization that supports hundreds of medium sized applications? How can you get these ideas to work?

Side note: DevOps is a buzzword I’m beginning to dislike. I appreciate what it’s after, but it seems to have been engulfed in meaninglessness by big companies wanting to make a buck.

Differing Skillsets

How do you manage continuous delivery in a team of people who range from right out of college to senior developer. How do you get newbies started? How do you teach old dogs new tricks?

Finally…

If you made it here, I hope you’re convinced you should read the book, or at very least add it to your Amazon Wishlist :) If you end up reading it after seeing this post, come on back and tell me what you think.

If you’ve read the book prior to reading this post, I’d love to hear your comments/criticisms/ideas in the comments.

After reading this book, if you’re not convinced that moving towards these concepts is worthwhile, you should probably find another profession.

Now, go forth and automate everything!

Breathing New Life Into an Old Macbook with an SSD and OS X Yosemite

My Christmas gift to myself this year was to install a new Solid State hard drive (SSD) in my old mid-2009 Macbook Pro. Wow, what a difference! The most honkin’ app I run, Adobe Lightroom, now takes about 5 seconds to load, compared with what felt like an eternity on my old hard drive.

This post outlines what I did to perform this upgrade, which, all in all, was pretty easy. I’m writing it down so it might help others and also so I don’t forget my own steps if anything goes wrong in the future :)

Why I decided to upgrade

My old Macbook has served me well and is in great shape. A new Macbook would be fantastic, but shelling out $200 versus over $2000 is a no brainer. It’s also maxed out on RAM (8GB), and it was running OS X 10.6 Snow Leopard – four major updates behind. So, it was really showing signs of age and I was missing out on some of the newer OS X features.

In addition to doing personal coding on my home machine in Node.js, Java and the odd bit of Ruby, I also use my Macbook for:

  • Using Adobe Lightroom to process photos
  • Using Photoshop Elements to touch up the odd photo
  • Using VMWare Fusion to run a Windows 7 Virtual Machine so I can run Quicken for personal finance
    • Side note, this is sad, isn’t it?

So, I do a few things in there that require some power beyond the piddly stuff.

The Drive

After reading a lot of reviews for Solid State Drives for mac, I chose a Crucial M500 480GB Drive. It had the best combination of good reviews as well as price. I made sure to search the Amazon reviews for it to confirm it worked with my 2009 Macbook pro. (For my model, this was a particularly helpful review).

I had the drive in my Amazon shopping cart for a long time before getting it. I eventually setup a camelcamelcamel.com alert for it and got it about $40 cheaper than it usually is.

What I needed before installation

Besides the hard drive itself, I needed the following

External hard drive enclosure

I wanted to reuse my old hard drive. So, I found enclosure that would let me use it as an external USB drive. I went with a Sabrent enclosure.

This was doubly awesome because I could use this to just pop the old drive in this and convert all my data over using “USB 3.0” (see later on).

One drawback is that it sucks a lot of power (again, see later on).

A thumb drive 8GB or larger

Since I was going to install a new version of OS X on a new hard drive with no recovery partition, I needed to make an OS X installer thumb drive. To do this, I needed a thumb drive 8GB or larger.

Tiny-ass screwdrivers

Finally, I made sure I had my trusty set set of small screwdrivers (pentalobe, etc.) to use for the tiny screws in the macbook and the internal hard drive. Having this little kit around is indispensable if you’re going to do anything with a Macbook, iPhone or iPad.

The steps

Here’s how I did it

Find a bunch of free time

Having a 17-month old baby, I had to wait for a day when I would be able to “tend” to the install. While it’s not a lot of work, it does take a while and needs to be checked in on. Kind of like… A baby? No, that’s not right – a baby IS a lot of work! :)

Create a bootable USB installer

I decided to go straight to the latest OS X and use 10.10 (Yosemite) . To start this out, you have to go to the App Store and download the Yosemite installer. This is a few GB and takes a while to download, so I did that early on.

After you download the installer, I copied the installer out of my Applications folder for safe keeping. Then I followed Apple’s instructions on how to create a USB installer. They’re very good and very easy.

Virtual Machine Prep

I had a feeling that VMWare Fusion might not play well between Snow Leopard and Yosemite, so, I backed up my important stuff from my Windows 7 image and stored it on my Mac drive. In my case, this was really just my Quicken files.

Backups

First things first: I backed up all the things! I use two different external hard drives to run my backups for extra redundancy, swapping the drives every couple of backups. So, I ran a time machine backup of my old hard drive on both of them for good measure.

Replace the drive.

For my mid-2009 Macbook pro, page 35 of this manual shows how to replace the drive.

Side note: It is unfortunate that newer Macbooks can’t be modified like this anymore.

Put the old drive in external enclosure

A couple of screws in the Sabrent enclosure and that was it.

It’s worth noting that this enclosure needed to be hooked up to a USB hub that had external power. My old macbook’s USB ports couldn’t power it.

Additionally, I realized that even though the enclosure supported USB 3.0, my old Macbook did not. Slower speeds, oh well!

Format the drive

I plugged in the bootable USB installer into the Macbook, held the Option key, and booted up.

I opened up Disk Utility and choose the new hard drive then formatted it.

Install Yosemite

Exit Disk Utility and then install Yosemite. It took about 45 minutes for mine to complete.

Migrate data

Once Yosemite was installed, I created a new user to test things out, making sure it had a different username than the one I used to use. Then, I opened Migration Assistant to move my data and settings over from the old drive to the fresh Yosemite install. You can also Migration Assistant from time machine backup on my existing external USB hard drive.

Install new XCode

I use Homebrew and after the upgrade, I was having some issues with various utilities. Running brew doctor gave me the hint I needed to upgrade Xcode from the app store. This took about 30 minutes to download and install.

Fix Homebrew

I ran brew update and brew prune along with brew uninstall macvim then brew install macvim --override-system-vim. I was having some issues there.

Deal with the VM

As expected, VMWare Fusion didn’t work across OS X versions. Migration Assistant was very clear about that. I decided to give up on VMware Fusion and just try out using VirtualBox since it’s free.

This article gave a really good overview of how to convert my VM over from VMWare Fusion to VirtualBox.

I also installed the VirtualBox Guest Additions by using the “Devices -> Insert Guest Additions DVD Image” once my VM was up. Then I could share folders, resize the screen, etc.

Time machine backups

One thing I did not anticipate was that I would have issues with my existing Time Machine backups. When I went to run a new Time Machine backup, I was told I didn’t have enough space on my external hard drive.

It seems like Time Machine has not been able to “reconnect” to my old backups and is trying to basically back everything up again and doesn’t know that it should delete older copies of my backups. this article from pondini.org has some good information about how to reconnect backups if this happens.

As of now, I have not been able to solve this issue and may just reformat my external hard drive and start a fresh backup with Yosemite. If I get this fixed, I will update this post.

Update 1/10/2015: I ended up reformatting my backup drive and just started over. Using tmutil inheritbackup and tmutil associatedisk as mentioned in the pondini article and this article by Simon Heimlicher unfortunately didn’t work for me.

Enjoy

That’s it, now it’s like I have a new Macbook!