インフラ屋のAWSはじめた日記─GUIを捨てよ

第6回 全然クラウドらしくないじゃん

この記事を読むのに必要な時間:およそ 11.5 分

おいおいおい。AWSをはじめて,そろそろ初心者を名乗っても良いかなと思い始めた今も,俺は結局AWSのCLIでしか作業していないじゃないか,ミドルウェアというものはどこに行ってしまったんだ。

コマンドラインでデータベースを起動したら,それが自動でレプリケーションされるわ,バックアップは取られているわでかなり便利になっているのはわかった。でも,なんか物足りなさを感じている。今日はもうクラウドの醍醐味を味わうために,AutoScalingというのに挑戦してみることにする。

AMI

とりあえず,俺はWebアプリケーションを動かす事をしてみたいから何か適当に構築しながらAutoScalingを楽しんで行ってみたいと思う。最終回にしてやっとEC2にログインしてpingとexit以外のコマンドを打つ時が来た。AuctoScalingというのを使うためにはまずはAMIというのを作る必要があるらしい。まずは既存のイメージからEC2を起動し,簡単なWEBアプリケーションを作り,そこからAMIを作成するということをする。

AMIを作るときのVPCは特にどこでも良いらしい。ただ,Security Groupのことなどを考えると,動かしたい所でAMIを作ったほうが,あとあとの手間が減りそうなのは想像がつくから,稼働させたいVPCで作ることにする。

ちょっとこのあたりで,先週までに作っていた構成を確認も兼ねてまとめてみることにする。

$ aws ec2 describe-vpcs
$ aws ec2 describe-subnets
$ aws ec2 describe-internet-gateways
$ aws ec2 describe-route-tables

画像

これでネットワークのCIDRとそれぞれのIDを列挙しておくことができた。

これがあったほうがこの後の作業が楽だということにはこの数日間で思い知らされている。もし,CLIだけでやるときは,できることなら,この図のようにidとCIDRのセットをまとめておくことをおすすめする。

$ aws ec2 describe-key-pairs

key-pairの名前もこれで[id_rsa]だということがわかった。

$ aws ec2 describe-security-groups

今回はSecurity Groupについてはもう一度作り直していくことにした。

$ aws ec2 create-security-group --vpc-id vpc-6ac1020f --group-name webapp-ssh  --description "eccube-web server ssh SG"
 {
     "GroupId": "sg-d2e353b7"
 }

Security Groupを作ったら,sshが接続できるようにする。

$ aws ec2 authorize-security-group-ingress --group-id sg-d2e353b7 --port 22 --protocol tcp --cidr m.y.I.p/32

Security Group管理表

ID Name Source Protocol
sg-d2e353b7 webapp-ssh myIp TCP:22

改めてEC2を起動しようと思ったけど,AMIのIDを覚えていないので,もう一度AMIのIDを調べるところからやり直す。これは,今後も頻繁に発生しそうだから,何かしらScriptを作っておくといいんだろう。

$ aws ec2 describe-images  --owners amazon |jq '.[][] |select(.ImageType == "machine") | {"Name" :.Name,"ImageId":.ImageId }' |grep -A 1 amzn-ami-hvm

このコマンドで,一番新しそうなamiを探して,起動時の--image-idに指定する

$ aws ec2 run-instances --key-name id_rsa --instance-type t2.micro --subnet-id subnet-d806ee81 --associate-public-ip-address --security-group-ids sg-d2e353b7  --image-id ami-35072834

これでEC2が立ち上がった。

        __|  __|_  )
        _|  (     /   Amazon Linux AMI
       ___|\___|___|

無事にログインもできたし,ここからはついにping以外のコマンドを投入していく時間だ。

$ sudo yum install httpd mysql php php-mbstring php-pdo php-mysql php-mcrypt
$ sudo chkconfig httpd on

なんだろう。いつもなら何も感じないこんなコマンドも,クラウド上でやるとこんなに感動的なのか。

とりあえず,今起動したApacheの動作を見るために,Security GroupでHTTPを開ける。

$ aws ec2 create-security-group --vpc-id vpc-6ac1020f --group-name webapp-http  --description "eccube-web server http SG"
{
    "GroupId": "sg-b15eeed4"
}
$ aws ec2 authorize-security-group-ingress --group-id sg-b15eeed4 --port 80 --protocol tcp --cidr 0.0.0.0/0

これで,Security Groupはこうなっている。

ID Name Source Protocol
sg-d2e353b7 webapp-ssh myIp TCP:22
sg-b15eeed4 webapp-http 0.0.0.0/0 TCP:80

今作ったhttpへのアクセスを認めていたSecurity Group webapp-httpを起動しているインスタンスにくっつけてみる。さっきEC2を起動した時にpublic IPばかり気にしてしまっていて,instance-idを残しておくのを忘れてしまっていた。

describe-instancesでインスタンスの情報を取得するというのも有りだけど,今回は別の方法でinstance-idを調べてみる。インスタンスにsshで接続できている事が前提になるけど,ec2-metadataというコマンドがあって,そのec2のいろいろな情報が見られる。

$ ec2-metadata
ami-id: ami-35072834
ami-launch-index: 0
ami-manifest-path: (unknown)
ancestor-ami-ids: not available
block-device-mapping:
         ami: /dev/xvda
         root: /dev/xvda
instance-id: i-44eb0fb1
instance-type: t2.micro
local-hostname: ip-172-16-32-209.ap-northeast-1.compute.internal
local-ipv4: 172.16.32.209
kernel-id: not available
placement: ap-northeast-1c
product-codes: not available
public-hostname:
public-ipv4: 54.x5.1xx.176
public-keys:
keyname:id_rsa
index:0
format:openssh-key
key:(begins from next line)
ssh-rsa =*********************************************************************************************************************==_id_rsa
ramdisk-id: not available
reservation-id: r-033810f1
security-groups: webapp-ssh
user-data: not available

けっこう便利かもしれない。これでinstance-idがわかったので,改めてSecurity Groupを付けなおす。Security Groupをつけるときは,modify-instance-attribute だろう多分。

$ aws ec2 modify-instance-attribute --groups sg-d2e353b7 sg-b15eeed4 --instance-id i-44eb0fb1

そしてApacheを起動して

$ sudo service httpd start

ブラウザでアクセスしてみる。

画像

“Amazon Linux AMI Test Page⁠と無事に表示された。感無量。

このままテストページで何かしても面白くないので,何かデータベースとつなぐものを動かしたい。そのためにもまずはSecurity Groupの設定を,今作ったmysql用のSecurity GroupをEC2とRDSにそれぞれ割り当てる。

$ aws ec2 create-security-group --group-name webapp-mysql --vpc-id vpc-6ac1020f  --description mysql
{
    "GroupId": "sg-b4ac1fd1"
}
$ aws ec2 authorize-security-group-ingress --group-id sg-b4ac1fd1 --source-group sg-b4ac1fd1 --port 3306 --protocol tcp
ID Name Source Protocol
sg-d2e353b7 webapp-ssh myIp TCP:22
sg-b15eeed4 webapp-http 0.0.0.0/0 TCP:80
sg-b4ac1fd1 webapp-mysql sg-b4ac1fd1 TCP:3306
$ aws ec2 modify-instance-attribute --groups sg-d2e353b7 sg-b15eeed4 sg-b4ac1fd1 --instance-id i-44eb0fb1
$ aws rds modify-db-instance --vpc-security-group-ids sg-b4ac1fd1 --db-instance-identifier test-db

Security Groupを変更してみて,EC2からデータベースにアクセスできるのかどうかを確かめてみる。

$ mysql -h test-db.**********.ap-northeast-1.rds.amazonaws.com -u root -p
Enter password:
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 10
Server version: 5.6.19-log MySQL Community Server (GPL)

Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql>

mysqlに接続できること。なんだろう,当たり前のことなんだけど,環境がクラウドになるだけでこんなにも嬉しいものなのかという感動をかみしめている。

簡単なWebアプリケーション

ミドルウェアとかその辺はこれで良いと思うけれど,今度はWebアプリケーションを作って動かしてみたいと思う。その前に,PHPでTimeZoneを設定しておく。

$ diff -Nur /etc/php.ini /etc/php.ini.orig
--- /etc/php.ini    2015-02-21 09:09:04.988734049 +0000
+++ /etc/php.ini.orig   2015-02-21 09:05:49.630312476 +0000
@@ -953,7 +953,7 @@
 [Date]
 ; Defines the default timezone used by the date functions
 ; http://www.php.net/manual/en/datetime.configuration.php#ini.date.timezone
-date.timezone = Asia/Tokyo
+;date.timezone =

 ; http://www.php.net/manual/en/datetime.configuration.php#ini.date.default-latitude
 ;date.default_latitude = 31.7667

そして,index.phpを作る。

<html>
  <head>
    <title>test application</title>
  </head>
  <body>
  <h1>InstanceID = <?php
   $instance_id = file_get_contents('http://169.254.169.254/latest/meta-data/instance-id');
   echo $instance_id;
?></h1>
あなたは
<?php
$dsn = 'mysql:dbname=counter;host=test-db.cojvgercnfvt.ap-northeast-1.rds.amazonaws.com';
$user = 'USERNAME’;
$password = *************;
try{

    $dbh = new PDO($dsn, $user, $password);
    $sql = "SELECT counter FROM counter LIMIT 1";
    $stmt = $dbh->query($sql);
    $result = $stmt->fetch(PDO::FETCH_ASSOC);
    echo $result['counter'];
    $sql = 'update counter set counter = counter + 1; ';
    $stmt = $dbh->prepare($sql);
    $flag = $stmt->execute(array());
    $dbh = null;

}catch (PDOException $e){
    print('Connection failed:'.$e->getMessage());
    die();
}

?>人目の訪問者です。
  </body>
</html>

すごくシンプルに,インスタンスIDとアクセスカウンターを表示するだけのアプリケーションをGoogleとコピペを駆使して頑張って開発した。

画像

このアプリケーションをAutoScalingでスケーリングさせてみる。そのためにはまず,このアプリケーションの入ったインスタンスからAMIを作らなくちゃいけない。

$ aws ec2 create-image --instance-id i-44eb0fb1 --name access-counter-version-1
{
    "ImageId": "ami-e118fbe1"
}

できているかの確認をするために,describe-images というコマンドを --owners をselfにして実行しみる。

$ aws ec2 describe-images --owners self
{
    "Images": [
        {
            ~略~
            "ImageId": "ami-e118fbe1",
            "State": "pending",
        }
            ~略~
    ]
}

State:の所がpendingからavailableになればAMIの作成は完了だ。

著者プロフィール

あけり

学生時代からマウスが机の上で無くなってしまうので,マウスに頼らないインフラエンジニアになると決意。そして,インフラエンジニアになって10年目の今年,ついにクラウドを触りだす。

コメント

コメントの記入