AWSでは、EC2インスタンスの状態を「AMI(Amazon Machine Image)」として保存できます。AMIを使うと、同じ環境を簡単に再現できるため、システムの複製やバックアップ、別アカウントへの移行に便利です。
例えば、開発環境で作成したEC2インスタンスを別のAWSアカウントに共有し、本番環境で使いたいという場面があります。このとき、AMIを共有することで、他のアカウントでも同じ環境のEC2インスタンスを起動できます。
しかし、AMI 共有には落とし穴があります!
通常のAMI(暗号化なし)は、AWSコンソールやCLIで簡単に共有できます。しかし、EBS(Elastic Block Store)をKMS(Key Management Service)で暗号化している場合、追加の設定が必要になるのです。
今回の記事では、KMSで暗号化されたボリュームを持つEC2のAMIを他アカウントで共有し、起動する手順を紹介します。手順を紹介と書きましたが、あえてエラーを起こして問題を解決しながら、最終的に起動する記事になっています。
共有AMIで起動してみた
Amazon マシンイメージ(AMI)は、AmazonEC2インスタンスをセットアップして起動するために必要なソフトウェアを提供するイメージです。AWSでは、他のアカウントでAMIを利用できるための仕組み"共有AMI"があります。
しかし、以下の点に注意が必要です。
-
条件次第でAMIを共有するだけでは不十分!
AMIはEBS スナップショットを参照しており、スナップショットも共有しないとEC2の起動に失敗します。 -
KMS キーポリシーの変更が必要!
暗号化されたEBSはKMSキーを使用しており、他のアカウントが復号(kms:Decrypt
)できるようにKMSキーポリシーを変更する必要があります。
この記事では、上記の失敗を経験しながら手順を紹介していきます。
手順
KMSで暗号化されたボリュームを持つEC2のAMIを他アカウントで共有し、起動する手順を実施していきます。
イメージは以下の通りです。
■前提
今回の手順の前提は以下の通りです。
- 共有元のAWSアカウントと共有先AWSアカウントがあること
- 共有元アカウントでAMIの元となる暗号化済みEC2インスタンスを用意すること
■AMI の作成と共有
共有元のAWSアカウントでAMIを作成し、共有設定をします。
■AMI を作成
EC2インスタンスの画面でAMIを作成するインスタンスを選択し、暗号化されていることを確認します。
↓
↓画面右上の[ アクション ]⇒[ イメージとテンプレート ]⇒[ イメージを作成 ]の順でクリックします。
↓イメージ名を入力し、他の設定はそのままで、[ イメージを作成 ]をクリックします。
↓
↓ステータスが[ 利用可能 ]になればOKです。
念のため、暗号化も確認しておきましょう。[ 暗号化済み ]が[ はい ]となっていて、KMSキーIDが暗号化設定時のキーと合っていれば問題ないです。
AMI作成は以上です。
■AMI の共有
つづいて、AMIの共有を行っていきます。
↓さきほどの作成したAMIを選択し、[ アクション ]から[ AMI許可を編集 ]をクリックします。
↓[ 共有アカウント ]の[ アカウントIDを追加 ]をクリックします。
↓共有先のAWSアカウントIDを入力し、[ AMIを共有 ]をクリックします。
↓入力したIDが追加されましたら、[ 変更を保存 ]をクリックします。
↓"正常に更新されました"と出ましたでしょうか。
AMIの共有は以上です。
■共有AMIでインスタンスを起動(失敗)
共有先アカウントで共有AMIが利用できるか確認し、インスタンスを起動してみましょう。
■共有 AMI で起動 ⇒ 失敗
↓共有先アカウントでEC2ダッシュボード画面から[ AMI ]をクリックし、フィルタリングを[ プライベートイメージ ]に変更してください。
さきほど共有設定をしたAMIが表示されるかと思います。表示されれば、ひとまず共有設定は成功です。
↓続いて、[ AMIからインスタンスを起動 ]をクリックします。
↓通常のEC2インスタンス起動画面が表示されますので、任意の設定値を入力し、起動しましょう。
↓
↓今回は共有先でもKMSキーを使って、暗号化します。
↓入力が完了しましたら、[ インスタンスを起動 ]をクリックします。
↓"起動を正常に開始されました"と表示されましたね。
↓しかし、インスタンスの画面に行ってみると、"失敗"の文字とともに、インスタンスがシャットダウンしています。これは起動に失敗しましたね。
エラーメッセージを見ると、ボリュームが存在しませんと書かれていますね。AWSのドキュメントを見ると、
AMI を共有するために、AMI の参照先の アマゾン EBS スナップショットを共有する必要はありません。
と書かれていますが、おそらくスナップショットの共有も必要な気がしてきますね。
■スナップショットの共有
ということで、スナップショットも共有してみましょう。
↓共有元アカウントでEC2ダッシュボード画面の[ スナップショット ]をクリックし、共有したAMIと紐づくスナップショットを選択し、[ アカウントIDを追加 ]をクリックします。
↓AMIのときと同様に、共有先アカウントIDを追加し、[ アクセス許可を変更 ]をクリックします。
↓
↓
追加されたのを確認できましたら、共有先アカウントでもスナップショットが共有されたか確認してみましょう。
共有先アカウントでもスナップショットが確認できました。
■共有 AMI でインスタンスを起動(再挑戦 ⇒ 失敗)
スナップショットが共有されたので、2度目の起動にチャレンジしてみましょう。
■再度共有 AMI で起動 ⇒ 失敗
一度目と同じく、共有されたAMIを選択し、[ AMIからインスタンスを起動 ]をクリックし、起動してください。
↓
↓"起動を正常に開始されました"と表示されましたね。
↓しかし、インスタンスの状態が"終了済み"と表示されています。
今度はスナップショットのエラーは出ていないですが、起動に失敗したようです。そして、エラーメッセージが出ないので、手がかりを探す必要が出てきました。
■CloudTrail でエラーを確認
↓とりあえずCloudTrailのイベントを確認してみましょう。
↓インスタンス起動時のイベントであるRunInstanceを見てみましたが、手掛かりはなかったため、KMSのイベントを見てみます。
↓
↓ReEncryptというイベントでエラーコードが出ていて、"AccessDeny"とありますね。
AWSドキュメントを見てみると、
暗号化されたスナップショットを共有する場合は、スナップショットの暗号化に使用されたカスタマー管理キーも共有する必要があります。
とあるので、共有元で暗号化した際に利用したKMSキーに、共有先アカウントがアクセスできるようにしなければいけないようですね。
■KMS キーポリシーを変更
KMSキーのポリシーを変更していきましょう。
■共有元アカウントでKMSキーポリシーを変更
↓共有元アカウントでKMSのダッシュボード画面にいき、該当のキーのキーポリシーを確認してみます。
現在のキーポリシーはデフォルトのままです。
{
"Version": "2012-10-17",
"Id": "key-consolepolicy-3",
"Statement": [
{
"Sid": "Enable IAM User Permissions",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::538815528650:root"
},
"Action": "kms:*",
"Resource": "*"
}
]
}
このキーポリシーを編集します。AWSのドキュメントに参考のポリシーがありますので、現在のキーポリシーと組み合わせてみました。
アカウントID部分は修正して利用してください。
{
"Id": "key-consolepolicy-3",
"Version": "2012-10-17",
"Statement": [
{
"Sid": "Enable IAM User Permissions",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::<共有元アカウントID>:root"
},
"Action": "kms:*",
"Resource": "*"
},
{
"Sid": "Allow use of the key",
"Effect": "Allow",
"Principal": {"AWS": [
"arn:aws:iam::<共有先アカウントID>:root"
]},
"Action": [
"kms:Encrypt",
"kms:Decrypt",
"kms:ReEncrypt*",
"kms:GenerateDataKey*",
"kms:DescribeKey"
],
"Resource": "*"
},
{
"Sid": "Allow attachment of persistent resources",
"Effect": "Allow",
"Principal": {"AWS": [
"arn:aws:iam::<共有先アカウントID>:root"
]},
"Action": [
"kms:CreateGrant",
"kms:ListGrants",
"kms:RevokeGrant"
],
"Resource": "*",
"Condition": {"Bool": {"kms:GrantIsForAWSResource": true}}
}
]
}
↓上記のポリシーを、キーポリシーに貼り付けて保存しましょう。
↓
↓
■ついに成功!共有 AMI からインスタンス起動
キーポリシーが修正できましたので、再度起動してみましょう。
■三度目の正直、AMI からインスタンス起動
共有先アカウントのAMIの画面で、[ AMIからインスタンスを起動 ]をクリックし、必要な設定を入力し、起動してみてください。
↓
↓おなじみの[ 起動を正常に開始されました ]が表示されましたね。
↓インスタンスの画面を見てみると、先ほどまでとは違う状態"保留中"が表示されています。
↓少し待つと、"実行中"となりました!
今度こそ、EC2の起動に成功しました!
■SSH で接続し、ファイルを確認
AMIの元となったEC2インスタンスには、テキストファイルを作成してあります。
↓接続確認し、ファイルがあるか見てみましょう。
↓
ファイルの存在確認ができました。
今回のハンズオンは以上です。
まとめ
今回の記事では、KMSで暗号化されたAMIを他のAWS アカウントで起動する方法を紹介しました。単純にAMIを共有するだけではなく、スナップショットの共有やKMSキーポリシーの変更も必要になることがわかりました。
エラーを解決しながら手順を紹介しましたので、必要なポイントをおさらいしておきます。
☆今回のポイント☆
-
AMI共有だけでは不十分!
EBSスナップショットの共有も必須 -
KMS キーの権限設定がカギ!
共有先アカウントに対してアクセス権限がないと復号できず、EC2 起動が失敗する。
参考リンク:特定の AWS アカウントとの AMI の共有、アマゾン EC2 AMI コピーの仕組み、Share the KMS key used to encrypt a shared Amazon EBS snapshot
↓ほかの協栄情報メンバーもAmazon EC2についての記事を公開しています。ぜひ参考にしてみてください。
■Amazon EC2インスタンス(RHEL9)にAWS CLIをインストールする手順(齊藤弘樹)
■RHEL9にCloudWatch Agentをインストールする手順【Amazon EC2】(齊藤弘樹)