AWSの仕様
に記載の通りですね。
これを楽にするためのスクリプトをかきました。
KMSはTerraformで作成している前提になります。
KMSの作成のTerraformコード
- modules/kms_rds_snapshot/main.tf
provider "aws" {
profile = var.delegator_alias
alias = "delegator"
region = "ap-northeast-1"
default_tags {
tags = {
Environment = var.env
Owner = var.owner
BillingGroup = "${var.project}/${var.env}"
IaC = "Terraform"
}
}
}
# 共有先のAWSアカウント情報取得
data "aws_caller_identity" "target" {
provider = aws.delegator
}
# 共有元のAWSアカウント情報取得
data "aws_caller_identity" "current" {}
# 暗号化RDS スナップショット共有のためKMSキーの権限付与
resource "aws_kms_key" "this" {
description = "rds snapshot encryption key"
policy = jsonencode({
Id = "key-consolepolicy-3"
Statement = [
{
"Sid" : "Enable IAM User Permissions",
"Effect" : "Allow",
"Principal" : {
"AWS" : "arn:aws:iam::${data.aws_caller_identity.current.account_id}:root"
},
"Action" : "kms:*",
"Resource" : "*"
},
{
"Sid" : "Allow use of the key",
"Effect" : "Allow",
"Principal" : {
"AWS" : "arn:aws:iam::${data.aws_caller_identity.target.account_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::${data.aws_caller_identity.target.account_id}:root"
},
"Action" : [
"kms:CreateGrant",
"kms:ListGrants",
"kms:RevokeGrant"
],
"Resource" : "*",
"Condition" : {
"Bool" : {
"kms:GrantIsForAWSResource" : "true"
}
}
}
]
Version = "2012-10-17"
})
multi_region = false
key_usage = "ENCRYPT_DECRYPT"
enable_key_rotation = false
customer_master_key_spec = "SYMMETRIC_DEFAULT"
}
resource "aws_kms_alias" "this" {
name = "alias/rds-snapshot-shared/${var.env}-key"
target_key_id = aws_kms_key.this.key_id
}
- modules/kms_rds_snapshot/variables.tf
# Variable
variable "project" {
}
variable "env" {
}
variable "owner" {
}
variable "default_config" {
}
variable "delegator_alias" {
}
- kms_rds_snapshot.tf
module "kms_rds_snapshot" {
source = "../../modules/kms_rds_snapshot"
env = var.env
project = var.project
owner = var.owner
delegator_alias = var.targetprofile
default_config = {}
}
- variables.tf
# Variable
variable "project" {
default = "testproject"
}
variable "env" {
default = "develop"
}
variable "region" {
default = "ap-northeast-1"
}
variable "owner" {
default = "SRE" # 実行者のオーナー情報適宜変更
}
# 作成対象のProfile名
variable "targetprofile" {
default = "sampleawsprofile"
}
- ファイルツリー
参考までに
├── environments
│ ├── developers_init
│ │ ├── README.md
│ │ ├── aws_info.txt
│ │ ├── backend.tf
│ │ ├── data.tf
│ │ ├── kms_rds_snapshot.tf
│ │ ├── main.tf
│ │ └── variables.tf
├── modules
│ ├── kms_rds_snapshot
│ │ ├── main.tf
│ │ └── variables.tf
└── README.md
別AWSアカウントにスナップショットをコピーするスクリプト
- copy_rds_snapshot.sh
#!/bin/bash
# エラーが発生した場合にスクリプトを終了させる
set -e
# ターゲットのDBクラスタ名を設定
_TARGETCLUSTER="コピー元のDBクラスタ名"
# 最新のDBクラスタスナップショットのARNを取得
_SNAPSHOTARN=$(aws rds describe-db-cluster-snapshots \
--db-cluster-identifier "${_TARGETCLUSTER}" \
--query 'sort_by(DBClusterSnapshots,&SnapshotCreateTime)[-1].[DBClusterSnapshotArn]' \
--output text)
# KMSキーのARNを設定
_KMSARN="Terraformで作成したKMSのARNを指定"
# スナップショットのコピーを作成
_TARGETSNAPSHOTID="${_TARGETCLUSTER}$(date +%Y%m%d)snapshot"
aws rds copy-db-cluster-snapshot \
--source-db-cluster-snapshot-identifier "${_SNAPSHOTARN}" \
--target-db-cluster-snapshot-identifier "${_TARGETSNAPSHOTID}" \
--kms-key-id "${_KMSARN}"
if [ $? -ne 0 ]; then
echo "スナップショットのコピー中にエラーが発生しました。"
exit 1
fi
# スナップショットが利用可能になるまで待機
echo "スナップショットのコピーが完了するまで待機中..."
aws rds wait db-cluster-snapshot-available \
--db-cluster-snapshot-identifier "${_TARGETSNAPSHOTID}"
if [ $? -ne 0 ]; then
echo "スナップショットが利用可能になるのを待つ中にエラーが発生しました。"
exit 1
fi
# スナップショットの属性を変更
echo "スナップショットの属性を変更中..."
aws rds modify-db-cluster-snapshot-attribute \
--db-cluster-snapshot-identifier "${_TARGETSNAPSHOTID}" \
--attribute-name restore \
--values-to-add '["コピーしたいAWSアカウントID"]' \
--region ap-northeast-1
if [ $? -ne 0 ]; then
echo "スナップショットの属性変更中にエラーが発生しました。"
exit 1
fi
echo "スナップショットの属性変更が完了しました。"
スクリプト修正
変更対象パラメータを環境に合わせて変更してください。
- コピー元のDBクラスタ名
- Terraformで作成したKMSのARNを指定
- コピーしたいAWSアカウントID
スナップショット作成が完了するまで
時間を要する関係上、それを待つための処理としてwaitを入れています。
実行方法
sh copy_rds_snapshot.sh
まとめ
なぜかAuroraClusterのスナップショットコピーが
Terraformでは実行できないのでスクリプトで実行する方法の紹介でした。
地味に面倒な処理をスクリプト化して実行中は他の作業ができるので
実装して良かったですね。