背景

CloudTrail皆さん使われてますか?

今回は複数のAWSアカウント(約16アカウント)でCloudTrailの有効化に伴い、CMKの作成が必要となりました。

コンソールで作るのは流石に大変だし。。ということでAWS CLIを使ってCMKを作成してみました。

今回対象のリージョンは以下の5つ

  • 東京
  • バージニア北部
  • シンガポール
  • フランクフルト
  • 北京

スクリプト

ここからスクリプトの中からポイントの部分に解説を入れていきます。
※スクリプト全体は一番下部に記載しておきます。

aws-vault設定

.sh

#スイッチロールの設定を行う。
export SWICHROLE=$ROLE
echo $SWICHROLE

shopt -s expand_aliases
alias av='aws-vault exec $SWICHROLE --no-session --'

#結果出力先ファイルの設定を行う。
export OUTPUT=./result-kms/create/${SWICHROLE}-kms-result-${NOW}.txt

#アカウントIDの取得を行う。
ACCOUNT=$(av aws sts get-caller-identity | jq -r .Account)

キーポリシーファイル作成

ベースとなるポリシーファイルを用意して、固有情報(アカウントID、リージョン)だけ書き換えを行っています。

.sh

echo -e "\U2705KMSキーポリシー作成"
cp ./base-key-policy.json ./key-policy-${SWICHROLE}.json
sudo sed -i -e "s/ap-northeast-1/${REGION}/" ./key-policy-${SWICHROLE}.json
sudo sed -i -e "s/12345678910/${ACCOUNT}/" ./key-policy-${SWICHROLE}.json

CMK、エイリアスの作成

上記で作成した、キーポリシーを元にCMKの作成とエイリアスの作成を行う。

.sh

#上記で作成したキーポリシーを使用して、CKMの作成を行う。
echo -e "\U2705KMSキー作成"
KEYID=$(av aws kms create-key  --key-usag ENCRYPT_DECRYPT --origin AWS_KMS --policy file://key-policy-${SWICHROLE}.json --region $REGION | jq -r .KeyMetadata.KeyId)
echo -e "\U2705 KEYID:${KEYID}"

#作成したCKMに対して、エイリアスの作成を行う。
echo -e "\U2705エイリアス作成"
av aws kms create-alias --alias-name alias/$KEYNAME --target-key-id $KEYID --region $REGION

作成したCMK、エイリアスの確認

最後に作成したCMKのエイリアスと設定内容を確認する。

.sh

#作成したCKMにエイリアスが作成されて、適切な設定が行われているか確認する。
echo -e "\U2705KMSキー確認"
av aws kms list-aliases --key-id ${KEYID} > $OUTPUT
実行結果

しかしここで失敗する。。

フランクフルトリージョンまで上手くいっていたが、中国で何故かスクリプトが失敗する。。

調べてみるとキーポリシーの作成で以下の様な記述がありました。

key-policy.json

{
  "Version": "2012-10-17",
  "Id": "Key policy created by CloudTrail",
  "Statement": [
    {
      "Sid": "Enable IAM User Permissions",
      "Effect": "Allow",
      "Principal": {
        "AWS": "arn:aws:iam::123456578910:root"
      },
      "Action": "kms:*",
      "Resource": "*"
    },

勘のいい方、馴染のある方はお気づきかもしれません。

そう、AWS中国のARNはarn:awsではなくarn:aws-cnでした。
なので、以下の様な処理を追加する必要がありました。

中国対応コマンド

中国の場合にはARNを置き換える以下の処理を追加することで対応可能です。

.sh

if [ $REGION = "cn-north-1" ]; then
  sudo sed -i -e "s/arn:aws/arn:aws-cn/" ./key-policy-${SWICHROLE}.json
fi

全体

create-kms-key.sh

#!/bin/bash -x
#使い方:bash create-kms-key.sh aws-vaultロール名_リージョン_Key名

#引数の受け取り
target_info=(${1//_/ })
ROLE=${target_info[0]}
REGION=${target_info[1]}
KEYNAME=${target_info[2]}

#現在のタイムスタンプを取得
NOW=$(date +%Y%m%d_%H%M%S_%3N)

#スイッチロールの設定を行う。
export SWICHROLE=$ROLE
echo $SWICHROLE

shopt -s expand_aliases
alias av='aws-vault exec $SWICHROLE --no-session --'

#結果出力先ファイルの設定を行う。
export OUTPUT=./result-kms/create/${SWICHROLE}-kms-result-${NOW}.txt

#アカウントIDの取得を行う。
ACCOUNT=$(av aws sts get-caller-identity | jq -r .Account)

echo "処理開始"

#KMSのキーポリシーの作成を行う。
#base-key-policy.jsonに記載のリージョン及び、アカウントIDの書き換えを行う。
echo -e "\U2705KMSキーポリシー作成"
cp ./base-key-policy.json ./key-policy-${SWICHROLE}.json
sudo sed -i -e "s/ap-northeast-1/${REGION}/" ./key-policy-${SWICHROLE}.json
sudo sed -i -e "s/12345678910/${ACCOUNT}/" ./key-policy-${SWICHROLE}.json

if [ $REGION = "cn-north-1" ]; then
  sudo sed -i -e "s/arn:aws/arn:aws-cn/" ./key-policy-${SWICHROLE}.json
fi

#上記で作成したキーポリシーを使用して、CKMの作成を行う。
echo -e "\U2705KMSキー作成"
KEYID=$(av aws kms create-key  --key-usag ENCRYPT_DECRYPT --origin AWS_KMS --policy file://key-policy-${SWICHROLE}.json --region $REGION | jq -r .KeyMetadata.KeyId)
echo -e "\U2705 KEYID:${KEYID}"

#作成したCKMに対して、エイリアスの作成を行う。
echo -e "\U2705エイリアス作成"
av aws kms create-alias --alias-name alias/$KEYNAME --target-key-id $KEYID --region $REGION

#作成したCKMにエイリアスが作成されて、適切な設定が行われているか確認する。
echo -e "\U2705KMSキー確認"
av aws kms list-aliases --key-id ${KEYID} > $OUTPUT

echo "処理終了"

まとめ

  • シェルスクリプト自体の知識が浅く、エラーハンドリングが甘いので深堀していきたい。
    • 中国など慣れない環境は事前調査大事
  • TerraformやCFnでも同じような、落とし穴があると思いますので注意が必要だったなと思いました。

元記事はこちら

【AWS】AWS CLIでCMKを沢山作ってみたら困ったこと
著者:@kurono


アイレットなら、AWS で稼働するサーバーを対象とした監視・運用・保守における煩わしい作業をすべて一括して対応し、経験豊富なプロフェッショナルが最適なシステム環境を実現いたします。AWS プレミアコンサルティングパートナーであるアイレットに、ぜひお任せください。

AWS 運用・保守サービスページ

その他のサービスについてのお問合せ、お見積り依頼は下記フォームよりお気軽にご相談ください。
https://cloudpack.jp/contact/form/