UbuntuでAmazon ECS用のインスタンスを作る

ECSで使うインスタンスはAmazonが公式に提供するAMIを使うのが一般的ですが、ホストの監視など構成によっては色々手を加えたい場合もあります。

提供されているAMIに手を加えてもいいんですが、せっかく？なのでUbuntuで自分で作ってみることにしました。

## EC2でUbuntu 14.04を起動

まずは、適当なEC2インスタンスを上げます。最近AmazonLinuxばっかり使っていて忘れていましたが、Ubuntuのデフォルトユーザは`ubuntu`ですね。`ec2-user`じゃなくて。

## UbuntuにDockerをインストール

https://docs.docker.com/engine/installation/linux/ubuntulinux/ を参考にUbuntuにDockerをインストール

```sh
apt-get update
apt-get install apt-transport-https ca-certificates -y
apt-key adv --keyserver hkp://p80.pool.sks-keyservers.net:80 --recv-keys 58118E89F3A912897C070ADBF76221572C52609D
echo "deb https://apt.dockerproject.org/repo ubuntu-$(lsb_release -c -s) main" > /etc/apt/sources.list.d/docker.list
apt-get update
apt-get purge lxc-docker -y
apt-cache policy docker-engine
apt-get install "linux-image-extra-$(uname -r)"  docker-engine -y

usermod -aG docker ubuntu
sed -i -e 's/GRUB_CMDLINE_LINUX=""/GRUB_CMDLINE_LINUX="cgroup_enable=memory swapaccount=1"/' /etc/default/grub
```

一度 reboot

```
reboot
```

## ECS Container Agentをインストール

つぎはhttp://docs.aws.amazon.com/ja_jp/AmazonECS/latest/developerguide/ecs-agent-install.html を参考にECS Container Agentをインストール

```sh
mkdir -p /var/log/ecs /var/lib/ecs/data

docker run --name ecs-agent \
--detach=true \
--restart=on-failure:10 \
--volume=/var/run/docker.sock:/var/run/docker.sock \
--volume=/var/log/ecs/:/log \
--volume=/var/lib/ecs/data:/data \
--volume=/sys/fs/cgroup:/sys/fs/cgroup:ro \
--volume=/var/run/docker/execdriver/native:/var/lib/docker/execdriver/native:ro \
--publish=127.0.0.1:51678:51678 \
--env=ECS_LOGFILE=/log/ecs-agent.log \
--env=ECS_LOGLEVEL=info \
--env=ECS_DATADIR=/data \
--env=ECS_CLUSTER=cluster_name \
amazon/amazon-ecs-agent:latest
```

AWS Consoleを確認すると登録されています。
最新版をのDockerをインストールしたので`1.10.3`になってます。

![Screen-Shot-2016-03-11-at-23.51.40.png](https://qiita-image-store.s3.amazonaws.com/0/4471/a8b6cc10-fedd-8e37-5046-56107e0ab0d9.png)

### ECS Container Agentを自動起動する

さて、最後に[Upstart](http://qiita.com/search?q=upstart&sort=rel)を使ってECS Container Agentを自動起動するようにします。

同時にECS Clusterの指定をEC2のTagで行える様にします。

![Screen-Shot-2016-03-12-at-00.13.36.png](https://qiita-image-store.s3.amazonaws.com/0/4471/3de8a306-6f76-9608-4011-f24e5a530866.png)

Tagの取得はawscli経由で行います。

```
apt-get install awscli -y
```

```
LC_ALL=C aws --region $(ec2metadata --availability-zone | sed -e 's/.$//') ec2 describe-tags --filter "Name=resource-id,Values=$(ec2metadata --instance-id)" "Name=key,Values=cluster" --query "Tags[*].[Value]" --output text
``` 

実行するインスタンスのRoleに`ec2:Describe*`を許可するPolicyを加えます。


IAM → Policies → Create Policy → Create Your Own Policyの「Review Policy」画面で下記の様に入力します。

Name: EC2DescribeFullAccess
Policy Document:

```json
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": "ec2:Describe*",
      "Resource": "*"
    }
  ]
}
```

その後、インスタンスロールにポリシーを当てます。

![Screen-Shot-2016-03-12-at-00.37.37.png](https://qiita-image-store.s3.amazonaws.com/0/4471/04d68ed6-8e4b-6862-6258-df55b50b7d51.png)

これでさっきのコマンドを実行すると、`cluster` Tagで指定した文字列が取得出来ます。

さて、Upstartの起動スクリプトです。下記のファイルを `/etc/init/ecs-agent.conf` に設置します。


```
description "ECS Agent Container"
author "masuidruve"
start on filesystem and started docker
stop on runlevel [!2345]
respawn

script
  mkdir -p /var/log/ecs /var/lib/ecs/data
  LC_ALL=C
  ECS_CLUSTER=$(aws --region $(ec2metadata --availability-zone | sed -e 's/.$//') ec2 describe-tags --filter "Name=resource-id,Values=$(ec2metadata --instance-id)" "Name=key,Values=cluster" --query "Tags[*].[Value]" --output text)
  exec docker run --name ecs-agent \
    --restart=on-failure:10 \
    --volume=/var/run/docker.sock:/var/run/docker.sock \
    --volume=/var/log/ecs/:/log \
    --volume=/var/lib/ecs/data:/data \
    --volume=/sys/fs/cgroup:/sys/fs/cgroup:ro \
    --volume=/var/run/docker/execdriver/native:/var/lib/docker/execdriver/native:ro \
    --publish=127.0.0.1:51678:51678 \
    --env=ECS_LOGFILE=/log/ecs-agent.log \
    --env=ECS_LOGLEVEL=info \
    --env=ECS_DATADIR=/data \
    --env=ECS_CLUSTER=$ECS_CLUSTER \
    amazon/amazon-ecs-agent:latest
end script

post-stop script
  /usr/bin/docker stop --time 2 ecs-agent || true
  /usr/bin/docker rm ecs-agent || true
  sleep 2
end script
```

これで準備完了。また再起動してみます。

```
reboot
```

## 確認

再度ログインして、`docker ps`を実行してecs-agentが起動しているか確認します。

```
CONTAINER ID        IMAGE                            COMMAND             CREATED             STATUS              PORTS                        NAMES
28f5948116a2        amazon/amazon-ecs-agent:latest   "/agent"            2 minutes ago       Up 2 minutes        127.0.0.1:51678->51678/tcp   ecs-agent
```

クラスタ名が正しく取得出来ているかは、下記のコマンドで確認できます。

```sh
docker inspect ecs-agent | grep "ECS_CLUSTER"
```

最後にAWS Consoleで確認しましょう。


## 宣伝

DevOps好きだ！と思っている方、一緒に働きませんか？ [3,000万人の予約を支えるDevOpsエンジニア募集！](https://www.wantedly.com/projects/27205)でお待ちしています。

よければ、[トレタメンバーのQiita](http://qiita.com/organizations/toreta)も見ていって下さい。