Tuesday, 19 August 2014

My wish list for Beginning Puppet

A few months ago a question in the very useful 'ask puppet' site attracted my attention. The authors of Beginning Puppet were asking for feedback about the desired content.

Since my answer has had some success, I'd like to report it here:

These are the things I would have liked to see as soon as I started experimenting with Puppet (in no specific order - this is mainly a brain dump):
  • What's a catalogue and how Puppet builds it
  • Recommended file structure for Puppet manifests
  • How to divide your infrastructure in environments
  • A clear indication that Puppet doesn't guarantee an "order of execution", and how to define dependencies between resources and classes (i.e. the "arrow" syntax to ensure that a class is always applied before/after another one).
  • Before ever writing a module, how to test it (and as a consequence, Continuous Integration for Puppet modules)
  • How to publish a module on github or puppetforge
  • A "build-up example" throughout the book. In other words, start building a module at the beginning, and keep adding elements as topics are discussed. For example, an apache module: start with making sure the apache package and its pre-requirements are installed, then add a file, then a template, then prepare the module for different environments, different OSs, etc.
  • Best practices for separating the module logic from the data, i.e. how to ensure that modules can be reused on different platforms/environments/OSs just with proper variable settings and without changes to the module logic.
  • Whether the hiera approach is recommended or not, and how to design a module with that in mind.
  • Best practices for dividing modules in classes
  • Variables scope, and best practices for variable names
  • Best practices for indentation, single/double quoting, module documentation
  • How to run Puppet in standalone/agent mode (so that the manifests can be verified easily locally)
  • Where Puppet looks for modules - how to install and use a 3rd party module
  • Common security problems
  • Load testing (e.g. with Gatling)
  • Continuous Integration (managing your modules with Jenkins or similar)
  • The 'facter' and what 'facts' are available and commonly used

Basic Docker commands

Just a list of docker commands that I've found quite useful so far.
List the containers available locally:
docker ps -a
Just the container IDs:
docker ps -a -q
Filter the running containers:
docker ps -a -q | grep Up
or simply:
docker ps -q 
Build an image:
docker build -t <user>/<image name> .
Run a container from an image, and execute bash shell:
docker run -i -t <user>/<image name> /bin/bash
Run a container from an image, in background, linking ports:
docker run -d -p <host port>:<container port> <user>/<image name>
(You can use -p multiple times, e.g. when the container exposes more than one port)
Show logs of running container:
docker logs <container id>
Stop/start/restart container:
docker stop/start/restart <container id>

UPDATE - Stop running container with a single command:
docker ps -a|grep Up|awk '{ print $1 }'|xargs docker stop 
UPDATE - The reason why I'm not using sudo to run these commands is that I added my user to the docker group, e.g.:
sudo usermod -aG docker

I hope you find this useful.

(Docker 1.1.2 on Ubuntu 14.04)

My presentation at ClueCon 2014

Back from ClueCon 2014, I've described the content of my presentation in this Truphone Labs Blog post.

The slides are here.

Any feedback is welcome, as usual.

Docker on Ubuntu: when apt-get update fails

I've been spending some time with Docker, and since digitalocean provides Ubuntu images with Docker already configured, setting up a new droplet and a few containers with my apps has become a matter of minutes.

One of the fist commands you want to run in your Dockerfile is certainly 'apt-get update'. I'm writing this with the hope to save the reader some precious time: if 'apt-get update' fails, you may want to ensure that docker's DNS configuration is complete (and servers are accessible).

In my case this meant simply adding the Google DNS servers in /etc/default/docker:

DOCKER_OPTS="--dns 8.8.8.8 --dns 8.8.4.4"

and restart docker with

sudo service docker restart

This StackOverflow question is related.