AWS hands-on の内容をコマンドラインでやってみる aws-api-tools
Phase-0 AWSコマンドラインツールの準備をする
普段使っているパソコンに aws-api-tools の実行環境を作成しても良いのですが、ec2で提供されているAmazon Linuxなら最初からコマンドがインストールされていて簡単です。
コマンド操作用ec2インスタンスを立ち上げる
AWS Management Consoleからec2インスタンスを起動しましょう。t1.micro タイプで問題ありません。
(以降、このインスタンスを作業用インスタンスと呼ぶことにします)
秘密鍵とX.509証明書をダウンロードする
ツールを使用してAPIにアクセスするためには秘密鍵とX.509証明書が必要になります。
AWSコンソールを開いて、画面右上の自分の名前をクリックして出てくるプルダウンメニューから "Security Credentials" をクリックします。
アクセス証明書のところにある "X.509証明書" で新しい証明書を作成します。小さいウインドウが開くので、"Private Key"と"X.509 Certifiate"をダウンロードします。
ダウンロードした秘密鍵と証明書を作業用インスタンスにコピーしてください。ここではec2-userのホーム下の aws ディレクトリに保存します。
まず作業用インスタンスにsshでログインしホームディレクトリ下に aws ディレクトリを作成しておきます。
$ mkdir aws
次にローカルPCにダウンロードした秘密鍵と証明書を作業用インスタンスにコピーします。
$ scp -i uekikazuki.pem ~/Downloads/cert-XXXXXXXXXX.pem ec2-user@ec2-54-248-176-167.ap-northeast-1.compute.amazonaws.com:~ec2-user/aws $ scp -i uekikazuki.pem Downloads/pk-XXXXXXXXXX.pem ec2-user@ec2-54-248-176-167.ap-northeast-1.compute.amazonaws.com:~ec2-user/aws
コマンドを実行する際にはコピーした秘密鍵と証明書のパスをコマンドラインオプションで指定するのですが、毎回パスを指定するのは手間なので、環境変数に設定しましょう。
あわせてEC2とRDSで使用するアベイラビリティゾーン(AZ)もTokyo(ap-northeast-1)に設定しておきます。(ここで指定するURLをエンドポイントを呼びます)
$ export EC2_PRIVATE_KEY=~/aws/pk-XXXXXXXXXX.pem $ export EC2_CERT=~/aws/cert-XXXXXXXXXX.pem $ export EC2_URL=https://ec2.ap-northeast-1.amazonaws.com $ export RDS_URL=https://rds.ap-northeast-1.amazonaws.com
Phase-1 EC2インスタンスを立ち上げる
sshとhttpで繋がるようにSecurity Groupを作成する
次にセキュリティグループを作成します。セキュリティグループとはいわゆるファイアウォールのことです。
まず cms-app というセキュリティグループを作成し、次にその作成したセキュリティグループに通信を許可したいポート(tcp/22とtcp/80)を追加していきます。
$ ec2-create-group cms-app -d "SG for cms app (port 80 and 22)" GROUP sg-e1bacee0 cms-app SG for cms app (port 80 and 22) $ ec2-authorize cms-app -P tcp -p 22 GROUP cms-app PERMISSION cms-app ALLOWS tcp 22 22 FROM CIDR 0.0.0.0/0 ingress $ ec2-authorize cms-app -P tcp -p 80 GROUP cms-app PERMISSION cms-app ALLOWS tcp 80 80 FROM CIDR 0.0.0.0/0 ingress
AMIからEC2インスタンスを作成する
ハンズオンで使用したAMI(Amazon Machine Images: EC2インスタンス作成時のひな形となるもの)を指定してインスタンスを作成します。今回使うAMIのIDは ami-d170f5d0 です。作成する際、セキュリティグループは先ほど作成した cms-app を使用し、インスタンスタイプは一番小さな t1.micro を使用します。
$ ec2-run-instances \ --group cms-app \ --instance-type t1.micro \ --instance-count 1 \ --key <key-pair-name> \ ami-d170f5d0 RESERVATION r-79d4587a 376158489050 cms-app INSTANCE i-7d496c7e ami-d170f5d0 pending 0 t1.micro 2013-02-05T12:49:04+0000 ap-northeast-1a aki-44992845 monitoring-disabled ebs paravirtual xen sg-e1bacee0 default false
作成したインスタンスにわかりやすく"Name"タグをつけておきます。NameタグをつけるとEC2 Management ConsoleのName列に表示されてインスタンスが区別しやすくなります。
タグをつける際には付与先のEC2インスタンスを指定します。EC2インスタンスは作成時に表示された i-xxxxxxxx がIDなので、これを指定します。
$ ec2-create-tags i-7d496c7e --tag Name=az-a-cms1 TAG instance i-7d496c7e Name az-a-cms1
EIPを割り当て、EC2インスタンスに関連づける
Elastic IP(固定グローバルIPアドレス)を取得して、作成したEC2インスタンスに関連づけます。
まず ec2-allocate-address を実行してEIPを取得します。
$ ec2-allocate-address ADDRESS 54.249.238.6 standard
表示されたEIPをEC2インスタンスに関連づけます。先ほどと同様EC2インスタンスは作成時に表示された i-xxxxxxxx がIDなので、これを指定します。
$ ec2-associate-address 54.249.238.6 --instance i-7d496c7e ADDRESS 54.249.238.6 i-7d496c7e
(a-blog cmsのセットアップ)
ここまでの作業でEIP(グローバルIPアドレス)を使ってEC2インスタンス上で動いているa-blog cmsというアプリケーションが表示できるはずです。早速ブラウザから表示してみましょう。
初期設定が済んでいないので http://54.249.239.207/setup/install.php というURLに移動してインストールウィザードが表示されます。画面の指示に従って初期設定をしてください。(基本的にデフォルトのままボタンをクリックしていけば良いだけです)
- データベースサーバ名
- localhost
- データベースが存在しなかった場合に、指定された名前でデータベースを作成する
- チェックする
- データベース名
- ablogcms
- データベースユーザー名
- root
- データベースパスワード
- XXXXXXXX
Phase-2 RDSインスタンスを立ち上げる
MySQL DB用Security Groupを作成する
RDS用のセキュリティグループ(ファイアウォール)を作成します。
EC2の時と同様まず cms-db というセキュリティグループを作成し、次にその作成したセキュリティグループに通信を許可したいポート(tcp/3306)を追加していきます。
ここで特徴的なのはアクセス元としてEC2で作成したセキュリティグループ cms-app を指定できることです。これによってRDSにEC2インスタンスからのみアクセスを許可することができます。
$ rds-create-db-security-group cms-db -d "db SG for cms (port 3306)" SECGROUP cms-db db SG for cms (port 3306)
なお --ec2-security-group-owner-id に指定するAWS Account Numberは ec2-describe-group で調べることができます。
$ ec2-describe-group cms-app GROUP sg-bba3d4ba 376158489050 cms-app SG for cms app (port 80 and 22) PERMISSION 376158489050 cms-app ALLOWS tcp 22 22 FROM CIDR 0.0.0.0/0 ingress PERMISSION 376158489050 cms-app ALLOWS tcp 80 80 FROM CIDR 0.0.0.0/0 ingress $ rds-authorize-db-security-group-ingress cms-db \ --ec2-security-group-name cms-app \ --ec2-security-group-owner-id 376158489050 SECGROUP cms-db db SG for cms (port 3306) EC2-SECGROUP cms-app sg-e1bacee0 376158489050 authorizing
MySQL DB用Parameter Groupを作成する
MySQLのデータベース設定ファイル(my.conf)にあたるパラメーターグループを作成します。パラメータグループを作成することで同じDB設定のRDSを複数作成することができるようになります。
なおパラメータグループ名(cms-db-mysql55)は、DBの種類(mysql)とバージョン(5.5)が分かるよう命名するのがコツだそうです。
$ rds-create-db-parameter-group cms-db-mysql55 \ --db-parameter-group-family mysql5.5 \ -d "db PG for cms(mysql-5.5)" DBPARAMETERGROUP cms-db-mysql55 mysql5.5 db PG for cms(mysql-5.5)
DBインスタンスを作成する
作成したセキュリティグループとパラメータグループを指定し、RDSインスタンス "cmsdb" を作成します。
なお以下で指定している "cmsdb" は「RDSのインスタンス名」のことで、--db-nameで指定している "mydb" はMySQLのデータベース名のことです。後ほどEC2上にあるMySQLデータをRDSにインポートしますが、その際に指定するのはMySQLデータベース名である "mydb" の方なのでご注意ください。
コマンドを実行してから実際に作成され使えるようになるまでに5分程度かかります。しばらくお待ちください。
$ rds-create-db-instance cmsdb \ --db-security-groups cms-db \ --db-instance-class db.t1.micro \ --engine mysql \ --db-parameter-group-name cms-db-mysql55 \ --db-name mydb \ --master-username awsuser \ --master-user-password mypassword \ --allocated-storage 5 \ --backup-retention-period 0 DBINSTANCE cmsdb db.t1.micro mysql 5 awsuser creating 1 **** n 5.5.27 general-public-license SECGROUP cms-db active PARAMGRP cms-db-mysql55 in-sync OPTIONGROUP default:mysql-5-5 in-sync
RDSインスタンスの状態は rds-describe-db-instances コマンドで確認することができます。"creating" が "available" になれば作成完了です。
$ rds-describe-db-instances cmsdb DBINSTANCE cmsdb 2013-02-15T13:51:23.868Z db.t1.micro mysql 5 awsuser available cmsdb.c9cxowny4ezp.ap-northeast-1.rds.amazonaws.com 3306 ap-northeast-1c 0 n 5.5.27 general-public-license SECGROUP cms-db active PARAMGRP cms-db-mysql55 in-sync OPTIONGROUP default:mysql-5-5 in-sync
(EC2上のDBデータをRDSに移行する)
EC2インスタンスにログインしてMySQLデータベースをバックアップ&RDSにリストアします。作業内容自体は一般的なMySQLの操作と変わりません。
データインポート時に指定するユーザ名とパスワードはRDSインスタンス作成時に指定した--master-username / --master-user-password のことです。また接続先ホスト名は rds-describe-db-instances コマンドで表示される「エンドポイント」と呼ばれるホスト名を指定します。インポート先のデータベースはRDSインスタンス作成時に --db-name で指定したデータベース名になります。
$ mysqldump -uroot -pXXXXXXXX ablogcms > backup.sql $ mysql -uawsuser -pmypassword -h cmsdb.c9cxowny4ezp.ap-northeast-1.rds.amazonaws.com mydb < backup.sql
インポートが完了したらEC2上のablogの設定ファイルを修正して、接続先データベースを変更します。
また以降の作業で混乱しないようにEC2上のMySQLプロセスは止めてしまいましょう。
$ sudo service mysqld stop Stopping mysqld: [ OK ] $ sudo chkconfig mysqld off $ sudo chkconfig --list mysqld mysqld 0:off 1:off 2:off 3:off 4:off 5:off 6:off
スケールアウトできるようAMIを作成する
ablogが動いているEC2インスタンスからカスタムAMIを作成します。AMIを作成しておいて、EC2インスタンス作成時にこのAMIを指定することで同じ設定のサーバをいくつでも作成することができるようになります。
$ ec2-create-image --name cms-app-image -d "ablog custom AMI image" i-a35e75a0 IMAGE ami-dd9116dc $ ec2-describe-images IMAGE ami-dd9116dc 376158489050/cms-app-image 376158489050 available private x86_64 machine aki-44992845 ebs paravirtual xen BLOCKDEVICEMAPPING EBS /dev/sda1 snap-9ba164b8 8 true standard
Phase-3 異なるAZにEC2インスタンスを立ち上げELBで負荷分散する
カスタムAMIからEC2インスタンスを起動する
先程作ったカスタムAMIを指定してEC2インスタンスを新たに起動します。さらにここでは1つ目とは異なるアベイラビリティゾーンで起動しています。
(1つ目のEC2インスタンスがap-northeast-1bで作成されていたので、ここではap-northeast-1aを指定しています)
$ ec2-describe-availability-zones AVAILABILITYZONE ap-northeast-1a available ap-northeast-1 AVAILABILITYZONE ap-northeast-1b available ap-northeast-1 AVAILABILITYZONE ap-northeast-1c available ap-northeast-1 $ ec2-run-instances \ --group cms-app \ --instance-type t1.micro \ --instance-count 1 \ --key <key-pair-name> \ --availability-zone ap-northeast-1a \ ami-dd9116dc
ロードバランサーを作成する
ELB "cms-lb" を作成します。ロードバランシングされるEC2インスタンスがあるリージョンとアベイラビリティゾーンを明示的に指定する必要があります。
$ elb-create-lb cms-lb \ --listener "lb-port=80,instance-port=80,protocol=http" \ --availability-zones ap-northeast-1a,ap-northeast-1b \ --region ap-northeast-1 DNS_NAME cms-lb-XXXXXXXXX.ap-northeast-1.elb.amazonaws.com
ロードバランサーにインスタンスを関連づける
ここでもリージョンは明示的に指定する必要があります。
$ elb-register-instances-with-lb cms-lb --region ap-northeast-1 --instances i-a35e75a0, i-af2209ac INSTANCE_ID i-af2209ac INSTANCE_ID i-a35e75a0 $ elb-describe-instance-health cms-lb --region=ap-northeast-1 INSTANCE_ID i-a35e75a0 InService N/A N/A INSTANCE_ID i-af2209ac InService N/A N/A
ロードバランサが作成できたら、ロードバランサ経由でEC2インスタンスにアクセスしてみます。
http://cms-lb-XXXXXXXXX.ap-northeast-1.elb.amazonaws.com/
試しに片方のapacheを停止させてみましょう。ヘルスチェックで一方がOutOfServiceになっていても、ablogは表示されていればOK。
(一方のablogが動いているEC2インスタンスにsshでログインする) $ sudo service httpd stop Stopping httpd: [ OK ] (次に作業用インスタンスからヘルスチェックを行う → どちらかがOutOfServiceになっているはず) $ elb-describe-instance-health cms-lb --region=ap-northeast-1 INSTANCE_ID i-a35e75a0 OutOfService Instance has failed at least the UnhealthyThreshold number of health checks consecutively. Instance INSTANCE_ID i-af2209ac InService N/A N/A
後始末
ELBやRDSはそのままにしておくと時間で課金されるので実験が終わったら削除しておくのを忘れないでください。
ELBの削除
$ elb-delete-lb cms-lb --region ap-northeast-1 Warning: Deleting a LoadBalancer can lead to service disruption to any customers connected to the LoadBalancer. Are you sure you want to delete this LoadBalancer? [Ny]y OK-Deleting LoadBalancer
EC2とEIPの削除
$ ec2-disassociate-address 54.249.238.6 ADDRESS 54.249.238.6 $ ec2-release-address 54.249.238.6 ADDRESS 54.249.238.6 $ ec2-terminate-instances i-a35e75a0 INSTANCE i-a35e75a0 running shutting-down $ ec2-terminate-instances i-af2209ac INSTANCE i-af2209ac running shutting-down
AMI、スナップショットの削除
AMIを作成する際には自動でスナップショットも作成されているので、AMIだけでなくスナップショットも削除します。
AMIを削除します。
$ ec2-deregister ami-dd9116dc IMAGE ami-dd9116dc
スナップショットを削除します。
$ ec2-describe-snapshots SNAPSHOT snap-9ba164b8 vol-be05909c completed 2013-02-15T14:32:10+0000 100% 376158489050 8 Created by CreateImage(i-a35e75a0) for ami-dd9116dc from vol-be05909c $ ec2-delete-snapshot snap-9ba164b8 SNAPSHOT snap-9ba164b8
RDSの削除
DBインスタンスの削除処理には時間がかかるので、rds-delete-db-instance後すぐにはパラメータグループを削除できません。
DBセキュリティグループ(cms-db)でEC2セキュリティグループ(cms-app)を参照しているので、先にcms-dbを削除してからcms-appを削除してください。
$ rds-delete-db-instance cmsdb -f --skip-final-snapshot DBINSTANCE cmsdb 2013-02-05T13:33:24.196Z db.t1.micro mysql 5 awsuser deleting cmsdb.c9cxowny4ezp.ap-northeast-1.rds.amazonaws.com 3306 ap-northeast-1a 1 n 5.5.27 general-public-license SECGROUP cms-db active PARAMGRP cms-db-mysql55 in-sync (RDSインスタンスが削除されるまでしばらく時間がかかります) $ rds-delete-db-parameter-group cms-db-mysql55 -f $ rds-delete-db-security-group cms-db -f $ ec2-delete-group cms-app RETURN true