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.ini

AWSへのAPIコールを正常に動作させるには、aws sdkpython実装である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

javaのメモ

## maven
export M2_HOME=/home/kw/maven/apache-maven-3.2.3
export M2=$M2_HOME/bin
export PATH=$M2:$PATH

## java7
#export JAVA_HOME=/usr/local/java/jdk1.7.0_67
#export PATH=/usr/local/java/jdk1.7.0_67/bin:$PATH
#export CLASSPATH=.:/usr/local/java
#export SCALA_HOME=/usr/local/share/scala
#export PATH=$PATH:$SCALA_HOME/bin

## java8
export JAVA_HOME=/usr/local/java/jdk1.8.0_31
export PATH=/usr/local/java/jdk1.8.0_31/bin:$PATH
export CLASSPATH=.:/usr/local/java
export SCALA_HOME=/usr/local/share/scala
export PATH=$PATH:$SCALA_HOME/bin

man chilli のDESCRIPTIONの和訳

WifiのアクセスポイントのOSSであるFON、のおソースの概要を読んだよ。と。chillispotね。
http://www.chillispot.org/

DESCRIPTION

<>


■アクセス方式2種
・UAM(Universal Access Method)
・WPA(Wireless Protected Access)

■3つの主要インタフェース
・downlink interface
クライアントのコネクションを受け入れる
・fadius interface
クライアントの認証
・uplink network interface
他のネットワークにフォワーディングする(インターネットだったり?)

              • -

認証は外部Radiusサーバが使われる。
UAM方式はRFC2865のCHAP-ChallengeとCHAP-Passwordが使用される
WPA方式はRFC2869のEAP-Message属性が使われる
Radiusからchilliへ暗号化キーの伝送はのRFC2548に記述のものが
使われる。radius interfaceはさらに多くをサポートしている。

              • -

downlink interfaceはクライアントからのDHCPリクエストと
ARPリクエストを受け付ける。
クライアントは「認証OK」と「認証NG」とに区分される。
「認証NG」のクライアントからのリクエストは認証サーバへと
リダイレクトされる。

              • -

ウェブサーバはリダイレクトするなどしてユーザネームと
パスワードをchilliに転送する。
chilliで受け取られた認証要求はradiusに送られる。
radiusで認証OKとなればユーザの認証は通ったとされる。
この認証方式をUAMという。

              • -

WPA方式はAPからchilliにcredentialsがRadiusプロトコル
使って転送される。chilliはさらにradiusサーバへ受け取った
リクエストをプロキシする。

              • -

uplink interfaceはTUN/TAPドライバーで実装されている。
tun interfaceが確率されるとchilliはスタートし、オプションで
外部スクリプトを呼び出すことができる。

              • -

ランタイムエラーはsyslogdに記録される。




ブログを引っ越しました

移転先はこちら。
http://kjwtnb.hatenablog.com/

今度ははてなブログです。自分のドメインをかぶせることができるみたいなので気分一新。
だったけれどあまり更新しなかったので有料版はやめました。

cabochaのインストール

最新版はうまくmakeできなかったので0.60をインストールした。
CRF++が必要なのでまずそれをインストール

wget http://kent.dl.sourceforge.net/sourceforge/crfpp/CRF++-0.51.tar.gz
tar xzvf CRF++-0.51.tar.gz
cd CRF++-0.51
./configure
make
sudo make install
##ldconfigもしたかな。。

cabochaのインスコ

wget http://cabocha.googlecode.com/files/cabocha-0.60.tar.gz
tar zxvf cabocha-0.60.tar.gz
cd cabocha-0.60
./configure --with-charset=UTF8 --enable-utf8-only
make
sudo make install
sudo /sbin/ldconfig

試す

$ cabocha
すもももももももものうち
すももも-D
ももも---D
ももの-D
うち
EOS

$ cabocha -f1
すもももももももものうち
* 0 1D 0/1 0.859394
すもも 名詞,一般,*,*,*,*,すもも,スモモ,スモモ O
も 助詞,係助詞,*,*,*,*,も,モ,モ O
* 1 3D 0/1 0.544641
もも 名詞,一般,*,*,*,*,もも,モモ,モモ O
も 助詞,係助詞,*,*,*,*,も,モ,モ O
* 2 3D 0/1 0.000000
もも 名詞,一般,*,*,*,*,もも,モモ,モモ O
の 助詞,連体化,*,*,*,*,の,ノ,ノ O
* 3 -1D 0/0 0.000000
うち 名詞,非自立,副詞可能,*,*,*,うち,ウチ,ウチ O
EOS

ソースの中にperlバインディングもあるのでインストールして使ってみた。

use strict;
use warnings;
use Data::Dumper;
use CaboCha;

my $sentence = "太郎はこの本を二郎を見た女性に渡した。";

my $c    = new CaboCha::Parser;
my $tree = $c->parse($sentence);
print $tree->toString($CaboCha::FORMAT_TREE);
print $tree->toString($CaboCha::FORMAT_LATTICE);