s3fs を使って EC2 に S3 の Bucket をマウントする


お仕事の絡みで、タイトルの要件が必要になりそうだったので備忘録も兼ねて。

# 前提

* EC2 の Distribution は Amazon Linux
* インスタンスは AutoScale によって増えたり減ったりする

# やること

1. S3 Bucket の準備
1. IAM の準備
	* IAM User で対応する場合
	* IAM Role で対応する場合
1. s3fs のインストール
1. s3fs の設定・起動

# やりかた

## S3 Bucket の準備

まぁ、普通に Management Console から追加するだけ。

ログとかはご随意に。

## IAM の準備

二通りのやり方があるので、お好みで。

### IAM User で対応する場合

このケースは、EC2 起動時のオプションとして IAM Role を **割り当てたくない(られない)** 場合に使うと良いか？

1. IAM Management Console で **Create a New Group of Users** をクリック
	![ScreenShot 01](http://d4dqxb4bcxr8q.cloudfront.net/img/ss/20140124-01/IAM_User/01.png)
1. グループ名を設定して **Continue**
	![ScreenShot 02](http://d4dqxb4bcxr8q.cloudfront.net/img/ss/20140124-01/IAM_User/02.png)
1. `Select Policy Template` の中にある `Amazon S3 Full Access` を **Select**<br />※割と下の方にあるので、スクロールしないと出てこない。
	![ScreenShot 03](http://d4dqxb4bcxr8q.cloudfront.net/img/ss/20140124-01/IAM_User/03.png)
1. テンプレートから生成された Policy 構文が表示されるので、そのまま **Continue**
	![ScreenShot 04](http://d4dqxb4bcxr8q.cloudfront.net/img/ss/20140124-01/IAM_User/04.png)
1. ユーザ名決めて **Continue**
	![ScreenShot 05](http://d4dqxb4bcxr8q.cloudfront.net/img/ss/20140124-01/IAM_User/05.png)
1. 内容に問題が無ければ **Continue**
	![ScreenShot 06](http://d4dqxb4bcxr8q.cloudfront.net/img/ss/20140124-01/IAM_User/06.png)
1. 作成に成功し、一番重要な `Access Key ID` と `Secret Access Key` が表示されるので、控える。<br />**Download Credencials** しとくと良い。
	![ScreenShot 07](http://d4dqxb4bcxr8q.cloudfront.net/img/ss/20140124-01/IAM_User/07.png)

### IAM Role で対応する場合

鍵情報などを EC2 のインスタンス内に残したくない場合はコッチかな？

EC2 インスタンスの起動時に下記で作成した IAM Role を設定する必要がある。

1. IAM Management Console の左ペインにある Roles から **Create New Role** をクリック
	![ScreenShot 01](http://d4dqxb4bcxr8q.cloudfront.net/img/ss/20140124-01/IAM_Role/01.png)
1. ロール名を決めて **Continue**
	![ScreenShot 02](http://d4dqxb4bcxr8q.cloudfront.net/img/ss/20140124-01/IAM_Role/02.png)
1. AWS Service Roles の Amazon EC2 を **Select**
	![ScreenShot 03](http://d4dqxb4bcxr8q.cloudfront.net/img/ss/20140124-01/IAM_Role/03.png)
1. Select Policy Template の中にある `Amazon S3 Full Access` を **Select**<br />※割と下の方にあるので、スクロールしないと出てこない。
	![ScreenShot 04](http://d4dqxb4bcxr8q.cloudfront.net/img/ss/20140124-01/IAM_Role/04.png)
1. テンプレートから生成された Policy 構文が表示されるので、そのまま **Continue**
	![ScreenShot 05](http://d4dqxb4bcxr8q.cloudfront.net/img/ss/20140124-01/IAM_Role/05.png)
1. 内容に問題が無ければ **Create Role**
	![ScreenShot 06](http://d4dqxb4bcxr8q.cloudfront.net/img/ss/20140124-01/IAM_Role/06.png)

## s3fs のインストール

2014年01月24日現在、最新版は **1.76** の様子。
[Google Code](https://code.google.com/p/s3fs/) にあるのが最新かと思いきや、 [GitHub](https://github.com/s3fs-fuse/s3fs-fuse) に移動しているようなので注意ｗ

なお、RPM などは用意されていないので、自分で `make` する必要がある。
`rpmbuild` でもしとくと幸せになれるかも？ｗ

### 先ずは、必要となるパッケージのインストール

Amazon のリポジトリにあるパッケージで賄える。

```bash:yum
sudo yum -y install gcc-c++ fuse fuse-devel libcurl-devel libxml2-devel openssl-devel
```

### 続いて、s3fs のソース取得

```bash:git
git clone https://github.com/s3fs-fuse/s3fs-fuse.git

```

### configure, make, make install

*/usr/bin/s3fs* に置きたかったので `--prefix=/usr` を `./configure` のオプションに食わせてます。

```bash:make
cd s3fs-fuse/
./autogen.sh
./configure --prefix=/usr
make
sudo make install
```

## s3fs の設定・起動

作成した IAM の種類に応じて、若干設定内容が変わる。

### マウント前の設定

マウントポイントとなるディレクトリを作る。
私は */mnt/s3fs* にしてる。

```bash:mkdir
sudo mkdir <Mount Point>
```

#### IAM を User で作成した場合

s3fs を用いてマウントする際の認証用に、作成時に控えた `Access Key ID` と `Secret Access Key` を設定する。

色々置き場があるっぽいが、ココでは */etc/passwd-s3fs* に配置する。
※置き場については、マニュアル参照のこと。

```bash:passwd-s3fs設定
echo "<Access Key ID>:<Secret Access Key>" | sudo tee -a /etc/passwd-s3fs
sudo chmod 640 /etc/passwd-s3fs
```

#### IAM を Role で作成した場合

EC2 インスタンス起動時に IAM Role を正しく選択していれば、特に設定するコトはない。はず。

### マウント

お待ちかねのマウント。

なお、デフォルトだと root:root でマウントされてしまって、読み書きが出来ない状態になってしまうので、
オプションに uid, gid を渡して、マウント時の Owner を変更する必要がある。
※uid, gid は `id <User Name>` コマンドで確認出来る。

下記の例では、`default_acl=public-read` としているが、これは外部に直接公開するケースが有り得たので、こうしている。
外部公開する必要が無いなら private にしておくのがオヌヌメ。
CloudFront 経由で配信したい場合でも Distribution を正しく設定すれば private で問題無かったはず。

#### IAM を User で作成した場合

```bash:s3fs
sudo /usr/bin/s3fs <Bucket Name> <Mount Point> -o rw,allow_other,uid=<UID>,gid=<GID>,default_acl=public-read
```


#### IAM を Role で作成した場合

```bash:s3fs
sudo /usr/bin/s3fs <Bucket Name> <Mount Point> -o rw,allow_other,uid=<UID>,gid=<GID>,default_acl=public-read,iam_role=<IAM Role Name>
```

### 確認

マウントポイントを `ls` するなり `df` するなりすれば良いんじゃないかな？

ちなみに、`df` した結果は以下。

<pre>
$ df -kh
Filesystem            Size  Used Avail Use% マウント位置
/dev/xvda1             30G   16G   13G  55% /
tmpfs                 298M     0  298M   0% /dev/shm
s3fs                  256T     0  256T   0% /mnt/s3fs
</pre>

256TB のファイルシステムがマウントされてますね！

### 起動時設定

このままだと、起動時に自動的にはマウントしてくれない。
ので、今回作ったインスタンスをベースにした AMI からの AutoScaling とか、普通にインスタンス再起動した時とかに、「あれ？S3 マウントしたディレクトリが見られない…！？」みたいなコトになる。
ので、起動時に自動的にマウントしてくれるように設定してしまう。

んで、このとき、一般的には */etc/fstab* に記載して終わりにするんだろうけど、IAM を Role にした場合、fstab の設定が読まれる時点ではまだ Amazon の API を叩けないっぽいので、マウントに失敗する。
ので、以下のように IAM の種類によってやり方を変える

#### IAM を User で作成した場合

User の場合は API 叩く必要が無いので、素直に fstab に書く。

```bash:/etc/fstab
echo "/usr/bin/s3fs#<Bucket Name> <Mount Point> fuse rw,allow_other,uid=<UID>,gid=<GID>,default_acl=public-read 0 0" | sudo tee -a /etc/fstab
```

#### IAM を Role で作成した場合

Role の場合は、API が叩けるようになる **起動時スクリプトが走るタイミング** でマウントする。

*/etc/rc.d/rc.local* とかでやると良いんじゃないかな？

```bash:/etc/rc.d/rc.local
echo "/usr/bin/s3fs <Bucket Name> <Mount Point> -o rw,allow_other,uid=<UID>,gid=<GID>,default_acl=public-read,iam_role=<IAM Role>" | sudo tee -a /etc/rc.d/rc.local

```

上記の例では、 */etc/rc.d/rc.local* の最下部に追記してるけど、他にも何か処理してるなら、順番は気を付けた方が良いかも。

# おわりに

と、偉そうなことを散々書いておきながら、まだ商用環境での稼働はしておりませんっ！ｗ
※遠からず対応するとは思うが、まだ実験中だったりする :-P

導入して、運用安定したらレポしようかしら…。