AWSの場合、EC2インスタンスが入れ替わる度に、実行先ホストを更新しなければなりません。
毎回実行先を更新するのは大変なので、予め用意されているEC2 external inventoryスクリプトを利用して、自動でEC2の実行先を生成してみました。
# Dynamic Inventoryとは
- Ansibleの対象となるホスト一覧を動的に生成することが出来る仕組み
- コマンド実行時に実行権限が付与されたファイルをインベントリファイルに指定した場合、そのファイルに記載されたスクリプトを実行した結果を対象ホストとして認識してくれる
参考URL
準備
※事前にwas configureを実行しておくか、AWS_ACCESS_KEY_ID等の環境変数を設定し、AWS CLIの初期設定は済ませておきます。
## botoをインストール
$ sudo pip install boto
## EC2 external inventoryスクリプトをダウンロード
$ curl -O https://raw.githubusercontent.com/ansible/ansible/devel/contrib/inventory/ec2.py
$ curl -O https://raw.githubusercontent.com/ansible/ansible/devel/contrib/inventory/ec2.ini
$ chmod +x ec2.py
AWSの情報を収集
ec2.pyを実行すると、全リージョンのEC2の情報が収集され、結果がJSON形式で返ってきます。
Public IP、リージョン、Tag、セキュリティグループなど、自動でグループ分けがされていることがわかります。
※複数Profileがある場合は「--profile プロファイル名」を指定する
$ ./ec2.py --list
{
"_meta": {
"hostvars": {
"54.xxx.xxx.xxx": {
"ec2__in_monitoring_element": false,
"ec2_ami_launch_index": "0",
"ec2_architecture": "x86_64",
"ec2_client_token": "",
"ec2_dns_name": "ec2-54-xxx-xxx-xxx.ap-northeast-1.compute.amazonaws.com",
"ec2_ebs_optimized": false,
"ec2_eventsSet": "",
"ec2_group_name": "",
"ec2_hypervisor": "xen",
"ec2_id": "i-xxxxxxxx",
"ec2_image_id": "ami-xxxxxxxx",
"ec2_instance_type": "t2.micro",
"ec2_ip_address": "54.xxx.xxx.xxx",
"ec2_item": "",
"ec2_kernel": "",
"ec2_key_name": "mykey",
"ec2_launch_time": "2015-12-06T15:12:15.000Z",
"ec2_monitored": false,
"ec2_monitoring": "",
"ec2_monitoring_state": "disabled",
"ec2_persistent": false,
"ec2_placement": "ap-northeast-1a",
"ec2_platform": "",
"ec2_previous_state": "",
"ec2_previous_state_code": 0,
"ec2_private_dns_name": "ip-172-31-31-65.ap-northeast-1.compute.internal",
"ec2_private_ip_address": "172.31.31.65",
"ec2_public_dns_name": "ec2-54-xxx-xxx-xxx.ap-northeast-1.compute.amazonaws.com",
"ec2_ramdisk": "",
"ec2_reason": "",
"ec2_region": "ap-northeast-1",
"ec2_requester_id": "",
"ec2_root_device_name": "/dev/xvda",
"ec2_root_device_type": "ebs",
"ec2_security_group_ids": "sg-xxxxxxxx",
"ec2_security_group_names": "launch-wizard-1",
"ec2_sourceDestCheck": "true",
"ec2_spot_instance_request_id": "",
"ec2_state": "running",
"ec2_state_code": 16,
"ec2_state_reason": "",
"ec2_subnet_id": "subnet-xxxxxxxx",
"ec2_tag_Memo": "This is test server.",
"ec2_tag_Name": "test-server",
"ec2_virtualization_type": "hvm",
"ec2_vpc_id": "vpc-xxxxxxxx"
}
}
},
"ami_xxxxxxxx": [
"54.xxx.xxx.xxx"
],
"ap-northeast-1": [
"54.xxx.xxx.xxx"
],
"ap-northeast-1a": [
"54.xxx.xxx.xxx"
],
"ec2": [
"54.xxx.xxx.xxx"
],
"i-xxxxxxxx": [
"54.xxx.xxx.xxx"
],
"key_mykey": [
"54.xxx.xxx.xxx"
],
"security_group_launch_wizard_1": [
"54.xxx.xxx.xxx"
],
"tag_Memo_This_is_test_server_": [
"54.xxx.xxx.xxx"
],
"tag_Name_test_server": [
"54.xxx.xxx.xxx"
],
"type_t2_micro": [
"54.xxx.xxx.xxx"
],
"vpc_id_vpc_xxxxxxxx": [
"54.xxx.xxx.xxx"
]
}
キャッシュファイルは以下に配置されています。
$ ls ~/.ansible/tmp/
ansible-ec2.cache ansible-ec2.index
キャッシュファイルの中を見てみると、先ほど収集した情報が記載されています。
$ cat ~/.ansible/tmp/ansible-ec2.cache
{
"_meta": {
"hostvars": {
"54.xxx.xxx.xxx": {
"ec2__in_monitoring_element": false,
"ec2_ami_launch_index": "0",
"ec2_architecture": "x86_64",
"ec2_client_token": "",
"ec2_dns_name": "ec2-54-xxx-xxx-xxx.ap-northeast-1.compute.amazonaws.com",
"ec2_ebs_optimized": false,
"ec2_eventsSet": "",
"ec2_group_name": "",
"ec2_hypervisor": "xen",
"ec2_id": "i-xxxxxxxx",
"ec2_image_id": "ami-xxxxxxxx",
"ec2_instance_type": "t2.micro",
"ec2_ip_address": "54.xxx.xxx.xxx",
"ec2_item": "",
"ec2_kernel": "",
"ec2_key_name": "mykey",
"ec2_launch_time": "2015-12-06T15:12:15.000Z",
"ec2_monitored": false,
"ec2_monitoring": "",
"ec2_monitoring_state": "disabled",
"ec2_persistent": false,
"ec2_placement": "ap-northeast-1a",
"ec2_platform": "",
"ec2_previous_state": "",
"ec2_previous_state_code": 0,
"ec2_private_dns_name": "ip-172-31-31-65.ap-northeast-1.compute.internal",
"ec2_private_ip_address": "172.31.31.65",
"ec2_public_dns_name": "ec2-54-xxx-xxx-xxx.ap-northeast-1.compute.amazonaws.com",
"ec2_ramdisk": "",
"ec2_reason": "",
"ec2_region": "ap-northeast-1",
"ec2_requester_id": "",
"ec2_root_device_name": "/dev/xvda",
"ec2_root_device_type": "ebs",
"ec2_security_group_ids": "sg-xxxxxxxx",
"ec2_security_group_names": "launch-wizard-1",
"ec2_sourceDestCheck": "true",
"ec2_spot_instance_request_id": "",
"ec2_state": "running",
"ec2_state_code": 16,
"ec2_state_reason": "",
"ec2_subnet_id": "subnet-xxxxxxxx",
"ec2_tag_Memo": "This is test server.",
"ec2_tag_Name": "test-server",
"ec2_virtualization_type": "hvm",
"ec2_vpc_id": "vpc-xxxxxxxx"
}
}
},
"ami_xxxxxxxx": [
"54.xxx.xxx.xxx"
],
"ap-northeast-1": [
"54.xxx.xxx.xxx"
],
"ap-northeast-1a": [
"54.xxx.xxx.xxx"
],
"ec2": [
"54.xxx.xxx.xxx"
],
"i-xxxxxxxx": [
"54.xxx.xxx.xxx"
],
"key_mykey": [
"54.xxx.xxx.xxx"
],
"security_group_launch_wizard_1": [
"54.xxx.xxx.xxx"
],
"tag_Memo_This_is_test_server_": [
"54.xxx.xxx.xxx"
],
"tag_Name_test_server": [
"54.xxx.xxx.xxx"
],
"type_t2_micro": [
"54.xxx.xxx.xxx"
],
"vpc_id_vpc_xxxxxxxx": [
"54.xxx.xxx.xxx"
]
}
コマンドの実行
とりあえずグループ分けされた内容を指定して、pingコマンドを実行してみます。
いずれも成功しています。
host指定の場合
$ ansible -i ec2.py 54.xxx.xxx.xxx -m ping --private-key="~/.ssh/mykey.pem" -u ec2-user
54.xxx.xxx.xxx | success >> {
"changed": false,
"ping": "pong"
}
タグ名指定
$ ansible -i ec2.py "tag_Name_test_server" -m ping --private-key="~/.ssh/mykey.pem" -u ec2-user
54.xxx.xxx.xxx | success >> {
"changed": false,
"ping": "pong"
}
Playbookの実行
続いて、適当なPlaybookを実行してみます。
今回は、試しにApache httpd,MySQL Client,PHPをインストールするPlaybookを用意してみました。
- testserver.yml
- name: testserver package install
hosts: all
sudo: yes
remote_user: ec2-user
gather_facts: no
roles:
- testserver
- roles/testserver/tasks/main.yml
- name: yum package install for testserver
yum:
name={{ item }}
state=present
with_items:
- httpd24
- mysql
- php55
- name: package are running and enabled
service:
name={{ item }}
state=running
enabled=yes
with_items:
- httpd
では、Playbookを実行します。
$ ansible-playbook -i inventory/ec2.py -l "tag_Name_test_server" testserver.yml --private-key="~/.ssh/mykey.pem" -u ec2-user
PLAY [testserver install] ******************************************************
TASK: [testserver | yum package install for testserver] *************************
changed: [54.xxx.xxx.xxx] => (item=httpd24,mysql,php55)
TASK: [testserver | package are running and enabled] ***************************
changed: [54.xxx.xxx.xxx] => (item=httpd)
PLAY RECAP ********************************************************************
54.xxx.xxx.xxx : ok=2 changed=2 unreachable=0 failed=0
成功したようです。
本当にインストールされたか、確認してみます。
$ ansible -i inventory/ec2.py "tag_Name_test_server" -m shell -a "rpm -qa | grep -e httpd -e mysql -e php" --private-key="~/.ssh/mykey.pem" -u ec2-user
54.xxx.xxx.xxx | success | rc=0 >>
httpd24-tools-2.4.16-1.62.amzn1.x86_64
php55-process-5.5.30-1.110.amzn1.x86_64
php-pear-1.9.5-2.17.amzn1.noarch
mysql-config-5.5.46-1.10.amzn1.x86_64
httpd24-2.4.16-1.62.amzn1.x86_64
mysql55-libs-5.5.46-1.10.amzn1.x86_64
php55-cli-5.5.30-1.110.amzn1.x86_64
php55-common-5.5.30-1.110.amzn1.x86_64
php55-pecl-jsonc-1.3.6-1.13.amzn1.x86_64
mysql-5.5-1.6.amzn1.noarch
mysql55-5.5.46-1.10.amzn1.x86_64
php55-xml-5.5.30-1.110.amzn1.x86_64
php55-5.5.30-1.110.amzn1.x86_64
$ ansible -i inventory/ec2.py "tag_Name_test_server" -m shell -a "ps -ef | grep [h]ttpd" --private-key="~/.ssh/mykey.pem" -u ec2-user
54.xxx.xxx.xxx | success | rc=0 >>
root 6856 1 0 05:55 ? 00:00:00 /usr/sbin/httpd
apache 6859 6856 0 05:55 ? 00:00:00 /usr/sbin/httpd
apache 6860 6856 0 05:55 ? 00:00:00 /usr/sbin/httpd
apache 6861 6856 0 05:55 ? 00:00:00 /usr/sbin/httpd
apache 6862 6856 0 05:55 ? 00:00:00 /usr/sbin/httpd
apache 6863 6856 0 05:55 ? 00:00:00 /usr/sbin/httpd
インストールされたことが確認できました。