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

  • 10
    いいね
  • 0
    コメント
この記事は最終更新日から1年以上が経過しています。

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 で動かしてみました