ECSで上げたコンテナは本当にVPC上インスタンスのサブネットやセキュリティグループ適用されるのか？

[dots girls Advent Calendar 2016](http://qiita.com/advent-calendar/2016/dots_girls)、今年もトップバッターを頂きました吉澤です！

今年の夏くらいに東京リージョンでもECRが使えるようになり、わざわざECRのみ別リージョンにするなど考える必要がなくなり、だいぶ現実的なサービスとなりました。
ECSのトップページに、このようなことが書いてるので、本当にコンテナから接続できるかどうか実験してみることにしました。

<img width="75%" alt="セキュリティグループ、Elastic Load Balancing、EBSボリューム、IAM ロールなどへのアクセスを実行できます。" src="https://qiita-image-store.s3.amazonaws.com/0/20557/6133cf2d-981b-f80c-83d0-20ca373e99ca.png">


今回はECSにて立てたコンテナに対して、セキュリティ的な検証をすべく、以下のような構成を考えて作ってVPCインスタンスからプライベートのサブネットグループへアクセス出来るかを検証します。

<img width="75%" alt="構成図" src="https://qiita-image-store.s3.amazonaws.com/0/20557/15b31b94-e976-f764-f842-0baf63f43223.png">

# AWSコンソールで準備

## VPCを作成

適当にwakana_testと名付けてVPCを作成します。

<img width="75%" alt="VPC作成" src="https://qiita-image-store.s3.amazonaws.com/0/20557/5ce9f6d3-c64d-c45e-923d-ffdfd42cb906.png">

<img width="75%" alt="VPC作成完了" src="https://qiita-image-store.s3.amazonaws.com/0/20557/c0624e46-f13d-1728-1a4e-4ec0ca73c1f3.png">

## サブネットを作成

webとredisの二つのサブネットを作成します。

<img width="75%" alt="web用のサブネットグループを作成" src="https://qiita-image-store.s3.amazonaws.com/0/20557/7bc5e85d-0b31-a8ca-3d1a-59df00bd09a4.png">

<img width="75%" alt="redis用のサブネットグループを作成" src="https://qiita-image-store.s3.amazonaws.com/0/20557/4f4428b5-3617-b3bb-05a6-cefb39d692a2.png">

<img width="75%" alt="サブネット作成完了" src="https://qiita-image-store.s3.amazonaws.com/0/20557/7cd1e637-7b76-343e-0cea-61939cc71a70.png">

## インターネットゲートウェイを作成

インターネットゲートウェイを作成し、先ほど作成したVPCにアタッチします。

<img width="75%" alt="インターネットゲートウェイ作成" src="https://qiita-image-store.s3.amazonaws.com/0/20557/966c8ecf-88f8-2057-95ed-f8901c82a0f2.png">

<img width="75%" alt="インターネットゲートウェイをVPCにアタッチ" src="https://qiita-image-store.s3.amazonaws.com/0/20557/831f4230-db37-a5e0-d8ca-90a133609477.png">

<img width="75%" alt="インターネットゲートウェイ設定完了" src="https://qiita-image-store.s3.amazonaws.com/0/20557/5bb2fb21-4bb7-e18b-049c-0435d134ed38.png">

## パブリックとプライベートのルートテーブルを作成

サブネット作成時にひとつ出来ているので、そちらはプライベートと名付け、パブリックを新しく作ります。
作成後はパブリックのみルートタブでインターネットゲートウェイに仕向けます。

<img width="75%" alt="パブリック用ルートテーブル作成" src="https://qiita-image-store.s3.amazonaws.com/0/20557/326edc5f-3e06-10b7-cfbb-e1ad687c6191.png">

<img width="75%" alt="パブリック用ルートテーブルにインターネットゲートウェイを設定" src="https://qiita-image-store.s3.amazonaws.com/0/20557/67b3b7f0-2d44-9712-008e-1d4e3a58e351.png">

## webのサブネットグループにパブリックルートテーブルを割り当て

サブネットグループのデフォルトがプライベートルートテーブルなので、webのサブネットグループにパブリックルートテーブルを割り当てます。

<img width="75%" alt="webのサブネットグループにパブリックルートテーブルを割り当て" src="https://qiita-image-store.s3.amazonaws.com/0/20557/c4a53ace-ddf5-0097-7454-1a1f3700bcc5.png">

## セキュリティグループを作成

webとredis用の二つ用を作成します。
今回は踏み台サーバーなど用意しないので、web用サーバーに直接ssh出来るように設定します。

<img width="75%" alt="web用セキュリティグループ作成" src="https://qiita-image-store.s3.amazonaws.com/0/20557/bf5598c7-bb3a-6d38-0829-269f7490ff4d.png">

<img width="75%" alt="redis用セキュリティグループ作成" src="https://qiita-image-store.s3.amazonaws.com/0/20557/2ecfddc7-28c1-4554-0110-83f19a4f02e8.png">

<img width="75%" alt="web用セキュリティグループインバウンド設定" src="https://qiita-image-store.s3.amazonaws.com/0/20557/efdeceeb-2269-8096-50a7-01320ecf485e.png">

<img width="75%" alt="redis用セキュリティグループインバウンド設定" src="https://qiita-image-store.s3.amazonaws.com/0/20557/e8166647-b84a-b49f-2e6e-8ca57a528733.png">

# ECRにリポジトリを作成

今回は適当にwakana_testを作成します。

<img width="75%" alt="ECRにリポジトリを作成" src="https://qiita-image-store.s3.amazonaws.com/0/20557/540a44c9-ba2e-3d43-dbc2-07246f02f5cb.png">

# Dockerまわりの準備

今回はすぐに動かせるNodeJSを用意します。

## package.jsonを作成

`$ npm init`

無心でEnterキーを連打します。

## index.jsを作成

お約束の`Hello World!`を返します。

```index.js
var express = require('express');
var app = express();

app.get('/', function (req, res) {
    res.send('Hello World!');
});
app.listen(3000);                     
```

## Dockerfileを作成

```Dockerfile
FROM node

WORKDIR /usr/src/app
RUN mkdir -p /usr/src/app
WORKDIR /usr/src/app
COPY package.json /usr/src/app/
RUN npm install express
COPY . /usr/src/app
EXPOSE 3000
CMD node /usr/src/app/index.js
```

# Dockerイメージをサーバーにpush

## ECRにログイン

`$ $(aws ecr get-login --region ap-northeast-1)`

私の環境ではAWS CLIが古くて動かなかったためAWS CLIのアップデートしました。

## Dockerfileよりイメージを作成

`$ docker build -t wakana_test .`

## イメージをpushできるようにタグ付け

`$ docker tag wakana_test:latest 308321613648.dkr.ecr.ap-northeast-1.amazonaws.com/wakana_test:latest`

## ECRにイメージをpush

`$ docker push 308321613648.dkr.ecr.ap-northeast-1.amazonaws.com/wakana_test:latest`

上がりました。

<img width="75%" alt="ECRにイメージのプッシュ完了" src="https://qiita-image-store.s3.amazonaws.com/0/20557/fc034017-e644-c4dc-58c9-fa04a6e6398b.png">

## ECSのクラスターを設定

適当にwakana-testを作成します。
ネットワーキングのところで、最初に作ったweb用のサブネットとセキュリティグループを割り当てます。

<img width="75%" alt="ECSのクラスター設定1" src="https://qiita-image-store.s3.amazonaws.com/0/20557/1a85377e-4a28-be7d-fe22-fb0c13b0a21e.png">

<img width="75%" alt="ECSのクラスター設定2" src="https://qiita-image-store.s3.amazonaws.com/0/20557/419e7c31-102b-b2ff-6dbd-7a78aa7c8af3.png">

<img width="75%" alt="ECSのクラスター設定3" src="https://qiita-image-store.s3.amazonaws.com/0/20557/883e00e0-0a9b-0196-1e08-4a1fd17bf2ed.png">

## タスクの作成

イメージからコンテナをビルドするタスクを定義します。
いろいろ細かく設定できるのですが今回はデフォルト値にします。

<img width="75%" alt="ECSのタスク設定1" src="https://qiita-image-store.s3.amazonaws.com/0/20557/05a939d0-189b-973e-6d1c-241643ba8374.png">

<img width="75%" alt="ECSのタスク設定2" src="https://qiita-image-store.s3.amazonaws.com/0/20557/023b35ed-55f4-477c-9224-c453057cf9b0.png">

## クラスターのサービスからタスクを割り当て

先程作ったタスクを割り当てます。

<img width="75%" alt="ECSクラスターにタスクを割り当て" src="https://qiita-image-store.s3.amazonaws.com/0/20557/ee500413-5709-e13c-7e0b-0fc6c0e9b013.png">

# コンテナにブラウザからアクセス出来るか確認

ACTIVEステータスになったらEC2のマネジメントコンソールからIP確認しブラウザからアクセスします。

<img width="75%" alt="EC2のマネジメントコンソールからIP確認" src="https://qiita-image-store.s3.amazonaws.com/0/20557/bcbafa37-82c7-ac45-5c0e-d81d0753e933.png">

<img width="75%" alt="Hello World！" src="https://qiita-image-store.s3.amazonaws.com/0/20557/feeaea4a-f9de-2315-467e-c1e67c01d0a6.png">

`Hello World！`と表示されました。

# ElastiCacheにてRedisサーバ作成

ElastiCacheにてRedisサーバーを作成します。
今回はレプリケーション無し最小構成で作成します。

## ElastiCacheのサブネットグループに、VPCグループ内のサブネットを割り当て

ElastiCache内のサブネットグループから、VPCのサブネットグループを割り当てます。

<img width="75%" alt="ElastiCacheをVPC内に設定" src="https://qiita-image-store.s3.amazonaws.com/0/20557/db59ac62-5a61-5f20-47a4-cefc9fbfa9dd.png">

## Redisサーバー作成

作成時に先ほどつくったサブネットグループを割り当てます。

<img width="75%" alt="Redisサーバー作成1" src="https://qiita-image-store.s3.amazonaws.com/0/20557/54ef866b-f297-c888-5829-43f951111241.png">

<img width="75%" alt="Redisサーバー作成2" src="https://qiita-image-store.s3.amazonaws.com/0/20557/5ae0145a-d695-f357-f80b-e411c2d93671.png">

# ローカル、コンテナ、インスタンスそれぞれからRedis疎通確認

## ローカル

Macなのでbrewでインストールします。

`$ brew install redis`

redis-cliでアクセスします。

<img width="75%" alt="Macからredisにアクセス" src="https://qiita-image-store.s3.amazonaws.com/0/20557/05a810fb-a84b-cd4c-c756-0bb4c8686de2.png">

拒否られました。

## コンテナ

インスタンスから`$ docker exec -it container_name bash`で入ります

`$ apt-get update -y`
`$ apt-get install -y redis-server`

redis-cliでアクセスします。

<img width="75%" alt="Dockerコンテナからredisにアクセス" src="https://qiita-image-store.s3.amazonaws.com/0/20557/d8f9c0ea-d254-2bde-8fd0-b87eee22bc59.png">

コンテナから入れました！
適当にデータいれてみました。

<img width="75%" alt="Redisテストコマンド" src="https://qiita-image-store.s3.amazonaws.com/0/20557/ebcdf9d3-b48d-8b08-3987-225f5b7403b6.png">

## EC2インスタンス

`yum`でインストール出来ません。

`$ sudo yum -y install gcc wget`
`$ sudo wget http://download.redis.io/redis-stable.tar.gz`
`$ sudo tar xvzf redis-stable.tar.gz`
`$ cd redis-stable`
`$ sudo make`

これでやっと起動できます。
redis-cliでアクセスします。

<img width="75%" alt="EC2インスタンスからredisにアクセス" src="https://qiita-image-store.s3.amazonaws.com/0/20557/6f82699c-a757-457f-4042-38a8ed0637cc.png">

繋がりました。
先ほどのハッシュ型データを取得します。

<img width="75%" alt="Redisテストコマンド" src="https://qiita-image-store.s3.amazonaws.com/0/20557/24fef58e-7cc8-0784-9840-01c723a10c31.png">

aaaが返ってきました。

# 結果

VPC内に立てたコンテナ上から非公開のサブネットゾーンに接続できました。
これで本番でもセキュアに運用できることが分かりました。

# dots.女子部について

インフラ、サーバー、フロント開発から運用ノウハウ、女性エンジニアのキャリアについてなどいろいろな観点から勉強したり、情報共有している女性エンジニアのための部活です。
興味がある方は是非SNSアカウントのフォローしてみて下さい！

[Twitter](https://twitter.com/dotsgirls)
[Facebook](https://www.facebook.com/dots%E5%A5%B3%E5%AD%90%E9%83%A8-457992851057604/)

明日はiOSの女神、[まきちゃん](http://qiita.com/akatsuki174)よろしくお願いいたします＼(^o^)／