Dynamic Inventory – memo –

Ansible dynamic inventory + Zabbix APIで監視対象を動的に構成管理より
例えばローカルの/etc/hostsに存在するホスト名をinventoryとして使いたければ

inventory.sh
#!/bin/bash
HOSTS=$(cat /etc/hosts | grep -v ^# | awk '{print $2}')
HOSTS=$(echo "$HOSTS" | sed -e 's/^\(.*\)$/"\1"/g')
HOSTS=$(echo $HOSTS | sed -e 's/\s/,/g')
echo "{\"all\": {\"hosts\": [$HOSTS]}}"

のようなスクリプトを書いて渡してやるだけでいい。

Dynamic Inventoryを使ってみるより
ansibleは、インベントリファイルに実行権限が付いていなければ、通常のインベントリファイルとして読み込み、
実行権限が付いていれば実行した結果帰ってくるjsonを読み込むという処理をしているよう。

Dynamic Inventory

Dynamic Inventoryを一部意訳してみた。
たぶん誤訳もある。そして意味がわかりにくいところもある。

Topics

クラウドやLDAPやCobberなど違ったプラットフォーム上のシステムについて、
inventoryファイルを管理することが可能である。

Ansible TowerではDBにWEBやRESTからアクセスできるinventry情報を保持する。
またすべてのホスト情報もDBに持つことで、playbook履歴を追うことが可能。

Example: The Cobbler External Inventory Script

多くのハードウェアを管理しているAnsibleユーザがCobberを利用していると推測される。
(元Ansible, Incで働いていたMichael DeHaanが作成している)

…中略…

Example: AWS EC2 External Inventory Script

AWSを利用している場合、ホストの増減が発生するためinventoryファイルの管理は難しいため、
EC2 external inventory scriptを利用したほうがよい。

このスクリプトを利用するためには2つの方法がある。
1つめは-iオプションを利用してansibleコマンドを実行することである。

ansible -i ec2.py -u ubuntu us-east-1d -m ping

2つめはスクリプトを/etc/ansible/hostsにコピーし、chmod +xを実行する。
また ec2.iniを/etc/ansible/ec2.iniにコピーする。
そしていつも通りにansibleを実行すること。

AWSへのAPI呼び出しを正常に行うには、Boto(PythonインターフェイスをAWSに設定する)を設定すること。
利用可能なさまざまな方法がありますが、最も簡単なのは、2つの環境変数をエクスポートすることだけです。

export AWS_ACCESS_KEY_ID='AK123'
export AWS_SECRET_ACCESS_KEY='abc123'

スクリプトを実行して、正しく動作するか確認可能

cd contrib/inventory
./ec2.py --list

しばらくすると、すべてのリージョンのEC2 inventoryが表示される。
Botoプロファイルを利用して、複数AWSアカウントを管理する場合–profile PROFILEというオプションをec2.pyに渡す。
プロファイル例は以下となる。

[profile dev]
aws_access_key_id = <dev access key>
aws_secret_access_key = <dev secret key>

[profile prod]
aws_access_key_id = <prod access key>
aws_secret_access_key = <prod secret key>

ec2.py –profile prod を実行することで、prodアカウントのinventoryを取得できる。
(ただしansible-playbookではサポートされていない)
AWS_PROFILE=prod ansible-playbook -i ec2.py myplaybook.ymlといった形でansible-playbookを利用できる。
ec2.iniを編集することで使用していないリージョンを除くことなどが可能。

キャッシュコントロールや宛先変数をec2.iniで設定することも可能。
デフォルトではAWSのすべてのサービス用に設定されているが、コメントアウトすることで制御可能。
例えばRDSやelasticacheを利用しないのであれば、Falseを設定する。

[ec2]
...

# To exclude RDS instances from the inventory, uncomment and set to False.
rds = False

# To exclude ElastiCache instances from the inventory, uncomment and set to False.
elasticache = False

inventoryファイルは名前と宛先アドレスを結びつけるだけです。
デフォルトで設定としてEC2外からansibleを実施するようになっていますが、これは最も効率的な方法ではありません。

EC2内でansibleを実行している場合、内部DNSとIPの利用は外部DNS名を使うよりも理にかなっています。
この場合ec2.iniのdestination_variableを内部DNSとして編集できます。
VPCを利用している時に特に有用です。

EC2 external inventoryは複数のグループへのマッピングが可能です。
(Global,Instance ID,Region,Availability Zone,Security Group,Tagsなど)

–host=HOST オプションを利用して特定EC2で利用できる変数を取得できる。
(ec2_architecture,ec2_description,…,ec2_vpc_id)

インスタンスで利用できる変数取得方法

cd contrib/inventory
./ec2.py --host ec2-12-12-12-12.compute-1.amazonaws.com

AWS inventory script はキャッシュしてAPIを呼び出さないようにするため
ec2.iniにキャッシュしないように設定するか、以下コマンドを実施すること。

./ec2.py --refresh-cache

Example: OpenStack External Inventory Script

OpenStackベースのクラウドを利用している場合は動的インベントリを利用して(openstack.py)、
OpenStackから直接データを取得できる。
OpenStack inventory script は以下からダウンロード可能。
https://raw.githubusercontent.com/ansible/ansible/devel/contrib/inventory/openstack.py

ansibleコマンドで-i openstack.py と明示的に指定するか、/etc/ansible/hosts へスクリプトを置くことで利用可能。

…中略…

Other inventory scripts

CobblerやEC2だけでなく、以下についてもinventory scriptを利用可能。

BSD Jails
DigitalOcean
Google Compute Engine
Linode
OpenShift
OpenStack Nova
Ovirt
SpaceWalk
Vagrant (not to be confused with the provisioner in vagrant, which is preferred)
Zabbix

使い方の詳細は今後追加されるかもしれない。現状 contrib/inventory ディレクトリがわかりやすい。
基本的にAWSのスクリプトと同じ。

Ansible Best Practices

Best Practicesを意訳してみた。
たぶん誤訳もある。Google翻訳の精度が向上したことをすごく感じた。

Content Organization

次の章では、playbookを構成するさまざまな方法の1つを示します。
要望に合う形で改変してください。
なにがどうあってもroleは必ず利用してください!

Directory Layout

production                # inventory file for production servers
staging                   # inventory file for staging environment

group_vars/
   group1                 # here we assign variables to particular groups
   group2                 # ""
host_vars/
   hostname1              # if systems need specific variables, put them here
   hostname2              # ""

library/                  # if any custom modules, put them here (optional)
filter_plugins/           # if any custom filter plugins, put them here (optional)

site.yml                  # master playbook
webservers.yml            # playbook for webserver tier
dbservers.yml             # playbook for dbserver tier

roles/
    common/               # this hierarchy represents a "role"
        tasks/            #
            main.yml      #  <-- tasks file can include smaller files if warranted
        handlers/         #
            main.yml      #  <-- handlers file
        templates/        #  <-- files for use with the template resource
            ntp.conf.j2   #  <------- templates end in .j2
        files/            #
            bar.txt       #  <-- files for use with the copy resource
            foo.sh        #  <-- script files for use with the script resource
        vars/             #
            main.yml      #  <-- variables associated with this role
        defaults/         #
            main.yml      #  <-- default lower priority variables for this role
        meta/             #
            main.yml      #  <-- role dependencies
        library/          # roles can also include custom modules
        lookup_plugins/   # or other types of plugins, like lookup in this case

    webtier/              # same kind of structure as "common" was above, done for the webtier role
    monitoring/           # ""
    fooapp/               # ""

Alternative Directory Layout

inventories/
   production/
      hosts               # inventory file for production servers
      group_vars/
         group1           # here we assign variables to particular groups
         group2           # ""
      host_vars/
         hostname1        # if systems need specific variables, put them here
         hostname2        # ""

   staging/
      hosts               # inventory file for staging environment
      group_vars/
         group1           # here we assign variables to particular groups
         group2           # ""
      host_vars/
         stagehost1       # if systems need specific variables, put them here
         stagehost2       # ""

library/
filter_plugins/

site.yml
webservers.yml
dbservers.yml

roles/
    common/
    webtier/
    monitoring/
    fooapp/

別の方法としてinventoryファイルとgroup_vars/host_varsを分割することが可能。
group_vars/host_vars がproductionとstagingで共通である必要が無い時はこちらの構成のほうが便利。

メリットは、より広い環境での柔軟性と異なる環境間での変数の完全な分離が可能であること。
デメリットは、ファイルが増えているため保守が難しいこと。

Use Dynamic Inventory With Clouds

クラウドを利用しているのであれば、Dynamic Inventoryを利用したほうがよい。
クラウドだけでなくシステムからサーバリストを出力できるような場合も、
Dynamic Inventoryを利用することができる。
(参考:Ansible dynamic inventory + Zabbix APIで監視対象を動的に構成管理)

How to Differentiate Staging vs Production

inventoryファイル分類方法をよく聞かれる。以下はそのよい例である。
グループ化方法を動的インベントリに適用することもできます。

以下の例ではすべての本番ホストがひとつのinventoryファイルに含まれています。
ホストの目的、データセンターの場所などに基づいてのグループ定義をオススメします。

# file: production

[atlanta-webservers]
www-atl-1.example.com
www-atl-2.example.com

[boston-webservers]
www-bos-1.example.com
www-bos-2.example.com

[atlanta-dbservers]
db-atl-1.example.com
db-atl-2.example.com

[boston-dbservers]
db-bos-1.example.com

# webservers in all geos
[webservers:children]
atlanta-webservers
boston-webservers

# dbservers in all geos
[dbservers:children]
atlanta-dbservers
boston-dbservers

# everything in the atlanta geo
[atlanta:children]
atlanta-webservers
atlanta-dbservers

# everything in the boston geo
[boston:children]
boston-webservers
boston-dbservers

Group And Host Variables

グループ化することですべてうまくいくわけではありません。変数を割り当てることも可能です。
例えばアトランタには独自のNTPサーバがある場合、

---
# file: group_vars/atlanta
ntp: ntp-atlanta.example.com
backup: backup-atlanta.example.com

WEBサーバ専用の変数は

---
# file: group_vars/webservers
apacheMaxRequestsPerChild: 3000
apacheMaxClients: 900

もしデフォルト値が存在する場合は

---
# file: group_vars/all
ntp: ntp-boston.example.com
backup: backup-boston.example.com

特定のハードウェアのみに適用する場合は(必要がなければ避けたほうがよいが)

---
# file: host_vars/db-bos-1.example.com
foo_agent_port: 86
bar_agent_port: 99

Dynamic Inventoryを利用する場合は、自動的にグループが作成されるため要注意。

Top Level Playbooks Are Separated By Role

site.yml:インフラストラクチャ全体を定義するplaybookが含まれている。そのためとても短い。

---
# file: site.yml
- include: webservers.yml
- include: dbservers.yml

webservers.ymlなどはグループとroleを指定するだけにすること。

---
# file: webservers.yml
- hosts: webservers
  roles:
    - common
    - webtier

webserversでの実行は2つの方法がある

ansible-playbook site.yml --limit webservers
ansible-playbook webservers.yml

Task And Handler Organization For A Role

以下はNTPサーバを設定するtaskファイルです。

---
# file: roles/common/tasks/main.yml

- name: be sure ntp is installed
  yum: name=ntp state=installed
  tags: ntp

- name: be sure ntp is configured
  template: src=ntp.conf.j2 dest=/etc/ntp.conf
  notify:
    - restart ntpd
  tags: ntp

- name: be sure ntpd is running and enabled
  service: name=ntpd state=started enabled=yes
  tags: ntp

以下がhandlerファイルとなります。タスクに変更があった場合最後に実行されます。

---
# file: roles/common/handlers/main.yml
- name: restart ntpd
  service: name=ntpd state=restarted

What This Organization Enables (Examples)

実行例について。
すべての構成を反映させる場合

ansible-playbook -i production site.yml

NTPのみを再構成する場合

ansible-playbook -i production site.yml --tags ntp

webserversを再構成する場合

ansible-playbook -i production webservers.yml

ボストンのwebserversを再構成する場合

ansible-playbook -i production webservers.yml --limit boston

10ホストずつ再構成する場合

ansible-playbook -i production webservers.yml --limit boston[1-10]
ansible-playbook -i production webservers.yml --limit boston[11-20]

基本的な使い方も可能

ansible boston -i production -m ping
ansible boston -i production -m command -a '/sbin/reboot'

有用なコマンドも覚えておくべき

# confirm what task names would be run if I ran this command and said "just ntp tasks"
ansible-playbook -i production webservers.yml --tags ntp --list-tasks

# confirm what hostnames might be communicated with if I said "limit to boston"
ansible-playbook -i production webservers.yml --limit boston --list-hosts

Deployment vs Configuration Organization

上記の設計モデルは典型的なもの。複数層でのデプロイが必要な場合はplaybookが追加され、
site.yml は deploy_exampledotcom.yml といったplaybookが追加されるかもしれないが、上記設計モデルと構成は変わらない。

1つのplaysにこだわらず、状況や目的に合わせてplaysを作成したほうがよい。

同じツールを利用してデプロイできるため、グループを再利用し、アプリケーション設定とは別のplaybookにOS設定を保存すればよい。

Staging vs Production

すでに記載しているがステージング環境と本番環境を別々にするためには inventory ファイルを別々にしたほうがよい。
1つのinventoryファイルにしてしまうと、予期せぬ動作をする可能性がある。

本番環境の前にステージング環境で試すことは非常に良いこと。サイズが違う場合は、グループ変数で制御すること。

Rolling Updates

‘serial’ キーワードを理解すること。これを利用して、制御すること。
Delegation, Rolling Updates, and Local Actions

Always Mention The State

stateパラメーターは多くのモジュールで利用されている。
‘state=present’や‘state=absent’についてplaybookに明示的に記載しておいたほうがよい。

Group By Roles

システムには複数のグループがある。
playbookは役割ごとに作成することが大切。

Operating System and Distribution Variance

異なるOS間でことなるパラメーターを利用する場合、group_by モジュールの利用がオススメ。
inventoryで定義しなくても、特定の条件に一致する動的なグループが作成される。

---

# talk to all hosts just so we can learn about them
- hosts: all
  tasks:
     - group_by: key=os_{{ ansible_distribution }}

# now just on the CentOS hosts...

- hosts: os_CentOS
  gather_facts: False
  tasks:
     - # tasks that only happen on CentOS go here

これによりすべてのホストがOSに基づいた動的グループに分類される。
グループ特有の設定が必要な場合は、以下のように設定します。

---
# file: group_vars/all
asdf: 10

---
# file: group_vars/os_CentOS
asdf: 42

上の例では、CentOSマシンはasdfに42の値を取得しますが、他のマシンは10になる。
これは変数の設定だけでなく、特定のシステムに特定の役割を適用するためにも使用できる。
変数だけが必要な場合は、OS名に基づいて変数が取り込むことも可能。

- hosts: all
  tasks:
    - include_vars: "os_{{ ansible_distribution }}.yml"
    - debug: var=asdf

Bundling Ansible Modules With Playbooks

libraryディレクトリがある場合、自動的にansibleのモジュールパスとして認識される。
playbookで実行されるモジュールを保持するためのよい方法。

Whitespace and Comments

空白を利用してわかりやすくすること、#でのコメントを推奨。

Always Name Tasks

タスクの名前は記載しなくてもよいが、タスクの目的を記載することを推奨。
playbook実行時に表示される。

Keep It Simple

とくかくシンプルに。ansibleのすべての機能を1度に使い分けてはいけない。
必要ないもの(vars,vars_files,vars_prompt,–extra-vars )は利用しないこと。

Version Control

gitなどのバージョン管理システムを利用し、変更した理由がわかるようにしておくこと。

Variables and Vaults

一般的な管理方法として、変数を見つけるためにgrepなどのツールが利用されます。
暗号化などで覆い隠されているときは、間接的に作業する必要があります。
playbook実行時に暗号化されていないファイルから変数を取得し
機密変数は暗号化されたファイルから取得します。

ベストプラクティスとして、group_vars/ のサブディレクトリを利用する。
vars と vault という2つのファイル名やプレフィックスを利用する。

ansibleベストプラクティスについてググってみた

ansibleベストプラクティスについてググってみた。そのまとめ。

参考-URL

公式のBestPractice

Ansible Tutorial

ベストプラクティスからはじめるAnsible

Ansible 初心者なら、まずは Ansible Galaxy から始めてみよう

実践!Ansibleベストプラクティス(前編)

参考-コマンド

# git clone https://github.com/yteraoka/ansible-tutorial.git
# cd ansible-tutorial
# git checkout playbook
# ansible-playbook --list-tasks -i test-servers site.yml
# git clone https://github.com/yukihirai0505/ansible-best-practice-hands-on
# cd ansible-best-practice-hands-on/httpdStore
# ansible all -m ping
# ansible-playbook -i stage site.yml

Ansible勉強会に参加したかった話

Ansible勉強会に参加できなかったため資料を確認した
気になったことをメモ

勉強になったこと

・YAML形式について、ネストするときはインデント(半角スペース*2)を利用
・WindowsはWinRMリモート接続経由でPowerShell(versionは3.0以上)操作可能
・変数展開するようなファイルはcopyモジュールではなくtemplateモジュールを利用
・変数の使い方

- name: mysqlを起動
  service:
    name: "{{ mysql_daemon_name }}"
    state: started
    enabled: yes

role分割

2016-01-30_232609
2016-01-30_232634

ansible – copyモジュールにはbackup=yesを

インストール

# sources.listに追記する
===
deb http://ftp.jp.debian.org/debian wheezy-backports main contrib non-free
===
root@hostname:/home/shimizu# aptitude update
...

root@hostname:/home/shimizu# aptitude install ansible
以下の新規パッケージがインストールされます:
  ansible libgmp10{a} libyaml-0-2{a} python-crypto{a} python-httplib2{a} python-jinja2{a}
  python-markupsafe{a} python-paramiko{a} python-selinux{a} python-yaml{a}
...

root@hostname:/home/shimizu# cd /etc/ansible
root@hostname:/etc/ansible# cat hosts
49.212.204.46

root@hostname:/etc/ansible# ansible -i hosts all -m ping -u shimizu --ask-pass
SSH password:
49.212.204.46 | success >> {
    "changed": false,
    "ping": "pong"
}

playbookを利用する

root@hostname:/etc/ansible# cat playbook1.yml
---
- hosts: all
  sudo: yes
  tasks:
    - name: test
      ping:
root@hostname:/etc/ansible# ansible-playbook playbook1.yml -u shimizu --ask-sudo-pass
sudo password:

PLAY [all] ********************************************************************

GATHERING FACTS ***************************************************************
ok: [49.212.204.46]

TASK: [test] ******************************************************************
ok: [49.212.204.46]

PLAY RECAP ********************************************************************
49.212.204.46              : ok=2    changed=0    unreachable=0    failed=0

### 各モジュールの説明を確認可能 ###
root@hostname:/etc/ansible# ansible-doc copy
...

root@hostname:/etc/ansible# cat playbook1.yml
---
- hosts: all
  sudo: yes
  tasks:
    - name: copy
      copy: src=test_ansible.txt dest=/home/shimizu owner=root group=root mode=0644

root@hostname:/etc/ansible# ansible-playbook playbook1.yml -u shimizu --ask-pass --ask-sudo-pass
SSH password:
sudo password [defaults to SSH password]:

PLAY [all] ********************************************************************

GATHERING FACTS ***************************************************************
ok: [49.212.204.46]

TASK: [copy] ******************************************************************
changed: [49.212.204.46]

PLAY RECAP ********************************************************************
49.212.204.46              : ok=2    changed=1    unreachable=0    failed=0

copyモジュールについて

冪等性が保証されているため、ファイルの内容が同じ(ハッシュを比較する)であればcopyしない
そして変更があった場合は、上書きcopyされる
以下のようにbackup=yesをつけると
リモートに日付がついたバックアップ(test_ansible.txt.2015-06-01@00:39~)が作成される

root@hostname:/etc/ansible# cat playbook1.yml
---
- hosts: all
  sudo: yes
  tasks:
    - name: copy
      copy: src=test_ansible.txt dest=/home/shimizu owner=root group=root mode=0644 backup=yes

Playbook Roles

2015-06-01_000557

playbookに

roles:
– mysql

と記載するとmysql配下が読み込まれる

参考

Ansible の Playbook を使ってみる
→playbook利用にあたり、必要な情報が網羅されていました
http://d.hatena.ne.jp/akishin999/20130815/1376520672
Ansible (7) playbookを書こう<後編>
→rolesを作るときの参考にしたい

Ansible (7) playbookを書こう<後編>


Ansible 入門
→モジュールやキーについて詳細まで記載されている
http://qiita.com/ArimaRyunosuke/items/1f9d840311584d8160bc
python製の構成管理ソフト ansible を使ってみたのでまとめ
→モジュールの説明が詳しい
http://d.hatena.ne.jp/hogem/20130615/1371306941

Ansible

概要

Ansibleについてやってみた
http://dotinstall.com/lessons/basic_ansible

Ansibleとは

サーバの構成管理ツール。サーバに設定したファイルの修正や管理ができる
agentなどクライアント管理にあたり特別なツールが必要ない。また並列で実行でき、高速に動作する
Pythonがインストールされており、鍵認証でのSSHが利用できればOK
Enterpriseツールやサポートなどもあり、有料

構成

2014-11-13_232015
ホストにはAnsibleをインストールする
Inventory:どのサーバを管理するか記載する
ansible.cfg:ansibleの全体的な設定を記載する
Playbook:どのような構成とするかを記載する

インストール

root@hostname:/home/shimizu# aptitude install python-pip
以下の新規パッケージがインストールされます:
  python-pip python-setuptools{a}
...

root@hostname:/home/shimizu# pip install ansible
...

root@hostname:/home/shimizu# cat /root/.pip/pip.log
...
src/MD2.c:31:20: fatal error: Python.h: そのようなファイルやディレクトリはありません
compilation terminated.
error: command 'gcc' failed with exit status 1
...

root@hostname:/home/shimizu# aptitude install python-dev
以下の新規パッケージがインストールされます:
  libexpat1-dev{a} python-dev python2.7-dev{a}
...

### 再度インストールしたところうまくいった ###
root@hostname:/home/shimizu# pip install ansible
...
Successfully installed pycrypto ecdsa
Cleaning up...
root@hostname:/home/shimizu# ansible --version
ansible 1.7.2

### SSH環境作成 ###
### クライアント ###
[root@ip-172-32-0-221 ec2-user]# useradd deploy
[root@ip-172-32-0-221 ec2-user]# cat /etc/passwd
...
deploy  ALL=(ALL)       ALL
...
[root@ip-172-32-0-221 ec2-user]# su deploy
[deploy@ip-172-32-0-221 ec2-user]$ cd /home/deploy/
[deploy@ip-172-32-0-221 .ssh]$ ssh-keygen -t rsa
Generating public/private rsa key pair.
Enter file in which to save the key (/home/deploy/.ssh/id_rsa):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /home/deploy/.ssh/id_rsa. # 秘密鍵
Your public key has been saved in /home/deploy/.ssh/id_rsa.pub. # 公開鍵
The key fingerprint is:
02:35:0c:37:22:21:06:61:53:50:5e:4f:42:d8:23:9d deploy@ip-172-32-0-221
The key's randomart image is:
+--[ RSA 2048]----+
|=**+B**.         |
|o.o+.E=o         |
|   .o ..         |
|     .           |
|      . S        |
|       .         |
|                 |
|                 |
|                 |
+-----------------+
[deploy@ip-172-32-0-221 .ssh]$ chmod 600 id_rsa.pub
[deploy@ip-172-32-0-221 ~]$ chmod 700 .ssh
[deploy@ip-172-32-0-221 ~]$ mv id_rsa.pub authorized_keys
### サーバ ###
### クライアントで作成した秘密鍵をコピーする ###
root@hostname:/home/shimizu# vi /root/.ssh/aws_rsa
...
root@hostname:/home/shimizu# chmod 600 /root/.ssh/aws_rsa
root@hostname:/home/shimizu# ssh -i /root/.ssh/aws_rsa deploy@tech.akat.info
Last login: Fri Nov 14 01:14:47 2014 from hostname.sakura.ne.jp

       __|  __|_  )
       _|  (     /   Amazon Linux AMI
      ___|\___|___|

https://aws.amazon.com/amazon-linux-ami/2014.09-release-notes/
[deploy@ip-172-32-0-221 ~]$

利用方法

### Inventoryファイルの作成 - 正規表現も利用可能###
root@hostname:/home/shimizu# mkdir /etc/ansible
root@hostname:/home/shimizu# cd /etc/ansible/
root@hostname:/etc/ansible# cat hosts
[web] # グループを作成できる
54.64.208.148
### Inventoryファイルのレスポンス確認 ###
root@hostname:/etc/ansible# ansible all -i hosts -m ping -u deploy --private-key=/root/.ssh/aws_rsa                                            54.64.208.148 | success >> {
    "changed": false,
    "ping": "pong"
}
### ローカルホストでテストすることも可能 ###
root@hostname:/etc/ansible# ansible localhost -m ping
localhost | success >> {
    "changed": false,
    "ping": "pong"
}

### コマンドを実行する ###
root@hostname:/etc/ansible# ansible all -i hosts -m command -a "ls /etc/php-fpm-5.5.d" -u deploy --private-key=/root/.ssh/aws_rsa
54.64.208.148 | success | rc=0 >>
php-fpm.conf
www.conf

### 設定ファイルを作成する ###
root@hostname:/etc/ansible# vi /etc/ansible/ansible.cfg
[defaults]
# リモード接続するときに並行して生成するプロセス数
forks=10
# ログファイルのパス
log_path=/var/log/ansible.log

### サーバの情報を取得する ###
root@hostname:/etc/ansible# ansible all -i hosts -m setup -u deploy --private-key=/root/.ssh/aws_rsa
54.64.208.148 | success >> {
    "ansible_facts": {
        "ansible_all_ipv4_addresses": [
            "172.32.0.221"
        ],
        "ansible_all_ipv6_addresses": [
            "fe80::48d:e7ff:fe9f:8b8f"
        ],
        "ansible_architecture": "x86_64",
        "ansible_bios_date": "06/02/2014",
        "ansible_bios_version": "4.2.amazon",
        "ansible_cmdline": {
            "console": "ttyS0",
            "root": "LABEL=/"
        },
        "ansible_date_time": {
            "date": "2014-11-14",
            "day": "14",
            "epoch": "1415977044",
            "hour": "23",
            "iso8601": "2014-11-14T14:57:24Z",
            "iso8601_micro": "2014-11-14T14:57:24.426875Z",
            "minute": "57",
            "month": "11",
            "second": "24",
            "time": "23:57:24",
            "tz": "JST",
            "tz_offset": "+0900",
            "weekday": "Friday",
            "year": "2014"
        },
        "ansible_default_ipv4": {
            "address": "172.32.0.221",
            "alias": "eth0",
            "gateway": "172.32.0.1",
            "interface": "eth0",
            "macaddress": "06:8d:e7:9f:8b:8f",
            "mtu": 9001,
            "netmask": "255.255.255.0",
            "network": "172.32.0.0",
            "type": "ether"
        },
        "ansible_default_ipv6": {},
        "ansible_devices": {
            "xvda": {
                "holders": [],
                "host": "",
                "model": null,
                "partitions": {
                    "xvda1": {
                        "sectors": "16773087",
                        "sectorsize": 512,
                        "size": "8.00 GB",
                        "start": "4096"
                    }
                },
                "removable": "0",
                "rotational": "0",
                "scheduler_mode": "noop",
                "sectors": "16777216",
                "sectorsize": "512",
                "size": "8.00 GB",
                "support_discard": "0",
                "vendor": null
            }
        },
        "ansible_distribution": "Amazon",
        "ansible_distribution_major_version": "NA",
        "ansible_distribution_release": "NA",
        "ansible_distribution_version": "2014.09",
        "ansible_domain": "",
        "ansible_env": {
            "AWS_AUTO_SCALING_HOME": "/opt/aws/apitools/as",
            "AWS_CLOUDWATCH_HOME": "/opt/aws/apitools/mon",
            "AWS_ELB_HOME": "/opt/aws/apitools/elb",
            "AWS_PATH": "/opt/aws",
            "AWS_RDS_HOME": "/opt/aws/apitools/rds",
            "EC2_AMITOOL_HOME": "/opt/aws/amitools/ec2",
            "EC2_HOME": "/opt/aws/apitools/ec2",
            "HOME": "/home/deploy",
            "JAVA_HOME": "/usr/lib/jvm/jre",
            "LANG": "en_US.UTF-8",
            "LC_CTYPE": "en_US.UTF-8",
            "LESSOPEN": "||/usr/bin/lesspipe.sh %s",
            "LESS_TERMCAP_mb": "\u001b[01;31m",
            "LESS_TERMCAP_md": "\u001b[01;38;5;208m",
            "LESS_TERMCAP_me": "\u001b[0m",
            "LESS_TERMCAP_se": "\u001b[0m",
            "LESS_TERMCAP_ue": "\u001b[0m",
            "LESS_TERMCAP_us": "\u001b[04;38;5;111m",
            "LOGNAME": "deploy",
            "MAIL": "/var/mail/deploy",
            "PATH": "/usr/local/bin:/bin:/usr/bin:/opt/aws/bin",
            "PWD": "/home/deploy",
            "SHELL": "/bin/bash",
            "SHLVL": "2",
            "SSH_CLIENT": "49.212.204.46 35705 22",
            "SSH_CONNECTION": "49.212.204.46 35705 172.32.0.221 22",
            "SSH_TTY": "/dev/pts/1",
            "TERM": "xterm",
            "USER": "deploy",
            "_": "/usr/bin/python"
        },
        "ansible_eth0": {
            "active": true,
            "device": "eth0",
            "ipv4": {
                "address": "172.32.0.221",
                "netmask": "255.255.255.0",
                "network": "172.32.0.0"
            },
            "ipv6": [
                {
                    "address": "fe80::48d:e7ff:fe9f:8b8f",
                    "prefix": "64",
                    "scope": "link"
                }
            ],
            "macaddress": "06:8d:e7:9f:8b:8f",
            "mtu": 9001,
            "promisc": false,
            "type": "ether"
        },
        "ansible_form_factor": "Other",
        "ansible_fqdn": "ip-172-32-0-221",
        "ansible_hostname": "ip-172-32-0-221",
        "ansible_interfaces": [
            "lo",
            "eth0"
        ],
        "ansible_kernel": "3.14.20-20.44.amzn1.x86_64",
        "ansible_lo": {
            "active": true,
            "device": "lo",
            "ipv4": {
                "address": "127.0.0.1",
                "netmask": "255.0.0.0",
                "network": "127.0.0.0"
            },
            "ipv6": [
                {
                    "address": "::1",
                    "prefix": "128",
                    "scope": "host"
                }
            ],
            "mtu": 65536,
            "promisc": false,
            "type": "loopback"
        },
        "ansible_machine": "x86_64",
        "ansible_memfree_mb": 73,
        "ansible_memtotal_mb": 996,
        "ansible_mounts": [
            {
                "device": "/dev/xvda1",
                "fstype": "ext4",
                "mount": "/",
                "options": "rw,noatime,data=ordered",
                "size_available": 5455257600,
                "size_total": 8318783488
            }
        ],
        "ansible_nodename": "ip-172-32-0-221",
        "ansible_os_family": "RedHat",
        "ansible_pkg_mgr": "yum",
        "ansible_processor": [
            "Intel(R) Xeon(R) CPU E5-2670 v2 @ 2.50GHz"
        ],
        "ansible_processor_cores": 1,
        "ansible_processor_count": 1,
        "ansible_processor_threads_per_core": 1,
        "ansible_processor_vcpus": 1,
        "ansible_product_name": "HVM domU",
        "ansible_product_serial": "NA",
        "ansible_product_uuid": "NA",
        "ansible_product_version": "4.2.amazon",
        "ansible_python_version": "2.6.9",
        "ansible_selinux": false,
        "ansible_ssh_host_key_dsa_public": "...",
        "ansible_ssh_host_key_ecdsa_public": "...",
        "ansible_ssh_host_key_rsa_public": "...",
        "ansible_swapfree_mb": 0,
        "ansible_swaptotal_mb": 0,
        "ansible_system": "Linux",
        "ansible_system_vendor": "Xen",
        "ansible_user_id": "deploy",
        "ansible_userspace_architecture": "x86_64",
        "ansible_userspace_bits": "64",
        "ansible_virtualization_role": "guest",
        "ansible_virtualization_type": "xen",
        "module_setup": true
    },
    "changed": false
}
### IPアドレスだけを取得する ###
root@hostname:/etc/ansible# cat playbook1.yml
---
- hosts: all
  sudo: yes
  tasks:
     - name: gathering ip address
       command: echo {{ ansible_eth0.ipv4.address }}

root@hostname:/etc/ansible# ansible-playbook playbook1.yml -u deploy --private-key=/root/.ssh/aws_rsa --ask-sudo-pass
sudo password:
 ____________
< PLAY [all] >
 ------------
        \   ^__^
         \  (oo)\_______
            (__)\       )\/\
                ||----w |
                ||     ||


 _________________
< GATHERING FACTS >
 -----------------
        \   ^__^
         \  (oo)\_______
            (__)\       )\/\
                ||----w |
                ||     ||


ok: [54.64.208.148]
 ____________________________
< TASK: gathering ip address >
 ----------------------------
        \   ^__^
         \  (oo)\_______
            (__)\       )\/\
                ||----w |
                ||     ||


changed: [54.64.208.148]
 ____________
< PLAY RECAP >
 ------------
        \   ^__^
         \  (oo)\_______
            (__)\       )\/\
                ||----w |
                ||     ||


54.64.208.148              : ok=2    changed=1    unreachable=0    failed=0

### Playbookを利用して、ユーザを作成してみる ###
root@hostname:/etc/ansible# cat playbook1.yml
---
- hosts: all
  sudo: yes
  tasks:
    - name: add a new user
      user: name=ansibletest

### tasksはあるべき状態を記載している
### つまり、すでにユーザansibletestがいる場合は何もしない

root@hostname:/etc/ansible# ansible-playbook playbook1.yml -u deploy --private-key=/root/.ssh/aws_rsa --ask-sudo-pass
sudo password:
 ____________
< PLAY [all] >
 ------------
        \   ^__^
         \  (oo)\_______
            (__)\       )\/\
                ||----w |
                ||     ||


 _________________
< GATHERING FACTS >
 -----------------
        \   ^__^
         \  (oo)\_______
            (__)\       )\/\
                ||----w |
                ||     ||


ok: [54.64.208.148]
 ______________________
< TASK: add a new user >
 ----------------------
        \   ^__^
         \  (oo)\_______
            (__)\       )\/\
                ||----w |
                ||     ||


changed: [54.64.208.148]
 ____________
< PLAY RECAP >
 ------------
        \   ^__^
         \  (oo)\_______
            (__)\       )\/\
                ||----w |
                ||     ||


54.64.208.148              : ok=2    changed=1    unreachable=0    failed=0

root@hostname:/etc/ansible# ansible-playbook playbook1.yml -u deploy --private-key=/root/.ssh/aws_rsa --ask-sudo-pass
sudo password:
 ____________
< PLAY [all] >
 ------------
        \   ^__^
         \  (oo)\_______
            (__)\       )\/\
                ||----w |
                ||     ||


 _________________
< GATHERING FACTS >
 -----------------
        \   ^__^
         \  (oo)\_______
            (__)\       )\/\
                ||----w |
                ||     ||


ok: [54.64.208.148]
 ______________________
< TASK: add a new user >
 ----------------------
        \   ^__^
         \  (oo)\_______
            (__)\       )\/\
                ||----w |
                ||     ||


ok: [54.64.208.148]
 ____________
< PLAY RECAP >
 ------------
        \   ^__^
         \  (oo)\_______
            (__)\       )\/\
                ||----w |
                ||     ||


54.64.208.148              : ok=2    changed=0    unreachable=0    failed=0 # 2回目はchangedが0となっている

### syntax check ###
root@hostname:/etc/ansible# ansible-playbook playbook1.yml --syntax-check

playbook: playbook1.yml

### タスクを表示 ###
root@hostname:/etc/ansible# ansible-playbook playbook1.yml --list-task

playbook: playbook1.yml

  play #1 (all):
    add a new user

### dry run ###
root@hostname:/etc/ansible# ansible-playbook playbook1.yml -u deploy --private-key=/root/.ssh/aws_rsa --ask-sudo-pass --check
sudo password:
 ____________
< PLAY [all] >
 ------------
        \   ^__^
         \  (oo)\_______
            (__)\       )\/\
                ||----w |
                ||     ||


 _________________
< GATHERING FACTS >
 -----------------
        \   ^__^
         \  (oo)\_______
            (__)\       )\/\
                ||----w |
                ||     ||


ok: [54.64.208.148]
 ______________________
< TASK: add a new user >
 ----------------------
        \   ^__^
         \  (oo)\_______
            (__)\       )\/\
                ||----w |
                ||     ||


changed: [54.64.208.148]
 ____________
< PLAY RECAP >
 ------------
        \   ^__^
         \  (oo)\_______
            (__)\       )\/\
                ||----w |
                ||     ||


54.64.208.148              : ok=2    changed=1    unreachable=0    failed=0

### 変数も利用可能 ###
root@hostname:/etc/ansible# cat playbook1.yml
---
- hosts: all
  sudo: yes
  vars:
      username: testuser
  tasks:
    - name: add a new user
      user: name={{username}}

### 変数をユーザに入力させることも可能 ###
root@hostname:/etc/ansible# cat playbook1.yml
---
- hosts: all
  sudo: yes
  vars_prompt:
      username: "Enter username"
  tasks:
    - name: add a new user
      user: name={{username}}
root@hostname:/etc/ansible# ansible-playbook playbook1.yml -u deploy --private-key=/root/.ssh/aws_rsa --ask-sudo-pass --check
sudo password:
Enter username: :
 ____________
< PLAY [all] >
 ------------
        \   ^__^
         \  (oo)\_______
            (__)\       )\/\
...

### ファイルをおく ###
root@hostname:/etc/ansible# cat test.txt
this is test
root@hostname:/etc/ansible# cat playbook1.yml
---
- hosts: all
  sudo: yes
  tasks:
     - name: copy test.txt
       copy: src=./test.txt dest=/home/ec2-user/test.txt owner=root
root@hostname:/etc/ansible# ansible-playbook playbook1.yml -u deploy --private-key=/root/.ssh/aws_rsa --ask-sudo-pass
sudo password:
 ____________
< PLAY [all] >
 ------------
        \   ^__^
         \  (oo)\_______
            (__)\       )\/\
                ||----w |
                ||     ||


 _________________
< GATHERING FACTS >
 -----------------
        \   ^__^
         \  (oo)\_______
            (__)\       )\/\
                ||----w |
                ||     ||


ok: [54.64.208.148]
 _____________________
< TASK: copy test.txt >
 ---------------------
        \   ^__^
         \  (oo)\_______
            (__)\       )\/\
                ||----w |
                ||     ||


changed: [54.64.208.148]
 ____________
< PLAY RECAP >
 ------------
        \   ^__^
         \  (oo)\_______
            (__)\       )\/\
                ||----w |
                ||     ||


54.64.208.148              : ok=2    changed=1    unreachable=0    failed=0

### 状況によって処理を変更する ###
root@hostname:/etc/ansible# cat playbook1.yml
---
- hosts: all
  sudo: yes
  tasks:
     - name: "command if debian"
       command: echo {{ ansible_eth0.ipv4.address }}
       when: ansible_os_family == "Debian"
root@hostname:/etc/ansible# ansible-playbook playbook1.yml -u deploy --private-key=/root/.ssh/aws_rsa --ask-sudo-pass
sudo password:
 ____________
< PLAY [all] >
 ------------
        \   ^__^
         \  (oo)\_______
            (__)\       )\/\
                ||----w |
                ||     ||


 _________________
< GATHERING FACTS >
 -----------------
        \   ^__^
         \  (oo)\_______
            (__)\       )\/\
                ||----w |
                ||     ||


ok: [54.64.208.148]
 _________________________
< TASK: command if debian >
 -------------------------
        \   ^__^
         \  (oo)\_______
            (__)\       )\/\
                ||----w |
                ||     ||


skipping: [54.64.208.148]
 ____________
< PLAY RECAP >
 ------------
        \   ^__^
         \  (oo)\_______
            (__)\       )\/\
                ||----w |
                ||     ||


54.64.208.148              : ok=1    changed=0    unreachable=0    failed=0


その他

・handlersを利用すれば、サーバに変更があったときのみ最後に1回処理をするなど可能となる
 (モジュールをインストール後にapacheを再起動するなど)
・OSによって挙動を変更することも可能
 (インストールパッケージ名を変更するなど)
・ansible-pullという応用コマンドもあり、push型のansibleにpull型の機能をもたせている
・モジュールの使い方確認方法 ansible-doc [モジュール名]
・他のPlayBookを読み込むことも可能(- include: other.yml)

参考URL

ansibleを使ってみる-幅広く使い方が記載されておりわかりやすい
http://tdoc.info/blog/2013/04/20/ansible.html
入門ansible(未発表箇所)