DebianからAnsibleをDebianが動いてるVagrant boxに使ってみる

nogajun
nogajun

_ chefもpuppetも挫折してfabricに手を出そうとしたけど、ちょっと違う感じがしたのでAnsibleに手を出してみたら意外とうまくいったのでメモっておきます。

てか、日本語のAnsible使って見ましたー系日記が全部CentOSってどういうことじゃい!と思いつつ。

参考

Vagrantの準備

1台だけで試すので普通に起動しました。ちなみにwheezy32は以前Packerで作ったWheezy 32bitのVagrant Boxです。

$ mkdir ansible-test
$ cd ansible-test
$ vagrant init wheezy32
$ vi Vagrantfile

26行目のコメントを外して

config.vm.network :private_network, ip: "192.168.33.10"

vagrant upで、起動しました。そして vagrant sshでログインできることを確認。

Ansibleのインストール

sidにはAnsibleが入ってるのでapt一発です。

$ sudo apt-get install ansible

Ansibleの疎通確認

Ansibleチュートリアルを読み替えつつ、まず最初に疎通確認ということでpingが通るか試してみた。

$ ansible 192.168.33.10 -m ping
No hosts matched

ふむふむ。/etc/ansible/hostsにノードを書いてあげればいいけど、面倒なのでカレントディレクトリにhostsを書いてオプションで指定してみる。

$ echo "192.168.33.10" > hosts
$ ansible -i hosts 192.168.33.10 -m ping
192.168.33.10 | FAILED => FAILED: ssh jun@192.168.33.10:22 : Private key file is encrypted
To connect as a different user, use -u <username>.

gnome-keyringが立ち上がるしなんかヘン。ていうかユーザー名はvagrantじゃなきゃダメだよね。

$ ansible -i hosts 192.168.33.10 -m ping -u vagrant
No handlers could be found for logger "paramiko.transport"
192.168.33.10 | FAILED => FAILED: ssh vagrant@192.168.33.10:22 : Private key file is encrypted
To connect as a different user, use -u <username>.

やっぱりダメだ。チュートリアルもここまでか。 と思ったけどググって本家ドキュメントのGetting StartedのYour First Commandsにこんな記述を発見。

Set up SSH agent to avoid retyping passwords:
$ ssh-agent bash
$ ssh-add ~/.ssh/id_rsa

ああ!ssh-agentで鍵を登録しておくのか! VagrantのSSH秘密鍵を登録して、もう一度pingを試してみる。

$ ssh-agent bash
$ ssh-add ~/.vagrant.d/insecure_private_key
Identity added: /home/jun/.vagrant.d/insecure_private_key (/home/jun/.vagrant.d/insecure_private_key)
$ ansible -i hosts 192.168.33.10 -m ping -u vagrant
192.168.33.10 | success >> {
        "changed": false,
        "ping": "pong"
}

わーい。とおったー。じゃあunameを表示。

$ ansible -i hosts 192.168.33.10 -u vagrant -a 'uname -a'
192.168.33.10 | success | rc=0 >>
Linux packer-virtualbox 3.2.0-4-686-pae #1 SMP Debian 3.2.46-1 i686 GNU/Linux

おk。だけど毎回-uオプションは面倒なので「Inventory and Patterns」を参考にhostsにansible_ssh_userを書いてみた。

$ cat hosts
192.168.33.10 ansible_ssh_user=vagrant

-uオプションを外してもう一度。

$ ansible -i hosts 192.168.33.10 -a 'uname -a'
192.168.33.10 | success | rc=0 >>
Linux packer-virtualbox 3.2.0-4-686-pae #1 SMP Debian 3.2.46-1 i686 GNU/Linux

いいね。ちゃんと表示されたよ。ってことで第1関門突破できた。


簡単なPlaybookを作って適用する

第1関門を突破したので、次は簡単なPlaybookを作ってパッケージをインストールしてみます。

Playbookの書き方は適当につまみ食いして書こうかと思ったけれど、日本語のドキュメントは全部CentOSのyumでそのまま使えないので、本家ドキュメントの「Playbooks」と「Ansible Modules」を見ながらこんな風に書いてみた。

first-playbook.yml

---
- hosts: 192.168.33.10
  user: vagrant
  sudo: yes
  tasks:
  - name: install apache
    apt: pkg=apache2 state=present update_cache=yes

CentOSと違うのはyum:じゃなくてapt:かな。それ以外は同じのはず。apt:のオプションはpkg=にパッケージ名、state=presentはインストールされている状態。 update_cache=yesはインストール前にapt-get updateを実行。といった感じ。

文法チェックにかけてみたら

$ ansible-playbook -i hosts first-playbook.yml --syntax-check
Playbook Syntax is fine

大丈夫っぽい。 チュートリアルに沿ってタスクの確認もしてみる。

$ ansible-playbook -i hosts first-playbook.yml --list-tasks

playbook: first-playbook.yml

    play #1 (192.168.33.10): task count=1
        install apache

ちゃんとありますね。ドライランでテスト実行してみます。

$ ansible-playbook -i hosts first-playbook.yml --check

PLAY [192.168.33.10] *********************

GATHERING FACTS *********************
ok: [192.168.33.10]

TASK: [install apache] *********************
failed: [192.168.33.10] => {"failed": true}
msg: Could not import python modules: apt, apt_pkg. Please install python-apt package.

FATAL: all hosts have already failed -- aborting

PLAY RECAP *********************
192.168.33.10                  : ok=1    changed=0    unreachable=0    failed=1

おおっと。エラーが出てる。 aptの実行に必要なpython-aptパッケージが足りないみたい。

えー、aptが使えないからpython-aptをインストールするわけだけれどaptが使えないということは手詰まりか…。

と思ったけれど単純にapt-get -y install python-aptを実行してあげればよいだけなので、actionを使ってこういう風に書き足してみた。

---
- hosts: 192.168.33.10
  user: vagrant
  sudo: yes
  tasks:
  - name: install python-apt
    action: command /usr/bin/apt-get -y install python-apt
  - name: install apache
    apt: pkg=apache2 state=present update_cache=yes

もう一度チェックをかけてみる。

$ ansible-playbook -i hosts first-playbook.yml --check

PLAY [192.168.33.10] *********************

GATHERING FACTS *********************
ok: [192.168.33.10]

TASK: [install python-apt] *********************
skipping: [192.168.33.10]

TASK: [install apache] *********************
failed: [192.168.33.10] => {"failed": true}
msg: Could not import python modules: apt, apt_pkg. Please install python-apt package.

FATAL: all hosts have already failed -- aborting

PLAY RECAP *********************
192.168.33.10                  : ok=1    changed=0    unreachable=0    failed=1

相変わらずapache2のインストールはコケているけどpython-aptのインストールは大丈夫なので、これで適用してみます。失敗してもvagrantなのでやり直せばいいしね。

$ ansible-playbook -i hosts first-playbook.yml

PLAY [192.168.33.10] *********************

GATHERING FACTS *********************
ok: [192.168.33.10]

TASK: [install python-apt] *********************
changed: [192.168.33.10]

TASK: [install apache] *********************
changed: [192.168.33.10]

PLAY RECAP *********************
192.168.33.10                  : ok=3    changed=2    unreachable=0    failed=0

うまくいった。vagrant sshで入って確認します。

$ vagrant ssh

vagrant@packer-virtualbox:~$ dpkg -l | grep apache
ii  apache2                              2.2.22-13                 i386         Apache HTTP Server metapackage
ii  apache2-mpm-worker                   2.2.22-13                 i386         Apache HTTP Server - high speed threaded model
ii  apache2-utils                        2.2.22-13                 i386         utility programs for webservers
ii  apache2.2-bin                        2.2.22-13                 i386         Apache HTTP Server common binary files
ii  apache2.2-common                     2.2.22-13                 i386         Apache HTTP Server common files

vagrant@packer-virtualbox:~$ dpkg -l | grep python-apt
ii  python-apt                           0.8.8.2                   i386         Python interface to libapt-pkg
ii  python-apt-common                    0.8.8.2                   all          Python interface to libapt-pkg (locales)

ちゃんとインストールされてる。 apacheをインストールしたのでブラウザで http://192.168.33.10/ にアクセスすると「It Works!」のメッセージが見られるはず。ということで確認したら見れた。

-vvvオプションをつけるとAnsibleが動いている時にどんなことをしているのかわかるので、つけて、もう一度実行してみた。

$ ansible-playbook -i hosts first-playbook.yml -vvv

PLAY [192.168.33.10] *********************

(長いので中略)

TASK: [install apache] *********************
<192.168.33.10> ESTABLISH CONNECTION FOR USER: vagrant on PORT 22 TO 192.168.33.10
<192.168.33.10> EXEC /bin/sh -c 'mkdir -p $HOME/.ansible/tmp/ansible-1379035773.63-262833540768519 && chmod a+rx $HOME/.ansible/tmp/ansible-1379035773.63-262833540768519 && echo $HOME/.ansible/tmp/ansible-1379035773.63-262833540768519'
<192.168.33.10> REMOTE_MODULE apt pkg=apache2 state=installed update_cache=yes
<192.168.33.10> PUT /tmp/tmpV60Loq TO /home/vagrant/.ansible/tmp/ansible-1379035773.63-262833540768519/apt
<192.168.33.10> EXEC /bin/sh -c 'sudo -k && sudo -H -S -p "[sudo via ansible, key=gjakztadddddarndfsdlhrihshoxzcfr] password: " -u root /bin/sh -c '"'"' /usr/bin/python /home/vagrant/.ansible/tmp/ansible-1379035773.63-262833540768519/apt; rm -rf /home/vagrant/.ansible/tmp/ansible-1379035773.63-262833540768519/ >/dev/null 2>&1'"'"''
ok: [192.168.33.10] => {"changed": false}

PLAY RECAP *********************
192.168.33.10                  : ok=3    changed=1    unreachable=0    failed=0

apache2のインストールを見るとインストール済みなので「changed: false」となってますね。 シェルスクリプトを使ったデプロイだと、インストールされている場合のことも考えないといけないので、これはいいかも。

やっと一歩を踏み出せた。


まとめ

ansibleチュートリアルでつまづいている人は、ssh-agentでvagrantの鍵を登録すればいいよ!