実際に仕事でも使ってるAnsibleだけど、使い始めた頃から本書にはお世話になってます。
改めて読み返してみると、最初のハードルから様々なプロダクトとの連携や高速化など、
痒いところに手がとどく内容だなと思います。
初めてAnsibleを触る人にも良いと思います。
あまり馴染みのないPython製のCRMをベースに話が進んでいく箇所は若干難儀しましたが。
特に面白かった所
前述の通りAnsibleの初歩から丁寧に解説してくれた上で、応用までしっかり導いてくれる一冊でした。
ある程度仕事で使った今でも、変数の付け方や高速化の手法など、細かな書き方の指針なんかも書いてくれていて、
はっとさせられます。
考えたこと
DockerやVagrantとの連携に関してはやはり実際に書いてみるのが一番だなと感じました。
それぞれのツールの役割が読んでるだけではよくわからなくなってしまいます。
写経の大事さが身にしみました。
ただ、Dockerのサンプルソースが一部分現時点では動かなくなっていました。
本書は1系の頃に書かれたこともあり、賞味期限も切れかけているのかなとも思います。
まとめ
この分野も日々進化しており、原著は2nd Editionが出ているようです。
まだ翻訳は出ていませんが、GitHubのサンプルソースをちらっとみた限り、
章立てもだいぶ変わっているようです。翻訳版は出るのでしょうかね、楽しみですね。
以前試したServerspecですが、Ansibleと連携するプロダクトがあるということで試してみました。
その名もansible_specです。
Ansibleで構成したサーバーの接続情報を共有したいというモチベーションはTestinfraと同様です。
やはり同じ接続設定をいろんなところに設定するのは避けたいところですよね。
インストール
gemでサクッとインストールします。特につまづくところはありませんでした。
1
| $ sudo gem install ansible_spec
|
設定
ansibleの設定がおいてあるディレクトリで下記を実行。
1
2
3
4
5
6
| $ ansiblespec-init
create spec
create spec/spec_helper.rb
create Rakefile
create .ansiblespec
create .rspec
|
.ansiblespec の内容は下記の通りです。
dynamic inventoryもサーポートしていて、inventoruyにはansibleのiオプションで指定するdynamic inventoryを実現するpythonスクリプトを指定します。
1
2
3
4
| ---
-
playbook: site.yml
inventory: ec2.py
|
site.ymlは下記の通りです。
hostsにはEC2のtagを指定しています。KeyはNameです。
roleにはテストのある位置を指定しています。
1
2
3
4
| - name: gside-TDD
hosts: tag_Name_gside_gentoo
roles:
- apache
|
テストはAnsibleでいうroleと同じディレクトリに配置します。
今回は roles/apache/spec/apache_spec.rb にファイルをおきました。内容は以前ServerSpecを試した時のものと同じです。。
ファイル名は *_spec.rb の形式でないといけないようです。
ディレクトリ構成に関しては確かに多くの構成はroleベースで書くことが多いので、roleを前提としている構成は実用には困らないかもしれません。
1
2
3
4
5
6
7
8
9
10
| require 'spec_helper'
describe service('apache2'), :if => os[:family] == 'gentoo' do
it { should be_enabled }
it { should be_running }
end
describe port(80) do
it { should be_listening }
end
|
実行
rake allで実行してもいいのですが、rake -T でテスト対象を一覧表示した上で個別に実行できます。
1
2
3
4
| $ rake -T
/usr/lib64/ruby/2.2.0/open3.rb:193: warning: Insecure world writable dir /usr/local/bin in PATH, mode 040757
rake all # Run serverspec to all test
rake serverspec:gside-TDD # Run serverspec for gside-TDD
|
これでテスト実行できると思ったのですが、このままだとうまく実行できませんでした。
実行結果の一部抜粋です。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
| $ rake serverspec:gside-TDD
/usr/lib64/ruby/2.2.0/open3.rb:193: warning: Insecure world writable dir /usr/local/bin in PATH, mode 040757
Run serverspec for gside-TDD to {"uri"=>"52.198.30.198", "port"=>22}
/usr/bin/ruby22 -I/usr/local/lib64/ruby/gems/2.2.0/gems/rspec-support-3.5.0/lib:/usr/local/lib64/ruby/gems/2.2.0/gems/rspec-core-3.5.4/lib /usr/local/lib64/ruby/gems/2.2.0/gems/rspec-core-3.5.4/exe/rspec --pattern \{roles\}/\{apache\}/spec/\*_spec.rb
/usr/lib64/ruby/2.2.0/open3.rb:193: warning: Insecure world writable dir /usr/local/bin in PATH, mode 040757
No backend type is specified. Fall back to :exec type.
No backend type is specified. Fall back to :exec type.
No backend type is specified. Fall back to :exec type.
....
should be listening (FAILED - 3)
Failures:
1) Service "apache2" should be enabled
On host `52.198.30.198'
Failure/Error: it { should be_enabled }
expected Service "apache2" to be enabled
/bin/sh -c rc-update\ show\ \|\ grep\ --\ \\\\s\\\*apache2\\\\s\\\*\\\\\\\|\\\\s\\\*\\\(boot\\\|default\\\)
# ./roles/apache/spec/apache_spec.rb:5:in `block (2 levels) in <top (required)>'
...
|
自動生成される spec/spec_helper.rbspec を下記のように修正したら動きました。
1
2
| - connection = ENV['TARGET_CONNECTION']
+ connection = 'ssh'
|
これで実行すると正しく動きました。
なんか設定が漏れているのかもしれませんが、一旦良しとしています。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
| $ rake serverspec:gside-TDD
/usr/lib64/ruby/2.2.0/open3.rb:193: warning: Insecure world writable dir /usr/local/bin in PATH, mode 040757
Run serverspec for gside-TDD to {"uri"=>"52.198.30.198", "port"=>22}
/usr/bin/ruby22 -I/usr/local/lib64/ruby/gems/2.2.0/gems/rspec-support-3.5.0/lib:/usr/local/lib64/ruby/gems/2.2.0/gems/rspec-core-3.5.4/lib /usr/local/lib64/ruby/gems/2.2.0/gems/rspec-core-3.5.4/exe/rspec --pattern \{roles\}/\{apache\}/spec/\*_spec.rb
/usr/lib64/ruby/2.2.0/open3.rb:193: warning: Insecure world writable dir /usr/local/bin in PATH, mode 040757
Service "apache2"
should be enabled
should be running
Port "80"
should be listening
Finished in 0.09668 seconds (files took 1.2 seconds to load)
3 examples, 0 failures
|
まとめ
インフラの構成管理とテストを色々試してきました。
Terraform, Ansibleを構成管理ツールとして、Testinfra又は Serverspec + ansible_spec で低レベルのテスト、infratasterで高レベルのテストを実施することができました。
それぞれのツールをもう少し深掘りしたいところですが、これでモダンなインフラへの入り口に立てたかなと思います。
AnsibleでGentooの環境を作れるのかなあと思ったら、モジュールが提供されていました。
Apacheをインストールしてデフォルトランレベルに登録するところまでやってみました。
Apacheのインストール
Ansibleの設定ファイルを書きます。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
| ---
- hosts: tag_Name_gside_gentoo
remote_user: gentoo
become: true
tasks:
- name: install apache
portage: >
package=apache
state=present
- name: add apache default runlevel
service: >
name=apache2
state=started
enabled=yes
|
ここでちょっとハマったのが、Ansibleを実行するホストだけでなくて、対象のホストのpythonのバージョンにも注意しないといけないことでした。
対象ホストがpython3系がデフォルトだったため、AttributeError: ‘dict’ object has no attribute ‘iteritems’ みたいなエラーが出てたので、pythonのデフォルトバージョンを2系にセットします。
1
2
3
4
5
| $ eselect python list
Available Python interpreters:
[1] python2.7
[2] python3.4 *
$ eselect python set 1
|
作成した設定ファイルを実行します。
1
| $ ansible-playbook gside.yaml -i ./ec2.py
|
Apacheの起動をテストする
Apacheをインストール・起動・デフォルトランレベルへの登録までできましたので、先日作ったServerSpecのテストを流してみます。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
| $ rake spec
(in /home/hoge)
/usr/bin/ruby21 -I/usr/local/lib64/ruby/gems/2.1.0/gems/rspec-support-3.5.0/lib:/usr/local/lib64/ruby/gems/2.1.0/gems/rspec-core-3.5.4/lib /usr/local/lib64/ruby/gems/2.1.0/gems/rspec-core-3.5.4/exe/rspec --pattern spec/gside.org/\*_spec.rb
/usr/local/lib64/ruby/gems/2.1.0/gems/rspec-core-3.5.4/lib/rspec/core/rake_task.rb:79: warning: Insecure world writable dir /usr/local/bin in PATH, mode 040757
Service "apache2"
should be enabled
should be running
Port "80"
should be listening
Finished in 0.09901 seconds (files took 1.02 seconds to load)
3 examples, 0 failures
|
まとめ
インスタンスの起動もTerraformでやったので、起動・セットアップ・テストまでコンソールからスムーズにできました。
TDDみたいな感覚でWebサーバーのセットアップができるのは非常い気持ちがいいですね。
仕事では利用しているAnsible。
プライベートで使っているサーバーも、構成管理することにしました。
まずは初期構築の部分をまとめてみました。
ansibleのインストール
Ansibleを利用するクライアント側にansibleをインストールします。
1
2
3
| $ pip install ansible
$ ansible --version
ansible 2.1.2.0
|
手元ではbotoが入ってなかったので、インストールしました。
Dynamic Inventoryのインストール
AWSのインスタンスをAnsibleで管理する場合、
インスタンスのIPではなく、Tag Nameで管理できると便利です。
Terminateして立ち上げ直した場合などはIPが変わりますし、
冗長構成の場合は複数台に対して同じ作業がしやすくなります。
そこで、Dynamic Inventoryという仕組みを使います。
ec2.pyとec2.iniをダウンロードします。
https://raw.githubusercontent.com/ansible/ansible/devel/contrib/inventory/ec2.py
https://raw.githubusercontent.com/ansible/ansible/devel/contrib/inventory/ec2.ini
動作確認です。
1
2
3
4
| $ export AWS_ACCESS_KEY_ID=XXXXXXXXXXXXXXXXXX
$ export AWS_SECRET_ACCESS_KEY=XXXXXXXXXXXXXXXXXXXXXXXXX
$ export AWS_DEFAULT_REGION=ap-noartheast-1
$ ./ec2.py --list
|
SSHの設定を書くために、同じディレクトリにansible.cfgを設置します。
sshの設定ファイルを読む設定と、Persistの設定を記載しています。
[ssh_connection]
control_path = %(directory)s/%%h-%%r
ssh_args = -o ControlPersist=15m -F ssh_config -q
scp_if_ssh=True
SSH接続する際の設定をssh_configに記載します。
接続ユーザーと鍵の設定をしています。
Host *
User ec2-user
IdentityFile /aws.pem
動作確認
ansibleコマンドでuptimeを打ってみます。
1
2
3
| ansible -i ec2.py tag_Name_gside -m command -a "uptime"
192.0.2.0 | SUCCESS | rc=0 >>
12:13:54 up 13 days, 14:16, 1 user, load average: 0.04, 0.03, 0.00
|
まとめ
そんなにハマるところはなかったですが、繋がらないなとハマったら、
sshの接続を疑うとこからはじめて見ましょう。
鍵の場所が正しくないとか、大体のミスは発見できます。