AWSの暗号化されたEBSスナップショットを持つAMIを他のアカウントと共有

# 1. はじめに

AWSで、EC2インスタンスのバックアップから、新しいEC2インスタンスをローンチするといったことが良く行われます。このバックアップとなる、[AMI(Amazon Machine Image)](http://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/AMIs.html)は、AWSコンソールでマウスクリックして簡単に作成できます。さらに、このAMIをAWSの他のアカウントで使いたい場合は、AWSコンソールでAWSアカウントIDを許可すれば、簡単に共有できます。

* AMI(Amazon Machine Image)でEC2インスタンスまるごとバックアップ
* AMI(Amazon Machine Image)から、新しいEC2インスタンスをローンチ

ただし、**EC2インスタンスのEBSが暗号化されていて、AMIを別AWSアカウントで共有したい場合**は、やることが一気に増えます。

AWS Blogで、[暗号化されたEBSスナップショットを持つAMIを作成し他のアカウントやリージョンで共有する方法](http://aws.typepad.com/sajp/2016/10/how-to-create-a-custom-ami-with-encrypted-amazon-ebs-snapshots-and-share-it-with.html)が参考になりますが、複雑な手順が必要です。ポイント等について、ご紹介します。

#  2. 前提

* EC2インスタンスのEBSが暗号化されている
* EBS-Backed なインスタンス
* 暗号化の鍵は**デフォルト aws/ebs**が指定されている
* AMIは別アカウントで共有
* ソースアカウント、ターゲットアカウントに適切なIAMユーザ、ロールのポリシー
* リージョンは東京で同一

別リージョンでも可能ですが、今回の例は同一リージョンになります。

# 3. ポイント

暗号化されたスナップショットを含むAMI自体を、そのままターゲットアカウントと共有することはできないので、ソースアカウント側のEBSボリューム単位の暗号化されたプライベートスナップショットを、ターゲットアカウントと共有します。ソースアカウント側の鍵を共有して、ターゲットアカウント側の鍵で再度暗号化したスナップショットからAMIを作成します。

![awsami.png](https://qiita-image-store.s3.amazonaws.com/0/111286/b492a48e-fdc2-2165-6fa5-1fa01d5c3016.png)

暗号化でデフォルトの aws/ebsが指定されている場合、AWS Blogに以下注意点が記述されています。最初は、これに気づかなくて、悩まされました。

※Note: **デフォルトEBS CMKで暗号化されたスナップショットは別のアカウントに共有することはできません。**サービスデフォルトCMKで暗号化されたリソースは同じアカウントでのみ共有できます。デフォルトEBS CMK (キーエリアスはaws/ebs)による暗号化されたスナップショットから始める場合は、**スナップショットをコピーし、KMSで作成したカスタムCMKにて再暗号化してください。**外部のアカウントIDがアクセスできるようにカスタムCMKの鍵ポリシーを変更することが出来ます。

# 4. 手順

## 4.1 事前準備

* ソースアカウント AWSアカウント番号 111111111111
    * 事前にカスタムCMK(鍵#2)を作成しておきます。**この鍵は、ターゲットアカウントの共有を許可します。**
* ターゲットアカウントAWSアカウント番号 999999999999
    * 事前にカスタムCMK(鍵#3)を作成しておきます

暗号鍵の作成は、 5. KMS作成をご参考ください。この手順も、手間がかかります。

## 4.2 ソースアカウントで操作

### ①  AMIの作成 インスタンスの作成⇒イメージの作成

通常の操作と同じです。

### ②  AMIのコピー 鍵 #2

デフォルトEBS CMKで暗号化されたスナップショットは別のアカウントに共有できないので、カスタムCMK(鍵#2)で暗号化します。

![amicopy.png](https://qiita-image-store.s3.amazonaws.com/0/111286/3bcaef44-6b9f-fd9f-36cd-f6f118502053.png)


### ③  プライベートスナップショット アクセス許可

プライベートスナップショットをターゲットアカウント(999999999999)に対してアクセス許可します。

![snapshotaccess.png](https://qiita-image-store.s3.amazonaws.com/0/111286/757acabb-0083-850b-df74-fd0bb8aa2525.png)

## 4.3 ターゲットアカウント

### ④  スナップショットのコピー 鍵 #3

共有されたスナップショットをターゲットアカウントで作成したカスタムCMK(鍵#3)でコピーします。

![snapshotcopy.png](https://qiita-image-store.s3.amazonaws.com/0/111286/5e091a0d-3df6-06d1-8e51-05bf04dd4d81.png)


### ⑤  EBSスナップショットからイメージを作成

EBSスナップショットからAMIを作成します。EBSボリュームがたくさんあると、大変です。

**注意　paravirtualの場合は、カーネルIDを忘れないように引き継いで指定します**

![snaptoimage.png](https://qiita-image-store.s3.amazonaws.com/0/111286/72f89e4b-e5a0-10a9-8c02-0af5a460268e.png)

### ⑥ AMIからインスタンス起動

通常の操作と同じです。

# 5. KMS作成

IAMの項目に、暗号化キーメニューがあります。

## 5.1 暗号化キー

####  リージョンを選択するメニュー

![makekey.png](https://qiita-image-store.s3.amazonaws.com/0/111286/7651152e-43f0-773e-ca93-236b02ca8ffe.png)

#### 暗号化キーの一覧画面

![keylist.png](https://qiita-image-store.s3.amazonaws.com/0/111286/046ea502-7e54-9918-1160-463c700e854f.png)

#### キーマテリアル

* [キーマテリアルのインポート ステップ 3: キーマテリアルを暗号化する](http://docs.aws.amazon.com/ja_jp/kms/latest/developerguide/importing-keys-encrypt-key-material.html)

![keymaterial.png](https://qiita-image-store.s3.amazonaws.com/0/111286/8757a114-87fb-cbbe-c14a-6a57e37aaa5b.png)

## 5.1  パブリックキーおよびインポートトークン

[パブリックキーおよびインポートトークンのダウンロード (AWS マネジメントコンソール)](http://docs.aws.amazon.com/ja_jp/kms/latest/developerguide/importing-keys-get-public-key-and-token.html#importing-keys-get-public-key-and-token-console)

* RSAES_OAEP_SHA_1 を選択
* ラップキーとインポートトークンのダウンロード
	* ファイル名が wrappingKey_CMK_key_ID_timestamp のラップキー (パブリックキー) 
	* ファイル名が importToken_CMK_key_ID_timestamp インポートトークン

## 5.2 キーマテリアルを暗号化

[例: OpenSSL でキーマテリアルを暗号化する](http://docs.aws.amazon.com/ja_jp/kms/latest/developerguide/importing-keys-encrypt-key-material.html#importing-keys-encrypt-key-material-openssl)

* バイナリキーマテリアルを生成し、AWS KMS へのインポート用に暗号化
* コンソールからパブリックキーをダウンロード

たとえば、wrappingKey_f44c4e20-f83c-48f4-adc6-a1ef38829760_0809092909

#### ① 次のコマンドを使用して、256 ビット対称キーを生成し、PlaintextKeyMaterial.bin という名前のファイルに保存します。 

```
$ openssl rand -out PlaintextKeyMaterial.bin 32
```

#### ②パブリックキーをPublicKey.binというファイル名で保存

```
$ cp wrappingKey_f44c4e20-f83c-48f4-adc6-a1ef38829760_0809092909 PublicKey.bin
```

####③ ダウンロードしたパブリックキーでキーマテリアルを暗号化して 「EncryptedKeyMaterial.bin」という名前のファイルに保存し

```
$ openssl rsautl -encrypt \
	-in PlaintextKeyMaterial.bin \
	-oaep \
	-inkey PublicKey.bin \
	-keyform DER \
	-pubin \
	-out EncryptedKeyMaterial.bin
```

#### 外部アカウント

暗号化キーを外部アカウントと共有します。

![outaccount.png](https://qiita-image-store.s3.amazonaws.com/0/111286/cda15873-11a5-502c-ac43-0a7515a9674f.png)

# 6. おわりに

いかがだったでしょうか？EBSが暗号化されてると、アカウント間の共有はとても敷居が高くなります。私も最初実行するにあたって、何のこっちゃと思ったのでみなさんに情報共有させていただきました。お役に立つことがあるのではと思っています。ところで、コード化してルーチン化してる人はいたりするでしょうか...

# 7. 参考

* [Amazon Machine Image AMIとスナップショットの違い](http://aws.typepad.com/sajp/2014/04/trainingfaqbest10.html)
    * スナップショット = 「EBS ボリュームの中のデータ」を特定のタイミングで取得しS3に保存したもの
    * AMI  = 「EBS ボリュームの中のデータ(スナップショット) とインスタンスを構成する管理情報」を含む起動テンプレート
* [暗号化されたスナップショットを持つ AMI](http://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/AMIEncryption.html)