これの話です。
何がやれるのか
こんな感じにタグ付けした時に、インベントリファイルに対象ホストのIPとかを直接書かずにタグ名でホストを扱うことができます。
インベントリファイルにこんな風に書いたのと同じ動作になります。
[tag_role_api]
xxx.xxx.xxx.xxx
[tag_role_db]
yyy.yyy.yyy.yyy
ec2を使うとサーバーのIPがコロコロ変わるのでインベントリファイルにIPを直で書くとインベントリファイルを都度都度更新することになってしまうので有用な方法です。
やり方
AWSのAPIを内部的に使用するのでアクセスキーが必要
EC2のread/writeが可能な権限を持ったIAMアカウントのAPIキーが必要です。AWSコンソールで事前に作っておく必要があります。
そして、環境変数にセットします。
export AWS_ACCESS_KEY_ID='AK123'
export AWS_SECRET_ACCESS_KEY='abc123'
ec2.py, ec2.iniを取得する
https://github.com/ansible/ansible/tree/devel/contrib/inventory このへんにいっぱいあるので取得します。見たらわかると思いますが、EC2以外にもいろんなクラウド用があります。
インベントリのディレクトリ構造
playbook
├── site.yml
├── hosts
│ ├── prod
│ │ ├── ec2.ini
│ │ └── ec2.py
│ └── stg
│ ├── ec2.ini
│ └── ec2.py
└── roles
ec2.iniをカスタマイズ
使わない種類のものを対象にしない
なんかエラーが出たのでroute53,RDS,elasticacheはFalseに設定しました。
# To tag instances on EC2 with the resource records that point to them from
# Route53, uncomment and set 'route53' to True.
route53 = False
# 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
stageを絞るためにinstance_filtersを指定
# Filters are key/value pairs separated by '=', to list multiple filters use
instance_filters = tag:stage=stg
# Filters are key/value pairs separated by '=', to list multiple filters use
instance_filters = tag:stage=prod
試してみる
まずはec2.pyが何を返すか見てみよう
$ k$ ./host/stg/ec2.py
{
"_meta": {
"hostvars": {
"52.69.149.28": {
"ec2__in_monitoring_element": false,
:
JSON形式で色々とれてきます。重要なのはこの辺りです。
"tag_role_api": [
"52.69.236.80"
],
"tag_role_db": [
"52.69.149.28"
],
"tag_stage_stg": [
"52.69.236.80",
"52.69.149.28"
],
tag_タグ名
_タグの値
という名前が付けられています。
これがAnsbleで言うグループ名になります。
-m ping してみる
$ ansible -i host/stg all -m ping
52.69.149.28 | success >> {
"changed": false,
"ping": "pong"
}
52.69.236.80 | success >> {
"changed": false,
"ping": "pong"
}
$ ansible -i host/stg tag_role_api -m ping
52.69.236.80 | success >> {
"changed": false,
"ping": "pong"
}
応用編
roleの兼任
dev環境とかはコスト削減の名のもとに、一個のサーバーにいろいろ入れて誤魔化せと言われます。
タグ名 | 値 |
---|---|
stage | dev |
role | api,db |
こんな感じでroleの値をカンマ区切りにすると・・・tag_role_api_db
というグループでくくられます。
group of group
---
- hosts: tag_role_api
roles:
- nginx
- tomcat
- hosts: tag_role_db
roles:
- mysql
こんなsite.ymlだったとすると、
$ ansible-playbook -i hosts/dev site.yml
とした時には空振ってしまいます。devのインベントリにはtag_role_api_db
というグループがあるだけで、tag_role_api
もtag_role_db
も無いからです。
ここにちょろっと書いてありますが、
[tag_role_api_db]
[tag_role_api:children]
tag_role_api_db
[tag_role_db:children]
tag_role_api_db
こんなファイルを書くとtag_role_api
とtag_role_db
が定義されるので期待通り動くと思います。