2016年7月15日金曜日

Fabricを使って、簡単にELB+EC2環境にローリングデプロイ

Python製のプロビジョニングツールであるFabricを使って、ELB + EC2環境にアプリケーションをローリングデプロイします。
ELBから1台ずつEC2インスタンスを切り離して、アプリケーションをデプロイしてリスタート、終わったら、ELBにEC2インスタンスを追加します。
なぜ、Fabricを使ったかというと、ほかのデプロイ自動化ツール、たとえばCapistranoやAnsibleだと、ELBのAPIを叩く処理を書くのがちょっと面倒そうだったからです。Fabricなら使いやすそうなPythonライブラリがあり、簡潔に書けるな、と考えたからです。
以下のFabricスクリプトは、ロールバックやヘルスチェックなどの処理を書いていません。もうちょっと高級なことがしたかったら、他の方法を考えたりするといいと思います。
※ ELBは、Classic load balancerを使っています。

Fabricのインストール
環境:Mac OS X
$ sudo easy_install fabric
$ sudo pip install boto
$ fab --version
Fabric 1.11.1
Paramiko 1.17.1
Fabricスクリプト
from fabric.api import *
from fabric.decorators import runs_once
import boto.ec2.elb
# EC2 settings
REGION = "ap-northeast-1"
AWS_ACCESS_KEY_ID = 'XXXXXXXXXX'
AWS_SECRET_ACCESS_KEY = 'XXXXXXXXXX'
ELB_NAME = 'my-elb'
SLEEP_TIME = 20
# Deploy setting
ORIGIN_APP_DIR = "/Users/yako/Desktop/myapp"
DEPLOY_DIR = "/usr/local/src"
# Init ELB
elb_connection = boto.ec2.elb.connect_to_region(
REGION,
aws_access_key_id = AWS_ACCESS_KEY_ID,
aws_secret_access_key = AWS_SECRET_ACCESS_KEY)
elb = elb_connection.get_all_load_balancers(ELB_NAME)[0]
# App operations
@task
def put_app():
put(ORIGIN_APP_DIR, '%s/' % DEPLOY_DIR)
@task
def app_start():
sudo("service myapp start")
@task
def app_stop():
sudo("service myapp stop")
@task
def app_restart():
sudo("service myapp restart")
# ELB operations
def get_ec2_id():
return run("curl http://169.254.169.254/latest/meta-data/instance-id")
@task
def remove_ec2_from_elb():
ec2_id = get_ec2_id()
elb.deregister_instances(ec2_id)
print("\n=> Removed %s from %s\n" % (ec2_id, ELB_NAME))
@task
def add_ec2_to_elb():
ec2_id = get_ec2_id()
elb.register_instances(ec2_id)
print("\n=> Add %s to %s\n" % (ec2_id, ELB_NAME))
# Deploy operations
@task
def all():
remove_ec2_from_elb()
run('sleep %s' % SLEEP_TIME)
put_app()
app_restart()
add_ec2_to_elb()
run('sleep %s' % SLEEP_TIME)
view raw deploy.py hosted with ❤ by GitHub
実行結果
$ fab -H 52.197.196.202,52.197.152.24 -f deploy all
[52.197.196.202] Executing task 'all'
[52.197.196.202] run: curl http://169.254.169.254/latest/meta-data/instance-id
[52.197.196.202] out: i-1096ad9f
=> Removed i-1096ad9f from my-elb
[52.197.196.202] run: sleep 20
[52.197.196.202] put: /Users/yako/Desktop/myapp/aaaa.txt -> /usr/local/src/myapp/aaaa.txt
[52.197.196.202] put: /Users/yako/Desktop/myapp/bbbb.txt -> /usr/local/src/myapp/bbbb.txt
[52.197.196.202] sudo: service myapp restart
[52.197.196.202] out: Stopping myapp: [ OK ]
[52.197.196.202] out:
[52.197.196.202] out: Starting myapp: [ OK ]
[52.197.196.202] out:
[52.197.196.202] out:
[52.197.196.202] run: curl http://169.254.169.254/latest/meta-data/instance-id
[52.197.196.202] out: i-1096ad9f
=> Add i-1096ad9f to my-elb
[52.197.196.202] run: sleep 20
[52.197.152.24] Executing task 'all'
[52.197.152.24] run: curl http://169.254.169.254/latest/meta-data/instance-id
[52.197.152.24] out: i-1296ad9d
=> Removed i-1296ad9d from my-elb
[52.197.152.24] run: sleep 20
[52.197.152.24] put: /Users/yako/Desktop/myapp/aaaa.txt -> /usr/local/src/myapp/aaaa.txt
[52.197.152.24] put: /Users/yako/Desktop/myapp/bbbb.txt -> /usr/local/src/myapp/bbbb.txt
[52.197.152.24] sudo: service myapp restart
[52.197.152.24] out: Stopping myapp: [ OK ]
[52.197.152.24] out:
[52.197.152.24] out: Starting myapp: [ OK ]
[52.197.152.24] out:
[52.197.152.24] out:
[52.197.152.24] run: curl http://169.254.169.254/latest/meta-data/instance-id
[52.197.152.24] out: i-1296ad9d
=> Add i-1296ad9d to my-elb
[52.197.152.24] run: sleep 20
Done.
Disconnecting from 52.197.196.202... done.
Disconnecting from 52.197.152.24... done.
view raw result.txt hosted with ❤ by GitHub

Top image from msburrows roll

2016年7月1日金曜日

HTTPヘッダーからPhusion Passengerのバージョンを隠す

Chrome DevToolsで自分のサイトを見ていたところ、Sinatraで作ったウェブアプリのHTTPヘッダーに、Phusion Passengerのバージョン情報が出ていて、気になってしまったので。消してみました。
こんな感じです。
Server:nginx + Phusion Passenger 5.0.29
X-Powered-By:Phusion Passenger 5.0.29
nginxの設定に以下の記述を入れてPhusion Passengerのバージョン情報を消しました。
情報を上書きすれば良いです。
server {
    listen 80;
    server_name rapper.hitokoto.co;

    more_set_headers 'Server: nginx';
    more_set_headers 'X-Powered-By';

top image from Saïda ...hide...