サーバの初期構築が面倒になってきたので、今更 Ansible を使いはじめました。
使い方も非常にシンプルで簡単ですし、エージェントのインストールが不要なところも素敵です。
本投稿では、基本的なAnsibleの利用方法とPlaybookの書き方を紹介します。
構成管理ツールについて
まず、構成管理ツールとはなんぞやと。
例えば、現在僕の自宅にはVMサーバがあり
そこには10台程仮想ホストを運用しています。
で、検証環境なんかで新しくサーバを構築したりしますが
手動で行う初期設定とかが結構大変なんです。
また、とあるパッケージを仮想ホスト全台にインストールしたい時や
ミドルウェアに脆弱性が見つかったときはアップデートが必要ですが、
10台もサーバがあると、1台1台作業していくはすごい大変ですね。
このような環境構築やデプロイなどを何度も行う場合は自動化したいところです。
導入の背景
サーバ作業を自動化しようと考えたとき、
最初に思い浮かぶのはシェルスクリプトを利用することではないでしょうか。
シェルスクリプトを使って環境構築やリリースを自動化することは可能ですが、
これにはいくつか問題があります。
・自動化したい作業内容を、環境毎にスクリプトを作らなきゃいけない。
・シェルスクリプトが実行途中で失敗した場合、実行前の状態に戻さなきゃならない。
(再実行すると不具合が起こる可能性がある)
・依存するライブラリのバージョンアップなどにより実行が失敗する可能性がある。
このような問題を解決するには、構成管理ツールを使うと便利です。
構成管理ツールは、処理を自動化するという観点ではなく、最終的にマシンを目的の状態にする、という観点で作成されたツールのことです。
例えば、「ユーザーを追加する」という目的を考えてみます。
シェルスクリプトではそのまま「ユーザーを追加する」という操作を書くため、
既にユーザーが存在する場合、何も考慮しないと再実行時に
「既にユーザーが存在する」というエラーとなってしまいます。
一方、構成管理ツールでは
「ユーザーが追加されている状態にする」という命令を使います。
「既に目的の状態となっているかどうか(=ユーザーが存在するかどうか)」という判断は
構成管理ツールが行ってくれるため、自前で判定処理を書く必要がありません。
上記の構成管理ツールの例のように
「同じ操作を何度やっても最終的な状態が同じになる」という性質を
「冪等性(べきとうせい)」といいます。
環境構築やデプロイでは、冪等性を意識して処理を自動化することが望ましく、
構成管理ツールはその助けとなります。
Ansibleを使ってみる
という訳で早速作業してみたいと思います。
実際の流れは以下の感じ。
1.Ansibleをインストールする
2.Ansibleコマンドを実行する
3.playbookを作成・実行する
同じ様な構成管理ツールとして、ChefとかPuppetがありますが
これらと違ってAnsibleは、対象のサーバに接続していく感じ。
対象のサーバにはとくにエージェントとかいらないのもAnsibleの魅力。
Ansibleから対象サーバへはSSH経由で操作が行われます。
1.Ansibleをインストールする
今回作業環境となるサーバがDebianになるので、インストールはaptから行います。
[bash]
apt-add-repository ppa:rquillo/ansible
apt-get update
apt-get install ansible
[/bash]
Redhat系でもyumで簡単にインストールできます。
[bash]
rpm -ivh http://ftp.riken.jp/Linux/fedora/epel/6/i386/epel-release-6-8.noarch.rpm
yum install ansible
[/bash]
インストールされた対象バージョン
[bash]
root@manage:/home/harada# ansible –version
ansible 2.2.0.0
config file = /etc/ansible/ansible.cfg
configured module search path = Default w/o overrides
[/bash]
インストールすると /etc/ansible 配下には以下のファイルとディレクトリができます。
[bash]
root@manage:~# ll /etc/ansible/
total 52
-rw-r–r– 1 root root 14413 Nov 20 17:34 ansible.cfg
-rw-r–r– 1 root root 404 Nov 20 16:45 hosts
drwxr-xr-x 2 root root 4096 Nov 20 17:34 roles/
[/bash]
・ansible.cfg
ansible の設定ファイル
・hosts
ansible で実行させる対象ホストを指定するファイル。
ansible コマンドのオプションでhostsファイルを指定しなければ
このファイルに記載されている内容が読まれます。
・roles ディレクトリ
インストール後は空のディレクトリですが、ここに playbook を複数格納して
メインの playbook で include ディレクティブを使用して取り込むことができます。
ansibleの設定
ansible.cfgの一部設定を編集します。
下記へと変更します。
[bash]
root@manage:/etc/ansible# vi ansible.cfg
ask_sudo_pass = True
ask_pass = True
remote_user = harada
[/bash]
ask_passのコメントアウトを外すことにより
ansibleコマンドの実行時にSSHに必要なパスフレーズを問い合わせるようになります。
※デフォだとSSHログインが鍵認証になります。
また、sudoする際はパスワードが必要になるので、ask_sudo_passもTrueにしておきます。
加えて、SSHを行うために必要なユーザも指定しておきます。
remote_userの箇所は各々の環境に合わせてください。
2.Ansibleコマンドを実行する
以下、管理サーバにて実施。
カレントディレクトリにて hosts という名前のファイル (インベントリファイルと呼ぶ。Ansible はこのファイルに記載したマシンにしかアクセスできない) を作成する。
ここでは10.0.0.3というホストを登録する。
[bash]
root@manage:~# echo 10.0.0.3 > hosts >> cat ./hosts
10.0.0.3
[/bash]
次に、Ansible を使って ping 疎通してみる。ここでは SSH パスワード認証するためのオプション -k を指定している。
[bash]
root@manage:/home/harada# ansible -i ./hosts 10.0.0.3 -u harada -k -m ping
SSH password:
10.0.0.3 | FAILED > to use the ‘ssh’ connection type with passwords, you must install the sshpass program
[/bash]
おっと、失敗。
なにやらsshpassってのがインストールされてねぇよと怒られている様です。
という訳でパッケージをインストールします。
[bash]
root@manage:/home/harada# apt-get install sshpass
Reading package lists… Done
Building dependency tree
Reading state information… Done
The following NEW packages will be installed:
sshpass
0 upgraded, 1 newly installed, 0 to remove and 3 not upgraded.
Need to get 10.2 kB of archives.
After this operation, 51.2 kB of additional disk space will be used.
Get:1 http://jp.archive.ubuntu.com/ubuntu/ trusty/universe sshpass i386 1.05-1 [10.2 kB]
Fetched 10.2 kB in 0s (78.0 kB/s)
Selecting previously unselected package sshpass.
(Reading database … 61614 files and directories currently installed.)
Preparing to unpack …/sshpass_1.05-1_i386.deb …
Unpacking sshpass (1.05-1) …
Processing triggers for man-db (2.6.7.1-1ubuntu1) …
Setting up sshpass (1.05-1) …
[/bash]
で、再度実行。
[bash]
root@manage:/home/harada# ansible -i ./hosts 10.0.0.3 -u harada -k -m ping
SSH password:
previous known host file not found
10.0.0.3 | FAILED => Using a SSH password instead of a key is not possible because Host Key checking is enabled and sshpass does not support this. Please add this host’s fingerprint to your known_hosts file to manage this host.
[/bash]
またもや失敗。
このサーバへは一度もSSHログインをしていなかったのだが、どうやらフィンガープリントへ登録しておく必要があるみたいです。
なので一度フィンガープリントへの登録が済ませておきます。
[bash]
root@manage:/home/harada# ssh harada@10.0.0.3
The authenticity of host ‘10.0.0.3 (10.0.0.3)’ can’t be established.
RSA key fingerprint is ba:73:75:0c:7c:7a:db:40:2b:53:04:3a:94:7a:ba:13.
Are you sure you want to continue connecting (yes/no)? yes
[/bash]
で、再チャレンジ。
[bash]
root@manage:/home/harada# ansible -i ./hosts 10.0.0.3 -u harada -k -m ping
SSH password:
10.0.0.3 | SUCCESS > {
"changed": false,
"ping": "pong"
}
[/bash]
上記の様な応答が返ってくればOK。
3.playbookを作成・実行する
moduleを組み合わせて対象サーバに実行する処理をまとめて書いたもの。
Chefのレシピに近くて、書き方はyml形式。
[bash]
root@manage:/etc/ansible/roles# cat ping.yml
—
– hosts: all
remote_user: harada
tasks:
– name: pingしてみる
ping:
[/bash]
hostsに登録してあるサーバすべてにpingモジュールで疎通確認をするもの。
書き方はこんなかんじ
[bash]
—
– hosts: all
remote_user: harada
tasks:
– name: pingしてみる
ping:
「—」はここから定義を始めますという意味です。
実行先の情報と実行先の権限を指定したり、変数を定義します。
– と hosts、hosts: と all の間はスペースが絶対に必要です。
tasks: はここから先は実行する項目を書くよという意味です。
タスク(項目)ごとに – name: で実行する項目を指定してあげます。
項目ごとに「-」をつけてあげます。
hosts の行から一貫した作業になりますので、インデントして階層構造にしています。
[/bash]
※実行結果
[bash]
root@manage:/etc/ansible/roles# ansible-playbook ping.yml
SSH password:
SUDO password[defaults to SSH password]:
PLAY [all] *********************************************************************
TASK [setup] *******************************************************************
ok: [localhost]
ok: [web]
ok: [db]
ok: [vyos]
ok: [dev]
ok: [kanshi]
ok: [ns]
TASK [pingしてみる] ****************************************************************
ok: [web]
ok: [vyos]
ok: [db]
ok: [localhost]
ok: [kanshi]
ok: [ns]
ok: [dev]
PLAY RECAP *********************************************************************
db : ok=2 changed=0 unreachable=0 failed=0
dev : ok=2 changed=0 unreachable=0 failed=0
kanshi : ok=2 changed=0 unreachable=0 failed=0
localhost : ok=2 changed=0 unreachable=0 failed=0
ns : ok=2 changed=0 unreachable=0 failed=0
vyos : ok=2 changed=0 unreachable=0 failed=0
web : ok=2 changed=0 unreachable=0 failed=0
[/bash]
こんな感じでOKが帰ってくれば成功。
unreachableとかfailedとか帰ってきたら失敗してますよー的な。
ちなみにsetupはサーバ情報を取得してる様で、設定でoffにすることもできます。
もうひとつ、yumでパッケージのupdadeをかけるときのplaybook
[bash]
root@manage:/etc/ansible/roles# cat yum_upgrade.yml
—
– hosts: web db kanshi ns dev
remote_user: harada
become: yes
tasks:
– name: yum update
yum: name=* state=latest
[/bash]
ansibleのモジュールにはyumコマンドが存在し、
stateにlatest指定で最新版に更新する、というものになります。
ちなみにyumモジュールのオプションはこんな感じ。
パラメータ | 必須 | デフォルト値 | 選択肢 | 説明 |
conf_file | no | – | – | 対象ホストで /etc/yum.conf以外のファイルを使用する場合に指定する |
disable_gpg_check | no | no | yes no |
パッケージの署名チェックを無効にする |
disablerepo | no | – | – | 無効にするリポジトリを指定する。複数の場合はカンマ区切りで記述する。 |
enablerepo | no | – | – | 有効にするリポジトリを指定する。複数の場合はカンマ区切りで記述する。 |
list | no | – | – | ? |
name | yes | – | – | パッケージ名を指定する。『state=latest』かつ『name=*』を指定した場合は『yum -y update』を実行する。URLやローカルパスの指定も可能。 |
state | no | present | present latest absent |
present:インストールされていること。 latest:最新に更新する。 absent:インストールされていない。 |
少しだけ触ってみただけですが、nagiosの監視追加とか、NTPの同期先変更とか
遊べそうなことはたくさんありそうなので、利用価値は高いツールです。
※参考サイト
http://iwamocchan11.hatenadiary.jp/entry/2015/09/23/193419
http://qiita.com/yamasaki-masahide/items/3bd2392cad9ac8811197
http://qiita.com/okochang/items/f264825e538dbce5dfac
http://yktmnb.b.osdn.me/?p=151
http://centos.sabakan.red/entry/2015/07/01/140000
http://blog.aotak.me/post/124898363221/ansible-%E3%81%AE%E3%82%A4%E3%83%B3%E3%83%99%E3%83%B3%E3%83%88%E3%83%AA%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E3%82%92%E4%BD%BF%E3%81%A3%E3%81%A6%E3%83%AA%E3%83%A2%E3%83%BC%E3%83%88%E3%83%9B%E3%82%B9%E3%83%88%E3%81%AB%E6%8E%A5%E7%B6%9A%E3%81%99%E3%82%8B
http://blog.pg1x.com/entry/2016/01/19/222120
http://www.atmarkit.co.jp/ait/articles/1603/24/news014.html