Notifies vs. Subscribes with Chef

Jul 22, 2016
I ran into this interesting scenario recently. At uShip, we have Chef code that writes a Consul config file for a service, let's say RabbitMQ, and when the template is updated, Consul needs to be reloaded. The current code looks something like the following:

template "#{consul_config_directory}/rabbit_config.json" do

execute 'consul reload' do
  action :nothing
  subscribes :run, "template[#{consul_config_directory}/rabbit_config.json"

When a developer needed to add a new service, Mongo, it was not clear that another subscribes statement also needed to be added. This meant that Consul did not pick up the config properly.

This got me thinking about when to use notifies versus subscribes in Chef code. They basically do the same thing but in this case, the intention would have been a bit clearer if the template notified Consul to reload instead of the other way around. Just something to consider the next time you're trying to decide which type of notification you want
Read more ...

404 When Contacting Apt Repositories using Chef and Test Kitchen

Jan 29, 2016


I'm starting a cookbook repository for an application from scratch. The cookbook will install Docker on a Linux VM and setup some default containers.


I ran into this weird case today where I was trying to install Git as the first package and I kept getting a 404 when trying to contact the Ubuntu Apt repositories using Test Kitchen. The odd part is that I could reach everything else so it wasn't a guest/host networking issue. Turns out, I needed to add the "apt" cookbook as a dependency so that apt-get update will be executed initially and then packages can actually be installed. Just something interesting to remember that I seem to have forgotten since the last time I ran into this.
Read more ...

Docker Machine and Ansible

Jul 31, 2015
I was recently working on the InvocationsOnline project and decided to switch to Docker instead of a standard Rails deployment. Long story short, the main reason is that we kept having issues with Puma not restarting properly and no way of being confident that we'd be able to deploy. I've been using Docker for a while and I figured that starting and destroying containers for deployment  would end up being easier in the long run.


We use Ansible to manage the configuration of the infrastructure. This allows us to make sure that all servers have the correct packages installed and, the case of the web servers, Nginx is configured properly. With the Docker deployment, this had to change a bit so that Nginx acts as a load balancer to Docker containers and we can have zero-downtime deployments.

Docker Machine

If you haven't been in the Docker ecosystem recently, Machine is Docker's answer to managing servers. With it, you can create local servers for development or cloud servers for deploying your applications. It also allows you to have the same interface for running Dockerized applications whether on your local machine or externally.

I first tried out Digital Ocean's "Docker" application which creates an Ubuntu server and installs Docker on it. After I was confident that I could get everything configured with Ansible and my application running on there, I decided that it may be a good time to switch to using Docker Machine to manage the servers. Aside from making it easy to interface with Docker on the remote server, it also leaves open the door for easier scaling if needed.

Ansible with Machine

After creating a new server with Machine, I then realized that I still needed to be able to SSH into the server outside of the context of Machine so that Ansible would be able to configure things.  A little background, Docker Machine creates a unique SSH keypair when it creates a server and then uses that when you want to connect or use the docker-machine ssh command. On the flipside, Ansible allows you to specify which private key to use for authentication by passing the --private-key flag with the location of the key you want to use. With Docker Machine, it's also easy to find the location, which is stored in the DOCKER_CERT_PATH environment variable, by running docker-machine env machine-name. If you run the referenced eval command then you should be able to call the $DOCKER_CERT_PATH wherever you need to. So from the directory my Ansible playbook, I can do:
eval "($docker-machine env krauss)"
ansible-playbook -i production --private-key=$DOCKER_CERT_PATH/id_rsa docker.yml


I hope this little nugget of info helps you if you're in a similar situation and good luck!
Read more ...

Minaswan is DEAD

Mar 4, 2013
I write this post with mixed emotions. Part of me is a bit hurt by the actions of some members of the Ruby community; the other part is completely disgusted.
I have always been a big proponent of the Ruby community and frequently encourage other people to just ”Try Ruby.” When anyone asks about my work, I tell them that I’ve been developing Ruby applications since 2008. I normally say this proudly but today, I’m ashamed.

What it all means

For those who aren’t in the know, MINASWAN stands for: Matz Is Nice And So We Are Nice. “Matz” is short for the creator of Ruby, Yukihiro Matsumoto. The anagram reminds us as a community to be respectful and helpful to others. What it does not mean is to only act this way towards Ruby community members and shun everyone else.

Home-cooked meal

We are a community, but this community is bigger than just Ruby. Building a web application these days is a lot like cooking a great meal, except the ingredients are programming languages. Mix in a bit of HTML and CSS. Slice up some SQL and Javascript. If you need a mobile app with that, sprinkle in some Objective-C and Java.
The thing to remember is that you need all of these ingredients, in certain proportions, to make something extraordinary. If you only use chicken/rosemary/broccoli every time, your meals are going to be pretty boring. This also happens with programming and you need to start changing the ingredients based on the type of meal you want to make.

Belligerent customers

Let’s say that I’m a world-reknowned chef who is famous for my filet mignon. This signature dish is cooked sous vide, topped with a stout beer sauce, and served with a side of charred asparagus.
One day, I decide to go to the restaurant across the street because I want to try their specialty. The filet here is grilled to the perfect temperature, topped with a red wine reduction, and served with a side of brussels sprouts sautéed in bacon fat.
Both of these dishes are excellent in their own right and I decide to ask the other chef how he gets the red wine to reduce to the correct consistency. At the same time, I also mention how my beer sauce is prepared. Instead of having a friendly discussion about the finer things in the culinary world, the other chef proceeds to berate my ingredients and my overall cooking style. Minaswan is DEAD.

Let’s have a beer together

Think of the second chef as a Ruby developer and I’m a developer in any other language. Is there any good reason to be treated in such a way as to have my craft belittled? Instead of saying “Try Ruby,” I want to say ”Fuck Ruby.”
If you hang out in the #rubyonrails room on IRC for any extended period of time, you will see: new developers written-off, developers from other languages scorned, and Windows users scoffed. I’m pretty sure Matz had none of that in mind when creating such a great programming language.
Instead of acting in such a way as to discourage people in other communities, we need to be much more welcoming. We need to be able to sit down together and share a pint. If we continue in this pattern, Ruby’s community will become a pretty lonely place to be.
The next time you’re talking to a new developer or someone versed in a different language, remember to be nice. Help these people out so we can grow our community because Minaswan needs to live.
Read more ...

Welcome to the Ruby GTFO!

Sep 16, 2012
I’ve been in the Ruby community for about four years and I absolutely love it. I have made so many friends who are always willing to help with any questions I may have. The purpose of this blog post is to discuss a few things I’ve observed, and hopefully you’ll take away something from it.

Observe and report

There are so many different types of people in the Ruby community and the skill level ranges from brand new programmers to seasoned veterans who have programmed in many different languages before Ruby. For the most part, everyone is happy to help one another out without even thinking about it. There are times, however, where people need to step back and look at where the person needing help is coming from.
The greatest display of this is when new programmers (either to Ruby or programming in general) have questions that may have a very obvious answer. We all have to start somewhere and many veteran programmers forget what it’s like to be in the shoes of a newbie. Here are some guidelines for newbies and veterans that may help the community as a whole.

Guidelines for n00bs

Read everything you can get your hands on. Many questions that may arise have been adressed previously. Always make sure to check documentation, blog posts, and even do a little code spelunking. I’m pretty sure it isn’t possible to have too much knowledge.
Learn to search effectively. Google is your friend. I constantly forget how to do certain things in Rails and searching on Google or StackOverflow usually finds exactly what I need.
Know how to ask questions. Aaron“Tenderlove” Patterson has great tips for how he wants to see questions asked. Basically just state what you are trying to do, what results you expected, and what the actual results were. Make sure to give enough information so that people can try and reproduce the what you did. Always err on the side of too much information rather than going back and forth because you didn’t give enough.

Guidelines for veterans

Remember your roots. This is probably the biggest thing to keep in mind when helping people out. We were all new to programming at some point so don’t get upset when people ask questions that may be seem trivial.
Be awesome at answering questions. Make sure to have patience, answer questions politely and completely, and show people where they can go for further information. You want help people get to the point where they can help themselves and then help others.
Learn a new language. The Pragrmatic Programmer recommends learning one new programming language every year. This has multiple benefits but a great one is that it will keep you humble, which goes back to the first guideline.

End of the line

This blog post is meant really as a jumping off point and a way to spark some conversation about this. I hope you take something from it, either as a new Ruby programmer or as someone who’s been around the block. If you have questions/thoughts/criticisms then reach out to me on email or Twitter
Read more ...

Automating my Work Day

Jul 18, 2012
I’ve always been a big proponent of “work smarter, not harder” and like to find ways to automate certain tasks. This is what drove me to create WorkingMan.

What is WorkingMan

WorkingMan is a Rubygem that makes it easy to start and stop your work day. It really just makes it easy to open specified applications and urls that you may commonly need to. For example, my work day typically starts by opening Google Chrome, Propane, X-Lite, Skype, and a few different urls.
Opening and closing these every day started to get really annoying and I wanted a way to do so without having to think about it. Enter WorkingMan.

The Code

This is really my first Rubygem that is worthy of use by anyone. I also wanted to experiment a bit with testing and so I started with Methadone from David Copeland. If you are curious at all about how to test command line Ruby applications, then definitely check out this gem.
I started by focusing on the user interface and how to make things as easy as possible. As such, there are two commands to really concern yourself with: start and stop. If everything is set up correctly in the YAML configuration file, then you’re golden. Check out my example configuration:

# Default applications for startup and shutdown. 
# Add/remove applications to customize 
  - 'Google Chrome'
  - 'Propane'
  - 'Skype'
  - 'X-Lite'
  - 'OmniFocus'

# URLs open in default browser 
  - ''
  - ''
  - ''

As you can see it’s pretty easy to set this up even if you aren’t a programmer. You can just take that file and modify it to your needs and the default location for the configuration is ~/.working_man.yml.

Project-specific Configuration

One feature that I really love is the ability to specify a different configuration file. Let’s say I have a Rails application in ~/Work/my_app and I want to always have the same urls open in my web browser when working on this app. Just add the configuration to that folder and use the --file option to point to that file. An example would be

Specify different configSource
$ working_man start -f ~/Work/my_app/working_man.yml


Tmuxinator is written by Allen Bargi and makes setting up project-specific Tmux sessions incredibly easy. This is also one of the biggest inspirations for WorkingMan. Pairing WorkingMan with Tmuxinator makes switching projects pretty effortless. This is an example Tmuxinator config that utilizes WorkingMan:

# you can make as many tabs as you wish...

project_name: 'MyApp'
project_root: '~/Work/my_app'
rvm: '1.9.3'
  - editor:
    layout: 'main-vertical'
      - 'vim .'
      - #empty, will just run plain bash 
  - shell: 'working_man start -f ~/Work/my_app/my_app_working_man.yml'

Wrap it up already

I urge you to try out WorkingMan and see if it helps make your day just a little less stressful. Also, make sure to check out the code and Flattr Me if you’d like. Now go and “Work hard today!”
Read more ...

The Great Nissan Debacle

Feb 14, 2012

What you are about to read may be shocking but I assure you that every word is true. I’m not writing this to get anything out of it except maybe a bit of stress relief and to enlighten others.

TL;DR: I won’t ever buy a Nissan.


My wife and I had a 2011 Toyota Camry which we were perfectly happy with. We were not really in the market for a new car but heard what sounded like a good deal on a 2011 Nissan. Since there were 49000 miles on the Camry after a year and a half, we decided to check out Kraft Nissan and see what the fuss was about.

16 January 2012

My wife heads to Kraft and they let her borrow a 2011 Armada to test drive and see how it is. Initial impressions were great. We really liked the car and started to think about purchasing it. She took the car back to Nissan after a few hours and we told them we’d like to think about things.

That night, we did some research online and compared prices. The price they were asking seemed like a good deal and was on par with others in the region.

17 January 2012

My wife tells the salesperson at Kraft that we’d like to test drive a Pathfinder instead just to keep our options open. We still preferred the Armada and were really thinking hard about moving on it. Kraft had also pulled credit scores to look into what the financing would be and overall, everything looked pretty decent.

That same morning, she receives a call from Flowers Nissan in Thomasville, GA and they were basically just following up on a lead that had been generated by her looking at vehicles on their website. They told her that they would basically do anything to beat Kraft’s price on a 2012 Armada and wanted to know how they could earn our business.

After talking everything over, we decided we wanted to do business with Kraft since we liked the salesperson and the price.

18 January 2012

We got all of our required paperwork in order to purchase the 2011 Armada and headed to Kraft Nissan. Upon arrival, they told us that we hadn’t actually been approved yet and that they were still working with other lenders to work out a deal. They also said we may want to check with Wells Fargo, our bank, and see if we can get a good rate. This is the first thing that upset us since we were under the assumption that all we would need to do is sign paperwork and drive away happy.

After about an hour, my wife has gotten both of us approved for a certain amount. Since we had a sour taste in our mouth with Kraft, she called Flowers and said, “We’ve been approved for X amount, can we do business on the 2012 Armada?” They told us we could and we began the process of going back-and-forth with our bank and the dealership for the next five hours.

That night, we drove up to Thomasville to pick up our new, sexy, black 2012 Armada. We gave Flowers and check from Wells Fargo and one from us, signed the paperwork and drove away happy.

19 January 2012

We discovered a small scratch on the rear of the vehicle. It was deep enough that it would probably require a bit of paint but not major. We also noticed the screen for the backup camera had bad reception in the dark. We told our salesperson and he said make a list of anything and that they’d be able to get the car in-and-out the following week. That weekend, we celebrated our son’s fourth birthday and had a good time.

23 January 2012

My wife called Flowers Nissan to discuss getting the car in for the repairs. We decided that we would rather wait and get the car in on the weekend since we both had to work. They told us that they really needed to get the car in that day since they were booked the rest of the week. She drove the car to Thomasville and the gave her a loaner to drive, saying that the car should be done the next day.

On her way back home, she receives a call from Flowers finance manager saying that he’s about to lose his job and we owed another $6000 on the car. Needless to say, she was incredibly freaked out and scared. We had left the paperwork in the Armada and so had no way to reference it. I told her not to worry and that we should be fine since we had signed for a certain amount and they let us drive the car away.

24 January 2012

My wife received another call from Flowers’ finance manager and she gave my cell phone number to him so I could take care of it since she was nine months pregnant. He called me and I told him that I did not agree with what he was saying and that it was their mistake; we shouldn’t be
held liable for that. I told him we’d be up later that day to sort things out and to pick up the Armada. After that phone call, I told my wife to call our friend who is also a lawyer and tell him what’s going on.

I ended up taking the second half of my work day off so I could sort everything out. About noon, we arrived in Thomasville and let our salesperson know we were on the way to pick up the car from the shop. When we arrived, I was approached by the finance manager who brought me into the office to go over the paperwork. I took a photo of the buyer’s order which turned out that they had made a mistake and were correct that we were supposed to have given more. I told him that I was going to take the order to our lawyer before doing anything. The car wasn’t out of the shop yet so we drove back to Tallahassee to talk to our lawyer.

After talking for a couple hours, our lawyer found multiple mistakes with the paperwork. The biggest mistakes were that they hadn’t done their math correctly and THEY didn’t sign any of the documents. At this point, we decided it’s best to go get the car and let them decide if they want to take us to court over $5200 (not $6000).

We drove back to Flowers and I was brought into an office with the finance manager, sales manager, and salesperson. I told them that I wasn’t going to pay the amount in question and that I was going to go ahead and get the car out of the shop, which I was in my legal right to do. They came back after about 20 minutes and said they would not release the car without the rest of the money.

I called our lawyer and he said I had two options: file an injunction and have the police make them release the car, or get all of the money back and void the deal. Filing an injunction would have cost at minimum $500 and at this point, we didn’t want to spend any more on this. We decided to just void the deal.

When I told them that we wanted to just get our money and the Camry back, they said they wouldn’t give us the Wells Fargo check and would send it by mail instead. This wasn’t acceptable because I didn’t want to have any liability on someone else. After involving our lawyer again, they finally brought a check for us and one for Wells Fargo. They then told us that we’d have to wait until the next day to pick up the Camry since they had already sent it to wholesale (BTW, they hadn’t even applied for the title so I question the legality of that).

26 January 2012

We finally drove back to Thomasville to pick up the Camry and ended up heading straight to Thomasville Toyota and purchasing a 2012 Highlander. Toyota was so quick and painless and we were out of there in about two hours.

Closing Thoughts

The entire process with Nissan was so despicable, that we will never buy a Nissan. I see Nissan Armadas on the road now, and am just sick to my stomach at the way we were treated. We were mis-led and multiple points and I’m ultimately glad we are in another Toyota. I hope this story serves as a warning to people to make sure you don’t let dealerships try to take advantage of you. Don’t be afraid to question everything and make sure you document the entire process. If something like this has happened to you, please let the corporations know and definitely don’t be silent about it.

Read more ...