少しくらいAnsibleを使ってみようと思ってブログや公式ドキュメントを読んでみたのでメモ。
参考にした主なものは以下のリンク。
Ansibleとは?みたいないのはリンクを読むとよくわかった。
- Ansibleの公式ドキュメント
- Playbookのサンプル
- Ansibleの概要を知るのにとてもよかった。
構成
ChefとかPuppetとは違ってこちらはAnsibleから対象のサーバに接続していく感じ。
対象のサーバにはとくにエージェントとかはいらない。
インストール
ほとんどパッケージ管理とかでいけるのでとても簡単。
Via Pip
$ sudo easy_install pip
$ sudo pip install ansible
Via Yum
$ sudo rpm -ivh http://ftp.riken.jp/Linux/fedora/epel/6/i386/epel-release-6-8.noarch.rpm
$ sudo yum install ansible
Via Apt
$ sudo apt-add-repository ppa:rquillo/ansible
$ sudo apt-get update
$ sudo apt-get install ansible
Via Homebrew
$ brew update
$ brew install ansible
インストールされた対象バージョン
$ ansible --version
ansible 1.6.2
基本的な書式
ansibleコマンドの後に-mオプションでモジュールを指定しても良いし-aオプションで直接コマンドを指定してもOK。
$ ansible 対象 -m モジュール
$ ansible 対象 -a 'コマンド'
実行基本例
pingモジュールは対象へのチェックとかに使える。
$ ansible all -m ping
target01.okochang.com | success >> {
"changed": false,
"ping": "pong"
}
$ ansible all -a "uname -r"
target01.okochang.com | success | rc=0 >>
3.10.35-43.137.amzn1.x86_64
対象ホストの指定方法
設定ファイル
以下のいずれかで良い。
- /etc/ansible/hosts
- export ANSIBLE_HOSTS="your config path"
設定ファイル内の書き方
基本的にはホスト名を書くだけでOKだけど、色々な書き方が出来る。
# グループ化
[webservers]
www01.okochang.com
www02.okochang.com
# 接続先のポートをデフォルトから変える
db01.okochang.com:22222
# IPアドレスを指定する
local.okochang.com ansible_ssh_port=22 ansible_ssh_host=192.168.0.10
# 範囲指定とかも出来る
app-[01:10].okochang.com
app-[a:d].okochang.com
# 対象毎にコネクションのタイプも指定出来る
localhost ansible_connection=local
other1.okochang.com ansible_connection=ssh ansible_ssh_user=ec2-user
# 変数を指定したりも出来る(ホスト毎)
host1 http_port=80 maxRequestPerChild=101
host2 http_port=8080 maxRequestPerChild=102
# グループ毎に変数を指定する
[foo-group]
host1
host2
[foo-group:vars]
ntp_server=ntp.okochang.com
proxy_servers=proxy.okochang.com
コマンド実行時
ワイルドカードが使える
$ ansible webserver* -m ping
複数を指定することが出来る
$ ansible webservers:dbservers -m ping
グループのうち特定ホストを除外する事も出来る
$ ansible webservers:\!webserver01 -m ping
ansibleコマンド実行時の便利オプション
やんごとなき理由ででSSHのパスワード認証を使いたい
$ ansible all -m ping --ask-pass
SSHの秘密鍵を指定したい
$ ansible all -m ping --private-key="~/.ssh/yourkey.pem"
接続先のSSHユーザーを指定したい(デフォルトはカレント)
$ ansible all -m ping -u ec2-user
sudoで実行したい
$ ansible all -m ping -u ec2-user --sudo
sudoするユーザーを指定したい
$ ansible all -m ping -u ec2-user --sudo --sudo-user okochang
sudoするときにはパスワードが必要なんですけどって場合
$ ansible all -m ping -u ec2-user --sudo --ask-sudo-pass
時間がかかる処理の場合はタイムアウトを指定
$ ansible webserver01 -B 180 -a "sleep 120"
設定ファイル
- /etc/ansible/ansible.cfg
- ~/.ansible.cfg
上記のいずれかで設定でき、デフォルトの動作を指定するものが多かった印象。
# 接続するときにホスト公開鍵の検証をするかしないか
$ host_key_checking = False
# リモード接続するときに平行して生成するプロセス数
forks=5
# ホストを指定する方法
hostfile=/etc/ansible/hosts
# ログファイルのパス
log_path=/var/log/ansible.log
# 色の設定
nocolor=0
# デフォルトで使用する接続先のポート
remote_port=22
AWSへの対応
AWSを使ってたりすると接続先のIPが変わったり台数が変わったり頻繁にあるのでその対応。
導入編
Githubにpythonのスクリプトとiniファイルが配布されている。
使うためにはbotoのインストールが必要だが、実行権限を付与するといい感じに使える。
$ sudo pip install boto
$ cd .ansible
$ curl -LO https://raw.github.com/ansible/ansible/devel/plugins/inventory/ec2.py
$ curl -LO https://raw.github.com/ansible/ansible/devel/plugins/inventory/ec2.ini
$ vi .bash_profile
export AWS_ACCESS_KEY_ID='YOURACCESSKEYID'
export AWS_SECRET_ACCESS_KEY='YOURSECRETACCESSKEY'
export EC2_INI_PATH=~/.ansible/ec2.ini
$ chmod +x .ansible/ec2.py
$ .ansible/ec2.py --list
使い方
全リージョンのEC2インスタンスに実行
$ ansible ec2 -i ~/.ansible/ec2.py -u ec2-user -m ping
リージョンを限定して実行
$ ansible ap-northeast-1 -i .ansible/ec2.py -u ec2-user -m ping
AZを限定して実行
$ ansible ap-northeast-1a -i .ansible/ec2.py -u ec2-user -m ping
セキュリティグループを限定して実行
$ ansible security_group_okochang-group -i .ansible/ec2.py -u ec2-user -m ping
タグを限定して実行(Nameタグにweb01の場合)
$ ansible tag_Name_web01 -i .ansible/ec2.py -u ec2-user -m ping
モジュール
Ansibleでの処理される小さい実行の単位。ChefでいうところのResources。
使い方のメモ
shell
$ ansible webservers -m shell -a 'ping -c 3 google.co.jp'
copy
$ ansible webservers -m copy -a "src=~/test.txt dest=/tmp/test.txt"
file
$ ansible webservers -m file -a "dest=/tmp/test.txt mode=600 owner=foo group=var"
yum
$ ansible webservers -m yum -a "name=httpd state=installed" -u ec2-user --sudo
$ ansible webservers -m yum -a "name=postfix state=removed" -u ec2-user --sudo
service
$ ansible webservers -m service -a "name=httpd state=started" -u ec2-user --sudo
$ ansible webservers -m service -a "name=httpd state=restarted" -u ec2-user --sudo
$ ansible webservers -m service -a "name=httpd state=stopped" -u ec2-user --sudo
$ ansible webservers -m git -a "repo=git://github.com/serverworks/aws-spec.git dest=/opt/aws-spec version=HEAD"
gitモジュール
$ ansible webservers -m git -a "repo=git://github.com/serverworks/aws-spec.git dest=/opt/aws-spec version=HEAD"
Playbooks
moduleを組み合わせて対象サーバに実行する処理をまとめて書いたもの。
Chefのレシピに近くて、書き方はyml形式。
pingモジュールを使ったplaybook
# test.con.yml
- hosts: all
remote_user: ec2-user
tasks:
- name: test connection
ping:
実行
$ ansible-playbook .ansible/playbooks/test_con.yml
shellモジュールを使ったplaybook
# shell_result.yml
- hosts: ec2
remote_user: ec2-user
tasks:
- name: run command and ignore the result
shell: /bin/echo foo
ignore_errors: True
先ほどのAWSに対応したスクリプトと合わせて使うことも出来る
$ ansible-playbook -i .ansible/ec2.py -u ec2-user .ansible/playbooks/shell_result.yml
Webサーバ用のPlaybookはこんな感じになる
# webserver.yml
- hosts: tag_Name_target01
vars:
http_port: 80
max_clients: 200
remote_user: ec2-user
sudo: yes
sudo_user: root
tasks:
- name: ensure apache is installed
yum: pkg=httpd state=installed
- name: write the apache config file
template: src=~/httpd.conf.j2 dest=/etc/httpd/conf/httpd.conf
notify:
- restart apache
- name: create virtual host file for {{ vhost }}
template: src=~/vhost.conf.j2 dest=/etc/httpd/conf.d/{{ vhost }}.conf
- name: ensure apache is running
service: name=httpd state=started
handlers:
- name: restart apache
service: name=httpd state=restarted
オプションで変数を指定したりが出来る
$ ansible-playbook -i .ansible/ec2.py -u ec2-user .ansible/playbooks/webserver.yml -e vhost=foo
ファイルをincludeする事も出来る
# foo_var.yml
- name: echo foo
command: /bin/echo foo
- name: echo var
command: /bin/echo var
# hoge.yml
- hosts: ec2
remote_user: ec2-user
tasks:
- include: foo_var.yml
実行
$ ansible-playbook -i .ansible/ec2.py -u ec2-user .ansible/playbooks/hoge.yml
Playbook Roles
Playbookを簡単に再利用出来るようにした仕組み。
決められた構成で配置すると自動的に再利用が出来る。
以下はcommonとwebserversのRoleの場合のディレクトリ構成。
https://github.com/okochang/ansible-sample-project
$ tree
.
├── roles
│ ├── common
│ │ ├── files
│ │ ├── handlers
│ │ │ └── main.yml
│ │ ├── meta
│ │ ├── tasks
│ │ │ └── main.yml
│ │ ├── templates
│ │ │ └── clock.j2
│ │ └── vars
│ └── webservers
│ ├── files
│ ├── handlers
│ │ └── main.yml
│ ├── meta
│ ├── tasks
│ │ ├── install_httpd.yml
│ │ └── main.yml
│ ├── templates
│ │ └── vhosts.conf.j2
│ └── vars
└── site.yml
実行する場合はこんな感じ。
$ ansible-playbook -i ~/.ansible/ec2.py -u ec2-user ./site.yml