Elastic Beanstalk with Docker と OpsWorks で Node + MongoDB する

Node + MongoDB のアプリを立ち上げたい

ある文脈で「HerokuはアカンけどAWSならええで」って言われたので、AWS使ってみた。

AWSでは、EC2やS3などを使ってアプリケーションの実行環境を編成するわけだが、その管理ツールとして以下のサービスが用意されている。EC2やS3がリソースなのに対して、これらはあくまでツールまたはサービスといえる。

  • Elastic Beanstalk
  • OpsWorks
  • Cloud Formation

できあがった構成

いじくってみた結果、最終的には App と Batch を Elastic Beanstalk with Docker でデプロイし、MongoDB を OpsWorks で編成できた感じなので、なんとなくメモにして残す。

  • AZ1

    • App
    • Batch
    • MongoDB Primary
  • AZ2

    • MognoDB Secondary

管理ユーティリティだったので最小気味構成。

断り書きになるが、今回触ってみるまでAWS童貞といっても過言ではなく、OpsWorksと Elastic Beanstalk のこのような使い分けがアリなのかはよく分かってないっす!!

Google先生と根気強く対話した結果、永続化するとこだけ Chef でアレして、アプリは Docker でイミュータブルにガンガン push すればいいんじゃね、くらいの気持ち。

1. AWSの準備

コマンドラインツール類を取得する。Macなので homebrew と pip で適当に入れた。

brew install ec2-api-tools
brew install aws-elasticbeanstalk
pip install awscli

2. OpsWorks: MongoDB

自分がやったときは先に次の EB + Docker を設定した結果、勝手に VPC(Virtual Private Cloud)が作られたので、OpsWorks の Stack も同じ VPC に設定した。

やったことは単純で、Setting up a MongoDB replicaset with AWS OpsWorks - Doug Bryant というOpsWorksでMongoDB設定するチュートリアル的な記事があったので、まんま参考にした。

Stackの設定

まずは Stack を追加する。ここで作成するインスタンスのデフォルトとか諸々も指定することになる。まんま参考にしているので、過不足に迷ったら元記事のほうも参照されたし。

  • 「Region」は Asia Pacific
  • 「VPC」は使いたいやつ
  • 「Default root device type」は EBS backed
  • Advanced をいくつか設定
    • 「Chef version」を 11.4 に設定
    • 「Use custom Chef cookbooks」は Yes
    • 「Repository URL」は参考記事の netinlet/chef-mongodb_replicaset
    • 「Custom JSON」に下記のJSONを貼り付け
{
  "mongodb" : {
    "replicaset_name": "mongo-rs",
      "cluster_name": "mongo-rs",
      "auto_configure": {
        "replicaset": true
      }
  }
}

Layerの設定

Custom Layer を追加して、Custom Chef Recipeを設定する。

  • 「Layer Type」は Custom
  • Custom Chef Recipe をいくつか設定
    • 「Setup」に mongodb::10gen_repomongodb::default
    • 「Configure」に mongodb::replicaset

インスタンスを配備

作成した Layer にインスタンスを追加する。レプリケーションするレシピを流すが、インスタンスが立ち上がってないと流せないので、Start しておく。

インスタンスタイプも確認しておく。今回は m1.medium にしておいた(豪勢気味)インスタンスを用意したら、スタックの画面右上から「Run Command」に入って、もろもろ設定して実行する。

  • 「Command」は Execute Recipes
  • 「Recipes to execute」は mongodb::replicaset

ここでは2つのインスタンスを追加して、それぞれ ap-northeast-1c と 1a に振り分けた。

3. Elastic Beanstalk with Docker: App & Batch

Gitで管理されたアプリケーションのルートで、eb init を実行する。

# 初期化スタート
eb init

# アクセスキーを作ってなかったら指定のURLから発行しておく(rootでないuserを作っておくほうがよい)
To get your AWS Access Key ID and Secret Access Key, 
  visit "https://aws-portal.amazon.com/gp/aws/securityCredentials".
Enter your AWS Access Key ID (current value is “***************"): 
Enter your AWS Secret Access Key:

# リージョンの選択
# ここでは Asia Pacific (6) を選択
Select an AWS Elastic Beanstalk service region.
Available service regions are:
1) US East (Virginia)
2) US West (Oregon)
3) US West (North California)
4) EU West (Ireland)
5) Asia Pacific (Singapore)
6) Asia Pacific (Tokyo)
7) Asia Pacific (Sydney)
8) South America (Sao Paulo)
Select (1 to 8): 6

# アプリケーション名と環境名を設定
# アプリが全体の大分類で、環境としてアプリやバッチが入るイメージ
Enter an AWS Elastic Beanstalk application name (auto-generated value is “foo-bar"): sample-app
Enter an AWS Elastic Beanstalk environment name (auto-generated value is “foo-bar-env"): sample-app-env

# 環境のtier選択
# ここでは Web Server (1) を選択
Select an environment tier.
Available environment tiers are:
1) WebServer::Standard::1.0
2) Worker::SQS/HTTP::1.0
Select (1 to 2): 1

# 実行環境
# ここでは Docker (41) を選択
Select a solution stack.
Available solution stacks are:
1) 64bit Amazon Linux 2014.03 v1.0.4 running PHP 5.5
2) 64bit Amazon Linux 2014.03 v1.0.4 running PHP 5.4
# 〜中略〜
39) 32bit Amazon Linux 2014.02 v1.0.1 running Ruby 1.8.7
40) 64bit Amazon Linux 2014.02 v1.0.1 running Ruby 1.8.7
41) 64bit Amazon Linux 2014.03 v1.0.1 running Docker 1.0.0
42) 64bit Amazon Linux 2014.03 v1.0.0 running Docker 1.0.0
Select (1 to 42): 41

# 環境の種類
# ここでは SingleInstance (2) を選択
Select an environment type.
Available environment types are:
1) LoadBalanced
2) SingleInstance
Select (1 to 2): 2

# RDSはいらない n
Create an RDS DB Instance? [y/n]: n

# インスタンスプロファイルはとりあえずなし y
Attach an instance profile (current value is "[Create a default instance profile]"):
Do you want to proceed without attaching an instance profile? [y/n]: y

ここまで終わると、.elasticbeanstalk/ に設定が保存されているはず。

とりあえず環境を起動してみる

eb start

eb start を実行してしばらくすると、Elastic Beanstalkの管理画面に環境が追加されたのが確認できる。たぶん勝手に立ち上がってるはず。ここではBatchサーバーも同様に立ち上げた。(キュー管理とかすると、Worker::SQSとか便利っぽい?)

アプリが起動時、MongoDBに繋ごうとするとサーバー的に疎通できずにコケているので、まだアプリケーションにアクセスはできない。

git aws.push

最新版のアプリをあげるときは、git aws.pushを使えばよい。

アプリとDBをつなぐ設定をちょびっと

で、一通りの環境は用意できたところで、AppとBatchからMongoDBのインスタンスにアクセスするために、VPCをちょろっと設定する。

「VPC -> Security Groups」で、AWS-OpsWorks-Custom-Server の Inbound Rules に App と Batch のセキュリティグループからのポート27017へのアクセスを許可するよう、Custom TCP ruleを追加した。これでMongoDBと疎通できるようになる(はず)

OpsWorksがSecurityGroupを大量生成していた...こういうもんなのかね

環境変数もちょろっと

MongoDBのアクセス情報などを環境変数に持たせる場合、Environment の Configuration -> Software Configuration から Environment Propertiesを設定できる。ここで設定した環境変数は、特になにもしなくてもDocker内のアプリに引き渡される

今回はmongoose用に、mongodb://ip-***-**-**-**.ap-northeast-1.compute.internal:27017/databasename 的な文字列を MONGO_URL として設定した。process.env.MONGO_URL で取得できる。アドレスはMongoのPrimaryインスタンスのPrivate DNSを指定した。

参考

Google I/O で $500 分の優待をもらったので、次はGCEで構成するのを試してみようかしら。