ども、cloudpack の 夜の Player かっぱ (@inokara) です。今年の紅白歌合戦出場は辞退しました。すいません。
はじめに
AWS 環境において fabric を利用して Play2 アプリケーションをリモートホストに対してデプロイしようとした際にリモートホストの情報を動的に取得したいと思ったので組み込んでみました。
boto
fabric が Python 実装ということで fabric から AWS 環境を扱おうとすると boto というライブラリが必須ですのでインストールしておきましょう。環境に応じてインストール方法は異なりますのでご注意下さい。
初めて知りましたが boto = AWS SDK for Python だったんですね。
実装
ギットハヴ
ツッコミ宜しくお願い致します!
ざっくりイメージ
以下のように EC2 のインスタンス Name タグを指定して Public IP アドレス等のデプロイ先の情報を取得してきます。
抜粋
該当する部分のみ抜粋。
from fabric.api import local, run, env, cd, lcd, execute, put, sudo from boto.ec2 import EC2Connection, get_region, connect_to_region def deploy_host(tag = "Name", value = "app-server", region = "region を指定"): key = "tag:"+tag env.hosts = _get_host_ip(region, key, value) def _get_host_ip(region, key, value ="*"): private_ip = [] conn = _create_connection(region) reservations = conn.get_all_instances(filters = {key : value}) for reservation in reservations: for instance in reservation.instances: print "Instance", instance.private_ip_address private_ip.append(str(instance.private_ip_address)) return private_ip def _create_connection(region): print "Connecting to ", region conn = connect_to_region( region_name = region ) print "Connection with AWS established" return conn 〜中略〜 def app_status(): execute(default_path) sudo('supervisorctl status %(app)s' % { 'app':env.app }, pty=True, shell=False) def app_start(): execute(set_path) with cd("%(current_path)s/%(snap_shot)s/" % { 'current_path':env.current_path, 'snap_shot':env.snap_shot }): run('if [ -f RUNNING_PID ]; then rm RUNNING_PID ; fi') sudo('supervisorctl start %(app)s' % { 'app':env.app }, pty=True, shell=False) def app_stop(): execute(default_path) sudo('supervisorctl stop %(app)s' % { 'app':env.app }, pty=True, shell=False
deploy_host
関数を引数で渡して実行します。
ポイントは…
- 冒頭の
boto.ec2
ライブラリを読み込んでいる部分 _get_host_ip
は_create_connection
を実行して AWS への接続を行う_get_host_ip
で取得された接続情報がenv.host
に代入される
IAM ロール
注意点としては fabric を実行するインスタンスは IAM ロールで以下の権限を付与しています。
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": "ec2:Describe*", "Resource": "*" }, { "Effect": "Allow", "Action": "elasticloadbalancing:Describe*", "Resource": "*" }, { "Effect": "Allow", "Action": [ "cloudwatch:ListMetrics", "cloudwatch:GetMetricStatistics", "cloudwatch:Describe*" ], "Resource": "*" }, { "Effect": "Allow", "Action": "autoscaling:Describe*", "Resource": "*" } ] }
多分、"Action": "ec2:Describe*"
だけあればイケるのではないかと思います。
demo
以下のように実行することでインスタンスの Name タグに app-server とあるインスタンスの IP アドレスを取得してサブコマンドで指定された処理を行います。
fab -f deploy.py deploy_host command
例えば、アプリケーションのステータスを取得したい場合には app_status
というコマンドを実行します。
fab -f deploy.py deploy_host app_status
以下のようにリモートホストにてコマンドを実行した結果が出力されます。
最後に
特に Play Framework に特化したことではありませんが、Capistrano でも同様に AWS SDK を利用してデプロイ先の情報を取得してデプロイを行うことが出来るので SDK ってサイコーって思ったりしています。
ということでおやすみなさい。
元記事はこちらです。
「Play2 アプリケーションのデプロイを fabric でやろうと思ったのでメモ(3)〜対象ホストを SDK で取得する巻〜」