Edited at

Docker + Serverspec を使ってCircleCI 上でインフラのテストを実行する

More than 3 years have passed since last update.


TL;DR


  • Itamae レシピを Docker + Serverspec でテストする

  • テストのためにDocker コンテナ上で sshd を実行したくない

  • CircleCI は docker exec 使えないので lxc-attach を使う


ローカル環境 (OS X) からテストを実行する


必要なモノをインストールする


  • docker

  • docker-machine

  • docker-machine-driver-xhyve

Homebrew などで適宜インストールしておいてください。

既にVirtualBox などを使っている場合は xhyve じゃなくても良いです。

cf. OS XのネイティブHypervisorを使うxhyveと、ネイティブDockerを立ち上げるdocker-machine-driver-xhyveを作った話


Docker コンテナを作成する

Docker Machine を作成して、コンテナを使う準備をします。スペックは適宜調整してください。

docker-machine create ci\

--driver xhyve\
--xhyve-memory-size 2048\
--xhyve-disk-size 5120\
--xhyve-cpu-count 1\
--xhyve-experimental-nfs-share;

Docker イメージをダウンロードする際にDNS が欲しいので適当に突っ込みます。

docker-machine ssh ci "sudo echo 'nameserver 8.8.8.8' > /etc/resolv.conf"

あとは、Docker コマンドを扱えるように docker-machine env ci を確認して環境変数を設定してください。


コンテナを使ってテストを実行する

プロビジョニングのためにSSH サーバーを立てる場合、プロビジョニング用のSSH ユーザや鍵の追加でサーバー構成に差分が出るため、コンテナ内でローカルホストに向けて Itamae を実行しています。

SSH サーバーの構成差分が特に気にならなければ、SSH サーバーを立てる方法でも良いと思います。Docker コンテナ的にはSSH サーバー立てるなということもありますが、テストのためのコンテナなら良いと思います。

SSH 経由で動かすなら下記の記事などを参考にすると良いと思います。

CircleCI + Docker による Itamaeレシピの継続的インテグレーション


コンテナを定義する

コンテナ内で Itamae とServerspec を動かすため、Ruby と合わせてインストールします。Itamae のレシピは COPY でコンテナ内に配置します。


Dockerfile

FROM alpine

RUN apk update && apk upgrade
RUN apk add --no-cache ruby ruby-io-console ruby-json
RUN gem install itamae rake serverspec --no-ri --no-rdoc

COPY . /usr/local/provisioning

CMD ["tail", "-f", "/dev/null"]


コンテナ自体は特にプロセスを実行する必要が無いので、代わりに tail -f /dev/null を実行させてテスト実行まで待機させています。 RUN はなるべく1行にまとめて実行したほうが良いですが、読みづらいので分けて書いておきます。

cf. Alpine Linux で軽量な Docker イメージを作る


Itamae + Serverspec を実行する

イメージをビルドして動かした後、 docker exec を使ってコンテナ上で Itamae とServerspec を動かすだけです。

docker build -t spec -f Dockerfile --no-cache .

docker run --name ci -it -d spec
docker exec -it ci /bin/sh -c 'cd /usr/local/provisioning && itamae local roles/ci.rb'
docker exec -it ci /bin/sh -c 'cd /usr/local/provisioning && rake spec'


CircleCI でテストを実行する

CircleCI は docker exec に対応していないので、 lxc-attach を使います。ローカルで構築した構成はそのまま使えるので、コマンドだけ置き換えればOK です。

cf. Docker Exec - CircleCI


circle.yml

machine:

services:
- docker

dependencies:
pre:
- docker build -t spec -f Dockerfile --no-cache .
- docker run --name ci -it -d spec
test:
pre:
- sudo lxc-attach -n "$(docker inspect --format '{{.Id}}' ci)" -- /bin/sh -c 'cd /usr/local/provisioning && itamae local roles/ci.rb'
override:
- sudo lxc-attach -n "$(docker inspect --format '{{.Id}}' ci)" -- /bin/sh -c 'cd /usr/local/provisioning && rake spec'



気になるところ

Docker コンテナに Ruby 環境 (Itamae と Serverspec) を作らなくて良いように、itamaelxc-attach 経由で実行できると良さそう。今のDocker イメージだとビルドに30秒くらいかかる。


追記

Infrataster も試しにCircleCI で動かしてみました