RDSリストア完了後に色々やりたいよね
最近家のAlexaの調子が悪い。
今までCDKTFネタばかりだったので、今回はAWSに特化した話題でいきます。
想定読者
- RDSの作成をトリガーとして後続処理を自動化したい人
処理概要
- RDSの作成完了をEventBridgeでキャッチ
- EventBridgeからStep Functionsを実行する
RDSの作成はどのように実施しているか
RDSの管理はCDK For Terraform で管理しており、
RDSのサフィックス名を別ファイルのパラメータとして管理し、変更が入った場合は
再作成するようにしています。
- 処理フロー
- 対象のRDSスナップショットの最新情報取得
IndividualConfig.rdsConfig.sourceDbName
はAuroraCluster名が入ります。
// snapshotAuroraの設定
const snapshotAurora = new aws.dataAwsDbClusterSnapshot.DataAwsDbClusterSnapshot(this, "snapshotAurora", {
dbClusterIdentifier: IndividualConfig.rdsConfig.sourceDbName,
mostRecent: true
});
情報を取得しているスナップショットですが、日次で取得しており、内容が変わるため
lifecycle
の ignoreChanges
で snapshot_identifier
を無視しています。
- AuroraClusterの作成コードサンプル
const auroraClusterName = `${config.projectName}-${process.env.ENV_ID}-cluster${IndividualConfig.rdsConfig.suffix}`;
const AuroraCluster = new aws.rdsCluster.RdsCluster(this, `auroracluster${IndividualConfig.rdsConfig.suffix}`, {
engine: "aurora-postgresql",
backupRetentionPeriod: 1
skipFinalSnapshot: true,
tags: {
Name: auroraClusterName,
},
engineVersion: IndividualConfig.rdsConfig.engineVersion, // Aurora PostgreSQL 14.9 に固定
snapshotIdentifier: snapshotAurora.dbClusterSnapshotArn, // restore パラメータがtrueであれば最新スナップショットからの復元
clusterIdentifier: auroraClusterName,
databaseName: projectName,
dbClusterParameterGroupName: `${projectName}-${process.env.ENV_ID}-cluster-psql14`,
vpcSecurityGroupIds: [vpcSecurityGroupIds.id],
dbSubnetGroupName: `${projectName}-${process.env.ENV_ID}-subnet`,
applyImmediately: false, // 即時適用
masterUsername: MasterUsername, // ユーザー名
manageMasterUserPassword: ManagePassword, // パスワードを自動生成
deletionProtection: IndividualConfig.rdsConfig.deletionProtection,
enabledCloudwatchLogsExports: IndividualConfig.rdsConfig.enabledCloudwatchLogsExports,
storageType: IndividualConfig.rdsConfig.storageType,
// Snapshotの変更は無視する。
lifecycle: {
createBeforeDestroy: true,
preventDestroy: false,
ignoreChanges: ['snapshot_identifier'],
},
});
IndividualConfig.rdsConfig.suffixの値を変更することで再作成するようにしていますが、
一工夫としてaws.rdsCluster.RdsCluster
のリソース名にも
IndividualConfig.rdsConfig.suffixを含めることで
削除と作成を同時に行うようにし時短を図っています。
含めないと削除が完了してから作成を行うため、接続できない時間が長くなってしまうため。
RDSの作成 をどのようにキャッチしているか
EventBridgeでRDSの作成をキャッチするようにしています。
データベース名の箇所は、AuroraCluster内のインスタンス名が入ります。
{
"detail": {
"EventID": ["RDS-EVENT-0005"],
"SourceIdentifier": ["データベース名"],
"SourceType": ["DB_INSTANCE"]
},
"detail-type": ["RDS DB Instance Event"],
"source": ["aws.rds"]
}
CDKTFで実装しインスタンス名が変わった場合はSourceIdentifier
の値も更新するようにしています。
- 実装例参考
const auroraInstanceNameBase = sample-auroracluster-instance;
const auroraRule = new aws.cloudwatchEventRule.CloudwatchEventRule(this, "rdsEventRule", {
name: `aurora-recreate`,
eventPattern: JSON.stringify({
source: [
"aws.rds"
],
"detail-type": [
"RDS DB Instance Event"
],
detail: {
"SourceIdentifier": [
auroraInstanceNameBase
],
"SourceType": [
"DB_INSTANCE"
],
"EventID": [
"RDS-EVENT-0005"
]
}
}),
});
あとはこのEventBridgeのターゲットにDB作成完了後に実施したい処理を指定するだけなのですが、
問題点がありまして、DBが作成完了しても利用可能な状態になるまで時間がかかるため、
そのまま処理を実行するとエラーが発生してしまいます。
そのためAuroraClusterが実際に利用可能かどうかをチェックする必要がありました。
そのチェック自体はStep Functionsを利用することで実装できました。
Step Functionsでの実装
- サンプルコード
{
"Comment": "A description of my state machine",
"StartAt": "Wait Instance Create",
"States": {
"Wait Instance Create": {
"Type": "Wait",
"Seconds": 60,
"Next": "DescribeDBInstances"
},
"DescribeDBInstances": {
"Type": "Task",
"Parameters": {
"DbInstanceIdentifier.$": "States.Format('sample-{}-instance{}', $.Env, $.UniqId)"
},
"Resource": "arn:aws:states:::aws-sdk:rds:describeDBInstances",
"ResultPath": "$.describeInstanceResult",
"Next": "Create Complete?"
},
"Create Complete?": {
"Type": "Choice",
"Choices": [
{
"Variable": "$.describeInstanceResult.DbInstances[0].DbInstanceStatus",
"StringEquals": "available",
"Next": "ModifyDBCluster"
}
],
"Default": "Wait Instance Create"
},
"ModifyDBCluster": {
"Type": "Task",
"End": true,
"Parameters": {
"DbClusterIdentifier.$": "States.Format('sample-{}-cluster{}', $.Env, $.UniqId)",
"StorageType": "aurora",
"ApplyImmediately": true
},
"Resource": "arn:aws:states:::aws-sdk:rds:modifyDBCluster"
}
}
}
- インプットサンプル
{
"Env": "test",
"UniqId": "suffix"
}
処理内容としては
sample-test-clustersuffix というAuroraClusterが
available
になるまでループします。
available
になったら対象のAuroraClusterのI/O最適化を無効にします。
ちなみにスナップショット元のAuroraClusterのI/O最適化が有効だった場合は
リストア後、I/O最適化が有効になっているので留意です。
今後の改善点
ループ処理回数に制限をかけていないため何十回もループし続けないように
追加実装を検討しています。
あと、一度AuroraClusterがavailable
になったとしても再起動処理されることがあったため
リトライ処理などの追加実装も考えています。
まとめ
色々はまりどころがありましたが、
AuroraClusterの仕様の知識やStep Functionsのスキルが向上したので
いい経験になったと感じています。
Discussion