環境:
Mac
aws-cli 1.7.0
eb-cli 3.0.10
Ruby 2.1.5
Rails 4.2.0
今回のポイント
- VPC の環境構築(Subnet, IGW, Route Table)
- VPC 内に Elastic Beanstalk 環境構築
- Elastic Beanstalk のプラットフォームは Rubyを選択、Rails アプリをデプロイする。
- Rails でブログアプリケーションを作る例とする。
- RDS(MySQL) を作成してアプリと連携する。Beanstalk 作成時ではなく別途作成して関連付けしない。
- ELB、EC2、RDS は VPC内のパブリックサブネットに置く。
- RDS はプライベートサブネットに置き、接続するには NAT インスタンス経由にすべきだろうけど、今回はパブリックサブネットにおいてインターネットから直接接続できるようにした。
- 無料枠で試すので EC2、RDS インスタンスは t2.micro を選択。
- 環境構築はコマンドライン(aws-cli, eb-cli)だけで行う。
- 管理コンソールからやったほうが簡単だけど1ヶ月もすると手順を忘れてしまうので、すべてコマンドで作成して、同じ環境を再現できるようにしたかった。
VPC からの環境構築は今回はじめてやるので理解が間違ってるところがあるかもしれない。
事前準備
IAM でユーザ作成し、「Administrator Access」権限を付与、AWS CLI のaws configure
コマンドでregion
、aws_access_key_id
、aws_secret_access_key
を設定しておくこと。
ざっくりやること一覧
- VPC 作成
- Subnet 作成
- IGW 作成
- Rroute Table 作成
- DB パラメータグループ作成
- DB サブネットグループ作成
- VPC セキュリティグループ作成
- RDS インスタンス作成
- Rails アプリケーション作成
- Elastic Beanstalk 環境設定
- Elastic Beanstalk 環境作成
- Rails アプリのデプロイ
- 環境の削除
VPC 環境構築
VPC 作成
VPC を作成する。
$ aws ec2 create-vpc --cidr-block 10.0.0.0/16 { "Vpc": { "InstanceTenancy": "default", "State": "pending", "VpcId": "vpc-d42ae5b1", "CidrBlock": "10.0.0.0/16", "DhcpOptionsId": "dopt-9ed4cafc" } }
VPC に Name タグを追加する。
$ aws ec2 create-tags --resources vpc-d42ae5b1 --tags Key=Name,Value="vpc blog"
VPC の作成と一緒に
も作成される。これらの関係性は以下の図のようになっている。
VPC のセキュリティ - Amazon Virtual Private Cloud
http://docs.aws.amazon.com/ja_jp/AmazonVPC/latest/UserGuide/VPC_Security.html
Route Table(main) を確認する。
$ aws ec2 describe-route-tables --filters "Name=vpc-id,Values=vpc-d42ae5b1" ... "RouteTableId": "rtb-f072a695", "VpcId": "vpc-d42ae5b1", ...
Route Table(main) に Name タグを追加する。
$ aws ec2 create-tags --resources rtb-f072a695 --tags Key=Name,Value="rtb blog main"
ACL を確認する。
$ aws ec2 describe-network-acls --filters "Name=vpc-id,Values=vpc-d42ae5b1" ... "NetworkAclId": "acl-2ace1b4f", "VpcId": "vpc-d42ae5b1", ...
ACL に Name タグを追加する。
$ aws ec2 create-tags --resources acl-2ace1b4f --tags Key=Name,Value="acl blog"
VPC セキュリティグループ(default)を確認する。
$ aws ec2 describe-security-groups --filters "Name=vpc-id,Values=vpc-d42ae5b1" ... "GroupName": "default", "VpcId": "vpc-d42ae5b1", "OwnerId": "123456789012", "GroupId": "sg-bdc574d8" ...
VPC セキュリティグループに Name タグを追加する。
$ aws ec2 create-tags --resources sg-bdc574d8 --tags Key=Name,Value="sg blog default"
VPC の DNS ホスト名を有効にする
VPC 内の RDS に外部から接続できるようにするため。
参考: VPC の DNS サポートを更新する
# 有効にする $ aws ec2 modify-vpc-attribute --vpc-id vpc-d42ae5b1 --enable-dns-hostnames # 確認 $ aws ec2 describe-vpc-attribute --vpc-id vpc-d42ae5b1 --attribute enableDnsHostnames { "VpcId": "vpc-d42ae5b1", "EnableDnsHostnames": { "Value": true } }
Subnet 作成
3つのサブネットを作成する。
3つともパブリックサブネットとする。
2つ目、3つ目は DB 用として使うので availability-zone を分ける。
自分のアカウントではap-northeast-1a
、ap-northeast-1c
の2つが使用可能となっている。
$ aws ec2 create-subnet --vpc-id vpc-d42ae5b1 --cidr-block 10.0.0.0/24 --availability-zone ap-northeast-1a { "Subnet": { "VpcId": "vpc-d42ae5b1", "CidrBlock": "10.0.0.0/24", "State": "pending", "AvailabilityZone": "ap-northeast-1a", "SubnetId": "subnet-f23be885", "AvailableIpAddressCount": 251 } } $ aws ec2 create-subnet --vpc-id vpc-d42ae5b1 --cidr-block 10.0.1.0/24 --availability-zone ap-northeast-1a { "Subnet": { "VpcId": "vpc-d42ae5b1", "CidrBlock": "10.0.1.0/24", "State": "pending", "AvailabilityZone": "ap-northeast-1a", "SubnetId": "subnet-ff3be888", "AvailableIpAddressCount": 251 } } $ aws ec2 create-subnet --vpc-id vpc-d42ae5b1 --cidr-block 10.0.2.0/24 --availability-zone ap-northeast-1c { "Subnet": { "VpcId": "vpc-d42ae5b1", "CidrBlock": "10.0.2.0/24", "State": "pending", "AvailabilityZone": "ap-northeast-1c", "SubnetId": "subnet-d721d58e", "AvailableIpAddressCount": 251 } }
サブネットに Name タグを追加する。
$ aws ec2 create-tags --resources subnet-f23be885 --tags Key=Name,Value="subnet public blog web" $ aws ec2 create-tags --resources subnet-ff3be888 --tags Key=Name,Value="subnet public blog db1" $ aws ec2 create-tags --resources subnet-d721d58e --tags Key=Name,Value="subnet public blog db2"
インターネットゲートウェイ作成
インターネットゲートウェイ(IGW)を作成する。
$ aws ec2 create-internet-gateway { "InternetGateway": { "Tags": [], "InternetGatewayId": "igw-85d63ce0", "Attachments": [] } }
IGW に Name タグを追加する。
$ aws ec2 create-tags --resources igw-85d63ce0 --tags Key=Name,Value="igw blog"
VPC に IGW をアタッチする。
$ aws ec2 attach-internet-gateway --internet-gateway-id igw-85d63ce0 --vpc-id vpc-d42ae5b1
確認する。
$ aws ec2 describe-internet-gateways --internet-gateway-id igw-85d63ce0 { "InternetGateways": [ { "Tags": [ { "Value": "igw blog", "Key": "Name" } ], "InternetGatewayId": "igw-85d63ce0", "Attachments": [ { "State": "available", "VpcId": "vpc-d42ae5b1" } ] } ] }
パブリックサブネット用のルートテーブル作成
デフォルトでサブネットが紐付くメインルートテーブルとは別に新たにカスタムルートテーブルを作成する。
こちらをパブリックサブネット用のルートテーブルとして使用する。
$ aws ec2 create-route-table --vpc-id vpc-d42ae5b1 { "RouteTable": { "Associations": [], "RouteTableId": "rtb-2073a745", "VpcId": "vpc-d42ae5b1", "PropagatingVgws": [], "Tags": [], "Routes": [ { "GatewayId": "local", "DestinationCidrBlock": "10.0.0.0/16", "State": "active", "Origin": "CreateRouteTable" } ] } }
ルートテーブルに Name タグを追加する。
$ aws ec2 create-tags --resources rtb-2073a745 --tags Key=Name,Value="rtb blog public"
パブリックサブネット用ルートテーブルにインターネットゲートウェイを関連付ける
$ aws ec2 create-route --route-table-id rtb-2073a745 --destination-cidr-block 0.0.0.0/0 --gateway-id igw-85d63ce0
サブネットのルートテーブルを切り替え
作成した3つのサブネットに設定されているメインルートテーブルから、新たに作成したパブリックサブネット用ルートテーブルに切り替える。
$ aws ec2 associate-route-table --route-table-id rtb-2073a745 --subnet-id subnet-f23be885 { "AssociationId": "rtbassoc-70924015" } $ aws ec2 associate-route-table --route-table-id rtb-2073a745 --subnet-id subnet-ff3be888 { "AssociationId": "rtbassoc-73924016" } $ aws ec2 associate-route-table --route-table-id rtb-2073a745 --subnet-id subnet-d721d58e { "AssociationId": "rtbassoc-7d924018" }
VPC 環境構築はここまで。
RDS 環境構築
ここからは RDS の環境構築を行う。
以前の投稿も参考に。
- MySQL 5.6(5.6.22) を使う。
- Beanstalk 環境作成時に同時に RDS も作成できるが、Beanstalk に関連付けすると Beanstalk 環境の削除時に RDS も一緒に削除しようとするので別途作成する。
- 今回は Multi-AZ Deployment はしない。
DB パラメーターグループ作成
DB パラメーターグループmydbparamgroup
を作成する。
$ aws rds create-db-parameter-group \ --db-parameter-group-name mydbparamgroup \ --db-parameter-group-family mysql5.6 \ --description "for myinstance" { "DBParameterGroup": { "DBParameterGroupName": "mydbparamgroup", "DBParameterGroupFamily": "mysql5.6", "Description": "for myinstance" } }
DB パラメーターグループのキャラクタセット関連のパラメータを更新する。
$ aws rds modify-db-parameter-group --db-parameter-group-name mydbparamgroup --parameters \ ParameterName=character_set_client,ParameterValue=utf8mb4,ApplyMethod=immediate \ ParameterName=character_set_connection,ParameterValue=utf8mb4,ApplyMethod=immediate \ ParameterName=character_set_database,ParameterValue=utf8mb4,ApplyMethod=immediate \ ParameterName=character_set_results,ParameterValue=utf8mb4,ApplyMethod=immediate \ ParameterName=character_set_server,ParameterValue=utf8mb4,ApplyMethod=immediate \ ParameterName=collation_connection,ParameterValue=utf8mb4_general_ci,ApplyMethod=immediate \ ParameterName=collation_server,ParameterValue=utf8mb4_general_ci,ApplyMethod=immediate \ ParameterName=skip-character-set-client-handshake,ParameterValue=0,ApplyMethod=pending-reboot { "DBParameterGroupName": "mydbparamgroup" }
続いて、init_connect パラメータを更新する。
$ aws rds modify-db-parameter-group --generate-cli-skeleton > init_connect.json
出力されたファイルを以下のように編集する。
{ "DBParameterGroupName": "mydbparamgroup", "Parameters": [ { "ParameterName": "init_connect", "ParameterValue": "SET SESSION time_zone = CASE WHEN POSITION('rds' IN CURRENT_USER()) = 1 THEN 'UTC' ELSE 'Asia/Tokyo' END;", "Description": "", "Source": "", "ApplyType": "", "DataType": "", "AllowedValues": "", "IsModifiable": true, "MinimumEngineVersion": "", "ApplyMethod": "immediate" } ] }
そして DB パラメータグループを更新する。--cli-input-json
オプションでファイルを指定。
$ aws rds modify-db-parameter-group --cli-input-json file://init_connect.json # 終わったら不要なので削除 $ rm init_connect.json
DB サブネットグループを作成
DB サブネットグループmydbsubnetgroup
を作成する。
DB 用に用意した2つのサブネットsubnet public blog db1
、subnet public blog db2
を設定する。
$ aws rds create-db-subnet-group \ --db-subnet-group-name mydbsubnetgroup \ --db-subnet-group-description "DB SubnetGroup for myinstance" \ --subnet-ids subnet-ff3be888 subnet-d721d58e { "DBSubnetGroup": { "Subnets": [ { "SubnetStatus": "Active", "SubnetIdentifier": "subnet-d721d58e", "SubnetAvailabilityZone": { "Name": "ap-northeast-1c" } }, { "SubnetStatus": "Active", "SubnetIdentifier": "subnet-ff3be888", "SubnetAvailabilityZone": { "Name": "ap-northeast-1a" } } ], "DBSubnetGroupName": "mydbsubnetgroup", "VpcId": "vpc-d42ae5b1", "DBSubnetGroupDescription": "DB SubnetGroup for myinstance", "SubnetGroupStatus": "Complete" } }
DB用 VPC セキュリティグループ作成
DB用 VPC セキュリティグループmyrds
を作成する。
ちなみに DB セキュリティグループと呼ばれるものがあるが、これは VPC 内ではない RDS に適用するもの。
昔の EC2-Classic Platform のアカウントのみ使える。
$ aws ec2 create-security-group \ --group-name myrds \ --description "RDS security group" \ --vpc-id vpc-d42ae5b1 { "GroupId": "sg-14c77671" }
DB用 VPC セキュリティグループに Name タグを追加する。
$ aws ec2 create-tags --resources sg-14c77671 --tags Key=Name,Value="sg blog rds"
RDS MySQL に外部から接続するために Inbound のルールを追加する。
$ aws ec2 authorize-security-group-ingress --group-id sg-14c77671 --protocol tcp --port 3306 --cidr 0.0.0.0/0
RDS インスタンス(MySQL)作成
- db-instance-identifier は
myinstance
とする。 - 上記で作成した DB パラメータグループをオプションで指定する。
- セキュリティグループにデフォルト、上で作成した
myrds
の2つを追加する。 - RDS MySQL に外部から接続したいので publicly-accessible を追加。
$ aws rds create-db-instance \ --db-instance-identifier myinstance \ --allocated-storage 5 \ --db-instance-class db.t2.micro \ --engine MySQL \ --engine-version 5.6.22 \ --master-username bloguser \ --master-user-password bloguser1234567890 \ --db-name blogdb \ --db-parameter-group-name mydbparamgroup \ --db-subnet-group-name mydbsubnetgroup \ --vpc-security-group-ids sg-bdc574d8 sg-14c77671 \ --storage-type standard \ --availability-zone ap-northeast-1a \ --no-multi-az \ --region ap-northeast-1 \ --publicly-accessible \ --no-auto-minor-version-upgrade
コマンドを実行すると RDS インスタンスの作成がはじまる。しばらく時間がかかるので待つ。
インスタンスの作成が完了したら、以下コマンドでエンドポイントを確認する。
$ aws rds describe-db-instances --db-instance-identifier myinstance | jq '.DBInstances[].Endpoint' { "Port": 3306, "Address": "myinstance.xxxxxxxxxxxx.ap-northeast-1.rds.amazonaws.com" }
PublicIp、PublicDnsName は以下コマンドで確認できる。
GUI 管理コンソールでは、EC2 Dashboard -> Network interfaces から確認できる。
$ aws ec2 describe-network-interfaces --filters "Name=description,Values=RDSNetworkInterface" ... "Description": "RDSNetworkInterface", "Association": { "PublicIp": "54.92.100.249", "PublicDnsName": "ec2-54-92-100-249.ap-northeast-1.compute.amazonaws.com", "IpOwnerId": "amazon-rds" }, ...
上で調べた Endpoint または PublicIp、PublicDnsName のいずれかをホストに指定して MySQL に接続できるか確認する。
$ mysql -h myinstance.xxxxxxxxxxxx.ap-northeast-1.rds.amazonaws.com -P 3306 -u bloguser -p -D blogdb $ mysql -h ec2-54-65-198-252.ap-northeast-1.compute.amazonaws.com -P 3306 -u bloguser -p -D blogdb $ mysql -h 54.65.198.252 -P 3306 -u bloguser -p -D blogdb
RDS 環境構築はここまで。
Rails アプリケーション作成
Rails プロジェクト新規作成
サンプルとしてブログアプリケーションを作成する。
DB には MySQL を使う。ローカル環境に MySQL インストール済み。
$ bundle exec rails new blog -d mysql --skip-bundle $ cd blog # アプリケーションサーバとして Puma を選択するので Gemfile に追加 $ echo "gem 'puma'" >> Gemfile # gem インストール $ bundle install --path vendor/bundle
scaffold 実行
scaffold コマンドでアプリの雛形を作成する。
$ bin/rails generate scaffold article title:string content:string
ルート修正
config/routes.rb
Rails.application.routes.draw do resources :articles root 'articles#index' end
タイムゾーンの設定
config/application.rb
config.time_zone = 'Tokyo' config.active_record.default_timezone = :local
マイグレーション実行
ローカル環境の MySQL に対してマイグレーションを実行する。
$ bin/rake db:create && bin/rake db:migrate
動作確認
ローカル環境でアプリを起動して MySQL にデータ登録、画面にデータ表示できるか確認する。
$ bin/rails s
本番 DB 設定
本番用の DB 設定を修正する。
config/database.yml
production: adapter: mysql2 encoding: utf8mb4 database: <%= ENV['RDS_DB_NAME'] %> username: <%= ENV['RDS_USERNAME'] %> password: <%= ENV['RDS_PASSWORD'] %> host: <%= ENV['RDS_HOSTNAME'] %> port: <%= ENV['RDS_PORT'] %>
Git コミット
Git リポジトリを作成してソースコード一式を add & commit する。
$ git init && git add -A && git commit -m "first commit"
Rails アプリケーション作成まここまで。
Elastic Beanstalk 環境構築
ここからは Elastic Beanstalk の環境構築を行う。
以前の投稿も参考に。
先ほど作成した Rails プロジェクトのディレクトリ内で以下手順を行う。
アプリケーション枠の作成
eb init
コマンドでアプリケーション枠を作成する。SSH キーペアは作成してアップロード済み。
$ eb init blog \ --platform "Ruby 2.1 (Puma)" \ --keyname aws-eb
.gitignore が更新されるので add & commit する。
$ git commit -am "updated .gitignore"
Elastic Beanstalk 環境のカスタマイズ設定
EC2 インスタンスのタイムゾーンを日本に変更するため、カスタマイズ設定ファイルを準備する。
.ebextensions
ディレクトリを作成する。
$ mkdir -p .ebextensions/scripts
Timezone を設定するシェルスクリプトを作成する。
.ebextensions/scripts/timezone.sh
#!/bin/bash cp -f /usr/share/zoneinfo/Japan /etc/localtime sed -i -e 's/ZONE=.*$/ZONE="Asia\/Tokyo"/' /etc/sysconfig/clock sed -i -e 's/UTC=.*$/UTC=false/' /etc/sysconfig/clock echo 'ARC=false' >> /etc/sysconfig/clock
.ebextensions ディレクトリ直下に config ファイルを作成する。
この config ファイルはデプロイする度に実行される。
タイムゾーン設定は初回の EC2 インスタンス作成時のみ実行すればよいので、test コマンドを使って2回目以降は実行されないようにした。
.ebextensions/01_timezone.config
container_commands: 01-change_timezone: test: '[ ! -f /root/.not-a-new-instance.txt ]' command: bash .ebextensions/scripts/timezone.sh 02-create_check_file: test: '[ ! -f /root/.not-a-new-instance.txt ]' command: touch /root/.not-a-new-instance.txt
ここまでできたら Git に add & commit する。
$ git add -A && git commit -m "add extensions"
Elastic Beanstalk 環境の作成
eb create
コマンドでインスタンスの作成を行う。オプションについてはこちら。
- 環境名は
blog-production
とする。 - 作成したVPC(
vpc blog
)を指定する。 - ELB と EC2 には同じパブリックサブネット(
subnet public blog web
)を指定する。 - ELB と EC2 をパブリックサブネットに置くので、それぞれ
elbpublic
とpublicip
を設定する。 - デフォルトのセキュリティグループ(
sg blog default
)を指定する。 - cname オプションで
com-example-blog-production
を設定する。- cname オプションを設定することで ELB に CNAME をつけることができる。URL スワップ時に使用する。
- sample オプションをつける。
sample オプションをつける理由:
eb create
コマンドを実行すると、環境構築 -> Rails アプリデプロイ -> DB マイグレーションまで行われるが、config/database.yml の DB 関連のパラメータは環境変数から取得するようなっており、まだ環境変数は未設定なのでパラメータが取得できず、DBマイグレーションに失敗してしまう。
しかし、eb setenv
による環境変数の設定はeb create
実行後でなければできない。
ワークアラウンドとして、1発目のデプロイでは--sample
オプションを与えて、カレントディレクトリの Rails プロジェクトではなく、サンプルアプリケーションをデプロイさせる方法で回避する。
$ eb create blog-production \ --sample \ --cname com-example-blog-production \ --instance_type t2.micro \ --region ap-northeast-1 \ --tier webserver \ --vpc.ec2subnets subnet-f23be885 \ --vpc.elbsubnets subnet-f23be885 \ --vpc.id vpc-d42ae5b1 \ --vpc.securitygroups sg-bdc574d8 \ --vpc.publicip \ --vpc.elbpublic Environment details for: blog-production Application name: blog Region: ap-northeast-1 Deployed Version: None Environment ID: e-3qvcc2mas3 Platform: 64bit Amazon Linux 2014.09 v1.2.0 running Ruby 2.1 (Puma) Tier: WebServer-Standard-1.0 CNAME: com-example-blog-production.elasticbeanstalk.com Updated: 2015-02-18 08:19:01.355000+00:00 Printing Status: INFO: createEnvironment is starting. INFO: Using elasticbeanstalk-ap-northeast-1-123456789012 as Amazon S3 storage bucket for environment data. INFO: Created security group named: sg-cac677af INFO: Created load balancer named: awseb-e-3-AWSEBLoa-19XNPJOJ2L4UJ INFO: Created security group named: sg-d2c677b7 INFO: Created Auto Scaling launch configuration named: awseb-e-3qvcc2mas3-stack-AWSEBAutoScalingLaunchConfiguration-1JJZT8EC6TQTN INFO: Waiting for EC2 instances to launch. This may take a few minutes. INFO: Created Auto Scaling group named: awseb-e-3qvcc2mas3-stack-AWSEBAutoScalingGroup-XQ9W5EU82FGI INFO: Created Auto Scaling group policy named: arn:aws:autoscaling:ap-northeast-1:123456789012:scalingPolicy:6c971967-dbd5-420c-b396-3e9077ca17c5:autoScalingGroupName/awseb-e-3qvcc2mas3-stack-AWSEBAutoScalingGroup-XQ9W5EU82FGI:policyName/awseb-e-3qvcc2mas3-stack-AWSEBAutoScalingScaleUpPolicy-1QMQK2YUBBKEQ INFO: Created Auto Scaling group policy named: arn:aws:autoscaling:ap-northeast-1:123456789012:scalingPolicy:ec062391-358f-4296-af75-71b20f5d1677:autoScalingGroupName/awseb-e-3qvcc2mas3-stack-AWSEBAutoScalingGroup-XQ9W5EU82FGI:policyName/awseb-e-3qvcc2mas3-stack-AWSEBAutoScalingScaleDownPolicy-6YRVJB2IR2C2 INFO: Created CloudWatch alarm named: awseb-e-3qvcc2mas3-stack-AWSEBCloudwatchAlarmHigh-O9GN3OBFYQK3 INFO: Created CloudWatch alarm named: awseb-e-3qvcc2mas3-stack-AWSEBCloudwatchAlarmLow-18E1BGLOHWKS INFO: Added EC2 instance 'i-f59d7eed' to Auto Scaling Group 'awseb-e-3qvcc2mas3-stack-AWSEBAutoScalingGroup-XQ9W5EU82FGI'. INFO: Application available at com-example-blog-production.elasticbeanstalk.com. INFO: Successfully launched environment: blog-production
画面確認
$ eb open # http://com-example-blog-production.elasticbeanstalk.com
Elastic Beanstalk 環境変数の設定
eb setenv
コマンドで環境変数を設定する。
$ eb setenv \ SECRET_KEY_BASE=`bin/rake secret` \ RDS_DB_NAME=blogdb \ RDS_USERNAME=bloguser \ RDS_PASSWORD=bloguser1234567890 \ RDS_HOSTNAME=myinstance.xxxxxxxxxxxx.ap-northeast-1.rds.amazonaws.com \ RDS_PORT=3306 INFO: Environment update is starting. INFO: Updating environment blog-production's configuration settings. INFO: Successfully deployed new configuration to environment. INFO: Environment update completed successfully.
確認
$ eb printenv Environment Variables: AWS_SECRET_KEY = None RDS_PORT = 3306 RAILS_SKIP_ASSET_COMPILATION = false BUNDLE_WITHOUT = test:development RDS_PASSWORD = bloguser1234567890 SECRET_KEY_BASE = 72ecc50883dd60d2668c5074053c5aae9c7acf5409eccab206053b2cf8e7039871d86ab349fa99cf208350ecbec5091dbd22a3f274b2cb242747d860f5fd6b93 RACK_ENV = production PARAM5 = None PARAM4 = None PARAM3 = None PARAM2 = None PARAM1 = None RDS_USERNAME = bloguser RDS_DB_NAME = blogdb RAILS_SKIP_MIGRATIONS = false AWS_ACCESS_KEY_ID = None RDS_HOSTNAME = myinstance.xxxxxxxxxxxx.ap-northeast-1.rds.amazonaws.com
Rails アプリのデプロイ
ここでカレントディレクトリの Rails プロジェクトをデプロイする。
$ eb deploy INFO: Environment update is starting. INFO: Deploying new version to instance(s). INFO: New application version was deployed to running EC2 instances. INFO: Environment update completed successfully.
画面確認。
$ eb open
アプリ画面が表示されることを確認。
とりあえず適当なデータを1件登録してみる。
ここで Beanstalk で作成した EC2 インスタンスのタイムゾーンと RDS に保存されたレコードの時間を確認する。
まず、EC2 インスタンスの PublicDns, PublicIp を確認する。
# 環境名 blog-production でフィルタする $ aws ec2 describe-instances --filters "Name=tag-value,Values=blog-production" | jq '.Reservations[].Instances[] | {PublicDnsName,PublicIpAddress}' # またはインスタンスID指定 # $ aws ec2 describe-instances --instance-ids i-f59d7eed --filters "Name=tag-value,Values=blog-production" | jq '.Reservations[].Instances[] | {PublicDnsName,PublicIpAddress}' { "PublicDnsName": "ec2-54-65-4-37.ap-northeast-1.compute.amazonaws.com", "PublicIpAddress": "54.65.4.37" }
EC2 インスタンスの SSH ログインしてタイムゾーンを確認。
$ ssh -i ~/.ssh/aws-eb ec2-user@54.65.4.37 [ec2-user@ip-10-0-0-189 ~]$ date 2015年 2月 18日 水曜日 17:34:28 JST
RDS MySQL にコマンド接続して、セッションの現在時間、テーブルの登録データの日時を確認。
$ mysql -h myinstance.xxxxxxxxxxxx.ap-northeast-1.rds.amazonaws.com -P 3306 -u bloguser -p -D blogdb mysql> select now(); +---------------------+ | now() | +---------------------+ | 2015-02-18 17:41:00 | +---------------------+ 1 row in set (0.01 sec) mysql> select * from articles; +----+-------+---------+---------------------+---------------------+ | id | title | content | created_at | updated_at | +----+-------+---------+---------------------+---------------------+ | 1 | foo | bar | 2015-02-18 17:35:40 | 2015-02-18 17:35:40 | +----+-------+---------+---------------------+---------------------+ 1 row in set (0.01 sec) mysql> \q
次回以降のデプロイでは DB マイグレーションが自動実行されないように環境変数RAILS_SKIP_MIGRATIONS
を false から true に変更しておく。
$ eb setenv RAILS_SKIP_MIGRATIONS=true
ここまでで環境構築からアプリデプロイまでの工程が完了した。
後片付け
ここからは、ここまで作成してきたもの削除して元に戻す作業を行う。
Elastic Beanstalk リソース群の削除
ELB、EC2 などの Beanstalk リソース群のすべてを削除する。
$ eb terminate The environment "blog-production" and all associated instances will be terminated. To confirm, type the environment name: blog-production INFO: terminateEnvironment is starting. INFO: Deleted CloudWatch alarm named: awseb-e-3qvcc2mas3-stack-AWSEBCloudwatchAlarmLow-18E1BGLOHWKS INFO: Deleted CloudWatch alarm named: awseb-e-3qvcc2mas3-stack-AWSEBCloudwatchAlarmHigh-O9GN3OBFYQK3 INFO: Deleted Auto Scaling group policy named: arn:aws:autoscaling:ap-northeast-1:123456789012:scalingPolicy:ec062391-358f-4296-af75-71b20f5d1677:autoScalingGroupName/awseb-e-3qvcc2mas3-stack-AWSEBAutoScalingGroup-XQ9W5EU82FGI:policyName/awseb-e-3qvcc2mas3-stack-AWSEBAutoScalingScaleDownPolicy-6YRVJB2IR2C2 INFO: Deleted Auto Scaling group policy named: arn:aws:autoscaling:ap-northeast-1:123456789012:scalingPolicy:6c971967-dbd5-420c-b396-3e9077ca17c5:autoScalingGroupName/awseb-e-3qvcc2mas3-stack-AWSEBAutoScalingGroup-XQ9W5EU82FGI:policyName/awseb-e-3qvcc2mas3-stack-AWSEBAutoScalingScaleUpPolicy-1QMQK2YUBBKEQ INFO: Waiting for EC2 instances to terminate. This may take a few minutes. INFO: Deleted Auto Scaling group named: awseb-e-3qvcc2mas3-stack-AWSEBAutoScalingGroup-XQ9W5EU82FGI INFO: Deleted Auto Scaling launch configuration named: awseb-e-3qvcc2mas3-stack-AWSEBAutoScalingLaunchConfiguration-1JJZT8EC6TQTN INFO: Deleted load balancer named: awseb-e-3-AWSEBLoa-19XNPJOJ2L4UJ INFO: Deleted security group named: sg-d2c677b7 INFO: Deleted security group named: sg-cac677af INFO: Deleting SNS topic for environment blog-production. INFO: terminateEnvironment completed successfully.
RDS 関連の削除
RDS インスタンスの削除
データも削除されるので注意!
# スナップショットは作らず削除 $ aws rds delete-db-instance --db-instance-identifier myinstance --skip-final-snapshot # スナップショットを作ってから削除 $ aws rds delete-db-instance --db-instance-identifier myinstance \ --no-skip-final-snapshot \ --final-db-snapshot-identifier myinstance-final-snapshot
インスタンス削除が完了するまで待つ。
DB パラメーターグループの削除
DB パラメーターグループmydbparamgroup
を削除する。
$ aws rds delete-db-parameter-group --db-parameter-group-name mydbparamgroup
DB サブネットグループの削除
DB サブネットグループmydbsubnetgroup
を削除する。
$ aws rds delete-db-subnet-group --db-subnet-group-name mydbsubnetgroup
VPC セキュリティグループの削除
VPC セキュリティグループmyrds
を削除する。
$ aws ec2 delete-security-group --group-id sg-14c77671
VPC 関連の削除
Subnet 削除
$ aws ec2 delete-subnet --subnet-id subnet-f23be885 $ aws ec2 delete-subnet --subnet-id subnet-ff3be888 $ aws ec2 delete-subnet --subnet-id subnet-d721d58e
カスタム Route Table 削除
$ aws ec2 delete-route-table --route-table-id rtb-2073a745
IGW を VPC からデタッチする
$ aws ec2 detach-internet-gateway --internet-gateway-id igw-85d63ce0 --vpc-id vpc-d42ae5b1
IGW 削除
$ aws ec2 delete-internet-gateway --internet-gateway-id igw-85d63ce0
VPC 削除
$ aws ec2 delete-vpc --vpc-id vpc-d42ae5b1
同時に
- Route Table(main)
- Network ACL
- Security Group(default)
も削除される。
ちなみにコマンドから削除する場合は、親の VPC から削除することはできず、上記のように子の方から順に依存関係を解除しないとその親は削除できない。
一方、GUIの管理コンソールから削除する場合は、親の VPC から削除することが可能で、その下に紐付くものすべて削除される(インスタンスが残っている場合などは無理)。