Amazon Elastic File System（EFS）を使ううえでの勘所

この記事は[AWS Advent Calendar 2018](https://qiita.com/advent-calendar/2018/aws)の9日目の記事です。

2018年7月に東京リージョンにローンチされたEFS。
QiitaでのEFSに関する投稿数からも、使う人が徐々に増えてきたようです（私もその一人です）。

今回はEFSを使ううえで、意識しておきたい点やTipsをお伝えしたいと思います。

**2020年4月 以下について追記**

- IAM認証とアクセスポイント
- AWS Backupのクロスリージョン対応
- AWS Backupによるアイテムレベルのリストア


**2019年3月 以下について追記**

- バーストモードの監視
- マウント時のnoresvportオプション
- AWS Backup

**2019年6月 以下について追記**

- AWS Backupの東京リージョン対応

# EFSとは？
- フルマネージド型のファイルストレージ
    - サーバ、ディスクなどの管理は不要
    - NFS v4でマウント可能
        - **Windowsはサポート対象外**
- 容量・性能ともにスケーラブル
    - ファイルの追加や削除に合わせてストレージ容量を直ちに自動で拡張または縮小することが可能
    - 保存容量に応じてスループット・IOPS性能が向上
    - 数千のNFS同時接続をサポート
- 高耐久性かつ高可用性を担保
    - 複数AZに複製されて保存される
    - 複数AZにある複数のEC2インスタンスから同時に読み書きが可能

詳しく知りたい方は以下をご確認ください。

[20180704 AWS Black Belt Online Seminar Amazon Elastic File System (Amazon EFS) 2018/8/9 update](https://www.slideshare.net/AmazonWebServicesJapan/20180704-aws-black-belt-online-seminar-amazon-elastic-file-system-amazon-efs-201889-update)

# 勘所
それでは、実際にEFSを導入する際に感じた疑問などをベースに、勘所を説明していきます。

## マウントターゲットはどのサブネットに配置すればいいの？ 
前提知識として、EFSはファイルシステムと呼ばれる単位で管理され、VPCを指定して作成します。
ファイルシステムを作成すると、**VPC内の各AZにはマウントターゲットが用意されます**。
EC2は同じAZに作成されているマウントターゲットに接続しますが、
**マウントターゲットとEC2が所属サブネットは分けたほうがいいのか？分けないほうがいいのか？**
という疑問が生じました。

図にするとこんな感じ。
![efs_subnet.png](https://qiita-image-store.s3.amazonaws.com/0/307226/d24d09cf-7d49-2371-8bc0-09c58101356c.png)

セキュリティ的に分けたほうがいいのかなあ、とか思っていましたが、[AWS Black Belt Online SeminarのQA](https://aws.amazon.com/jp/blogs/news/webinar-bb-efs-2018/)にて、以下の記述を見つけました。

> Q. 作成時のsubnet指定は、EFSをマウントするEC2インスタンスが所属しているsubnetを選択すればよいですか？
>> A. はい。 EC2 インスタンスが属するサブネットに EFS マウントターゲットを作成することができます。この場合、ネットワーク的にもアクセス効率の良い構成になります。

ふーむ、なるほど。
ということで、上記およびセキュリティ等々を鑑みて、私としては以下の観点でマウントターゲットの配置サブネットを考慮することとしました。

- **基本的にはマウントターゲットとマウント対象のEC2を同一サブネット上に配置する**
- ただし、以下の場合はサブネットを分けることを検討する
    - EC2がパブリックなサブネットに配置されるなど、セキュリティ上の懸念がある
        - ただし、マウントターゲットはセキュリティグループを使ったポートレベルでの通信制御が可能
    - EC2が配置されるサブネットのCIDRをなるべく節約したい
        - 1つのマウントターゲットで使われるIPは1つなので問題ないとは思いますが、一応。。。
    - 同一AZ内の複数のサブネットにマウント対象のEC2が存在する

無理やり理由を挙げた感も否めませんが、、、もっといい観点があれば、どなたかご教示いただけると嬉しいです。


## パフォーマンスモード、スループットモードは何を選択すればいいの？
そもそもパフォーマンスモード、スループットモードって何？って方は、以下を熟読ください。

[20180704 AWS Black Belt Online Seminar Amazon Elastic File System (Amazon EFS) 2018/8/9 update](https://www.slideshare.net/AmazonWebServicesJapan/20180704-aws-black-belt-online-seminar-amazon-elastic-file-system-amazon-efs-201889-update)

そして、上記の資料に「パフォーマンスモード、スループットモードは何を選択すればいいの？」の答えもしっかり書いてあります。以下、引用です。

![20180704-aws-black-belt-online-seminar-amazon-elastic-file-system-amazon-efs-201889-update-67-638.jpg](https://image.slidesharecdn.com/20180704aws-blackbeltamazonefs-180810054653/95/20180704-aws-black-belt-online-seminar-amazon-elastic-file-system-amazon-efs-201889-update-67-638.jpg?cb=1533885583)

要は、**特別な使い方でないなら、パフォーマンスモードは汎用、スループットモードはバースト**ってことですね。

### バーストモードの注意点
EFSの使い方によっては「すぐにクレジットを使い切ってしまい、スループットが制限されてしまった」なんてことが起き得ります。
**そんなことが起きないよう、BurstCreditBalanceメトリクスにアラームを設定しておき、クレジットの消費状況を監視できるようにしておきましょう！**

### モードの変更・料金体系
モードの変更や料金体系はそれぞれ異なりますので気をつけてください。
簡単ですがまとめてみました。

||パフォーマンスモード|スループットモード|
|:-:|:-:|:-:|
|モードの変更|不可[^1]|可能[^2]|
|追加課金|汎用、最大I/Oともになし|プロビジョンドスループットは確保するスループットに応じて課金|

[^1]: パフォーマンスモードを変更したい場合は、「ファイルシステム再作成→データ移動→EC2側でマウント設定変更」が必要
[^2]: プロビジョンドスループットの場合、スループットの増加はいつでも可能だが、減少は24時間に1回


## マウントはマウントヘルパーを使ったほうがいいの？
マウントヘルパーとはEFSを簡単にマウントすることができる機能です。
この機能は、AWSが公開しているamazon-efs-utilsというパッケージを導入することで使うことができます。

以下、私なりに感じたマウントヘルパー（というかamazon-efs-utils）のメリデメを列挙します。

- メリット
    - マウントコマンドが簡単
        - `sudo mount -t efs <ファイルシステムID>:/ <マウント対象ディレクトリ>`だけでOK
    - 転送時のデータ暗号化が簡単
        - ただし、**amazon-efs-utilsを使わなくても暗号化は可能**
    - マウントヘルパー、stunnelプロセスのログ取得が可能
- デメリット
    - Amazon Linux以外のLinuxディストリビューションで利用する場合、パッケージの導入が少しめんどくさい
        - Gitからクローンのうえ、ビルドおよびインストールが必要

こんなところでしょうか。
というわけで、「パッケージの導入が制限されている」などといった特別な理由がない限り、**マウントヘルパーは使ったほうがよいです**。

[公式ドキュメント](https://docs.aws.amazon.com/ja_jp/efs/latest/ug/using-amazon-efs-utils.html#overview-amazon-efs-utils)も以下のように言っています。
> Amazon EFS ファイルシステムをマウントするために、amazon-efs-utils に含まれているマウントヘルパーを使用することをお勧めします。

が、もちろん従来通りNFSクライアントを使ったマウントも可能です。
両者のマウント方法については、それぞれ以下をご確認ください。

[EFS マウントヘルパーを使用してマウントする](https://docs.aws.amazon.com/ja_jp/efs/latest/ug/mounting-fs.html#mounting-fs-mount-helper)
[EFS マウントヘルパーを使用せずにファイルシステムをマウントする](https://docs.aws.amazon.com/ja_jp/efs/latest/ug/mounting-fs-old.html)

**NFSクライアントを使ったマウントについて追記です。マウント時に推奨されるオプションとして、以前(少なくとも2018年7月ごろ)はなかった'noresvportオプション'が追加されています。**
**一昔前にマウントへルパーを使わずにEFSをマウントした方は、fstabを見直してみましょう。**
[マウントに関する追加の考慮事項](https://docs.aws.amazon.com/ja_jp/efs/latest/ug/mounting-fs-mount-cmd-general.html)

## データの暗号化って必要？
EFSにおけるデータの暗号化は2種類あります。
「TLSを使用した転送データの暗号化」と「AWS KMSを使用した保存データの暗号化」です。
で、この暗号化が必要かどうかですが、
うーん、**システムのセキュリティ要件等々を考慮の上、必要であれば対応する**、だと思います。

・・・そりゃそうだろ！って感じですよね、すいません。

### 転送データの暗号化を行う上でのTips
本項をこれで終わらせるのもあれなので、ここでは暗号化を実施するうえでのTips的なものをご紹介します。
なお、「保存データの暗号化」はやったことがないので、「転送データの暗号化」についてのみ書いています。

- 設定方法はマウントヘルパーを使う場合と使わない場合で異なる
    - マウントヘルパーを使う場合は[こちら](https://docs.aws.amazon.com/ja_jp/efs/latest/ug/encryption.html#encryption-in-transit)
- マウントヘルパーを使わない場合は[こちら](https://docs.aws.amazon.com/ja_jp/efs/latest/ug/encryption.html#how-encrypt-transit)
- stunnelのアップグレードが必要
    - 手順は[こちら](https://docs.aws.amazon.com/ja_jp/efs/latest/ug/using-amazon-efs-utils.html#upgrading-stunnel)
    - 上記の手順にて、stunnelのバージョンが5.46となっている（2018年11月29日時点）が、**最新のバージョンを指定**する（5.46だとエラーとなった）
- 暗号化にはインターネット接続が必要
    - マウント時に実行されるTLSハンドシェイクにおいて、OCSPにより暗号化に用いる証明書の失効確認を外部のサーバに対して実行するため

## EFSのフェイルオーバーってどうなってるの？
前述のとおり、EFSのマウントターゲットには以下の特徴があります。

- ファイルシステムが作成されたVPC内の各AZにマウントターゲットを持つ
- EC2は同じAZのマウントターゲットに接続する

また、マウントするEFSファイルシステムをefstabにて指定する方法は、私が知る限りで3つあります（ほかにもあったら教えてください）。

- マウントヘルパーを使ってファイルシステムIDを指定する
    - `fs-12345678`
- マウントヘルパーを使わずファイルシステムのDNS名を指定する
    - `file-system-id.efs.aws-region.amazonaws.com`
- マウントヘルパーを使わずマウントターゲットのDNS名を指定する
    - `availability-zone.file-system-id.efs.aws-region.amazonaws.com`

なお、DNS名を使ったマウントについては以下をご確認ください。

[DNS 名を使用して Amazon EC2 にマウントする](https://docs.aws.amazon.com/ja_jp/efs/latest/ug/mounting-fs-mount-cmd-dns-name.html)

ここでひとつ疑問が生じました。
**EFSってAZ間のフェイルオーバーとかやってくれるの？**
**マウントターゲットを明示的に指定しなければ（ファイルシステムIDやファイルシステムのDNS名で指定すれば）できるんじゃないの？**

図にするとこんな感じ。
![efs_failover.png](https://qiita-image-store.s3.amazonaws.com/0/307226/6908aae7-e454-16ca-3f44-406e3a8d853b.png)

こちら、調べてもよくわからなかったのでサポートに問い合わせてみました。
結論としては、**EFSにフェイルオーバー機能はない**、とのことでした。
ファイルシステムをどのような方法でマウントしたかに関わらず、EFSには、いずれかのAZで障害が発生した際に自動的に別AZに切り替わりフェイルオーバーされる、もしくはマウントが解除されるといった機能はないようです。

うーん、残念。

## EFSのバックアップってどうなってるの？
これまでEFSのバックアップ機能は提供されていませんでしたが、**2019年1月リリースのAWS Backupというサービスにて、EFSのバックアップ取得が可能になりました！！！**
詳細については、以下をご確認ください。
[AWS Backup でお手軽に EFS バックアップを取得する](https://dev.classmethod.jp/cloud/aws/efs-aws-backup/)

**クロスリージョンバックアップについて追記です。2020年1月のアップデートにて、AWS Backupを使ったEFSのクロスリージョンバックアップが可能になりました！**
**災対に困っていた人には朗報ですね！**
[AWS Backup はクロスリージョンバックアップをサポート](https://aws.amazon.com/jp/about-aws/whats-new/2020/01/aws-backup-supports-cross-region-backup/)

### リストア
バックアップを取得すると、当然リストアも気になるかと思います。
現在AWS Backupが提供しているリストア方式は、以下の3つになります。

- ファイルシステム単位
- フォルダ単位**←New!!**
- ファイル単位**←New!!**

**フォルダ、ファイル単位のリストアは2020年1月にリリースされた機能です。**
[AWS Backup は、Amazon Elastic File System (EFS) のアイテムレベルのリカバリの高速復元エクスペリエンスを提供](https://aws.amazon.com/jp/about-aws/whats-new/2020/01/aws-backup-delivers-fast-restore-experience-amazon-efs-item-level-recovery/)

これによって、EFSの実用性がさらに増した気がします（特定のファイルのためにファイルシステムごと戻すのって正直つらいので…）。

一方で、本機能はまだまだ発展途上のようで、、、以下にイケてない点を挙げます。

- リストアするファイル名やフォルダ名を入力しなければならない（リストア元のディレクトリ構成を把握しておく必要がある）
- 元のディレクトリには復元されず、リストア用ディレクトリが作成され、そこに復元される

実際のリストアイメージは以下をご確認ください。
[[アップデート]AWS Backupを使ってEFSのファイル/フォルダレベルでリストアができるようになりました](https://dev.classmethod.jp/articles/efs_itemlevel_recovery/)

## EFSってアクセス制御できるの？
EFSへのアクセス制御ですが、以前はマウントポイントに設定するセキュリティグループを使うことで、CIDRやセキュリティグループ単位での制御は実現できました。
しかし、**2020年1月に以下の機能が追加されました！**
[New for Amazon EFS – IAM Authorization and Access Points](https://aws.amazon.com/jp/blogs/aws/new-for-amazon-efs-iam-authorization-and-access-points/)

機能の概要はこちら。

- NFSクライアントのIAM認証と承認
    - クライアントを識別し、IAMポリシーを使用したクライアント固有のアクセス制限
    - **IAM認証機能を使うにはamazon-efs-utilsが必要**
- EFSアクセスポイント
    - OSユーザーとグループの使用を強制し、オプションでファイルシステムのディレクトリへのアクセスを制限
    - **OSユーザーとグループの指定は名前ではなくID**

設定方法などについては、例のごとくクラメソさんの以下ブログをご確認ください。
[[アップデート] Amazon EFSでIAM認証とアクセスポイントの設定が可能に](https://dev.classmethod.jp/articles/update-for-amazon-efs-iam-authorization-and-access-points/)

実際に触ったりできてないのですが、こんな感じで使い分けたり併用することで、柔軟なアクセス制御を実現できそうです。
**※厳密には、セキュリティグループの使用は必須です。そのうえでIAM認証やアクセスポイントも使う必要があるか検討しましょう**

|方式|実現したいこと(例)|
|:-:|:-:|
|セキュリティグループ|特定のインスタンスやサブネットからのみアクセス許可したい|
|IAM認証|あるインスタンスのみ書き込み許可、その他のインスタンスからは読み取りのみ許可したい|
|アクセスポイント|EFS上のディレクトリへのアクセス権を、OSユーザーやグループ単位で制御したい|


---

# まとめ
- マウントターゲットの配置
    - 基本的にはマウントターゲットとEC2を同一サブネット上に配置する（**公式がそう言ってる**）
- パフォーマンスモード、スループットモード
    - 特別な使い方でないなら、パフォーマンスモードは汎用、スループットモードはバースト（**公式がそう言ってる**）
    - ただし、モードの変更可否や料金体系に注意
    - バーストを使うときはBurstCreditBalanceを監視
- EFSのマウント方法
    - 特別な理由がない限り、マウントヘルパーを使う（**公式がそう言ってる**）
    - もちろんNFSクライアントを使ったマウントも可能
- データの暗号化
    - 「転送データの暗号化」と「保存データの暗号化」の2種類
    - システムのセキュリティ要件等々を考慮の上、必要であれば対応
- EFSのフェイルオーバー
    - AZ障害時に別AZのマウントターゲットへ切り替わるような機能は存在しない
    - AZ障害時にマウントが解除されることもない
- EFSのバックアップ
    - クロスリージョン対応のAWS Backupを使おう**←New!!**
    - フォルダ・アイテム単位でのリストアが可能**←New!!**
- EFSのアクセス制御
    - 必要に応じてIAM認証やアクセスポイントを使おう**←New!!**