AWS
Ansible

Ansibleのドキュメントを読んでみたメモ

More than 1 year has passed since last update.

少しくらいAnsibleを使ってみようと思ってブログや公式ドキュメントを読んでみたのでメモ。

参考にした主なものは以下のリンク。

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