ansible dynamic inventoryの日本語の翻訳っぽいもの
雑だけれども読み通した。使って覚えるのが早い。。
http://docs.ansible.com/ansible/intro_dynamic_inventory.html
Dynamic Inventory
- 例: Cobbler 外部インベントリスクリプト
- 例: AWS EC2 外部インベントリスクリプト
- その他の在庫スクリプト
- 複数のインベントリリソースの使用
- 動的グループの静的グループ構成管理システムのユーザは別のソフトウェアシステムにインベントリを保持しておきたいものだ。
AnsibleはInventoryというテキストベースの管理システムを提供している。もし他のものを使いたい時は
どうするか。よくある例としてはcloudからinventoryを取得するというものだ。LDAP,Cobblerや高価なCMDBといったソフトウェアからなど。
Ansibleはこれらの外部インベントリシステムからデータ取得するオプションをサポートしている。https://github.com/ansible/ansible/tree/devel/contrib/inventory を確認すればオプションを確認できる。
Ansible Towerを使えばInventoryのデータベース管理ができ、WEBからのアクセスとRESTでのアクセスが可能になる。TowerはDynamic Inventoryを同期しGUIからのInventoryエディタを提供する。全てのホストをDB管理でき過去のイベント履歴やplaybookの実行結果を保持しておくこともできる。
自身のdynamic inventoryソースを記述する場合はhttp://docs.ansible.com/ansible/developing_inventory.html を参考にすること
☆Cobblerは個人的に使う予定はないので「例: Cobbler 外部インベントリスクリプト」は省略
■■■例: AWS EC2 外部インベントリスクリプト■■■
もしAWSでEC2を使うような場合はinventoryファイルを管理するのはベストアプローチではないかもしれない。autoscalingを使ったり、インスタンスの管理アプリケーションを使っていれば時間の経過とともにホストは起動したり停止したりするからだ。そういう場合はEC2外部Inventoryスクリプトを
利用することができる。このスクリプト(ec2.py)の使い方は2通りある。1つ目はansibleコマンドの-iオプションの引数に使う方法。
$ ansible -i ec2.py -u ubuntu us-east-1d -m ping
2つ目はコンフィグで設定中のinventory(see: ansible.cfg, default.inventory)にec2.pyを設置(/etc/ansible/hostsにrename)し、実行権限を付与しておく。また、ec2.iniを同じパス(/etc/ansible/ec2.ini)に設置しておく。そうすれば通常のstatic inventoryを扱うのと変わりなく扱える。
ec2.pyとec2.iniは下記のURLにある。
https://raw.github.com/ansible/ansible/devel/contrib/inventory/ec2.py
https://raw.githubusercontent.com/ansible/ansible/devel/contrib/inventory/ec2.iniAWSへのAPIコールを正常に動作させるには、aws sdkのpython実装であるBotoを正常に設定する必要がある。設定の方法はこのURL(http://docs.pythonboto.org/en/latest/boto_config_tut.html)に説明があるが、一番簡単な方法としては2つの環境変数をexportしておくことだ。
export AWS_ACCESS_KEY_ID='AK123'
export AWS_SECRET_ACCESS_KEY='abc123'正常に動作するかどうかはec2.py自体を実行してみることだ。
$ ./ec2.py --list
しばらくして全リージョンのEC2のInventory情報がJSONフォーマットで出力される。
複数のAWSアカウントを運用している場合は --profile PROFILEをec2.pyに渡すことで使い分けることができる。(see: $ aws configure help)
[profile dev]
aws_access_key_id =
aws_secret_access_key =[profile prod]
aws_access_key_id =
aws_secret_access_key =
ec2.py --profile prodとすることでproductionアカウントのInventoryを取得することができる。playbooksを使うような場合は
$ ansible-playbook -i 'ec2.py --profile prod' myplaybook.yml
というようにすることもできるし環境変数AWS_PROFILEを使い
$ AWS_PROFILE=prod ansible-playbook -i ec2.py myplaybook.yml
とすることもできる。
各リージョンは独自のAPIコールを必要とする場合があるので、リージョンを限って使用したい場合はec2.iniを編集してリージョンを限定するなどしてもよいだろう。ec2.iniはその他にキャッシュコントロールやdestination variablesなども設定することもできる。
Dynamic Inventoryはある名前(Key)から目的のアドレスを簡単にマッピングするようになっているのが肝だ。デフォルトのec2.iniはEC2の外部から(つまり自分のラップトップやAWSの外部(?)から)ansibleを動作することを前提にしている。そして、これは効果的なEC2の運用方法とはなっていない。
もしEC2上からansibleを動作させるなら、internal DNSやinternal IPを利用するのが効果的だ(public DNSを利用するよりは)。こういう場合はec2.iniのdestination_variableをprivate DNSに変更することができる。
この方法はVPC内部のprivate subnetでansibleを動作させるような場合(private IPでのみアクセスてきるような場合)に特に重要となる。
ec2.iniのvpc_destination_variableはboto.ec2.instanceの引数をよしなに?してくれる。ec2.pyは複数のグループ指定を利用してのインスタンスへのマッピングを提供する。
- Global
全てのインスタンスは 'ec2'グループに入る
$ ./inventory/ec2.py | jq .ec2
[
"172.31.2.232",
"172.31.10.107",
"172.31.30.229"
]
- Instancd ID
これは一つのインスタンスのみが所属するグループとなる。(インスタンスIDはユニークだから。)
- Region
指定したリージョンに所属する全てのインスタンス
$ ./inventory/ec2.py | jq '."ap-northeast-1"'
[
"172.31.2.232",
"172.31.10.107",
"172.31.30.229"
]
- Availability Zone
$ ./inventory/ec2.py | jq '."ap-northeast-1a"'
[
"172.31.2.232",
"172.31.10.107"
]
- Security Group
インスタンスが所属しているセキュリティグループを指定することもできる。alphanumericsを除き、全てのdash(-)はunderscore(_)に変換される。各セキュリティグループはsecurity_group_というprefixが付与される。
$ ./inventory/ec2.py | jq .security_group_redmine
[
"172.31.30.229"
]
- Tags
全てのインスタンスはkey/valueでタグを様々に付与することができる。付与したタグでグループを指定することができ、Name/redis-master-001というタグはtag_Name_redis_master_001という具合で指定できる。
ansibleが特定のサーバーとやり取りしている時、ec2.pyは--hostオプションを付与して呼ばれる。instance IDを取得するのにindex cacheのホスト情報を利用するためだ。特定インスタンスの情報を取得するのにAPIコールを作成し、playbook上で利用可能となる変数を作成する。playbook上でex2_をprefixとして利用可能になる変数は下記の通りだ。
ec2_architecture
ec2_description
ec2_dns_name
ec2_id
ec2_image_id
ec2_instance_type
ec2_ip_address
ec2_kernel
ec2_key_name
ec2_launch_time
ec2_monitored
ec2_ownerId
ec2_placement
ec2_platform
ec2_previous_state
ec2_private_dns_name
ec2_private_ip_address
ec2_public_dns_name
ec2_ramdisk
ec2_region
ec2_root_device_name
ec2_root_device_type
ec2_security_group_ids
ec2_security_group_names
ec2_spot_instance_request_id
ec2_state
ec2_state_code
ec2_state_reason
ec2_status
ec2_subnet_id
ec2_tag_Name
ec2_tenancy
ec2_virtualization_type
ec2_vpc_id
ec2_security_group_idsとec2_security_group_namesは全てのセキュリティグループのカンマ区切りのリスト。EC2タグはec2_tag_KEYのフォーマットとなっている。
各インスタンスで利用できる変数は下記コマンドで確認できる。
$ ./ec2.py --host PRIVATE_OR_PUBLIC_ADDRESS
ec2.pyはAPIコールを繰り返さないように結果をキャッシュする。設定はec2.iniでできる。明示的にキャッシュクリアしたい場合は下記のようなコマンドで対応する
$ ./ec2.py --refresh-cache
■■■その他の在庫スクリプト■■■
その他のInventory Scriptには下記のようなものがある。BSD Jails
DigitalOcean
Google Compute Engine
Linode
OpenShift
OpenStack Nova
Red Hat's SpaceWalk
Vagrant (not to be confused with the provisioner in vagrant, which is preferred)
Zabbix
利用に際しての詳細はコードを確認してください。contrib/inventory以下にあるスクリプトです。
ec2.pyもある。
■■■複数のインベントリリソースの使用■■■
- i オプションでディレクトリが指定された場合、ansibleは同時に複数のInventoryリソースを使います。
その場合、dynamic inventoryとstatic inventoryを同時に使うこともできます。
■■■動的グループの静的グループ■■■
static inventoryでグループ内グループ定義する時、子グループが定義されていなければansibleはエラーを返す。
もし動的グループの子グループを静的に作るときはstatic inventoryファイル内で動的グループを空で定義しておけばよい。[tag_Name_staging_foo]
[tag_Name_staging_bar]
[staging:children]
tag_Name_staging_foo
tag_Name_staging_bar