後でまた見返したい Git を理解するための濃い記事まとめ。
www.slideshare.net
チュートリアル
gitの入門用のチュートリアル"Learn Git Branching"を訳した | 48JIGEN *Reloaded*
環境: Xcode7 GM
iOS9 対応で行った作業メモ。
HTTPS 接続にする必要あり。今回はとりあえずHTTPを許可するようにInfo.plist
に以下の手順で追加する。
NSAppTransportSecurity
を Dictionary で追加。NSAllowsArbitraryLoads
をBooleanで追加し、YESを設定。openURL
、canOpenURL
のようなメソッドでカスタムURLスキームを呼び出す場合、Info.plist
に登録しなければ使えないようになった。
admob SDK を使ってるのだが、アプリ起動時に以下のような許可されてないスキームのエラーが出るようになった。
-canOpenURL: failed for URL: "itms-books://" - error: "This app is not allowed to query for scheme itms-books" -canOpenURL: failed for URL: "kindle://home" - error: "This app is not allowed to query for scheme kindle"
Info.plist
に以下の手順で追加する。
LSApplicationQueriesSchemes
を Array で追加。item 0
が追加されるので String でitms-books
を入力。item 1
を追加し String でkindle
を入力。これで再度起動してみると、スキームが許可されてないエラーから、スキーム起動失敗のエラーに変わった。
これはスキームで起動させるアプリがインストールされていないためなので問題なし。
-canOpenURL: failed for URL: "itms-books://" - error: "(null)" -canOpenURL: failed for URL: "kindle://home" - error: "(null)"
ここまでの作業でInfo.plist
は以下のようになった。
実機でアプリを起動しようとしたら admob SDK で以下のエラーが出た。
ld: '/.../Google-Mobile-Ads-SDK/GoogleMobileAdsSdkiOS-7.4.1/GoogleMobileAds.framework/GoogleMobileAds(GADGestureIdUtil.o)' does not contain bitcode. You must rebuild it with bitcode enabled (Xcode setting ENABLE_BITCODE), obtain an updated library from the vendor, or disable bitcode for this target. for architecture armv7 clang: error: linker command failed with exit code 1 (use -v to see invocation)
とりあえず Bitcode をオフにすることでビルドが通るようになった。
Target -> Build Settings -> Build Options -> Enable Bitcode を NO に変更。
選択行(複数行可)を上に移動
選択行(複数行可)を上に移動
超使う。ソースコード上の定義にジャンプしたり、戻ったり。
トラックパッドの左右スワイプでも同様なことができるがデカいファイル上で行うと固まったりするので、上のコマンドでやるほうがよい。
ビルド
ビルド&シミュレータ起動。
クリーン
ビルドのキャンセル。
プロジェクトナビゲーター表示。左ペインのソースコードツリーのこと。
Command(⌘) + 2,3,4,5… で左ペインをメニューをそれぞれ表示する。
現在、開いているファイルのプロジェクトナビゲーター上の位置に移動して表示。
現在開いているファイルに対して検索を行う。
全ファイルに対して検索を行う。
さらに検索窓の上の 「Find」部分を「Replace」に入れ替えることで置換用窓が現れる。
これを使えば全ファイルを対象に一括置換が可能。置換前にプレビューで確認できるので安心して置換できる。
ファイル名でインクリメンタル絞り込みを行いつつ検索する。
現在開いているウインドウを分割して2つのファイルを表示する。(画面分割形式 は Assistant Editor の設定で指定できる)
ウィンドウを閉じるにはCmd + Enter
。表示と違うので注意。
Utilities の表示・非表示。画面右ペインのこと。
Command(⌘) + Option(⌥) + 2,3,4,5… で右ペインをメニューをそれぞれ表示する。
画面左ペインの表示・非表示。
Scheme 編集画面を開く。
Target を切り替える。
ブレイクポイントを枠外にドラッグで移動させて離すと削除される。
これ知らずに右クリックから Delete Breakpoint で削除してて面倒くさいと思ってた・・
環境:
Xcode 6.1
iOS 8.1 Simulator
結論から言うと Xcode 6.1 と iOS 8.1 Simulator の環境で、 iOS Simulator の言語設定に対応したローカライズファイルLocalizable.strings
を用意しても反映されないバグがあるらしい。
ワークアラウンドとして iOS Simulator 側の言語設定はなく、Xcode の Edit Scheme -> Run -> Option -> Application Language で言語設定すればいけた。
参考:
xcode - iOS 8.1 Simulator Localization broken (NSLocalizedString) - Stack Overflow
http://stackoverflow.com/questions/26504304/ios-8-1-simulator-localization-broken-nslocalizedstring
iOS8のシミュレーターでLocalizationのテストをする
http://www.rizastar.com/blog_xcode/ios8-simulator-localization-test/
ローカライズについてはこの資料が分かりやすかった。
Xcode のローカライズ処方箋 #yhios
http://www.slideshare.net/tomohirokumagai54/xcode-yhios
環境:
Mac
aws-cli 1.7.0
eb-cli 3.0.10
Ruby 2.1.5
Rails 4.2.0
VPC からの環境構築は今回はじめてやるので理解が間違ってるところがあるかもしれない。
IAM でユーザ作成し、「Administrator Access」権限を付与、AWS CLI のaws configure
コマンドでregion
、aws_access_key_id
、aws_secret_access_key
を設定しておくこと。
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 内の 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 } }
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 の環境構築を行う。
以前の投稿も参考に。
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 サブネットグループ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 セキュリティグループ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
myinstance
とする。myrds
の2つを追加する。$ 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 環境構築はここまで。
サンプルとしてブログアプリケーションを作成する。
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 コマンドでアプリの雛形を作成する。
$ 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 設定を修正する。
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 リポジトリを作成してソースコード一式を add & commit する。
$ git init && git add -A && git commit -m "first commit"
Rails アプリケーション作成まここまで。
ここからは 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"
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"
eb create
コマンドでインスタンスの作成を行う。オプションについてはこちら。
blog-production
とする。vpc blog
)を指定する。subnet public blog web
)を指定する。elbpublic
とpublicip
を設定する。sg blog default
)を指定する。com-example-blog-production
を設定する。
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
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 プロジェクトをデプロイする。
$ 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
ここまでで環境構築からアプリデプロイまでの工程が完了した。
ここからは、ここまで作成してきたもの削除して元に戻す作業を行う。
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.
データも削除されるので注意!
# スナップショットは作らず削除 $ 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 パラメーターグループmydbparamgroup
を削除する。
$ aws rds delete-db-parameter-group --db-parameter-group-name mydbparamgroup
DB サブネットグループmydbsubnetgroup
を削除する。
$ aws rds delete-db-subnet-group --db-subnet-group-name mydbsubnetgroup
VPC セキュリティグループmyrds
を削除する。
$ aws ec2 delete-security-group --group-id sg-14c77671
$ aws ec2 delete-subnet --subnet-id subnet-f23be885 $ aws ec2 delete-subnet --subnet-id subnet-ff3be888 $ aws ec2 delete-subnet --subnet-id subnet-d721d58e
$ aws ec2 delete-route-table --route-table-id rtb-2073a745
$ aws ec2 detach-internet-gateway --internet-gateway-id igw-85d63ce0 --vpc-id vpc-d42ae5b1
$ aws ec2 delete-internet-gateway --internet-gateway-id igw-85d63ce0
$ aws ec2 delete-vpc --vpc-id vpc-d42ae5b1
同時に
も削除される。
ちなみにコマンドから削除する場合は、親の VPC から削除することはできず、上記のように子の方から順に依存関係を解除しないとその親は削除できない。
一方、GUIの管理コンソールから削除する場合は、親の VPC から削除することが可能で、その下に紐付くものすべて削除される(インスタンスが残っている場合などは無理)。
環境:
Mac
aws-cli 1.7.0
jq 1.4
RDS MySQL(5.6.22)
RDS MySQL の文字コードとタイムゾーンの設定を行ったのでその手順メモ。
操作はすべて aws-cli のコマンドラインで行う。
RDS MySQL の文字コードおよび照合順序はデフォルトの状態でインスタンスを立ち上げると以下のようになる。
mysql> show global variables like 'character\_set\_%'; +--------------------------+--------+ | Variable_name | Value | +--------------------------+--------+ | character_set_client | latin1 | | character_set_connection | latin1 | | character_set_database | latin1 | | character_set_filesystem | binary | | character_set_results | latin1 | | character_set_server | latin1 | | character_set_system | utf8 | +--------------------------+--------+ 7 rows in set (0.01 sec) mysql> show global variables like 'collation%'; +----------------------+-------------------+ | Variable_name | Value | +----------------------+-------------------+ | collation_connection | latin1_swedish_ci | | collation_database | latin1_swedish_ci | | collation_server | latin1_swedish_ci | +----------------------+-------------------+
登録するデータとして絵文字が含まれるので utf8mb4 を使えるように設定を行う。
RDS の設定値を変更するにはDB パラメーターグループを通して行う。
まずは、mysql5.6 用の DB パラメーターグループの雛形を元にして新規の DB パラメーターグループをrds create-db-parameter-group
コマンドで作成する。
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 パラメーターグループのキャラクタセット関連のパラメータの初期値をrds describe-db-parameters
コマンドで確認する。
ParameterValue はすべて未設定となっている。
$ aws rds describe-db-parameters --db-parameter-group-name mydbparamgroup \ | jq '.Parameters[] | select(.ParameterName | contains("character") or contains("collation")) | { Description,DataType,Source,IsModifiable,ParameterName,ParameterValue,ApplyType }' { "Description": "Don't ignore character set information sent by the client.", "DataType": "boolean", "Source": "engine-default", "IsModifiable": true, "ParameterName": "character-set-client-handshake", "ParameterValue": null, "ApplyType": "static" } { "Description": "The character set for statements that arrive from the client.", "DataType": "string", "Source": "engine-default", "IsModifiable": true, "ParameterName": "character_set_client", "ParameterValue": null, "ApplyType": "dynamic" } { "Description": "The character set used for literals that do not have a character set introducer and for number-to-string conversion.", "DataType": "string", "Source": "engine-default", "IsModifiable": true, "ParameterName": "character_set_connection", "ParameterValue": null, "ApplyType": "dynamic" } { "Description": "The character set used by the default database.", "DataType": "string", "Source": "engine-default", "IsModifiable": true, "ParameterName": "character_set_database", "ParameterValue": null, "ApplyType": "dynamic" } { "Description": "The file system character set.", "DataType": "string", "Source": "engine-default", "IsModifiable": true, "ParameterName": "character_set_filesystem", "ParameterValue": null, "ApplyType": "dynamic" } { "Description": "The character set used for returning query results to the client.", "DataType": "string", "Source": "engine-default", "IsModifiable": true, "ParameterName": "character_set_results", "ParameterValue": null, "ApplyType": "dynamic" } { "Description": "The server's default character set.", "DataType": "string", "Source": "engine-default", "IsModifiable": true, "ParameterName": "character_set_server", "ParameterValue": null, "ApplyType": "dynamic" } { "Description": "The collation of the connection character set.", "DataType": "string", "Source": "engine-default", "IsModifiable": true, "ParameterName": "collation_connection", "ParameterValue": null, "ApplyType": "dynamic" } { "Description": "The server's default collation.", "DataType": "string", "Source": "engine-default", "IsModifiable": true, "ParameterName": "collation_server", "ParameterValue": null, "ApplyType": "dynamic" } { "Description": "Ignore character set information sent by the client.", "DataType": "boolean", "Source": "engine-default", "IsModifiable": true, "ParameterName": "skip-character-set-client-handshake", "ParameterValue": null, "ApplyType": "static" }
DB パラメーターグループのキャラクタセット関連のパラメータをrds modify-db-parameter-group
コマンドで更新する。
character_set_filesystem
、character_set_system
以外のキャラクタセットはutf8mb4
を設定する。utf8mb4_general_ci
にする。skip-character-set-client-handshake
は TRUE にするとクライアント側が要求してきたキャラクタセットは無視して強制的にサーバ側のcharacter-set-server
で指定したキャラクタセットで応答するようになるらしい。$ 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" }
DB パラメータグループに反映されたかrds describe-db-parameters
コマンドで確認してみる。
$ aws rds describe-db-parameters --db-parameter-group-name mydbparamgroup \ | jq '[ .Parameters[] | select(.ParameterName | contains("character") or contains("collation")) | { key: .ParameterName, value: .ParameterValue } ] | from_entries' { "character-set-client-handshake": null, "character_set_client": "utf8mb4", "character_set_connection": "utf8mb4", "character_set_database": "utf8mb4", "character_set_filesystem": null, "character_set_results": "utf8mb4", "character_set_server": "utf8mb4", "collation_connection": "utf8mb4_general_ci", "collation_server": "utf8mb4_general_ci", "skip-character-set-client-handshake": "0" }
create-db-instance
コマンドで RDS MySQL インスタンスを作成する。
myinstance
とする。$ 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 \ --storage-type standard \ --no-multi-az \ --region ap-northeast-1 \ --publicly-accessible \ --no-auto-minor-version-upgrade
コマンドを実行すると RDS インスタンスの作成がはじまる。しばらく時間がかかるので待つ。
default VPC
内に作成される。default VPC security group
が設定される。default
が設定される。インスタンスの作成が完了したら、rds describe-db-instances
コマンドでエンドポイントを確認する。
$ aws rds describe-db-instances --db-instance-identifier myinstance ... "Endpoint": { "Port": 3306, "Address": "myinstance.xxxxxxxxxxxx.ap-northeast-1.rds.amazonaws.com" }, ...
PublicIp、PublicDnsName はec2 describe-network-interfaces
コマンドで確認できる。
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" }, ...
RDS MySQL に外部から接続するためにdefault VPC security group
に Inbound のルールを追加する。
セキュリティグループ ID を確認。
$ aws rds describe-db-instances --db-instance-identifier myinstance ... "VpcSecurityGroups": [ { "Status": "active", "VpcSecurityGroupId": "sg-xxxxxxxx" } ], ...
ec2 authorize-security-group-ingress
コマンドで追加する。
$ aws ec2 authorize-security-group-ingress --group-id sg-xxxxxxxx --protocol tcp --port 3306 --cidr 0.0.0.0/0
上で調べた Endpoint または PublicIp、PublicDnsName のいずれかをホストに指定して MySQL に接続する。
$ mysql -h myinstance.xxxxxxxxxxxx.ap-northeast-1.rds.amazonaws.com -P 3306 -u bloguser -p -D blogdb
MySQL に接続できたら、キャラクタセットの設定を確認する。
mysql> show create database blogdb\G *************************** 1. row *************************** Database: blogdb Create Database: CREATE DATABASE `blogdb` /*!40100 DEFAULT CHARACTER SET utf8mb4 */ 1 row in set (0.01 sec) mysql> show variables like 'character\_set\_%'; +--------------------------+---------+ | Variable_name | Value | +--------------------------+---------+ | character_set_client | utf8 | | character_set_connection | utf8 | | character_set_database | utf8mb4 | | character_set_filesystem | binary | | character_set_results | utf8 | | character_set_server | utf8mb4 | | character_set_system | utf8 | +--------------------------+---------+ mysql> show global variables like 'character\_set\_%'; +--------------------------+---------+ | Variable_name | Value | +--------------------------+---------+ | character_set_client | utf8mb4 | | character_set_connection | utf8mb4 | | character_set_database | utf8mb4 | | character_set_filesystem | binary | | character_set_results | utf8mb4 | | character_set_server | utf8mb4 | | character_set_system | utf8 | +--------------------------+---------+ mysql> show variables like 'collation%'; +----------------------+--------------------+ | Variable_name | Value | +----------------------+--------------------+ | collation_connection | utf8_general_ci | | collation_database | utf8mb4_general_ci | | collation_server | utf8mb4_general_ci | +----------------------+--------------------+ mysql> show global variables like 'collation%'; +----------------------+--------------------+ | Variable_name | Value | +----------------------+--------------------+ | collation_connection | utf8mb4_general_ci | | collation_database | utf8mb4_general_ci | | collation_server | utf8mb4_general_ci | +----------------------+--------------------+
global variables は指定通り utf8mb4 になっているが、session の variables は utf8 になっている箇所がある・・・
MySQL クライアント側のキャラクタセットがどうなっているか調べてみる。
今、手元の Mac にインストールした MySQL(Server version: 5.6.19 Homebrew)から接続しているので、そのローカルの MySQL にログインする。
$ mysql -uroot mysql> show variables like 'character\_set\_%'; +--------------------------+--------+ | Variable_name | Value | +--------------------------+--------+ | character_set_client | utf8 | | character_set_connection | utf8 | | character_set_database | utf8 | | character_set_filesystem | binary | | character_set_results | utf8 | | character_set_server | utf8 | | character_set_system | utf8 | +--------------------------+--------+ mysql> show global variables like 'character\_set\_%'; +--------------------------+--------+ | Variable_name | Value | +--------------------------+--------+ | character_set_client | utf8 | | character_set_connection | utf8 | | character_set_database | utf8 | | character_set_filesystem | binary | | character_set_results | utf8 | | character_set_server | utf8 | | character_set_system | utf8 | +--------------------------+--------+ mysql> show variables like 'collation%'; +----------------------+-----------------+ | Variable_name | Value | +----------------------+-----------------+ | collation_connection | utf8_general_ci | | collation_database | utf8_general_ci | | collation_server | utf8_general_ci | +----------------------+-----------------+ mysql> show global variables like 'collation%'; +----------------------+-----------------+ | Variable_name | Value | +----------------------+-----------------+ | collation_connection | utf8_general_ci | | collation_database | utf8_general_ci | | collation_server | utf8_general_ci | +----------------------+-----------------+
character_set_client
など、すべて utf8 になっていたのでこれが原因だろう。クライアント側でキャラクタセットを指定して再度、RDS MySQL に接続してみる。
コマンドラインのオプションで--default-character-set
を指定する。
$ mysql --default-character-set=utf8mb4 -h myinstance.xxxxxxxxxxxx.ap-northeast-1.rds.amazonaws.com -P 3306 -u bloguser -p
再度、キャラクタセットの設定を確認する。
mysql> show variables like 'character\_set\_%'; +--------------------------+---------+ | Variable_name | Value | +--------------------------+---------+ | character_set_client | utf8mb4 | | character_set_connection | utf8mb4 | | character_set_database | utf8mb4 | | character_set_filesystem | binary | | character_set_results | utf8mb4 | | character_set_server | utf8mb4 | | character_set_system | utf8 | +--------------------------+---------+ mysql> show global variables like 'character\_set\_%'; +--------------------------+---------+ | Variable_name | Value | +--------------------------+---------+ | character_set_client | utf8mb4 | | character_set_connection | utf8mb4 | | character_set_database | utf8mb4 | | character_set_filesystem | binary | | character_set_results | utf8mb4 | | character_set_server | utf8mb4 | | character_set_system | utf8 | +--------------------------+---------+ mysql> show variables like 'collation%'; +----------------------+--------------------+ | Variable_name | Value | +----------------------+--------------------+ | collation_connection | utf8mb4_general_ci | | collation_database | utf8mb4_general_ci | | collation_server | utf8mb4_general_ci | +----------------------+--------------------+ mysql> show global variables like 'collation%'; +----------------------+--------------------+ | Variable_name | Value | +----------------------+--------------------+ | collation_connection | utf8mb4_general_ci | | collation_database | utf8mb4_general_ci | | collation_server | utf8mb4_general_ci | +----------------------+--------------------+
今度はセッションの設定も utf8mb4 となった。
一応、skip-character-set-client-handshake
を TRUE の場合もやってみた。
DB パラメータグループを更新する。
$ aws rds modify-db-parameter-group --db-parameter-group-name mydbparamgroup --parameters \ ParameterName=skip-character-set-client-handshake,ParameterValue=1,ApplyMethod=pending-reboot
変更を反映させるためにrds reboot-db-instance
コマンドで RDS インスタンスの再起動させる。
$ aws rds reboot-db-instance --db-instance-identifier myinstance
同じように RDS MySQL に接続してキャラクタセットを確認したところ、クライアント側で要求したキャラクタセットは無視されて、すべて utf8mb4 となることが確認できた。
※追記:タイムゾーンの設定が可能になり以下で設定できる。init_connectを使ったワークアラウンドは不要になった
$ aws rds modify-db-parameter-group --db-parameter-group-name mydbparamgroup --parameters \ ParameterName=time_zone,ParameterValue=Asia/Tokyo,ApplyMethod=immediate
Amazon Web Services ブログ: Amazon RDS (MySQL, MariaDB)がlocal time zoneをサポートしました
http://aws.typepad.com/aws_japan/2015/12/amazon-rds-local-timezone-support.html
--
以下、タイムゾーンの変更ができなかった頃のワークアラウンド
RDS MySQL のタイムゾーンを JST にしたいが、現時点ではタイムゾーンの変更はできず、デフォルトの UTC となっている。
調べてみるとワークアラウンドとして、init_connect
変数を使って接続毎にタイムゾーンを設定する方法があるようなので、それをやってみる。
以下を参考にさせてもらった。
AWS - RDS(MySQL)でJSTを使う たった1つの冴えたやり方 - Qiita
http://qiita.com/j3tm0t0/items/089ef96ba131df079ca4
MySQL,RDS - RDS(MySQLエンジンにてタイムゾーンを変更する方法を整理) - Qiita
http://qiita.com/mitzi2funk/items/4726986e8288b1599786
» AWS RDSのタイムゾーンについて Tech Fun.cc
http://techfun.cc/aws/aws-rds-timezone.html
init_connect
で単純にSET SESSION time_zone = 'Asia/Tokyo';
とやるのでは問題が発生するとのこと。
RDS 管理用のrdsadmin
というユーザがいて、このユーザが何かする時に Timezone が UTC 以外だと不具合が発生してしまうみたい。
以下のようにrdsadmin
ユーザ以外の接続時のみ Timezone を変更するようにすればよい。
SET SESSION time_zone = CASE WHEN POSITION('rds' IN CURRENT_USER()) = 1 THEN 'UTC' ELSE 'Asia/Tokyo' END;
# ローカル Mac の現在時間 $ date 2015年 2月17日 火曜日 01時27分19秒 JST # RDS MySQL に接続 $ mysql -h myinstance.xxxxxxxxxxxx.ap-northeast-1.rds.amazonaws.com -P 3306 -u bloguser -p # 現在時間、タイムゾーン確認 mysql> select now(); +---------------------+ | now() | +---------------------+ | 2015-02-16 16:27:51 | +---------------------+ mysql> show variables like '%time_zone'; +------------------+-------+ | Variable_name | Value | +------------------+-------+ | system_time_zone | UTC | | time_zone | UTC | +------------------+-------+ mysql> show global variables like '%time_zone'; +------------------+-------+ | Variable_name | Value | +------------------+-------+ | system_time_zone | UTC | | time_zone | UTC | +------------------+-------+
UTC となっている。ローカルは JST なので当然ながら時間はズレている。
init_connect
変数を設定DB パラメータグループのinit_connect
変数を更新する。
SET 文を aws-cli の直接コマンドに埋め込むのではなく、ファイルに書いてそれをアップロードする方法で行う。
まずはテンプレートとなるファイルを--generate-cli-skeleton
オプションで出力させる。
$ 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
設定が反映されるまで待つ。
反映されたら再度 RDS MySQL に接続して確認してみる。
# ローカル Mac の現在時間 $ date 2015年 2月17日 火曜日 01時38分03秒 JST # RDS MySQL 接続 $ mysql -h myinstance.xxxxxxxxxxxx.ap-northeast-1.rds.amazonaws.com -P 3306 -u bloguser -p # 現在時間、タイムゾーン確認 mysql> select now(); +---------------------+ | now() | +---------------------+ | 2015-02-17 01:38:18 | +---------------------+ mysql> show variables like '%time_zone'; +------------------+------------+ | Variable_name | Value | +------------------+------------+ | system_time_zone | UTC | | time_zone | Asia/Tokyo | +------------------+------------+ mysql> show global variables like '%time_zone'; +------------------+-------+ | Variable_name | Value | +------------------+-------+ | system_time_zone | UTC | | time_zone | UTC | +------------------+-------+
このセッションのtime_zone
がAsia/Tokyo
になっているのが確認できた。
default VPC security group
に追加した Inbound ルールをec2 revoke-security-group-ingress
コマンドで取り消す。
$ aws ec2 revoke-security-group-ingress --group-id sg-xxxxxxxx --protocol tcp --port 3306 --cidr 0.0.0.0/0
RDS インスタンスmyinstance
をrds delete-db-instance
コマンドで削除する(データも消えるので注意!)。
# スナップショットは作らず削除 $ 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 パラメーターグループmydbparamgroup
をrds delete-db-parameter-group
コマンドで削除する。
$ aws rds delete-db-parameter-group --db-parameter-group-name mydbparamgroup
以上。
DB パラメータグループの JSON データから jq コマンドで目的のデータを抽出するためにいろいろ試行錯誤しながら試した。
記録しておかないと次に再現できないのでメモしておく。
元 JSON データ
{ "Parameters": [ { "Description": "Controls whether user-defined functions that have only an xxx symbol for the main function can be loaded", "DataType": "boolean", "AllowedValues": "0,1", "Source": "engine-default", "IsModifiable": false, "ParameterName": "allow-suspicious-udfs", "ApplyType": "static" }, { "Description": "The MySQL installation base directory.", "DataType": "string", "IsModifiable": false, "Source": "system", "ParameterValue": "/rdsdbbin/mysql", "ParameterName": "basedir", "ApplyType": "static" }, ... ] }
上記の元データから jq コマンドを使って、あるパラメータに特定の文字列を含むものだけを抽出して出力してみる。
jq コマンドはjq '.'
、jq '.Parameters[]'
のようにシングルクォートで囲ったフィルタ式を渡すことで実行する。
ParameterName に"character"を含むものを抽出する。
.Parameters[]
で Parameters の配列の全ての要素を取り出して出力する。.Parameters
とは違う。contains()
で()内の入力値に部分一致するかどうかの真偽値を返す。select()
で ()内の条件が真になれば、その要素を出力する、偽であれば何も返さない。$ aws rds describe-db-parameters --db-parameter-group-name mydbparamgroup \ | jq '.Parameters[] | select(.ParameterName | contains("character"))'
下は上と同じように動作する、別の書き方。
$ aws rds describe-db-parameters --db-parameter-group-name mydbparamgroup \ | jq '.Parameters[] | select(contains({ParameterName: "character"}))'
出力結果:
{ "Description": "Don't ignore character set information sent by the client.", "DataType": "boolean", "AllowedValues": "0,1", "Source": "engine-default", "IsModifiable": true, "ParameterName": "character-set-client-handshake", "ApplyType": "static" } { "Description": "The character set for statements that arrive from the client.", "DataType": "string", "IsModifiable": true, "AllowedValues": "big5,dec8,cp850,hp8,koi8r,latin1,latin2,swe7,ascii,ujis,sjis,hebrew,tis620,euckr,koi8u,gb2312,greek,cp1250,gbk,latin5,armscii8,utf8,cp866,keybcs2,macce,macroman,cp852,latin7,utf8mb4,cp1251,cp1256,cp1257,binary,geostd8,cp932,eucjpms", "Source": "user", "ParameterValue": "utf8mb4", "ParameterName": "character_set_client", "ApplyType": "dynamic" } ...
{}
を利用することで、JSON の内容を組み替えたオブジェクトを生成して出力してる。
$ aws rds describe-db-parameters --db-parameter-group-name mydbparamgroup \ | jq '.Parameters[] | select(.ParameterName | contains("character")) | { desc: .Description, name: .ParameterName, value: .ParameterValue }'
出力結果:
{ "desc": "Don't ignore character set information sent by the client.", "name": "character-set-client-handshake", "value": null } { "desc": "The character set for statements that arrive from the client.", "name": "character_set_client", "value": "utf8mb4" } ...
[]
で囲んで配列を作成from_entries
で key-value のペアからオブジェクトへ変換$ aws rds describe-db-parameters --db-parameter-group-name mydbparamgroup \ | jq '[ .Parameters[] | select(.ParameterName | contains("character")) | { key: .ParameterName, value: .ParameterValue} ] | from_entries'
出力結果:
{ "character-set-client-handshake": null, "character_set_client": "utf8mb4", "character_set_connection": "utf8mb4", "character_set_database": "utf8mb4", "character_set_filesystem": null, "character_set_results": "utf8mb4", "character_set_server": "utf8mb4", "skip-character-set-client-handshake": "0" }
"character"または、"collation"を含むものを抽出。or
を使う。
$ aws rds describe-db-parameters --db-parameter-group-name mydbparamgroup \ | jq '.Parameters[] | select(.ParameterName | contains("character") or contains("collation"))' # 上と同じ $ aws rds describe-db-parameters --db-parameter-group-name mydbparamgroup \ | jq '.Parameters[] | select(contains({ParameterName: "character"}) or contains({ParameterName: "collation"}))'
今までものをすべて組み合わせたもの。
desc, name, value のみ
$ aws rds describe-db-parameters --db-parameter-group-name mydbparamgroup \ | jq '.Parameters[] | select(.ParameterName | contains("character") or contains("collation")) | { desc: .Description, name: .ParameterName, value: .ParameterValue }' { "desc": "Don't ignore character set information sent by the client.", "name": "character-set-client-handshake", "value": null } { "desc": "The character set for statements that arrive from the client.", "name": "character_set_client", "value": "utf8mb4" } ...
key-value 形式
$ aws rds describe-db-parameters --db-parameter-group-name mydbparamgroup \ | jq '[ .Parameters[] | select(.ParameterName | contains("character") or contains("collation")) | { key: .ParameterName, value: .ParameterValue } ] | from_entries' { "character-set-client-handshake": null, "character_set_client": "utf8mb4", "character_set_connection": "utf8mb4", "character_set_database": "utf8mb4", "character_set_filesystem": null, "character_set_results": "utf8mb4", "character_set_server": "utf8mb4", "collation_connection": "utf8mb4_general_ci", "collation_server": "utf8mb4_general_ci", "skip-character-set-client-handshake": "0" }
参考:
jq Manual
http://stedolan.github.io/jq/manual/
軽量JSONパーサー『jq』のドキュメント:『jq Manual』をざっくり日本語訳してみました | Developers.IO
http://dev.classmethod.jp/tool/jq-manual-japanese-translation-roughly/
ゼロから始めるjqチュートリアル - JSONを解析/自在に出力する
http://blog.serverfrog.jp/jq-tutorial/
jq コマンドを使う日常のご紹介 - Qiita
http://qiita.com/takeshinoda@github/items/2dec7a72930ec1f658af
環境:
Mac
eb-cli 3.0.10
ruby 2.1.5
rails 4.2.0
今回は、Elastic Beanstalk 用のコマンドラインツールである EB CLI を使って Rails アプリをデプロイしてみる。
最近出た EB CLI 3系はコマンドが2系から大幅に変更されている。
現時点(2015/2/12)では3系に対応した日本語ドキュメントはまだ用意されていないので英語の方を参照する。
http://docs.aws.amazon.com/elasticbeanstalk/latest/dg/command-reference-eb.html
コマンド一覧を見てみると Heroku に似てきた気がする。
EB CLI のインストール手順は省略。homebrew でインストールした。
まずは、Elastic Beanstalk 側で用意してあるサンプルアプリケーションをデプロイしてみる。
カレントディレクトリにソースコードを何も用意していないと自動的にこのサンプルアプリケーションがデプロイされる。
最初にeb init
コマンドを実行し、対話形式で入力していく。
eb の初回起動時にはAWS Access Key ID
やAWS Secret Access Key
を入力する。
たぶん IAM でAWSElasticBeanstalkFullAccess
権限を持たせたユーザのものを入力すれば大丈夫なはず(自分はAdministratorAccess
のユーザを使ったが)。
続いて、アプリケーション名入力、プラットフォームの選択、SSH セットアップを行う。
~/.ssh
ディレクトリにaws-eb
、aws-eb.pub
という名前で作成される。$ mkdir my-hello-app && cd my-hello-app $ eb init Enter Application Name (default is "my-hello-app"): # <= アプリケーション名の入力。未入力だとディレクトリ名となる Application my-hello-app has been created. Select a platform. 1) PHP 2) Node.js 3) IIS 4) Tomcat 5) Python 6) Ruby 7) Docker 8) GlassFish 9) Go (default is 1): 6 # <= Ruby 選択 Select a platform version. 1) Ruby 2.1 (Puma) 2) Ruby 2.1 (Passenger Standalone) 3) Ruby 2.0 (Puma) 4) Ruby 2.0 (Passenger Standalone) 5) Ruby 1.9.3 (default is 1): 1 # <= Ruby 2.1.5 & Puma を選択 Do you want to set up SSH for your instances? (y/n): y # <= SSHのセットアップを行う Type a keypair name. (Default is aws-eb): # <= 未入力 Generating public/private rsa key pair. Enter passphrase (empty for no passphrase): # <= 未入力 Enter same passphrase again: Your identification has been saved in /Users/xyk/.ssh/aws-eb. Your public key has been saved in /Users/xyk/.ssh/aws-eb.pub. ... WARNING: Uploaded SSH public key for "aws-eb" into EC2 for region ap-northeast-1.
この時点でカレントディレクトリに.elasticbeanstalk/config.yml
が作成される。
$ cat .elasticbeanstalk/config.yml branch-defaults: default: environment: null global: application_name: my-hello-app default_ec2_keyname: aws-eb default_platform: Ruby 2.1 (Puma) default_region: null profile: null
GUIの管理画面を見てみるとアプリケーション「my-hello-app」が作成されているのが確認できる。
続いてeb create
を実行する。
環境名と CNAME を入力すると Beanstalk リソース群のプロビジョニングが開始される。
といったことが行われる。これらが作成できるまでしばらく時間がかかる。
$ eb create Enter Environment Name (default is my-hello-app-dev): # <= 環境名の入力。未入力だと「アプリケーション名-dev」になる Enter DNS CNAME prefix (default is my-hello-app-dev): # <= CNAME の入力。デフォルト選択をしようとしたが既に使用済みだったのでエラーとなった。 That cname is not available. Please choose another Enter DNS CNAME prefix (default is my-hello-app-dev): my-hello-app-20150212 # <= 被ってない名前にする必要あり WARNING: The current directory does not contain any source code. Elastic Beanstalk is launching the sample application instead. Environment details for: my-hello-app-dev Application name: my-hello-app Region: ap-northeast-1 Deployed Version: None Environment ID: e-pdxw4mbwye Platform: 64bit Amazon Linux 2014.09 v1.1.0 running Ruby 2.1 (Puma) Tier: WebServer-Standard- CNAME: my-hello-app-20150212.elasticbeanstalk.com Updated: 2015-02-12 10:15:36.529000+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-57ec5a32 INFO: Created load balancer named: awseb-e-p-AWSEBLoa-PCXS7HIVUX8D INFO: Created security group named: awseb-e-pdxw4mbwye-stack-AWSEBSecurityGroup-IY32FV0GOCS INFO: Created Auto Scaling launch configuration named: awseb-e-pdxw4mbwye-stack-AWSEBAutoScalingLaunchConfiguration-3YG1CAINBBRQ INFO: Created Auto Scaling group named: awseb-e-pdxw4mbwye-stack-AWSEBAutoScalingGroup-1NJ3F09C0837P INFO: Waiting for EC2 instances to launch. This may take a few minutes. INFO: Created Auto Scaling group policy named: arn:aws:autoscaling:ap-northeast-1:123456789012:scalingPolicy:00f26acf-6a88-471a-8134-4f5eade5a324:autoScalingGroupName/awseb-e-pdxw4mbwye-stack-AWSEBAutoScalingGroup-1NJ3F09C0837P:policyName/awseb-e-pdxw4mbwye-stack-AWSEBAutoScalingScaleDownPolicy-1U1W1179JQYO7 INFO: Created Auto Scaling group policy named: arn:aws:autoscaling:ap-northeast-1:123456789012:scalingPolicy:f8ab2930-6e5a-4b93-ad5c-432d757b1042:autoScalingGroupName/awseb-e-pdxw4mbwye-stack-AWSEBAutoScalingGroup-1NJ3F09C0837P:policyName/awseb-e-pdxw4mbwye-stack-AWSEBAutoScalingScaleUpPolicy-JKXHVAQQK4R3 INFO: Created CloudWatch alarm named: awseb-e-pdxw4mbwye-stack-AWSEBCloudwatchAlarmLow-7MXXI4P9QOVN INFO: Created CloudWatch alarm named: awseb-e-pdxw4mbwye-stack-AWSEBCloudwatchAlarmHigh-1K56EXRQ89PIO INFO: Added EC2 instance 'i-7ec12766' to Auto Scaling Group 'awseb-e-pdxw4mbwye-stack-AWSEBAutoScalingGroup-1NJ3F09C0837P'. INFO: Application available at my-hello-app-20150212.elasticbeanstalk.com. INFO: Successfully launched environment: my-hello-app-dev
ちなみにeb create
の引数オプションで--sample
を指定しても強制的にサンプルアプリケーションのデプロイとなる。
$ eb create my-hello-app-dev --sample
ここまでで Beanstalk 環境構築とサンプルアプリケーションのデプロイが完了した。非常に簡単。
eb open
コマンドでデプロイされたサンプルアプリケーションをブラウザで開く。
$ eb open
URL は (CNAME prefix).elasticbeanstalk.com となる。
今回の場合だと
http://my-hello-app-20150212.elasticbeanstalk.com
となる。
この時点でconfig.yml
は以下のようになっている。
$ cat .elasticbeanstalk/config.yml branch-defaults: default: environment: my-hello-app-dev global: application_name: my-hello-app default_ec2_keyname: aws-eb default_platform: Ruby 2.1 (Puma) default_region: null profile: null
eb terminate
コマンドを実行すると上記で作成した Beanstalk のリソース群がすべて削除される。
$ eb terminate The environment "my-hello-app-dev" and all associated instances will be terminated. To confirm, type the environment name: my-hello-app-dev # <= 確認のため削除対象の環境名の入力。 INFO: terminateEnvironment is starting. INFO: Deleted CloudWatch alarm named: awseb-e-pdxw4mbwye-stack-AWSEBCloudwatchAlarmLow-7MXXI4P9QOVN INFO: Deleted CloudWatch alarm named: awseb-e-pdxw4mbwye-stack-AWSEBCloudwatchAlarmHigh-1K56EXRQ89PIO INFO: Deleted Auto Scaling group policy named: arn:aws:autoscaling:ap-northeast-1:123456789012:scalingPolicy:00f26acf-6a88-471a-8134-4f5eade5a324:autoScalingGroupName/awseb-e-pdxw4mbwye-stack-AWSEBAutoScalingGroup-1NJ3F09C0837P:policyName/awseb-e-pdxw4mbwye-stack-AWSEBAutoScalingScaleDownPolicy-1U1W1179JQYO7 INFO: Deleted Auto Scaling group policy named: arn:aws:autoscaling:ap-northeast-1:123456789012:scalingPolicy:f8ab2930-6e5a-4b93-ad5c-432d757b1042:autoScalingGroupName/awseb-e-pdxw4mbwye-stack-AWSEBAutoScalingGroup-1NJ3F09C0837P:policyName/awseb-e-pdxw4mbwye-stack-AWSEBAutoScalingScaleUpPolicy-JKXHVAQQK4R3 INFO: Waiting for EC2 instances to terminate. This may take a few minutes. INFO: Deleted Auto Scaling group named: awseb-e-pdxw4mbwye-stack-AWSEBAutoScalingGroup-1NJ3F09C0837P INFO: Deleted Auto Scaling launch configuration named: awseb-e-pdxw4mbwye-stack-AWSEBAutoScalingLaunchConfiguration-3YG1CAINBBRQ INFO: Deleted security group named: awseb-e-pdxw4mbwye-stack-AWSEBSecurityGroup-IY32FV0GOCS INFO: Deleted load balancer named: awseb-e-p-AWSEBLoa-PCXS7HIVUX8D INFO: Deleted security group named: sg-57ec5a32 INFO: Deleting SNS topic for environment my-hello-app-dev. INFO: terminateEnvironment completed successfully.
アプリケーション枠の削除は GUI からやるしかないっぽい。
次は実際に自分で作成した Rails アプリをデプロイしてみる。
プロジェクト新規作成
$ bundle exec rails new fooapp --skip-bundle $ cd fooapp # アプリケーションサーバとして Puma を選択するので Gemfile に追加 $ echo "gem 'puma'" >> Gemfile # gem インストール $ bundle install --path vendor/bundle
コントローラ作成
bin/rails g controller welcome
ビュー作成
app/views/welcome/index.html.erb
<h2>Hello World</h2> <p> The time is now: <%= Time.now %> </p>
ルート追加
config/routes.rb
Rails.application.routes.draw do root 'welcome#index' end
ローカルで動作確認
$ bin/rails s
$ git init && git add -A && git commit -m "first commit"
$ eb init Enter Application Name (default is "fooapp"): # <= アプリケーション名の入力。未入力だとディレクトリ名となる Application fooapp has been created. It appears you are using Ruby. Is this correct? (y/n): y # <= カレントディレクトリの状態から Rails アプリケーションであると認識してくれるので YES Select a platform version. 1) Ruby 2.1 (Puma) 2) Ruby 2.1 (Passenger Standalone) 3) Ruby 2.0 (Puma) 4) Ruby 2.0 (Passenger Standalone) 5) Ruby 1.9.3 (default is 1): 1 # <= Ruby 2.1.5 & Puma を選択 Do you want to set up SSH for your instances? (y/n): y # <= SSHのセットアップを行う Select a keypair. 1) aws-eb 2) [ Create new KeyPair ] (default is 2): 1 # <= キーペアは前回作成したものを使いまわす
またはeb init
コマンドに引数オプションで指定してもよい。
$ eb init fooapp \ --platform "Ruby 2.1 (Puma)" \ --keyname aws-eb
.gitignore が更新されるので確認。
$ git diff diff --git a/.gitignore b/.gitignore index 050c9d9..964c20f 100644 --- a/.gitignore +++ b/.gitignore @@ -15,3 +15,8 @@ /log/* !/log/.keep /tmp + +# Elastic Beanstalk Files +.elasticbeanstalk/* +!.elasticbeanstalk/*.cfg.yml +!.elasticbeanstalk/*.global.yml
コミット。
$ git commit -am "updated .gitignore"
$ eb create Enter Environment Name (default is fooapp-dev): # <= 環境名の入力。未入力だと「アプリケーション名-dev」になる Enter DNS CNAME prefix (default is fooapp-dev): fooapp-dev-20150212 # <= CNAME の入力 Environment details for: fooapp-dev Application name: fooapp Region: ap-northeast-1 Deployed Version: 61ce Environment ID: e-xmzmibygyi Platform: 64bit Amazon Linux 2014.09 v1.1.0 running Ruby 2.1 (Puma) Tier: WebServer-Standard- CNAME: fooapp-dev-20150212.elasticbeanstalk.com Updated: 2015-02-12 12:14:39.613000+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-8ad462ef INFO: Created load balancer named: awseb-e-x-AWSEBLoa-IZJ7KWMA0A30 INFO: Created security group named: awseb-e-xmzmibygyi-stack-AWSEBSecurityGroup-1D7SIRQQT32SW INFO: Created Auto Scaling launch configuration named: awseb-e-xmzmibygyi-stack-AWSEBAutoScalingLaunchConfiguration-C6SUL1CBOYNE INFO: Waiting for EC2 instances to launch. This may take a few minutes. INFO: Created Auto Scaling group named: awseb-e-xmzmibygyi-stack-AWSEBAutoScalingGroup-1UK527EJKFE1G INFO: Created Auto Scaling group policy named: arn:aws:autoscaling:ap-northeast-1:123456789012:scalingPolicy:667e6f8b-e3b7-4d1f-af92-2007c9026687:autoScalingGroupName/awseb-e-xmzmibygyi-stack-AWSEBAutoScalingGroup-1UK527EJKFE1G:policyName/awseb-e-xmzmibygyi-stack-AWSEBAutoScalingScaleDownPolicy-18233HAQI73WN INFO: Created Auto Scaling group policy named: arn:aws:autoscaling:ap-northeast-1:123456789012:scalingPolicy:8415d59d-b349-4df6-8f84-e7f6963b0fa5:autoScalingGroupName/awseb-e-xmzmibygyi-stack-AWSEBAutoScalingGroup-1UK527EJKFE1G:policyName/awseb-e-xmzmibygyi-stack-AWSEBAutoScalingScaleUpPolicy-1I30QUM7E5BWU INFO: Created CloudWatch alarm named: awseb-e-xmzmibygyi-stack-AWSEBCloudwatchAlarmHigh-1GM6DNUY8LMMB INFO: Created CloudWatch alarm named: awseb-e-xmzmibygyi-stack-AWSEBCloudwatchAlarmLow-1DXV8TCCTG40H INFO: Added EC2 instance 'i-67dc3a7f' to Auto Scaling Group 'awseb-e-xmzmibygyi-stack-AWSEBAutoScalingGroup-1UK527EJKFE1G'. INFO: Application available at fooapp-dev-20150212.elasticbeanstalk.com. INFO: Successfully launched environment: fooapp-dev
またはeb create
コマンドに引数オプションで指定してもよい。
eb create fooapp-dev --cname fooapp-dev-20150212
ブラウザで確認。
$ eb open
ブラウザで開いてみると画面に以下のようなエラーが出た。
An unhandled lowlevel error occured. The application logs may have details.
eb logs
コマンドでサーバ側のログを確認する。
$ eb logs ... ------------------------------------- /var/log/puma/puma.log ------------------------------------- === puma startup: 2015-02-12 12:22:27 +0000 === === puma startup: 2015-02-12 12:22:27 +0000 === [20244] - Worker 0 (pid: 20248) booted, phase: 0 2015-02-12 12:24:17 +0000: Rack app error: #<RuntimeError: Missing `secret_token` and `secret_key_base` for 'production' environment, set these values in `config/secrets.yml`> ...
production 環境時のsecret_key_base
を設定し忘れていたため、エラーが出ていた。
config/secrets.yml では以下のようにsecret_key_base
を環境変数から取得して設定している。
# config/secrets.yml production: secret_key_base: <%= ENV["SECRET_KEY_BASE"] %>
Beanstalk の環境変数をeb printenv
コマンドで確認してみる。
$ eb printenv Environment Variables: AWS_SECRET_KEY = None RAILS_SKIP_ASSET_COMPILATION = false BUNDLE_WITHOUT = test:development RACK_ENV = production PARAM5 = None PARAM4 = None PARAM3 = None PARAM2 = None PARAM1 = None RAILS_SKIP_MIGRATIONS = false AWS_ACCESS_KEY_ID = None
これらの環境変数は Beansstalk のプラットフォームが Ruby の場合に Beansstalk 側であらかじめ用意してくれるパラメータとなる。
eb setenv
コマンドで環境変数SECRET_KEY_BASE
を追加する。
$ eb setenv SECRET_KEY_BASE=`bin/rake secret` INFO: Environment update is starting. INFO: Updating environment fooapp-dev's configuration settings. INFO: Successfully deployed new configuration to environment. INFO: Environment update completed successfully.
確認。
$ eb printenv Environment Variables: AWS_SECRET_KEY = None RAILS_SKIP_ASSET_COMPILATION = false SECRET_KEY_BASE = 87cea6cb25eba020d7c5b51d0b20377a29eaa6df475f5e1cef41f31eb67b2b0c7a932902afc3f5b44107439d0f5e7a02a25db33043a81a952190dbfde7fbff8c RACK_ENV = production PARAM5 = None PARAM4 = None PARAM3 = None PARAM2 = None PARAM1 = None BUNDLE_WITHOUT = test:development RAILS_SKIP_MIGRATIONS = false AWS_ACCESS_KEY_ID = None
再度、ブラウザで確認してみると今度は正しく表示された。
$ eb open
このeb setenv
コマンドは v3 から追加されたものでこれによってコマンドから環境変数が設定できるようになった。
設定できるタイミングはeb create
の実行後となる。
ちなみに v2 ではコマンドから環境変数を設定できず、GUI からやるか、以下のようなオプションファイルを用意することで環境変数を設定できたけど、このファイルは git で管理する必要があった。
# .ebextensions/01env.config option_settings: - namespace: aws:elasticbeanstalk:application:environment option_name: SECRET_KEY_BASE value: xxxxxxx
という問題があってちょっと困っていたのでこれが解決できてよかった。
ソースコードの修正を反映するには、 git にコミット後にeb deploy
コマンドを実行する。
eb deploy
次回は VPC 内に Beanstalk 環境を構築したり RDS と連携する方法をやってみる。
環境:rails 4.2.0
Rails でリクエストの HTTP ヘッダはrequest.headers
から取得できる。
すべてログに出力するなら
# すべてログに出力する request.headers.sort.map { |k, v| logger.info "#{k}:#{v}" }
個別に取得するなら
# ユーザーエージェントを取得する request.headers[:HTTP_USER_AGENT]
request.env
からでも取得できる。
# ユーザーエージェントを取得する request.env['HTTP_USER_AGENT']
今回やりたいことはクライアント側から HTTP ヘッダに API のバージョンを埋め込んでリクエストしてくるので、すべてのリクエストの API バージョンを取り出してログに出力したい。
リクエストのパラメータを curl で再現すると以下のようなかんじ。
curl localhost:3000 -H 'API_VERSION: 1.0'
共通処理として書きたいのでapplication_controller
のフィルタで書く。
HTTP ヘッダのパラメータ名にはHTTP_
という prefix が自動的に付与されるようなので忘れずに追加する。
# app/controllers/application_controller.rb class ApplicationController < ActionController::Base protect_from_forgery with: :exception before_action :http_header_log private def http_header_log logger.info("api_version:#{request.headers[:HTTP_API_VERSION]}") end end
これですべてのリクエストに対してログ出力できるようになった。
続いてlograge
という gem を使って HTTP ヘッダを出力する方法もやってみた。
roidrage/lograge
https://github.com/roidrage/lograge
この gem は Rails のログ出力フォーマットをカスタマイズするもの。
Rails のデフォルトのログは複数行出力されるが、これを使うと Apache のように1リクエスト毎1行で出力されるようになるので見やすい。
gem 追加
gem 'lograge'
反映させたい環境の config に以下を追加すればOK。
# config/environments/production.rb config.lograge.enabled = true
今回は HTTP ヘッダのAPI_VERSION
をログ出力に追加するため、さらに以下の設定を追加する。
まずappend_info_to_payload
メソッドを追加し、そこで HTTP ヘッダよりAPI_VERSION
を取得してpayload
ハッシュに入れる。
# app/controllers/application_controller.rb class ApplicationController < ActionController::Base protect_from_forgery with: :exception def append_info_to_payload(payload) super payload[:api_version] = request.headers[:HTTP_API_VERSION] end end
そして config にcustom_options
でログ出力に追加するものを指定する。
time
はデフォルトで表示されないのでこれも追加しておく。
# config/environments/production.rb config.lograge.enabled = true config.lograge.custom_options = lambda do |event| {:time => event.time, :api_version => event.payload[:api_version]} end
これで以下のようにログ出力されるようになった。
method=GET path=/ format=*/* controller=articles action=index status=200 duration=88.37 view=87.28 db=0.11 time=2015-02-01 17:39:35 +0900 api_version=1.0
環境:
ruby: 2.2.0 Rails: 4.1.8 ClearDB(MySQL): 5.5.40
Heroku の MySQL アドオン「ClearDB」で文字コードutf8mb4
で保存する方法についてメモ。
Rails + MySQL でutf8mb4
を扱う方法は以前書いた。
ClearDB ではデフォルトのキャラクタセットは以下のように UTF8 になっている。
mysql> show create database heroku_1234567890abcde; +------------------------+---------------------------------------------------------------------------------+ | Database | Create Database | +------------------------+---------------------------------------------------------------------------------+ | heroku_1234567890abcde | CREATE DATABASE `heroku_1234567890abcde` /*!40100 DEFAULT CHARACTER SET utf8 */ | +------------------------+---------------------------------------------------------------------------------+ mysql> show variables like 'character\_set\_%'; +--------------------------+--------+ | Variable_name | Value | +--------------------------+--------+ | character_set_client | utf8 | | character_set_connection | utf8 | | character_set_database | utf8 | | character_set_filesystem | binary | | character_set_results | utf8 | | character_set_server | latin1 | | character_set_system | utf8 | +--------------------------+--------+
絵文字を扱いたいのでutf8mb4
に変更したい。
しかしmy.cnf
は触れないし、RDS の DB パラメーターグループのようなもので変更できる手段もなさそう。
なので ActiveRecord が発行するテーブルの create 文にオプションでキャラクタセットを追加してテーブル単位にutf8mb4
を設定するように、またクライアント側の接続 URL のキャラクタエンコーディングにutf8mb4
を追加して対応した。
ClearDB を使うまでの手順は以前書いたとおりに進める。
Heroku 上の Rails アプリから DB に接続するための URL としてconfig/database.yml
に書かれた設定ではなく Heroku の環境変数DATABASE_URL
が使用される。なのでこの URL にencoding=utf8mb4
を追加する。
変更前:
$ heroku config | grep DATABASE_URL CLEARDB_DATABASE_URL: mysql://<username>:<password>@<host>/<database>?reconnect=true DATABASE_URL: mysql2://<username>:<password>@<host>/<database>?reconnect=true
変更:
$ heroku config:set DATABASE_URL="mysql2://<username>:<password>@<host>/<database>?reconnect=true&encoding=utf8mb4"
COLLATE も指定する場合
$ heroku config:set DATABASE_URL="mysql2://<username>:<password>@<host>/<database>?reconnect=true&encoding=utf8mb4&collation=utf8mb4_general_ci"
変更後:
$ heroku config | grep DATABASE_URL CLEARDB_DATABASE_URL: mysql://<username>:<password>@<host>/<database>?reconnect=true DATABASE_URL: mysql2://<username>:<password>@<host>/<database>?reconnect=true&encoding=utf8mb4
以下のようにマイグレーションファイルのcreate_table
している部分にオプションとして CHARSET を追加する。
class CreateArticles < ActiveRecord::Migration def change create_table :articles, options: 'ENGINE=InnoDB DEFAULT CHARSET=utf8mb4' do |t| # COLLATE も指定する場合 # create_table :articles, options: 'ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci' do |t| t.string :title t.string :content t.timestamps end end end
変更をコミットして Heroku にプッシュしてデプロイする。
デプロイ完了後、テーブルがまだ未作成ならheroku run rake db:migrate
で作成、作成済みならheroku run rake db:migrate:reset
を実行して ClearDB にテーブルを再作成する。
ClearDB に直接接続する
$ mysql -u <username> -p -h <host> -D <database>
確認
mysql> show create database heroku_1234567890abcde; +------------------------+------------------------------------------------------------------------------------+ | Database | Create Database | +------------------------+------------------------------------------------------------------------------------+ | heroku_1234567890abcde | CREATE DATABASE `heroku_1234567890abcde` /*!40100 DEFAULT CHARACTER SET utf8mb4 */ | +------------------------+------------------------------------------------------------------------------------+ mysql> show create table articles; CREATE TABLE `articles` ( `id` int(11) NOT NULL AUTO_INCREMENT, `title` varchar(255) DEFAULT NULL, `content` varchar(255) DEFAULT NULL, `created_at` datetime DEFAULT NULL, `updated_at` datetime DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 mysql> show variables like 'character\_set\_%'; +--------------------------+---------+ | Variable_name | Value | +--------------------------+---------+ | character_set_client | utf8 | | character_set_connection | utf8 | | character_set_database | utf8mb4 | | character_set_filesystem | binary | | character_set_results | utf8 | | character_set_server | latin1 | | character_set_system | utf8 | +--------------------------+---------+
これでutf8mb4
で保存できるようになった。
環境: Mac
Pygments という Python のパッケージがあり、その中の pygmentize コマンドラインツールを使うことでシンタックスハイライト表示できるようになる。
まずは Pygments のインストール。
$ pip install Pygments
または
$ sudo easy_install Pygments
次にlessfilter
という名前でシェルスクリプトファイルを作成してパスが通っている場所に置く。
# パス確認 $ printenv PATH
/usr/local/bin/
配下に作ることにする。
$ vi /usr/local/bin/lessfilter $ chmod 755 /usr/local/bin/lessfilter
lessfilter
#!/bin/bash case "$1" in *.sh|*.awk|*.diff|*.patch|*.sql|\ *.php|*.pl|*.pm|*.py|*.rb|*.haml|*.slim|\ *.java|*.groovy|*.scala|*.clj|*.cljs|\ *.c|*.h|*.m|*.swift|*.go|*.lua|*.hs|*.erl|*.fs|*.ml|*.exs|\ *.html|*.js|*.coffee|*.css|*.sass|*.scss|\ *.json|*.xml|*.yaml|*.yml) pygmentize -O encoding=utf-8 -O style=monokai -f terminal256 -g "$1" ;; .zshrc|.bashrc|.bash_aliases|.bash_environment) pygmentize -O encoding=utf-8 -O style=monokai -f terminal256 -l sh "$1" ;; Gemfile|Rakefile) pygmentize -O encoding=utf-8 -O style=monokai -f terminal256 -l ruby "$1" ;; *) grep '#!/bin/bash\|#!/bin/sh' "$1" > /dev/null if [ "$?" -eq "0" ]; then pygmentize -O encoding=utf-8 -O style=monokai -f terminal256 -l sh "$1" else exit 1 fi esac exit 0
lessfilter
では pygmentize コマンドを使ってファイルを開く。
-g
オプションを指定することで入力ファイル名から lexer を推測してくれる。
ここに pygments で使える lexer 一覧があるので必要な物を自分で追加してカスタマイズする。
続いて環境変数LESS
、LESSOPEN
を設定する。
zsh を使っているので.zshrc
に以下を追加。bash なら.bashrc
などに。
# cat alias c='pygmentize -O style=monokai -f terminal256 -g -O encoding=utf-8' function cl() { c $1 | nl -n ln -b a } alias cl=cl # less export LESS='-R' export LESSOPEN='|lessfilter %s'
反映
$ source ~/.zshrc
使い方
# cat のシンタックスハイライト $ c foo.rb # cat + 行番号表示 $ cl foo.rb # less のシンタックスハイライト $ less foo.rb
通常の cat コマンドとは別にc
とcl
いうエイリアスで設定する。
こちらを使うとシンタックスハイライト表示になる。
こちらの記事を参考にしました。
catやlessをシンタックスハイライト+行番号表示してコードを見やすくする - Qiita
http://qiita.com/zaru/items/4a7811ac21f74a13481c
linux - Get colors in 'less'' command - Super User
http://superuser.com/questions/117841/get-colors-in-less-command
追記
lessfilter
を修正した。
lessfilter
#!/bin/bash case `basename $1` in *.log) ;; .zshrc) pygmentize -O encoding=utf-8 -O style=monokai -f terminal256 -l sh "$1" ;; Gemfile|Podfile) pygmentize -O encoding=utf-8 -O style=monokai -f terminal256 -l ruby "$1" ;; *) head -n 1 "$1" | grep '#!/bin/bash\|#!/bin/sh' > /dev/null if [ "$?" -eq "0" ]; then pygmentize -O encoding=utf-8 -O style=monokai -f terminal256 -l sh "$1" else pygmentize -O encoding=utf-8 -O style=monokai -f terminal256 -g "$1" fi ;; esac
-g
でよしなにやってくれるので-g
で開く場合、拡張子に対応する lexer がない場合はてっきりシンタックスハイライトは適用されないと思っていたが、そういう場合は text とみなされ TextLexer が適用されるみたい。で、ログファイルのようなでかいファイルを開くときにもシンタックスハイライトしようとして解析に時間がかかって開けなくて困った。なのでとりあえず個別に除外するようにした。他にもあればここに追加していく。
ちなみに-g
でどの lexer が適用されるかは-N
オプションで確認することができる。
$ pygmentize -N config/application.rb rb $ pygmentize -N log/development.log text