読者です 読者をやめる 読者になる 読者になる

私をペロペロするがよい

lazy_dog のブログです。

Ansible を覚えてみた (その流れ)

Ansible の初歩までの道程をまとめた。

Ansible って何?

今話題の Chef とか Puppet とかと大体同じやつです。

  • 対象のサーバに対し、設定を行ったりファイルを設置したりする
  • 既に設定済みで何度やっても、対象の全てのサーバが「あるべき状態」に必ずなる → 冪等性
  • Playbook という、クライアントのサーバに対し何をやるか、という設定ファイルを作成する

初歩程度は使いこなせるまでの順序

  • 環境を整える
  • ansible コマンドで ping を飛ばせるようになる
  • データ形式YAML」を覚えつつ、Playbook を作れるようになる

こんな感じで覚えた。

環境を整える

Ansible はサーバ・クライアントの二つに分かれる。クライアントには Ansible のパッケージは一切不要。もちろん、サーバは自分自身がクライアントになることもできる。

Ansible に必要なのは下記の通り。

  • サーバ: Python 2.6 以降 (Python3 は非対応)、Ansible 本体
  • クライアント: Python2.4 以降 (同上)
  • SSH で繋がる環境

Arch Linux 環境で使う場合

Arch Linux は、デフォルトでインストールされている Python のバージョンが 3 系 のため、Python2 をインストールして、エイリアスを作成する必要がある。

[root@bag-ansible-01 ~]# pacman -S python2

... (略)

[root@bag-ansible-01 ~]# ln -s /usr/bin/python2 /usr/bin/python
[root@bag-ansible-01 ~]# python --version
Python 2.7.8

python って打って、Python2 が返ってこなければならない。この辺りは、Arch Linux の OS インストール時に処理しておくと楽。

SSH とか名前解決

Ansible は SSH を使用してクライアントに接続する。SSHPython のパッケージである paramiko を使用するので、OpenSSH には依存せずバージョンなどの指定は関係ない。

Ansible は名前もしくは IP アドレスを指定で、クライアントに接続する。指定の方法は後述する hosts (Ansible 専用) に記載することになるが、管理やコマンドの確認が楽になるため、名前解決できるように DNS か /etc/hosts に記載したほうがいいと思った。

Ansible インストール

サーバにのみ、Ansible パッケージをインストールする。クライアントは SSH が通り、Python の 2 系が使用可能であればよい。

[root@bag-ansible-01 ~]# pacman -S ansible
resolving dependencies...
looking for inter-conflicts...

Packages (8): python2-crypto-2.6.1-2  python2-ecdsa-0.11-2  python2-jinja-2.7.3-1  python2-markupsafe-0.23-1
              python2-paramiko-1.14.1-1  python2-setuptools-1:5.7-1  python2-yaml-3.11-1  ansible-1.7.1-1

....

他のディストリビューションなら、yum や pip でインストールできる。

Installation ? Ansible Documentation
http://docs.ansible.com/intro_installation.html

/etc/ansible/hosts を作成する

/etc/ansible/hosts に、Ansible で管理するホストを記載する。IP アドレス・ホスト名の両方が記載可能であるが、今回は管理が楽になるため DNS を通してホスト名での記載にする。裏の名前を用いて、管理セグメントで接続させる。

[root@bag-ansible-01 ~]# cat /etc/ansible/hosts
[VM-back]
b1-bag-ansible-01
b1-bag-pacmanrepo-01
b1-bag-rss-01
b1-bag-dns-01

[Physical-back]
b1-israel
b1-baghdad
b1-palestine

"[hoge]" の箇所はグループ名となり、このグループ名を対象に指定して、操作することができる。

/etc/ansible/ansible.config 設定

host_key_checking を False にした。これによって、~/.ssh/known_hosts のホストのキーを無視できる。セキュリティとの兼ね合いもあるが、とりあえず無効にした。

他はデフォルト。

サーバに ansible ユーザーを作成

Ansible 実行用のユーザーとして、"ansible" ユーザーを作成する。

[root@bag-ansible-01 ~]# useradd -m ansible
[root@bag-ansible-01 ~]# su ansible
[ansible@bag-ansible-01 ~]$ ssh-keygen
[ansible@bag-ansible-01 ~]$ passwd

これで、、

Ansible を使用できる最低限の環境は揃ったことになる。

Ansible を構成するファイルのおさらい

Ansible のサーバ側を構成する設定ファイルについて。

基本的に、Playbook と呼ばれる各クライアントを設定するレシピのファイルを除けば、Ansible のサーバの設定ファイルは、下記二つのみである。

  • /etc/ansible/ansible.cfg
  • /etc/ansible/hosts

ansible.cfg は、Ansible の全体的な設定を行うファイルである。hosts は上記で説明した通り、管理するクライアントをグループごとに羅列するファイルになる。

ansible コマンドで ping を飛ばせるようになる

ansible コマンドで、各クライアントに ping を飛ばしてみる。

[root@bag-ansible-01 ~]# ansible VM-back -m ping -u root --ask-pass
SSH password:
b1-bag-dns-01 | success >> {
    "changed": false,
    "ping": "pong"
}

b1-bag-ansible-01 | success >> {
    "changed": false,
    "ping": "pong"
}

....

無事、"pong" と返ってきた。サーバとクライアントの疎通が正常に行われていることが分かる。もし上手くいかない場合、python へのバージョンが通っていないか、ssh での接続ができていない可能性がある。ssh コマンドで接続したりして、正常に繋がるか確認すると良い。

ansible コマンド詳細

上のコマンドは、下記の通りとなる。

# ansible {ホスト名・IP アドレス、もしくはグループ名} -m {実行モジュール名} -u {ユーザー名} --ask-pass
 → "--ask-pass" は、ssh 鍵交換でのログインを行わない場合のパスワード指定をするか否か、のオプション。

"-m" で指定するモジュールは、Ansible で用意されているものとなり、シェルで実行できるファイルではない。ちなみに "-a" で、モジュールに対するオプションを指定することができる。

この通り、ansible コマンドで全ての動作を行えるが、より複雑なことをしたい場合、ワンライナーのコマンドでは限界が出てくる。なので、Playbook という「何をやりたいか」が記載されたファイルを作成し、これを ansible-playbook コマンドに読み込ませ実行させることで、より高度で複雑、かつ大規模な運用を行うことができる。

データ形式yaml」を覚えつつ、Playbook を作れるようになる

Playbook は「どのホストに対し、何をやりたいか」ということを記載した設定ファイルとなる。Playbook は YAML という形式を採用しており、シンプルに見えるが、プログラマではない人間の固い頭では理解が難しく、書くに難しい。。。

YAML を覚えよう

おいらが説明するよりかは、他の方の説明の方が大変分かりやすいので、そちらを提示いたしやす。。。御参考させて頂いたのが下記。

Yamlファイル - Bukkit Japan Wiki
http://bukkitwiki.jp/Yaml%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB
ansible使いのためのYAML入門 - @znz blog
http://blog.n-z.jp/blog/2014-06-21-ansible-yaml.html
YAML入門 (全9回) - プログラミングならドットインストール
http://dotinstall.com/lessons/basic_yaml

おいらの雑な覚えかた

本当に雑で恐縮だが、、、同じ色の物がリスト (塊) であると意識したら理解できた。

work ディレクトリ準備

Playbook を書く前に、作業用ディレクトリを準備し、その中で Playbook や設定ファイルなどを格納するようにする。きちんとしたフォルダ構成であれば Mercurial や git でも管理しやすくなる。

/etc/ansible/config/
.
`-- roles
    `-- common
        |-- defaults
        |-- files
        |   `-- tmp
        |-- meta
        `-- tasks

Best Practice なディレクトリ構成については、公式のドキュメントを含めて、色々な所で論じられているので参考にすると吉。

Best Practices ? Ansible Documentation
http://docs.ansible.com/playbooks_best_practices.html
Ansibleのファイルとディレクトリ管理 | /var/log/azumakuniyuki
http://blog.azumakuniyuki.org/2014/05/manage-files-for-ansible.html

どういう単位でフォルダを作成しなければならないかとか、色々難しいところ。

Playbook を書いてみる: ユーザーの作成

"/etc/ansible/config/roles/common/tasks" に、"ansible" ユーザーを作成する Playbook を作ってみる。モジュールは user を使用する。

---
# Add ansible user
- hosts: VM-back
  sudo: yes
  vars:
    password: <<hogehoge>>

  tasks:
    - name: Add ansible user
      user: name=ansible password={{password}}

パスワードは /etc/shadow と同じくハッシュ化したパスワードになる。SHA-512 で作っておけば、セキュリティ的には基本問題ない。

※ インターネット上では、"$1" を指定して MD5 でパスワード作ってる人が何人かいたので。。。理解なしのコピペは本当に危険です。

ひつまぶし食べたい: /etc/shadowについて勉強してみた
ddhttp://hitsumabushi-pc.blogspot.jp/2011/12/etcshadow.htmlMan page of CRYPT
http://linuxjm.sourceforge.jp/html/LDP_man-pages/man3/crypt.3.html
user - Manage user accounts ? Ansible Documentation
http://docs.ansible.com/user_module.html

実行してみよう

ansible-playbook コマンドで実行する。

[root@bag-ansible-01 tasks]# ansible-playbook 01_Add_ansible_user.yml -u root --ask-pass
SSH password:

PLAY [VM-back] ****************************************************************
ok: [b1-bag-ansible-01]
ok: [b1-bag-dns-01]
ok: [b1-bag-rss-01]
ok: [b1-bag-pacmanrepo-01]

TASK: [Add ansible user] ******************************************************
ok: [b1-bag-ansible-01]
ok: [b1-bag-pacmanrepo-01]
ok: [b1-bag-dns-01]
ok: [b1-bag-rss-01]

PLAY RECAP ********************************************************************
b1-bag-ansible-01          : ok=2    changed=0    unreachable=0    failed=0
b1-bag-dns-01              : ok=2    changed=0    unreachable=0    failed=0
b1-bag-pacmanrepo-01       : ok=2    changed=0    unreachable=0    failed=0
b1-bag-rss-01              : ok=2    changed=0    unreachable=0    failed=0

対象のマシンに対し、ansible ユーザーが作成され、パスワードも設定された。

ansible-playbook コマンド詳細

# ansible-playbook {Playbook ファイル名.yml} -u {実行ユーザー} --ask-pass
 → "--ask-pass" は、パスワード指定をするか否か、のオプション。

Playbook: ansible ユーザーの ssh 公開鍵を追加

先程作成した ansible ユーザーに対して、公開鍵を ~/.ssh/authorized_keys に追加する。

---
- hosts: VM-back
  tasks:
  - name: Add authorized key ansible user
    authorized_key: user=ansible key="{{ lookup('file', '/home/ansible/.ssh/id_rsa.pub') }}"

これで、ansible ユーザーで、各ホストに ansible ユーザーで ssh 鍵交換ログインができるようになった。

まとめ

Playbook を作成するところまで。この調子で Playbook を増やしていけば、段々と覚えていけるはず。

今後は、大規模になった場合の Playbook の分割のセオリーや、テクニックを覚えていきたい。

参考

Ansible Documentation ? Ansible Documentation
http://docs.ansible.com/index.html
Ansible チュートリアル | Ansible Tutorial in Japanese
http://yteraoka.github.io/ansible-tutorial/