[EB] Elastic Beanstalk Deep Tips Vol.1 Encrypt Volume for Docker Container Image

2018.02.27

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

はじめに

社内ではElastic Beanstalkの人という謎の認知をされている小室です。

現在関わっているプロジェクトでは、分間数万アクセス程のシステムをEB Dockerを利用してSpringBootアプリケーションを稼働させ日々運用しています。このシリーズではElastic Beanstalkアプリケーションを本格的なエンタープライズ要件を満たすために、様々なDeepなTipsを公開していきます。これらの手順については2018/02/27現在のものであり、今後のサービスのアップデートによっては大幅に改善される可能性もあるのでご留意ください。しかし現時点ではこのTipsを使うことでEBが標準でサポートしていない様々な要件に対応する唯一の方法です。EBを深く使う場合はこちらを参照ください。

Encrypt Volumes (Docker on EB)

EBはインスタンスを立ち上げ、そのインスタンス内部でアプリケーションを実行します。そのため立ち上げたインスタンスのRoot DeviceにはEBS Volumeがアタッチされています。当然これらは暗号化されていません。

またEB Dockerの場合はRoot Device以外にContainer Imageを保存するためのもう一つVolumeが追加されています。このVolumeはRoot DeviceにアタッチされているVolumeとはまた別物です。さて、これらすべてにEBS Encryptionを実施する際にはどうすればよいでしょうか?EBのコンソールやAPIにはそのような設定項目は存在しません。エンタープライズ向けシステムでは、Volumeの暗号化などを要件として求められることがあります。この要件にEBで対応するためには以下のような作業が必要です(2018/02/25現在)

イメージ

Root DeviceのEBS Volumeは暗号化カスタムAMIを使う

AWSが提供しているEB用のAMIは当然ながら特に暗号化などされていません。Root Deviceを暗号化するためには少々面倒な手順が必要になります。AMIを暗号化したものを カスタムAMI として設定することでRoot Deviceの暗号化は可能です。手順は以下になります。

  1. AMIのPublicイメージで aws-elasticbeanstalk.*docker で検索する
  2. AMIをコピーする。コピーの際に暗号化オプションにチェックを入れKMSのキーを指定し暗号化を実施する *1
  3. これでようやく暗号化したAMI(正確には暗号化したsnapshotを持ったAMI)が作成される

上記手順を通り最終的に作成したAMIをEBのカスタムAMIへ指定することでRoot Deviceの暗号化が完了します。暗号化AMIの作成については何度か過去エントリーに記載していますのでこちらも合わせて御覧ください。

[いつの間に?] Amazon提供のAMIを自分のアカウントへ直接コピーできるようになっていた

EBのカスタムAMIを指定してのEBS Volumeの暗号化手順についてはこちらに記載しました。

[入門] AMIのコピーでエラーが出たら [EBS Encryption]

Container Image VolumeにアタッチされているEBSは空の暗号化済みSnapshotを使う

上記手順ではRoot Deviceの暗号化のみです。Dockerプラットフォームを選択することで新たに追加されているContainer Image保存用のVolumeは暗号化されません。どうすればよいでしょうか?

こちらはEBの環境設定にオプション設定値を上書きする必要があります。

まずは暗号化済みのEBS Snapshotを作成しましょう。Amazon EBS ボリュームの作成 このあたりを参考にして暗号化ボリュームを作成します。以下の手順です。

  1. 単独のEBS Volumeを作成する
  2. 作成オプションで暗号化を有効にして、KMSのキーを設定し作成を完了させる
  3. 作成したVolumeのSnapshotを作成する
  4. 暗号化Snapshotを指定して設定値を書き換える

暗号化EBS Volumeを作成する

EC2サービスから Elastic Block Store以下にある Volumes メニューを選択します。 Create Volume をクリックします。

このVolumeは暗号化してほしいので Encrypt this Volume にチェックを入れ暗号化に必要なKMSのキーを選択します。EB Dockerのために使いたいので念のためタグには以下のように記載しておきましょう。

Volumeからスナップショットを作成する

最終的に必要なのは暗号化されたEBS Snapshotです。先程作成したVolumeからスナップショットを作成します。

これで準備が出来ました。

作成したSnapshotを利用してEBの設定値を書き換える

その後、作成した暗号化VolumeのSnapshotを作成します。このSnapshotを利用することでContainer Image保存用Volumeの暗号化を行うことができます。

上記手順で暗号化したSnapshotを作成したら以下のJsonを作成しましょう。 ApplicationName, EnvironmentName はそれぞれ状況に応じて書き換えてください。

{
"ApplicationName": "EB-Sample-App",
"EnvironmentName": "ebdocker-sample-blue",
"OptionSettings": [
{ "Namespace" : "aws:autoscaling:launchconfiguration", "OptionName" : "BlockDeviceMappings", "Value" : "/dev/xvdcz=snap-08cb893054b94e645:12:true:gp2" }
]
}

以下のコマンドを実行すると環境の更新が開始されます。この修正はインスタンスの入れ替えが発生するのでご注意ください。この設定変更はコンソール上には存在しないため、このAPI経由でしか更新できないようです。

$ aws elasticbeanstalk --profile update-environment --cli-input-json file://update-eb-docker-volume.json
{
"EnvironmentName": "ebdocker-sample-blue",
"EnvironmentId": "e-xxxxxxxxx",
"ApplicationName": "EB-Sample-App",
"VersionLabel": "Sample Application",
"SolutionStackName": "64bit Amazon Linux 2017.09 v2.8.4 running Docker 17.09.1-ce",
"PlatformArn": "arn:aws:elasticbeanstalk:us-east-1::platform/Docker running on 64bit Amazon Linux/2.8.4",
"EndpointURL": "awseb-e-h-AWSEBLoa-aaaaaaaaaaa-xxxxxx.us-east-1.elb.amazonaws.com",
"CNAME": "ebdocker-sample-blue.us-east-1.elasticbeanstalk.com",
"DateCreated": "2018-02-26T09:38:39.085Z",
"DateUpdated": "2018-02-27T09:11:55.546Z",
"Status": "Updating",
"AbortableOperationInProgress": true,
"Health": "Grey",
"Tier": {
"Name": "WebServer",
"Type": "Standard",
"Version": "1.0"
},
"EnvironmentArn": "arn:aws:elasticbeanstalk:us-east-1:xxxxxxxxxxxx:environment/EB-Sample-App/ebdocker-sample-blue"
}

すべての更新が完了すればEBでは以下のように表示されているかと思います。

ではVolumeが暗号化されているかを確認してみます。

暗号化できていました。アタッチしているDeviceも /dev/xvdcz なのでDocker Image Containerの保存用Volumeが指定されています。おめでとうございます。このEB環境で今後立ち上がるEC2インスタンスのEBS Volumeはすべて暗号化された状態になります。

まとめ

EBS Volumeの暗号化はEBにおいては茨の道です。なかなかベストな手順がありません。自分自身この手順にたどり着くまでドキュメントを何度も読み直し、何度も手順を作り直しました。 同じVolumeの暗号化とはいえすべて同じ手順ではありません。どこにアタッチされていて、どのVolumeを使っているか、AMIから作成されるVolumeはどれかなどを見極め、それぞれ必要に応じて設定値や作業を変更する必要があります。願わくばEBのオプション設定一つで暗号化が完了できると良いのですが。

EB管理下のEC2インスタンスのVolume暗号化が必要になった場合は、参照にしていただければ幸いです。

脚注

  1. 超地味ですが、公式AMIを自分のアカウントに簡単にコピーできるようになっていました。以前はコピーが禁止されていてインスタンスをわざわざ立ち上げていた気がするんですが。いつアップデートがあったんでしょうか