Re:boot!

35歳からのエンジニアWay

Docker for Macで docker入門

随分と前にdockerを少しいじった事はあったのですが、気づいたらいつの間にかDocker for Macなるものが出来てました。

Docker for Macさえインストールすれば、dockerコンテナを動かすためのdocker daemonが起動できるので、昔と違ってVirtual Boxを使ったりする必要がなくなったようですね。

サクっと入門してみました。

Docker for Macインストール

公式サイトからdmgファイルを落としてポチポチするだけです。

docs.docker.com

Hello Worldしてみます

$ docker run hello-world

Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
78445dd45222: Pulling fs layer
78445dd45222: Pull complete
Digest: sha256:c5515758d4c5e1e838e9cd307f6c6a0d620b5e07e6f927b07d05f6d12a1ac8d7
Status: Downloaded newer image for hello-world:latest

Hello from Docker!
This message shows that your installation appears to be working correctly.

通常であれば

  1. dockerコンテナを構成するためのDockerfileを作る
  2. docker buildを行なってコンテナイメージを作成する
  3. docker runしてコンテナを起動する

といった流れが基本ですが、imageがない状態でrunを行うと(docker hubから?)ビルド済みイメージをダウンロードして起動してくれるようです。

上記のコマンドでも「ローカルにイメージがなかったからダウンロードしてきた」という流れが読めます。 ローカルにあるイメージはdocker imagesコマンドで確認ができます。

$ docker images

REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
hello-world         latest              48b5124b2768        7 days ago          1.84 kB

(停止中の)コンテナ一覧は docker ps -a で確認できます。

$ docker ps -a

CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS                      PORTS               NAMES
4cdf1befef68        hello-world         "/hello"            25 minutes ago      Exited (0) 25 minutes ago                       compassionate_agnesi

いらなくなったコンテナは docker rm $CONTAINER ID で削除できます。

$ docker rm 4cdf1befef68

基本的なことはコレくらいですかね。

Nginxを立ち上げてみる

qiita.com

qiita.com

containerに使うOSはalpine linuxデファクトとなりつつあるようなので、alpine linuxを利用します。 まずは素のappine linuxコンテナを立ち上げてログインできる様にします。

Dockerfile

FROM alpine:latest

Dockerfileを元にビルド

$ docker build -t nginx .

-tでタグ名を指定できます(イメージの名前みたいなもの?) 上のリンクにも書かれていたように起動してインストールに必要な手順を試しながら書き出します。

$ docker run -it nginx sh

試したコマンドを元にDockerfileを作りました。 /var/run/nginxディレクトリがないせいでpidファイルが作れず、nginxデーモンが起動できないので手元からnginx.confをコピーする様にしています。 EXPOSEがlistenポートの指定なので、これで80番ポートでnginxにアクセスできるはずです。

Dockerfile

FROM alpine:latest

RUN apk --no-cache add nginx && \
    ln -sf /dev/stdout /var/log/nginx/access.log && \
    ln -sf /dev/stderr /var/log/nginx/error.log

COPY ./nginx.conf /etc/nginx/nginx.conf

EXPOSE 80

CMD ["/usr/sbin/nginx", "-g", "daemon off;"]

ファイルを元に再ビルドします。

$ docker build -t nginx

できたイメージでコンテナを立ち上げます。 -pオプションを使うことで、localhostの8080番ポートを80番ポートにフォワードしておきます。

$ docker run --rm -p 8080:80 nginx

ブラウザで http:localhost:8080 にアクセスしてnginxの画面が出たので成功ですね。

ロードバランス用にpacker+ansibleでAPサーバ用AMIを作成する

前回までのエントリで、一般的なAPサーバ+DBサーバ(RDS)という構成は作る事ができたので、次はAPサーバを2台にしてELBでロードバランシングしてみたいと思います。

ELBはAWSのL7ロードバランサ機能ですね。ここでは一旦ELBは置いておいて今回はAPサーバを増やす下準備をしたいと思います。

前回もansibleを使ったので比較的手間なくnginx,wordpressのインストールを行えましたが、毎回マネージメントコンソールでEC2インスタンスを作る所からやるのは手間です。

趣味や勉強でやる程度の数ならまだしも、実運用で何十台と同じ役割をするインスタンスを作るとなると流石にやってられません。

そこで登場するのがpacker(とterraform)です。packerを使えば役割毎のAMI(雛形となるOSイメージ)を簡単に作る事が出来るようです。

ということで今回はWordpressを動かすAPサーバをpackerでAMI化してみたいと思います。

packerとはどんなもの?

packerがどんなものなのかは下記の記事が参考になりました。

thinkit.co.jp

packerは(仮想)マシン上に展開するOSのイメージを作るツールです。

AWSはもちろん、他のクラウドサービスやDockerのイメージも作成できるらしいです。

公式サイトは以下。

www.packer.io

今回はpakcerを使ってAMIを作るのですが、packerを使えばコンフィグを各だけで以下の様な事をやってくれます。

はい、こんな感じです。まあ使ってみないと良くわかんないので、さっさと触っていきたいと思います。

packerでAMIイメージを作る

まずはpackerをインストールします。Macならhomebrewでサクッとインストールできます。

$ brew tap homebrew/binary
$ brew install terraform
$ pakcer -v
#=> 0.10.1

v0.10.1がインストールされました。作成するAMI用の設定ファイルを作ります。今回は下記の設定ファイルを前回とってきたansibleのディレクトリに「wordpress.json」という名前で保存しました。

{
  "builders": [{
    "type": "amazon-ebs",
    "region": "ap-northeast-1",
    "source_ami": "ami-9f0c67f8",
    "ami_name": "aws-wordpress",
    "instance_type": "t2.micro",
    "vpc_id": "vpc-xxxxxxxx",
    "subnet_id": "subnet-xxxxxxxx",
    "associate_public_ip_address": true,
    "ssh_username": "ec2-user",
    "ssh_timeout": "5m",
    "ssh_pty": "true",
    "security_group_id": "sg-xxxxxxxx"
  }],
  "provisioners":[{
    "type": "shell",
    "inline": [
      "sudo yum -y update",
      "sudo yum -y --enablerepo=epel install ansible",
      "mkdir -p /tmp/ansible-local"
    ]
  }, {
    "type": "file",
    "source": "./",
    "destination": "/tmp/ansible-local"
  }, {
    "type": "ansible-local",
    "playbook_file": "site.yml",
    "role_paths": [
      "roles"
    ],
    "staging_directory": "/tmp/ansible-local"
  }]
}

サラっと書きましたが、このファイルを作るにはちょっとばかり試行錯誤しました。

見ればなんとなくわかるところも多いと思うので、ポイントとなりそうな部分だけ説明してみようと思います。

buildersの項目

作成するAMIの基本的な設定を記述するセクションですね。

type 作成するイメージの種類(AWS用、DegitalOcean用、VMWare用...など)、今回はAWSのEC2インスタンスのAMIなので「amazon-ebs」にしてあります。

source_ami 作成するAMIの元となるイメージのIDです。AMIは色々な物が用意されていますが、今回は新規インスタンスを立ち上げる時に選択できる、Amazon LinuxのAMI IDを指定してあります。

f:id:yusan09:20170112000947j:plain

ami_name 作成するAMIの名前です。

ssh_timeout ec2インスタンスの作成作業をした後、実際にsshでログイン出来る様になるまでには(初期化作業が走るため)少しタイムラグがあります。

初期化に少し時間がかかっても大丈夫なように、ssh_timeoutを少し長めに設定してあります。

associate_public_ip_address 例えばローカルでDockerイメージを作る場合などは必要ないですが、今回の様にEC2インスタンスを使ってAMIを作る場合はインスタンスsshでログインする必要が出てきます。

associate_public_ip_addressをtrueにすることでグローバルIPインスタンスに付与し、SSHでのログインを可能にしています。

provisioners

名前の通りプロビジョニングに関する設定を各ことです。やることは前回のansibleファイルを実行するだけなのですが、EC2インスタンスのローカル上でansibleを実行するために、少し手間がかかっています。

どういうことをしているのか簡単にまとめると

  • ansibleを実行するために、yumでansibleをインストールする
  • 実行するansibleのファイル一式をローカルからEC2インスタンスに送る
  • ansibleを実行する

といった感じです。

ansibleをEC2ローカルで実行する(ansible-local)ための設定は下記が非常に参考になりました。

qiita.com

設定が終われば後はbuildを実行してイメージを作成するだけです。

$ packer build wordpress.json

成功すると下記の様にAMIの項目の中に自分で作成したイメージが表示されます。後はこのAMIを使ってEC2インスタンスを立ち上げるだけです。しかし、EC2インスタンスの立ち上げに関してもマネージメントコンソールは使いたくないので、次回terraformを使った方法を試してみたいと思います。

f:id:yusan09:20170112234647j:plain

【AWS勉強】EC2+RDSを使った基本構成を構築してWordPressを立ち上げてみる。その2

前回のエントリでAWS上で必要なものの構築はほぼ終えたはずなので、引き続きWordpressの構築や疎通の確認をしたいと思います。

前回のエントリはこちら

reboot.hateblo.jp

RDSへmysql clientでアクセスできるか確認

まずはRDS上のMySQLへAPサーバからmysql clientでアクセスできるか試してみます。

まずはグローバルIPを持っているAPサーバへSSHでログインします。

$ ssh -i .ssh/aws-wordpress.pem ec2-user@xxx.xxx.xxx.xxx

mysql clientが入っていないのでインストールします。

$ sudo yum -y install mysql

RDSのエンドポイント(mysql clientからの接続先)はマネジメントコンソールで確認することができます。「RDSサービス」の中の「インスタンス」を開きましょう。

f:id:yusan09:20170105222231j:plain

マネジメントコンソールからIPアドレスは確認できませんでした。恐らくマルチAZで冗長化するために、アプリケーション側からIPアドレス直でアクセスしてしまうとフェイルオーバーが自動で出来ないためでしょう。

オンプレならkeepalivedでVIPふっておくとかって感じだと思うんですが、AWSDNSで切り替えする感じですかね。たぶん....。

一応APサーバからdigとか使えばIPアドレスをチェックはできます。

$ dig db-wordpress.xxxxxxxxxxxx.ap-northeast-1.rds.amazonaws.com
#=> db-wordpress.cb5biuximzqp.ap-northeast-1.rds.amazonaws.com. 4 IN A 10.0.3.47

あれ?10.0.3.0/24内のアドレスが返ってきました...。想定としてはAPサーバと同じAZの10.0.2.0/24のアドレスが返ってくるかなと思ってたのですが。

この辺の優先度は変えられたりするんでしょうか。まあ、また改めて調べるとしてとりあえずmysql clientでアクセスしてみます。

$ mysql -p -u wordpress -h db-wordpress.xxxxxxxxxxxx.ap-northeast-1.rds.amazonaws.com
mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| innodb             |
| mysql              |
| performance_schema |
| sys                |
| wordpress          |
+--------------------+

ユーザ名やデータベース名は、前回のエントリのRDSインスタンスの作成のタイミングで指定しています。

とりあえずこれでAPサーバ->RDSの疎通は確認できました。

APサーバでWordpressが動くようにする

次はHTTPでのアクセス確認も兼ねてWordpressをセットアップします。

といってもWordpressを動かすまでの手順を説明しても仕方ないので、Ansibleでサクッと設定しちゃいたいと思います。

Ansibleを使うのは他の目論見もあるのですが、とりあえず今はおいておきます。

私の手元の環境はMacなので、brew installしてサクッとインストール

$ brew install ansible

はい。簡単ですね。

Wordpressの設定用のファイルもきっとあるだろうと思ってググってみると、案の定ありました。

github.com

ansible公式のexampleですね。

手元に持ってきます。

$ git clone https://github.com/ansible/ansible-examples.git
$ cd ansible-examples/wordpress-nginx
$ ls -1
LICENSE.md
README.md
group_vars
hosts.example
roles
site.yml

セットアップする対象ホストを指定するためにhostsという名前でファイルを作ります。

# hostsファイルの中身
[all]
xxx.xxx.xxx.xxx ansible_ssh_user=ec2-user ansible_ssh_private_key_file=/Users/mind/.ssh/aws-wordpress.pem

xxx.xxx.xxx.xxxの部分はAPサーバのグローバルIP(Elastic IP)です。作ったファイルを使ってセットアップを行なってみます。

$ ansible-playbook -i hosts --sudo site.yml

#=>
failed: [52.198.208.8] => {"failed": true}
msg: the python mysqldb module is required

FATAL: all hosts have already failed -- aborting

エラーが出てしまいました。少し手間取りましたがセットアップされる側にyumで「MySQL-python27」をインストールすれば良いようです。(Amazon LinuxpythonのバージョンによってはMySQL-python26でないとダメな場合もあるようです。)

ansbileにインストールする設定を追加します。今回はroles/common/tasks/main.ymlに設定を追加しました。ファイルの最後に以下を追加します。

- name: install mysql python mysqldb module
  yum: name=MySQL-python27 state=latest

改めてansible-playbookを実行します。

$ ansible-playbook -i hosts --sudo site.yml

#=>
~略~
PLAY RECAP ********************************************************************
52.198.208.8               : ok=25   changed=7    unreachable=0    failed=0

無事完了しました。これで取り敢えずWordpressのセットアップは終わったはずです。

curlでチェックしてみます。

$ curl xxx.xxx.xxx.xxx (APサーバのグローバルIP)
#=>
curl: (7) Failed connect to xxx.xxx.xxx.xxx:80; Connection refused

う〜ん。アクセスが出来ませんでした。APサーバに入って原因を調べたところ、どうもnginxのconfigでエラーが出てちゃんと立ち上がってないようです。

$ sudo /etc/init.d/nginx start
nginx を起動中: nginx: [emerg] a duplicate default server for 0.0.0.0:80 in /etc/nginx/nginx.conf:41

どうやら80番ボートのデフォルトを握るバーチャルホスト(存在しないドメインにリクエストが来た場合に表示される)の設定が重複しているようですね。nginx.conf内のserverディレクティブの内容をまるまる消せば大丈夫そうだったので、バッサリ削除しました。

もういちどチャレンジ。

$ sudo  /etc/init.d/nginx start

Starting nginx:                                            [  OK  ]

上手く立ち上がりました。今度はいけるだろうとブラウザから直接IPでアクセスしたところ、無事に表示できました。こんな感じです。

f:id:yusan09:20170106001526j:plain

後はブラウザでポチポチするだけといきたい所ですが、このままだとWordpressはローカルのmysqldへアクセスしにいってしまいます。

接続先を変えるためにansibleのwp-config.phpを修正し、接続先をRDSのエンドポイントへと変更します。

変更するファイルは「roles/wordpress/templates/wp-config.php」です。

 /** MySQL hostname */
-define('DB_HOST', 'localhost');
+define('DB_HOST', 'db-wordpress.xxxxxxxxxx.ap-northeast-1.rds.amazonaws.com');

また、wp-config.phpではdbのパスワードが「secret」になっているのでgroup_vars/allファイルの中の「wp_db_password」も自分の使うパスワードに変えておきます。

-wp_db_password: secret
+wp_db_password: xxxxxxx

後は変更を反映するためにansible-playbookを再度実行して、ブラウザからポチポチ設定を行えばOKです。

【AWS勉強】EC2+RDSを使った基本構成を構築してWordPressを立ち上げてみる。その1

まずは勉強の手始めとして、EC2+RDSを使ってWordPressを立ち上げてみたいと思います。アプリケーションサーバ+データベースサーバという、WEBでは最も基本的な構成ですね。

私も仕事でAWSを少しは触ったことがあるとはいえ、一から構築はしたことはありません。実際のところDBも普通にEC2インスタンスMySQLをインストールして運用していたので、何気にRDSを使ったこともなかったりします。まあ、言ってしまえば初心者レベルですね。

とはいえEC2?RDS?VPC?といったド素人レベルでもないわけですが、せっかくなので「AWSを使うのはホントに初めて」くらいの人も意識して、捕捉を入れながら説明してみたいと思います。

構成図

f:id:yusan09:20170105001327p:plain

細かい部分は置いておくとして、まずは作ろうと思っている構成を説明したいと思います。今回は図の様にパブリック用のサブネットとプライベート用のサブネットを用意して、WordPressを動かします。この図を見て何をする必要があるのかパッと挙げられる人は、初心者レベルはクリアしてると言っても良いのではないでしょうか。

では早速ですが、構成と利用するサービスについて触れていきたいと思います。用意するサーバは2つです。

EC2は仮想ホストを作る事が出来るサービスです。簡単に言えば管理画面からポチポチするだけでサーバが用意できるサービスですね。OSも様々なものから選べます。

aws.amazon.com

EC2のインスタンス(仮想サーバ)を1つ用意して、WordPressが動く環境を作ります。また、Wordpress用のデータベースをとしてRDSを利用して、MySQLを立ち上げます。

aws.amazon.com

RDSは(リレーショナル)データベースの立ち上げに特化したサービスです。EC2を使って自分でMySQLを運用することもできますが、RDSならセットアップやスケール、バックアップ、冗長化などが非常に手軽に出来るようになっています。さらにAWSが独自開発したMySQL互換のDB「Amazon Aurora」が使えるのも大きな特徴です。

aws.amazon.com

ネットワークはVPCを利用して作ります。VPCはアカウントごとに独立した仮想論理ネットワークで、他のアカウントやAWS自体のネットワークに影響を受けません。

docs.aws.amazon.com

今回は10.0.0.0/16のVPCを用意します。実際にホストが参加するネットワークは図のように、別途サブネットとしてVPCの中に作ります。

役割 サブネット
public netowrk 10.0.1.0/24
private network 10.0.2.0/24

WANに足を持つサブネットとして10.0.1.0/24、プライベート用のネットワークとして10.0.2.0/24を用意します。同一のVPCの中にあるサブネット(に所属するホスト)同士は、特に意識せずともルーティングが追加されお互いに疎通がとれるようです。

ただしWANに足を持つといっても10.0.1.0/24はプライベートなアドレスです。当然その中にあるインスタンス(仮想ホスト)に割り当てられるアドレスも、プライベートなアドレスとなってしまいます。これはAWSの制約なのですがグローバルIPを直接インスタンスに割り振ることはできないようです。

では、どうやってWANにつなぐのかというと、やり方は大きくわけて2通りあるようです。(ELBを使うなど他にも方法はあるかも)

前者の方法はグローバルIPを用意し、EC2インスタンスのプライベートアドレスにNATをする方法です。ユーザから直接アクセスを受けるAPサーバはこの方法を使ってインターネットと接続します。

Elastic IPがNAT用のグローバルIPを提供してくれるサービス、インターネットゲートウェイはインターネット接続するための(デフォルト)ゲートウェイを用意してくれるサービスです。

docs.aws.amazon.com

docs.aws.amazon.com

後者の方法はNATゲートウェイを作って外とアクセスする方法です。ユーザからアクセスを受ける必要がなく、サーバから外に出る必要がある場合に利用できます。例えばyumでインストールを行う場合などに必要ですね。

以前はNAT用のインスタンスを立ち上げゲートウェイにするしかなかったようですが、2015年12月よりマネージドなNATゲートウェイサービスも開始されているので、今はこちらを利用するのがベストプラクティスではないでしょうか。

docs.aws.amazon.com

プライベートなネットワークにあるDBサーバなどは、WANのアドレスは振らずNATゲートウェイを通して外に出るのが一般的でしょう。今回の場合であればRDSインスタンスが該当しますね。

さて、おおまかな構成はこの辺りにして実際に構築する手順を説明していきたいと思います。

ネットワーク(VPC・サブネット)の作成

まずはAPサーバ(EC2)、DBサーバ(RDS)用のネットワークを作成です。

EC2インスタンスもRDSインスタンスもネットワークに所属しなければ何もできないので、インスタンスを作る前にVPC作成しておく必要があります。

やるべき作業は大まかに4つです。

  • VPCを作成する
  • 作成したVPCに属するサブネット3つを作成する
  • インターネットゲートウェイを作成し、VPCにアタッチする
  • 必要なルートテーブルを作成し、各サブネットに割り当てる

それでは順番に見ていきましょう。

VPCを作成する

まずはVPCを作成します。VPCは仮想スイッチ、この後作るサブネットはVLANだと思えば概念的には近い気がします。

AWSのマネージメントコンソールにログインして、左上の「メニュー」から「VPC」を選びます。

f:id:yusan09:20161230233902j:plain

左のサイドバーメニューの中から「VPC」を選びます。

f:id:yusan09:20161230234211j:plain

上のメニューから「VPCの作成」を選びます。

f:id:yusan09:20161230234459j:plain

必要なパラメータを入力します。今回は以下の様にしました。

f:id:yusan09:20161230235204j:plain

  • ネームタグ: vpc-wordpress
  • CIDRブロック: 10.0.0.0/16
  • テナンシー: デフォルト

テナンシーではデフォルトの他に「ハードウェア専有」を選ぶ事ができます。AWSは基本的に仮想ホストが使われるため、一つの物理サーバに複数の企業のインスタンスが生成される可能性があります。コンプライアンス上、他社と物理的に同居が出来ない場合などに利用されるようです。

作成したVPCに属するサブネット3つを作成する

作成したVPCに属するサブネットを3つ作ります。

具体的にはAPサーバ用(10.0.1.0/24)1つと、DBサーバ用(10.0.2.0/24, 10.0.3.0/24)2つです。表にしてまとめると以下の通りです。

Name tag CIDR block アベイラビリティーゾーン 用途
vpc-wordpress-subnet1 10.0.1.0/24 ap-northeast-1a APサーバ
vpc-db-subnet1 10.0.2.0/24 ap-northeast-1a DBサーバ
vpc-db-subnet2 10.0.3.0/24 ap-northeast-1c DBサーバ

アベイラビリティーゾーン(略してAZ)は一言でいえば物理サーバの(置かれているデータセンタの)場所ですね。ap-northeast-1aは東京に当たります。AWSは東京以外にも世界各地にデータセンタがあります。

そのため、マルチAZ(複数のアベイラビリティゾーンを利用して)でシステムを構築することで、たとえ1つのAZが完全にダウンしたとしてもサービスを続けられます。

マルチAZによる冗長性は、AWS上でのシステム構築のベストプラクティスとされています。

今回の構成図には10.0.3.0/24はありませんでしたが、RDSを利用するにはマルチAZ用に、異るAZに属するサブネット2つを用意する必要があります。

なので、実際には利用しませんがDB用のサブネットを2つ作成し、この2つのサブネットは「1a」「1c」と異なったAZを指定してあります。

前置きが長くなりましたが、例としてvpc-wordpress-subnet1(10.0.1.0/24)のサブネットを作る手順を説明したいと思います。

左のサイドバーメニューの中から「サブネット」を選びます。

f:id:yusan09:20161231000221j:plain

上のメニューから「サブネットの作成」を選びます。

必要なパラメータを入力します。

f:id:yusan09:20161231001532j:plain

VPCには先程作った vpc-wordpress を選択します。

vpc-db-subnet1、vpc-db-subnet2の2つも同様の手順で作成すればOKです。

インターネットゲートウェイを作成し、VPCにアタッチする

次はインターネットゲートウェイの作成と、ルートテーブル(ルーティング)の編集をします。

物理ネットワークの場合と同じで、WANに疎通のあるルータを用意してデフォルトゲートウェイを指定する感じです。

本来ならホスト毎にルーティングを設定しないといけない所ですが、AWSではVPC単位でルーティングを制御するようです。この辺りは少し慣れが必要そうですね。

左のサイドバーメニューの中から「インターネットゲートウェイ」を選びます。

f:id:yusan09:20161231101132j:plain

上のメニューから「インターネットゲートウェイの作成」を選びます。

f:id:yusan09:20161231102456j:plain

必要なパラメータを入力します。

f:id:yusan09:20161231103535j:plain

インターネットゲートウェイは作成しただけでは意味がなく、VPCにアタッチする必要があります。

物理ネットワークで言えば、ルータを既存のネットワークにLANケーブルでつなぐイメージでしょうか。

上のメニューから「VPCにアタッチ」を選びます。

f:id:yusan09:20161231102854j:plain

アタッチ先として、さきほど作った vpc-wordpress を選択します。

f:id:yusan09:20161231103955j:plain

必要なルートテーブルを作成し、各サブネットに割り当てる

アタッチしたインターネットゲートウェイを通して外への疎通が出来る様にします。

左のメニューから「ルートテーブル」を選択します。

f:id:yusan09:20161231111045j:plain

VPCを作成した時点で既にvpn-wordpressに関するルートテーブルが出来ているので選択します。

さらに下の窓の「ルート」タブを押し、「編集」を選択します。

f:id:yusan09:20161231111343j:plain

インターネットゲートウェイをデフォルトルートとするルーティングを追加します。

ターゲットはIPアドレスで指定する必要はなく、インターネットゲートウェイの名前で指定します。

ターゲットのフォームをフォーカスすると選択肢が表示されるので、特にメモをしておく必要もありません。

続いてルートテーブルとサブネットの紐付けをします。

下の窓の「サブネットの関連付け」から「編集」を押します。

f:id:yusan09:20170104224925j:plain

WANからのアクセスを受けるのはAPサーバのみなので、vpc-wordpress-subnet1にのみチェックをいれ保存を押します。

f:id:yusan09:20170104225401j:plain

これでWANに出るためのルーティングに関してもOKです。

vpc-db-subnet1, vpc-db-subnet2に関しては「10.0.0.0/16 local」のみを持つルートテーブルを別途作成し、同様の方法で関連付けすればOKです。

これでネットワークの設定に関しては終了です。

EC2インスタンスの準備

ネットワークが出来たのでAPサーバ用のEC2インスタンスを作っていきます。

まずはサービスから「EC2」を選択します。

f:id:yusan09:20161231120835j:plain

画面中央下の「インスタンスの作成」を選択します。

f:id:yusan09:20161231121942j:plain

ステップ 1: Amazon マシンイメージ(AMI)

まずはAMI(Amazonマシンイメージ)の選択画面が表示されます。

AMIはインスタンス上に展開されるOSのイメージファイルです。

アプリケーションも含めたOSの初期テンプレートファイルだと思えばいいでしょう。

docs.aws.amazon.com

AWSが用意した物の他にも、自分で作成したもの、サードパーティー(企業)が用意したもの、他のAWSユーザ公開しているものなどから選べます。

今回はスタンダードなAmazonLinuxのAMIを選択します。

f:id:yusan09:20170101144016j:plain

ステップ 2: インスタンスタイプの選択

次に「インスタンスタイプ」を選択します。

インスタンスタイプごとに仮想マシンのスペックや、利用料金が異なります。今回は「t2.micro」を選びます。

f:id:yusan09:20170101144359j:plain

ステップ 3: インスタンスの詳細の設定

続いてインスタンスの詳細を設定します。様々な設定項目がありますが、今回は基本的にデフォルトのままで進めます。

VPCとサブネットの設定のみ先程作った「vpc-wordpress」「vpc-wordpress-subnet1」を選ぶ様に変更します。

これで今から作るインスタンスは先程作ったVPCネットワーク内に作られる事となります。

f:id:yusan09:20170101145146j:plain

ステップ 4: ストレージの追加

次にAMIをインストールするストレージを選びます。AWSではEC2インスタンスが直接ストレージ(SSD・HDD)をマウントするわけではなく、EBSと呼ばれるストレージをネットワーク越しに接続して利用します。

EBSは自動的にレブリカが作られるため可用性が高いだけでなく、容量を拡張したりスナップショットを取ったりと、一般的な物理ストレージで悩みどころとなる点を解決してくれる、様々な便利 が備わっています。

今回はデフォルトのまま8GBのストレージを利用します。

aws.amazon.com

ステップ 5: Add Tags

次にタグの追加を行います。タグはEC2インスタンスの管理をしやすくするためのメタ情報ですね。

Nameに「ap-wordpress1」を入力しておきます。

f:id:yusan09:20170101150831j:plain

ステップ 6: セキュリティグループの設定

次はセキュリティーグループの設定です。

セキュリティーグループはインスタンスへのin,outをネットワーク、ポート単位で制御できるAWS独自のファイアウォール機能ですね。

言ってしまえば複数インスタンスにまとめて設定できるiptablesって感じでしょうか。結構便利な機能です。

docs.aws.amazon.com

WEBアプリケーション向けにセキュリティグループを一つ新規作成しておきます。次回から似た用途のインスタンスを作成した場合は、同じセキュリティーグループを適用すればOKです。

新規作成する場合、最初からSSHは許可されてます。今回はpingでの確認とWEBサーバとして動かすためのルールを追加しておきます。

f:id:yusan09:20170101173844j:plain

最後に作成するインスタンスの設定確認画面が表示され、作成を行おうとするとSSHキーの選択画面(新規作成画面)が表示されます。

作成はキーペア名を入力して「キーペアのダウンロード」ボタンを押すだけです。

f:id:yusan09:20170101174713j:plain

ボタンを押すとpemファイル(秘密鍵)がダウンロードされます。公開鍵は自動的にインスタンスに配置されるので、特に何かをする必要はありません。

これでAPサーバ用のEC2インスタンスの作成は終了です。

WANからアクセス出来るようにする

APサーバ用のインスタンスはできましたが、今のままではグローバルIPがなく、WANに疎通が取れない状態です。もちろん、HTTPでのアクセスも、SSHでのアクセスも出来ません。

そこで、Elastic IPを利用してグローバルIPを紐付け、SSHでアクセスをしてみます。

まずは左メニューから「Elastic IP」を選択します。

f:id:yusan09:20170102174254j:plain

最初は利用できるグローバルIPが0個なので、AWSからアドレスを割り当ててもらう必要があります。

「新しいアドレスの割当」を選択します。

f:id:yusan09:20170102174651j:plain

割当が終了すると取得済みのアドレス一覧が表示されます。取得したアドレスはまだどのインスタンスにも紐付いていないので、先程作ったEC2インスタンスにアタッチする必要があります。

一覧から取得アドレスにチェックを入れ、上のメニューから「アドレスの関連付け」を選択します。

f:id:yusan09:20170102175208j:plain

アタッチするインスタンスを選択します。

インスタンス名とIPアドレスを選択する必要がありますが、プルダウンで選択する事が出来るのでさほど手間ではないはずです。

f:id:yusan09:20170102175456j:plain

これでWANからSSHでのアクセスが可能となっているはずです。試しに手元からsshでログイン出来るか試してみます。

$ ssh -i .ssh/aws-wordpress.pem ec2-user@52.xxx.xxx.xxx

秘密鍵にはEC2インスタンス作成時に生成したキーペアを指定し、ユーザにはec2-userを指定します。Amazon Linx以外のOSの場合は、デフォルトユーザが異るようなので注意が必要でしょう。

RDSを立ち上げる

WordPressをインストールするにはデータベースが必要なので、先にRDSの準備を進めていきます。

RDSを触るのは初めてだったので少し苦戦しましたが、色々いじって整理しなおした手順をまとめてあります。

設定の流れは以下の通りです。

  • DB用のセキュリティーグループの作成
  • RDS用のサブネットグループの作成
  • RDSインスタンスの作成
    • エンジンの選択
    • 稼働環境の選択
    • DBの詳細設定
    • その他の設定

DB用のセキュリティーグループの作成

RDSインスタンスを作る前には事前にやっておく作業が2つあります。

まずはその内の1つDB用のセキュリティーグループを作成します。

セキュリティーグループの作成は「EC2サービス」内の左メニュー「セキュリティーグループ」から行います。

f:id:yusan09:20170104231352j:plain

上部の「セキュリティーグループの作成」を選択します。

f:id:yusan09:20170104231818j:plain

ssh, ICMP他、APサーバ、mysqlクライアントでのアクセスを考慮して、同一VPC内から3306ポートのアクセスを許可しておきます。

f:id:yusan09:20170104233327j:plain

RDS用のサブネットグループの作成

もう1つの事前準備がRDS用サブネットグループの作成です。

RDS用というのが肝なのですが、RDSには(VPC内に作った)単一のサブネットを割り当てることは出来ません。

そのためDB用のサブネットを作った時にも軽く触れた様に、異るAZにある複数のサブネットをグループ化し、割り当てる必要があります

最初はこれがわからずに躓きました。やっぱり実際に触ってみないとわからないものですね。

では手順を説明していきます。

サービスメニューから「RDS」を選択します。

f:id:yusan09:20170102223326j:plain

左のメニューから「サブネットグループ」を選びます。

f:id:yusan09:20170104234349j:plain

上のメニューから「DBサブネットグループの作成」を選びます。

f:id:yusan09:20170104234416j:plain

VPCの中に作ったAZの異る2つのDB用サブネットを割り当てます。マルチAZを利用しない場合も必ずこの手順は必要です。

f:id:yusan09:20170104234724j:plain

  • 名前: wordpress-db-subnet
  • 説明: subnet for db
  • VPC ID: vpc-wordpress
  • サブネットグループに追加するサブネット:
    • vpc-db-subnet1 (ap-northeast-1a, 10.0.2.0/24)
    • vpc-db-subnet2 (ap-northeast-1c, 10.0.3.0/24)

RDSインスタンスの作成

これで下準備が整ったので、やっとRDSインスタンスの作成に入ります。

エンジンの選択

まずは使用するデータベースエンジンの選択です。

エンジンには色々なものが利用できますが、今回は(無料だし)スタンダードな「MySQL」を使ってみます。「Amazon Aurora」もそのうち使ってみたいですね。

f:id:yusan09:20170102224524j:plain

稼働環境の選択

次は環境選択のメニューが出てきました。今回はただの勉強用なので「開発/テスト」を選びましたが、無料枠が終わってしまえば出ない選択肢なのでしょうか?

f:id:yusan09:20170102224854j:plain

DBの詳細設定

次はDBの詳細設定で、容量やDBのバージョンの設定を行います。今回は無料枠内でためしているので、残念ながら使えないオプションもあるようです。例えば容量に上限があったり、マルチAZが使えないといった内容です。

今回は使えませんが、マルチAZは後々勉強するために使ってみたい所ですね。

以下、設定の内容です。

  • ライセンスモデル: General Public License
  • DBエンジンのバージョン: 5.6.27
  • DBインスタンスのクラス: db.t2.micro
  • マルチAZ配置: いいえ
  • ストレージタイプ: 汎用(SSD
  • ストレージ割り当て: 5GB
  • DBインスタンス識別子: db-wordpress
  • マスターユーザの名前: wordpress
  • スターパスワード: xxxxxxxx
  • パスワードの確認: xxxxxxxx

f:id:yusan09:20170102232208j:plain

f:id:yusan09:20170102232220j:plain

その他の設定

次は「ネットワーク&セキュリティ」「データベースの設定」の設定です。

まずは「ネットワーク&セキュリティ」の設定内容を書き出してみます。

f:id:yusan09:20170105000221j:plain

DBはプライベートセグメントに置きたいので、「パプリックアクセス可能」は「いいえ」にしてあります。

DB用のサブネットは先程作った「wordpress-db-subnet」を選択しています。VPCセキュリティーグループも同様に事前に作った「db(VPC)」を選択します。

次は(MySQL上の)データベースの設定です。

f:id:yusan09:20170102233804j:plain

  • データベースの名前: wordpress
  • データベースのポート: 3306
  • DBパラメータグループ: default.mysql5.6
  • オプショングループ: default:mysql-5-6
  • タグをスナップショットへコピー: チェックなし
  • 暗号を有効化: いいえ

RDSではいわゆるmy.cnfが直接変更できないので「DBパラメータグループ」を使ってパラメータ変更を行う様です。

同様にMySQLのオプション機能も「オプショングループ」を使って設定を行います。

詳しくは以下で説明されています。

docs.aws.amazon.com

docs.aws.amazon.com

今回はとりあえず変更なしのデフォルト値を指定しています。

残りは「バックアップ」「モニタリング」「メンテナンス」の設定です。

f:id:yusan09:20170102234941j:plain

  • バックアップの保存期間: 7日
  • バックアップウィンドウ: 指定なし
  • 拡張モニタリングを有効にする: いいえ
  • マイナーバージョン自動アップグレード: はい
  • メンテナンスウィンドウ: 指定なし

値は全てデフォルトのままです。ウィンドウ(メンテナンス時間)を指定して「バックアップ」「マイナーバージョン自動アップグレード」が出来るのはマネージドならではの機能ですね。

また「拡張モニタリング」を有効にすれば、より多くのシステムリソースをチェックできる様になるようです。

詳しくは以下が参考になります。

dev.classmethod.jp

まとめ

かなり長くなってしまいましたが、以上で必要なネットワーク、インスタンスの設定までが終わった(はず)です。

といってもまだWordpressもインストールしてませんし、HTTPでのアクセス、RDSへの接続も確認できていません。

次回はこの辺りの作業をしたいと思います。

夫婦で(自分softbank,妻au)から格安SIMに変えるのために色々調べてみた

ちょっと前はフリーテル、最近はUQバイルと格安SIMのCMが結構TVで流れてますね。大分安くなるらしいので前々から興味があったのですが、やっぱり通信が遅くなりで心配だったのでずーっと二の足を踏んでいました。

しかし、妻と2人分で2万円/月ほど携帯代がかかっている上に、最近友人が格安SIMに変えて凄く良いと言っていたので、思い切って二人とも変える事にしました。

自分が変えるだけならさほど悩む事もないのですが、二人分となるとそうもいきません。

たぶん同じような状況の人も多いと思うので、せっかくだから参考に調べた内容をまとめておきます。

状況の確認

まずは自分たちの状況確認です。私も妻も結婚する前から自分で契約した端末を使ってるので、実はキャリアすら違います。

共通点

  • 月9,000円〜1万円ほど携帯代にかかっている。
  • 2年縛り解除のタイミングまではまだかなりある。
  • デザリングは使っていない
  • 自宅ではWiFiで接続しているので、そこまで大容量はいらない

自分

  • キャリアはsoftbank
  • iPhone5s
  • ホワイトプランR
  • パケットし放題フラット for 4G LTE
  • PCメインなのであまりスマホは使わない
  • データ通信量が7.5GBあるけどほとんどオーバーしない
  • 電話はほとんど使わない。使ってもLINEとかFaceTime

  • キャリアはau
  • iPhone5
  • スマホメイン
  • 契約中のサービスは忘れた
  • データ通信量が7.5GBあるけどほとんどオーバーしない
  • 電話はほとんど使わない。電話はほとんど使わない。使ってもLINEとかFaceTime

変更する上での条件

格安SIMに変える上で重要な点もまとめてみました。ここがハッキリしてないとサービスを選ぶ上で迷ってしまいますからね。

  • とりあえず格安SIMに変えて安くしたい
  • 今は使っているキャリアがバラバラなのでまとめてしまいたい(自分が複数回線まとめて契約)
  • 二人とも電話通話は必要(家に固定電話がないので)

自分

  • iPhone以外に変えてもいい(何かするときはPCの方が多い)
  • 電話番号はそのまま使いたい(MNP利用したい)

  • iPhoneのまま使いたい
  • 電話番号は変わっても良い(連絡はほとんどLINEだから困らない)
  • 速度があまりに遅いのは嫌

自分はあまりスマホを使わないので安ければ安いほど良いくらいですが、妻は普段スマホしか使わないのでやっぱり速度が遅すぎるのはNG。iPhoneもそのまま使いたいらしいので、利用するサービスを一緒にするなら妻の条件に合わせる感じですね。

SIMフリーにできるかどうか

サービスを選ぶ上で大事なのがSIMフリーかどうかです。なぜなら利用する携帯がSIMフリーかどうかで選べるサービスが大分違ってくるからです。

SIMフリーとは簡単に言えばdocomo, au, Softbankどのキャリアでも使えるスマホの事ですね。格安SIM各社は3キャリア全てに対応している事はまれなので、SIMフリーでなければ自分が今使っているキャリアに対応したサービスを選ぶ必要があるわけです。

もし最初からSIMフリーの端末を買った場合は問題ないですが、キャリアの割賦で購入した場合はそのキャリアでしか使えない様にSIMロック(制限)がかけられています

私も妻もキャリアで買った端末なので、残念ながらSIMロックがかかっています。しかし、SIMロック解除してSIMフリーにすれば色々なサービスが使えるというのは知っていたので、まずはそれぞれSIMロックを解除できるのかを調べてみました。

昔は裏技っぽい方法でしか解除できなかった様ですが、今はキャリアに連絡をすればSIMロックは解除してもらえます。ただし、各キャリアとも解除には条件があります。

www.au.kddi.com

www.softbank.jp

iPhoneであれば少なくとも2015年9月以降に販売された「iPhone6s iPhone6s Plus」以降でないとSIMロック解除は不可能なようですね。残念。

なるべく買い替えはしたくないので、まずはそれぞれのキャリアで使えるサービスを調べてみました。

格安SIMはdocomo無双

auSoftbankそれぞれ対応しているサービスを調べた所、以下の通りでした。

キャリア 格安SIM
au mineo,UQバイ
Softbank ワイモバイ

ほとんど対応してない件\(^o^)/ しかも、ワイモバイルは結局ソフトバンクの中古端末はSIMフリー化しないと使えないらしいです。

どうやから格安SIMサービスのほとんどはdocomoにしか対応していないというのが現状だそうな。

こうなったら自分は新しく端末を買うしかありません。さらに自分と妻で利用するサービスは統一したいので、選択肢がmineo、UQバイに絞られてしまいました。まあ、選択肢が多すぎても迷うだけなので、これはこれで良いのかもしれません。

mineoとUQバイルを比較

さて、選択肢が2つに絞れたので2つを比較してみたいと思います。比較する上で特に大事なのはやっぱり「料金と速度」でしょう。その他にもメリットデメリットがありそうですが、自分で細々と調べるのは手間なのでとりあえず雑誌を一冊購入しました。

f:id:yusan09:20170103110741j:plain

この本ですね。

ざっと読んでみました。大雑把な結論だけ言えば「mineoの方が安いけど、UQバイルの方が圧倒的に速い」ようです。雑誌でも細々とした金額の違いよりは、速度やその他のサービスを重視した方が良いと書いてあったので、こうなるとUQバイルが有力候補ですね。

UQバイルが速いのにはちゃんと理由があります。他の格安SIMサービスがキャリアから回線を卸してもらって利用しているのに対し、UQバイルを運営するUQコミュニケーションズ株式会社はKDDIの系列会社です。

要はUQバイルはauの準公式的な扱いのサービスだとということでしょう。

雑誌の内容としてはその他にも格安SIMの比較ランキングやビギナー向けの解説、オススメ携帯端末ランキングなどが掲載されています。特にdocomoユーザなら各サービスの速度を徹底比較した記事は非常に参考になると思いました。どれにするか悩んでいる人や、まったく知識がない人は買って損はないと思います。

続いて料金を比較してみたいと思います。今回は電話も使うので通話有りのプランのみです。

UQバイルの料金

まずはUQバイルからです。

2017年2月から「おしゃべりプラン」というのが始まるようで、今あるプランも新しいものに移行するようです。

おしゃべりプランS

  • 月額2,980円(13ヶ月目までは1,980円)
  • 5分間回数制限なし(2017年3月までは90分間無料)
  • 月間データ容量1GB (25ヶ月目までは2GB)

おしゃべりプランM

  • 月額3,980円(13ヶ月目までは2,980円)
  • 5分間回数制限なし(2017年3月までは180分間無料)
  • 月間データ容量3GB (25ヶ月目までは6GB)

1年間経つと金額が高くなる(本来の金額になる)ようですが、公式サイトは非常にわかりにくい書き方がされていました。こういうの辞めて欲しいですよね。上で書いたものは本来の金額をベースに書き直したものです。

高い方のおしゃべりプランMでも26ヶ月移行は3GBになってしまいます。家ではWiFiを使うとはいえ正直ちょっと少ないですね。

長く使うと割高感が増すのはサービスとしてどうなのかな〜という気がします。

mineoの料金

docomoauで少し値段が違いますが、今回はauのデュアルタイプ(音声通話付き)を調べてみました。

基本データ容量 月額料金
500MB 1,310円
1GB 1,410円
3GB 1,510円
5GB 2,190円
10GB 3,130円

確かにUQバイルに比べて圧倒的にmineoの方が安いですね。

データ通信容量が同じ3GBでも値段が倍以上違います。仮に同じデータ通信量3GBで2回線契約したとして、その差額を計算してみると 3,980 × 2 - 1,510 × 2 = 4,940です。

つまり二人分だと、1ヶ月で5,000円近くmineoの方が安いということになります。

さらにmineoは複数回線契約すると50円/月安くなる上、余ったデータ容量をユーザ間でシェアする機能があるためさらにお得感があります。ここまで値段が違うと流石に悩みますね。

iPhone5は公式サポートされていない

さて、とりあえずどちらにするか悩みつつも、UQバイル・mineoへの切替方法を調べていた所、なんと妻が使っているiPhone5はどちらも公式サポートされていない事がわかりました。\(^o^)/

もうなんか色々めんどくさすぎますね。結局サポートに連絡するのが一番なんでしょうか。

しかし、妻までiPhoneを新しく買うとなるとかなり費用がかかってしまいます。ということで面倒ながらも調べてみたところ、非公式ながら一応iPhone5でも利用できるようです。

itstrike.biz

king.mineo.jp

この情報を信じれば使えるわけですが、流石に非公式となるとちょっと怖いですね。そこで良い方法がないかなと調べた所、UQバイルは15日間無料で試す事ができる他、mineoはプリペイドで手軽に試す事が出来る事がわかりました。

www.uqwimax.jp

mineo.jp

この辺を使って動作確認すれば、ある程度安心して切り替えられそうです。両方一度試してみれば体感速度の違いもわかりますし、どちらを使うか決める上でも、非常に参考になりそうです。ということでUQバイルの無料トライアルと、mineoのプリペイドを試してみようと思います。

結果はまた後日。

AWSの認定資格があるらしいので詳しく調べてみた。

AWSの勉強をしようと少し調べていた際に見つけたのですが、AWSの公式認定資格があるようですね。

aws.amazon.com

資格を取ること自体の意義はさておき、いくつかサイトを調べてみた所、実践力が問われる試験内容のようです。

ということで、少し興味が湧いたので調べてみました。

資格の概要

資格試験は全部で5つ用意されています。

  • AWS認定ソリューションアーキテクト アソシエイトレベル
  • AWS認定デベロッパー アソシエイトレベル
  • AWS認定SysOpsアドミニストレータ アソシエイトレベル
  • AWS認定ソリューションアーキテクト プロフェッショナルレベル
  • AWS認定DevOpsエンジニア プロフェッショナルレベル

https://d0.awsstatic.com/training-and-certification/certification-roadmaps/aws-certification-path.png

図からも分かる通り難易度は2つに別れています。プロフェッショナルを受けるためには、先にアソシエイトレベルに合格する必要があります。

分野は大きく3つに別れていて、名前から察するに

  • ソリューションアーキテクト = 構築(サービス内容や構築の知識)
  • デベロッパー = 開発(AWSAPIや、AWS上でのアプリケーション開発の知識)
  • SysOps = 運用(AWS上でのオペレーションや、チューニングの知識)

という感じでしょうか。また図を見ても分かる通り、デベロッパー+SysOpsでDevOpsということですね。

ソリューションアーキテクトがAWSのサービス知識を問われる、最もベーシックな内容っぽいので勉強するならここからが良さそうです。

試験自体は合格するとLinkdinのプロフィールやEメールにAWSの認定ロゴを入れたり、Linkedin AWS認定コミュニティーのメンバーになれるようです。

ただし有効期限は2年間なので、資格を維持するには再認定を受けるか、上位資格を取る必要があるとの事です。

AWS認定試験の費用

アソシエイトレベル、プロフェッショナルレベルで金額が変わります。また、有料ですが本試験の他に、模擬試験も用意されています。

難易度 試験受験料(税込み)
アソシエイトレベル 16,200円
プロフェッショナルレベル 32,400円
難易度 模擬試験受験料(税込み)
アソシエイトレベル 2,160円
プロフェッショナルレベル 4,320円

仮に5つの試験全てに一発で合格したとして、必要な費用の合計は113,400円(税込み)ですね。結構な額です。

AWS認定試験の受験会場

試験の申し込みを進めると会場が選択肢で確認する事ができます。2016年12月現在では下記の15会場が用意されているようです。

AWS認定試験の日程

試験日程は特に決まりはないようです。試験会場と一緒で申し込みをする途中で確認できますが、各会場ともバラバラで確認しづらいです。

頻度は月に1度ほどなので決して多いとはいえませんが、資格試験の中では多い方でしょうか。試験日も平日が結構多いので、試験を受けに行くだけでも一苦労ありそうです。

AWS認定試験の勉強方法

今のところ対策本はあるものの過去問が出版されていたりということはないので、地道に知識をつけて模擬試験で練習するしかなさそうです。合格者のブログを参考に、勉強に活用できそうなものをザッと挙げると以下の感じでした。

  • 参考書籍を読みながら実践
  • AWSホワイトペーパーを読む
  • AWSクラウドサービス活用資料集を読む
  • AWSの有料トレーニングを受ける
  • セルフスペースラボ
  • AWS WEB問題集

参考書籍を読みながら実績

合格者のサイトを見ていると、とにかく実践して手を動かすのが大事と言ってる人がほとんどです。それだけ実践的な内容ということでしょうか。ということで、参考になりそうな書籍を探してみました。

合格対策 AWS認定ソリューションアーキテクト - アソシエイト

合格対策 AWS認定ソリューションアーキテクト - アソシエイト

今のところ出版されている認定試験に関する本はこれだけのようですね。コメントをみる限りかなり入門的な内容みたいですが、著者の方は後ほど紹介する有料トレーニングの講師を勤める方のようなので、内容としては確かなのではないでしょうか。

出版されたのも2016年8月なので、現時点ではかなり新しい情報が載っているはずです。また、この本は目次を見る限りサービス全般について1つずつ紹介している様だったので、始めの1冊に良さそうかなと思います。

ということで、とりあえず買ってみました。(まだ、読んではないですが)

AWSは移り変わりが激しいので、買うならなるべく最近出版されたものの方が良いだろうと思います。さらに試験を受ける事も考えれば、なるべく各サービスを一つずつ紹介している様な本が良いでしょう。

ということで他にも参考になりそうな本を探してみました。

Amazon Web Servicesではじめる新米プログラマのためのクラウド超入門

Amazon Web Servicesではじめる新米プログラマのためのクラウド超入門

2016年6月に出版されているので比較的新しく、入門的な内容としてザッとサービスを紹介してくれているようです。

私自身はEC2、VPC、S3、Route53、S3辺りは使った事があったり、ざっと目次を見る限りそもそもWebに関する基礎知識も解説している様なので、前半半分は読んでも微妙かなという内容な感じでした。ただ、後半は使ったことがないサービスも含まれていたり、いまいち理解しきれていないIAMや、Dockerに関しても書かれているようなので、結構良さそうです。

Amazon Web Services企業導入ガイドブック -企業担当者が知っておくべきAWSサービスの全貌から、セキュリティ概要、システム設計、導入プロセス、運用まで-

Amazon Web Services企業導入ガイドブック -企業担当者が知っておくべきAWSサービスの全貌から、セキュリティ概要、システム設計、導入プロセス、運用まで-

2015年3月発売なので少し古いですが、目次を見る限り比較的多くのサービスについて1つずつ解説してる本のようです。近くの図書館にあるので一度見に行って見ようと思ってます。

ホワイトペーパを読む

ホワイトペーパー | AWS

ホワイトペーパーとは自社サービスの優位性を示すために、導入事例やベストプラクティス、他社サービスとの比較などをまとめた資料全般の事です。

サービスの概要を簡潔にまとめた資料を中心に、PDF/kindleで利用できるファイルがダウンロードできます。一部は日本語版も用意されていますが、基本的には英語しかないようです。

AWSクラウドサービス活用資料集を読む

aws.amazon.com

俗にBlackBeltと呼ばれているものみたいですね。活用資料と言うくらいなので、特にユースケースの紹介が多いんでしょうか。基本はオンラインでのセミナーで、その場で質問する事が可能なようです。

過去のセミナー分の資料はSlideshareとPDF、一部動画で見ることができます。

AWSの有料トレーニングを受ける

コースの説明 - AWS トレーニング | AWS

お金はかかってしまいますが、AWS認定トレーニングパートナーによるワークショップが用意されています。内容は半日〜3日間ほどで、ハンズオン中心にAWSの使い方を学ぶ内容となっているようです。コースの数もかなりあります。会社から補助が出るなら良さそうですね。

コース名 受講料(税込み) 期間
AWS Technical Essentials 1 $648 1日間
AWS Technical Essentials 2 $648 1日間
Architecting on AWS $1944 3日間
Advanced Architecting on AWS $1944 3日間
AWS 認定試験準備ワークショップ ソリューションアーキテクト – アソシエイト $262 4時間
Developing on AWS $1944 3日間
DevOps Engineering on AWS $1944 3日間
Systems Operations on AWS $1944 3日間
AWS Security Fundamentals - E-learning 無料 4時間
AWS Security Fundamentals - Classroom $648 1日間
Security Operations on AWS $1944 3日間
Big Data Technology Fundamentals 無料 3時間
Big Data on AWS $1944 3日間
Data Warehousing on AWS $1944 3日間

セルフスペースラボ

aws.amazon.com

オンラインで手順に沿って、AWSを使った実践練習ができるサービスです。基本的には有料ですが一部無料のセミナーもあります。最も実践的に手を動かして学べそうな感じですね。

セルフスペースラボはQUICKLABがサービスを提供しているようです。

qwiklabs.com

受講にはクレジットが必要で、$8/8クレジットから購入することが出来きます。コースは1クレジットで受ける事ができるものもあれば、数十クレジットが必要なコースもあるようです。

Lab Catalog | Qwiklabs

AWS WEB問題集

AWS WEB問題集で学習しよう – 赤本ではなく黒本の問題集から学習する方向け

個人運営の様ですが、AWSに関するオリジナルの問題を掲載しているサイトです。2016年12月現在、問題数も650問を越えているのでかなりの量が用意されています。

試験を受けるならかなり役に立ちそうです。

まとめ

AWS認定資格について調べてみましたが、合格するために勉強すればしっかり実践的な知識も身につきそうな感じですね。

試験を受けるかはともかく、とりあえず買った本を読み進めてボチボチ実践勉強をしていこうかと思います。

サーバレスアーキテクチャの入門をしてみた

さて、エンジニア復帰したのは良いものの、この2年ほどの技術的な知識が止まったままなので、ちょっとコツコツ勉強をしながらアウトプットしていきたいと思います。

ぼちぼちと技術系のサイトや雑誌を見た感じ、インフラで言えばAWSがますます一般的になって、大企業の採用事例もかなり増えているようですね。またWeb系の企業であれば、どの企業も多かれ少なかれInfrastructure as Codeに取りくんでる感じでしょうか。

完全にDockerコンテナ上でサービスを動かしてる所も、ぼちぼち出てきてるようです。

後は、Goを導入している事例も増えてきたな〜と思いました。インフラ的には並列処理が有効な処理の場合に、自前で作ってパフォーマンスを上げる!みたいな事例が多い感じでしょうか。

この様な「最適化のためにミドルウェア自前で作っちゃう」みたい領域は、Scalaが担っていくかもと思っていたのですがそうでもなかったですね。今後はGoが席巻していきそうな予感がします。

まあ、この辺の技術は当然のごとく勉強していかなければならないでしょう。しかし、ある程度は触った事もありますし、私は基本的にミーハーなので「まだみんながあんまり手を出してない所」が一番好みだったりもします。

そこで勉強の手始めとして目にとまったのが「サーバレスアーキテクチャ」でした。

サーバレスアーキテクチャは近年のアプリケーションレイヤでのキーワード「Microservices」を実現する一つの手段とも考えられているみたいです。そう考えれば、ちゃんと技術的なトレンドを汲んで生まれたものだと言えますね。

2017年のバスワード感が漂ってるので、ミーハーには持って来いなテーマです。

サーバレスアーキテクチャとは?

定義はあいまいなようですが、より実際の使い方を考慮して言うと

  • 事前にプロセスを立ち上げておかずに
  • ユーザアクセス(何かのイベント)をトリガとして
  • 事前に用意した処理を
  • 新しいプロセスを立ち上げた上で処理する

といった仕組みのようです。詳しくは次のエントリを見ると良いと思います。

www.publickey1.jp

thinkit.co.jp

いくつか記事を読んでいると現状「Amazon API GatewayAmazonAWS Lamdaを使って出来る仕組み」以外のなにものでもない感じですね。

AWS Lambdaを使えばアプリケーションサーバ(常駐プロセス)を自分で用意する必要がないので、そういった意味で「サーバレス」という事でしょう。(もちろん裏ではコンテナが起動して、プロセスが立ち上がって、処理がおわったらコンテナが捨てられるといった事が行われいるようですが)

この様な特徴を持っていることからFaaS(Function as a Service)という風にも呼ばれているようです。

サーバレスアーキテクチャの利用例

理解を深めるには実際にやってみるのが手っ取り早いので、具体的な例を探してみました。

典型的な例としては「画像処理」が良く挙げられるようですね。

blog.serverworks.co.jp

この例ではS3への画像アップロードをトリガにリサイズを行い、出来たサムネイルを再びS3に保存するといった事を行なっているようです。他にも動的にサムネイルを作っている例もありました。

qiita.com

確かに非同期で行いたい処理を投げたり、コンバーターみたいな使い方は相性が良さそうです。スケールアウトもしやすそうなので、スパイクな負荷がかかるような場合は特に向いてそう。パッと思いつくとこだと、プッシュ通知とか、スクレイピングAPIを叩いて結果をjsonに変換した上で返すといった風な使い方ができそうです。

サーバレスアーキテクチャHello World

では、まずは手始めにサーバレスでHello Worldをやってみたいと思います。

利用するのは以下の3つです。

SERVERLESS FRAMEWORKは一言でいえば、「AWS Lambda上で動くプログラムを、手元で作って管理するためのツールセット」です。

serverless.com

AWS Lambdaの設定を手元のコンフィグで管理したり、作ったプログラムをAWS Lambdaにデプロイするといった事が可能です。

また、SERVERLESS FRAMEWORK自体はnode.jsで動きますが、AWS Lambdaが2016年12月現在対応しているNode.js、PythonJava(Scala)、C#のそれぞれを管理するためのテンプレートも用意されているようです。つまり、好きな言語で作ってSERVERLESS FRAMEWORKで管理できるってことです。

さて、これ以上ぐだぐだ言っててもピンとこないので、早速Hello Worldしてみたいと思います。

大まかな流れとしては次の通りです。

  1. SERVERLESS FRAMEWORKのインストール
  2. IAMユーザのクレデンシャルの設定
  3. プロジェクトの作成
  4. デプロイ
  5. 実行テスト
  6. APIとして使えるようにする

SERVERLESS FRAMEWORKのインストール

まずはSERVERLESS FRAMEWORKをインストールします。

インストール手順のページを見ると次の様に書いてあるので、node.js ver4以上が必要ですね。私はv4.7.0をインストールしました。

Note: Serverless runs on Node v4 or higher.

$ npm install serverless -g
$ serverless -v # => 1.4.0

v1.4.0がインストールされました。

IAMユーザのクレデンシャルの設定

SERVERLESS FRAMEWORKは手元の端末からAWSを操作するので、権限を持ったIAMユーザのクレデンシャル(アクセスキーとシークレット)を設定する必要があります。

やるべき事は大きく2つです。

  • IAMでSERVERLESSの利用に必要な権限を持ったユーザのクレデンシャルを取得
  • 取得したクレデンシャルをSERVERLESSに設定

ちなみにSERVERLESSを使うためにはAWS Lambda、Amazon API Gatewayの他にもCloud formationの権限が必要となるようです、今回はとりあえずIAMで「AdministratorAccess」を与えたユーザを作ってアクセスキーとシークレットを取得しました。

試してはいませんが、必要な権限にのみ絞りたい場合は「AWSLambdaFullAccess」「AmazonAPIGatewayInvokeFullAccess」と、下記の手順でCloud formationに関する権限を与えればよさそうです。

qiita.com

クレデンシャルを取得したら、SERVERLESSへのクレデンシャルの設定を行います。クレデンシャルの設定にはいくつかの方法があるようで、公式ページのCredentialsにまとまっています。好みに合わせて自分の好きな方法を選べば良いでしょう。

今回は他のサイトにも倣ってaws-cliでクレデンシャルを保存しておく方法を利用しました。aws-cliのインストールとクレデンシャルのセットアップ方法は公式サイトに説明があります。

docs.aws.amazon.com

公式サイトとは違い、手元のリージョンはap-northeast-1(東京リージョン)を選びました。

$ aws configure

# input
AWS Access Key ID [None]: XXXXXXXXXXXXXXXXXX
AWS Secret Access Key [None]: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
Default region name [None]: ap-northeast-1
Default output format [None]: json

プロジェクトの作成

続いてプロジェクトの作成を行います。作成にはserverless createコマンドを使います。同時にディレクトリと、Lambda上で動かすプログラムの言語を指定します。

$ serverless create --template aws-nodejs --path hello-serverless

# output
Serverless: Generating boilerplate...
Serverless: Generating boilerplate in "/Users/xxxx/hello-serverless"
 _______                             __
|   _   .-----.----.--.--.-----.----|  .-----.-----.-----.
|   |___|  -__|   _|  |  |  -__|   _|  |  -__|__ --|__ --|
|____   |_____|__|  \___/|_____|__| |__|_____|_____|_____|
|   |   |             The Serverless Application Framework
|       |                           serverless.com, v1.4.0
 -------'

Serverless: Successfully generated boilerplate for template: "aws-nodejs"

今回はnode.jsを利用する事にしました。別の言語で作りたい場合は下記のページを参考に--templateの値を変えればOKです。

serverless.com

作成されたディレクトリの中身には「handler.js」「serverless.yml」の2ファイルがありました。前者がLamda上で動かすプログラム、後者が設定ファイルですね。

# handler.jsの中身

'use strict';

module.exports.hello = (event, context, callback) => {
  const response = {
    statusCode: 200,
    body: JSON.stringify({
      message: 'Go Serverless v1.0! Your function executed successfully!',
      input: event,
    }),
  };

  callback(null, response);

  // Use this code if you don't use the http event with the LAMBDA-PROXY integration
  // callback(null, { message: 'Go Serverless v1.0! Your function executed successfully!', event });
};

bodyの部分が実際にレスポンスとして返すないようでしょう。Go Serverless v1.0! Your function executed successfully!と、引数のeventの内容を文字列にして返す様です。

# serverless.ymlの中身(コメント部分は割愛)

service: aws-nodejs

provider:
  name: aws
  runtime: nodejs4.3

functions:
  hello:
    handler: handler.hello

hander.helloの部分が恐らくLamda上に配置する関数名でしょう。handler.jsのmodule.exports.helloの部分と対応している感じでしょうか。

デプロイ

まずは動作を確認してみたいので、とりあえずデプロイしてみます。

$ serverless deploy

# output
Serverless: Packaging service...
Serverless: Uploading CloudFormation file to S3...
Serverless: Uploading service .zip file to S3 (583 B)...
Serverless: Updating Stack...
Serverless: Checking Stack update progress...
.........
Serverless: Stack update finished...
Service Information
service: aws-nodejs
stage: dev
region: us-east-1
api keys:
  None
endpoints:
  None
functions:
  aws-nodejs-dev-hello: arn:aws:lambda:us-east-1:xxxxxxxxxxxx:function:aws-nodejs-dev-hello

この様に進捗が出た後に、デプロイされた内容に関する情報が出力されるようです。「Serverless: Stack update finished...」以降の部分ですね。この値は「serverless info」コマンドで確認する事ができます。

$ serverless info

# output
Service Information
service: aws-nodejs
stage: dev
region: us-east-1
api keys:
  None
endpoints:
  None
functions:
  serverless-dev-hello: arn:aws:lambda:ap-northeast-1:xxxxxxxxxxxx:function:serverless-dev-hello

値を見てみるとaws-cliで東京リージョンを指定しましたが「us-east-1」になっています。endpointsはこのプログラムを呼び出すためののURLが入る所ですが、現在は「None」になっています。この辺りの値の変更はserver.xmlで設定を追加することで行うことが出来ます

実行テスト

実際にAPIとして使うためには、server.xmlに設定を追加してAmazon API Gatewayを使える様にする必要がありますが、「serverless invoke」コマンドを使うことでプログラムの実行結果を見ることができます。

$ serverless invoke -f hello

{
    "statusCode": 200,
    "body": "{\"message\":\"Go Serverless v1.0! Your function executed successfully!\",\"input\":{}}"
}

手元で実行するとこの様な結果が帰ってきました。正しく動作していそうですね。

APIとして使える様にする

さて、手元での動作が確認できたので、Amazon API Gatewayと組み合わせてエンドポイントを追加し、URLを叩いたら実行されるようにしたいと思います。

この変更は下記の様にserverless.ymlのfunctionsにeventsの項目を追加することで可能です。合わせてリージョンを東京に変更してあります。

# serverless.yml

 provider:
   name: aws
   runtime: nodejs4.3
+  region: ap-northeast-1

 functions:
   hello:
     handler: handler.hello
+    events:
+     - http:
+          path: hello
+          method: get

変更が出来たらデプロイして反映させます。

$ serverless deploy

# output
Serverless: Creating Stack...
Serverless: Checking Stack create progress...
.....
Serverless: Stack create finished...
Serverless: Packaging service...
Serverless: Uploading CloudFormation file to S3...
Serverless: Uploading service .zip file to S3 (583 B)...
Serverless: Updating Stack...
Serverless: Checking Stack update progress...
..............................
Serverless: Stack update finished...
Service Information
service: aws-nodejs
stage: dev
region: ap-northeast-1
api keys:
  None
endpoints:
  GET - https://xxxxxxxxxx.execute-api.ap-northeast-1.amazonaws.com/dev/hello
functions:
  aws-nodejs-dev-hello: arn:aws:lambda:ap-northeast-1:xxxxxxxxxxxx:function:aws-nodejs-dev-hello

この様にendpointsにURLが表示されました(URLのサブドメインは一部マスクしてあります。)後はこのURLにアクセスしてみるだけです。

$ curl https://xxxxxxxxxx.execute-api.ap-northeast-1.amazonaws.com/dev/hello

# output
{"message":"Go Serverless v1.0! Your function executed successfully!","input":{"resource":"/hello","path":"/hello","httpMethod":"GET","headers":
以下省略 

この様にちゃんと出力が帰ってきます。入門としてはこのくらいで十分でしょう。テスト後には「serverless remove」コマンドを実行することでデプロイした内容を削除することが出来ます。

$ serverless remove

# output
Serverless: Getting all objects in S3 bucket...
Serverless: Removing objects in S3 bucket...
Serverless: Removing Stack...
Serverless: Checking Stack removal progress...
...................
Serverless: Stack removal finished...

まとめ

SERVERLESS FRAMEWORKもあるので、Hello Worldする程度なら非常に手軽に試すことができました。ただ、あまりサーバレスアーキテクチャ(Lamda)の良さという点では実感が少ないですね。

ユーザアクセス以外のトリガになる処理を利用してみたり、実際に業務で利用してみればそのありがたさが実感できるのかもしれません。

今回は良さを実感は出来ませんでしたが、改めてサーバレスアーキテクチャのメリット・デメリットを簡単にまとめると以下の感じでしょうか。

メリット

  • 実行されるそれぞれの処理がステートレスで、お互いにシェアードナッシングなので安全安心。
  • 同様に上記の理由から疎結合でスケール(アウト)しやすい。
  • 常駐プロセスがいないので可用性が高く、本当に必要な分のリソースにのみ確保すれば良いので安くあがる

要は安全かつ拡張性が高くて安いってことですね。

デメリット

  • 都度プロセスが立ち上がるのでオーバーヘッドが大きい
  • 処理が疎結合になって分離するため、デバッグ(シナリオテスト)などのコストが高い

やはりオーバーヘッドが高いのは大きなデメリットのようです。実際に解説記事をいくつか読んでいても、まだ全てをサーバレスアーキテクチャにするのは(負荷の高さを考えると)時期尚早といった感じでした。

処理をあまり疎結合にしすぎると今度は開発コストが増大しそうなので、仮にオーバーヘッドが減ったとしても結局全てサーバレスアーキテクチャでという考えは、いずれにせよ難しいのかもしれませんね。