はじめまして。食べログの DevOps / データサイエンスチームの爲岡 (ためおか) です。
Twitter やら GitHub やら、たいてい @zettaittenani というアカウント名で活動しています。
どうでもいいですが今のところかぶったことはないです。
今回は DevOps にフォーカスして、Ansible の実行環境を Docker を使って構築した話をします。
背景
食べログの開発環境構築には Ansible を利用していますが、諸々の事情で開発環境構築用の Ansible playbook を整理するタスクが発生しました。
Ansible は基本的には冪等性を担保していますが、command モジュールなどはその限りではなく、新しい開発環境のための Ansible playbook を冪等性が担保される、されないを意識しながら書いていくのは面倒な作業です。
そのため、下記のような requirements を満たすテスト環境を構築しよう、という話になりました。
- 開発中の playbook がバグを含んでいて、それによって冪等性が担保できない状態に陥った場合、playbook の実行対象となる新しい環境を簡単に立ち上げられる。
- まっさらな環境に対して初めて playbook を実行した際の結果を簡単に確認できる。
そこで、検証用の Ansible target 環境を Docker コンテナで構築し、環境を壊してしまったらまたコンテナを作り直せばよい状態ができれば、上記2つを満たすことができ、ハッピーなのでは? と考えました。
で、手元の環境を汚すのも嫌なので、どうせなら Ansible controller も含めて Docker で作ってしまおう! というのが今回の話です。
2019/03/13 追記
本内容を GitHub リポジトリ (ansible_tester) として公開しておりますので、
コピペが面倒な方はぜひご利用ください。
前提
手元のホストに Docker がインストールされていることを確認します。
無ければインストールします。
$ docker -v
Docker version 18.09.0, ...
controller 構築
Ansible は ssh 経由で実行されますが、official に配布されているまっさらなcentos
にはopenssh-server
, openssh-clients
いずれもインストールされていないため、下記のようなDockerfile
を用意します。
controller に関しては、openssh-clients
がインストールされたcentos
ベースの image を用意します。
Ansible は、ホストが CentOS であれば EPEL リポジトリからもインストールできるそうですが、公式ではpip
でインストールしているのでそちらに合わせました。
※2018/12/14(金) 追記
Dockerfile
の最後にCMD /sbin/init
が抜けていたため、修正しました。
@ikemo さん、ありがとうございましたmm
FROM centos:7.5.1804
MAINTAINER "zettaittenani"
# infra settings
RUN yum check
RUN yum -y update
RUN yum -y install openssh-clients
# application settings
RUN curl -L https://bootstrap.pypa.io/get-pip.py | python
RUN pip install ansible
CMD /sbin/init
target 構築
target にはopenssh-server
がインストールされたcentos
ベースの image を用意します。
今回は開発環境での playbook の実行検証が目的なので、UsePAM は no にして root login を許可しています。
また、EXPOSE 22
で controller からの ssh アクセスを受けられるよう設定しています。
FROM centos:7.5.1804
MAINTAINER "zettaittenani"
# infra settings
RUN yum check
RUN yum -y update
RUN yum -y install openssh-server
RUN sed -ri 's/^#PermitEmptyPasswords no/PermitEmptyPasswords yes/' /etc/ssh/sshd_config
RUN sed -ri 's/^#PermitRootLogin yes/PermitRootLogin yes/' /etc/ssh/sshd_config
RUN sed -ri 's/^UsePAM yes/UsePAM no/' /etc/ssh/sshd_config
RUN passwd -d root
# start sshd when booting
RUN /bin/systemctl enable sshd
EXPOSE 22
CMD /sbin/init
docker-compose にまとめる
2つの image の build からコンテナ立ち上げまでを一挙に行いたいので、
そのためのdocker-compose.yml
を用意します。
まず、テスト実行用の簡素な Ansible playbook を用意します。
hosts
に関しては、docker-compose
でコンテナを立ち上げる際に名前解決できるように自動で設定してくれるようで、下記のようにtarget
と書くだけでOKです。
なんて楽なんだ…。
[managed_node]
target
---
- name: Test
hosts: managed_node
user: root
tasks:
- name: Hello
shell: date >> now.txt
次に下記のようなdocker-compose.yml
を用意して、この Ansible playbook を controller にマウントするよう設定します。
version: '3'
services:
controller:
build: ./controller
privileged: true
volumes:
- "./ansible_dir:/ansible"
target:
build: ./target
privileged: true
コンテナを立ち上げる
ホストで下記コマンドを実行して Docker コンテナを立ち上げます。
$ pwd
/some_dir
$ docker-compose up -d --build
これで controller と target、どちらのコンテナも立ち上がったはずです。
別々の shell からdocker-compose
コマンドで各コンテナが立ち上がったことを確認します。
# @shell 1 (controller 用)
$ docker-compose exec controller /bin/bash
$ [root@xxxxxxxxxxxx ~]#
# @shell 2 (target 用)
$ docker-compose exec target /bin/bash
$ [root@xxxxxxxxxxxx ~]#
疎通確認
コンテナは用意できたので最後に疎通確認です。
controller のコンテナから target に対して playbook をテスト実行します。
# @shell 1 (controller 用)
[root@xxxxxxxxxxxx ~]# cd ansible
[root@xxxxxxxxxxxx ~]# ansible-playbook -k ./setup.yml -vvv -i ./hosts
...
PLAY RECAP *********************************************************************************************************************************************************************************************************************************************************************
xxx.xxx.xxx.xxx : ok=2 changed=1 unreachable=0 failed=0
実行できました。
次に target の Docker コンテナでテスト結果を確認してみます。
# @shell 2 (target 用)
[root@xxxxxxxxxxxx ~]# cat now.txt
xxxx年 xx月 xx日 x曜日 xx時xx分xx秒 JST
はい、確かに controller から target に対して playbook が実行できていますね。
playbook 自体はマウントしているものなので、手元のホストの shell 上で編集するなりなんなりできますし、実行する際は controller のコンテナでansible-playbook
コマンドを叩けば良いです。
実行結果は target のコンテナ上で確認できますし、target が壊れたらdocker-compose down/up
するだけでOK。
これはかなり幸せな環境ではないでしょうか!
最後までお読みいただきありがとうございました。
Happy Ansible Life!!