Redshiftクラスターをリストアするシェルファイルを作ってみる

2020.12.09

こんにちは。複数のRedshiftクラスター(本番・検証)環境を運用していると、「検証環境のクラスターを本番環境の最新スナップショットで更新する」作業が定期的に発生します。コンソール画面からの設定は可能ですが設定する内容が多いので時間がかかってしまいます。調べてみると、CLIコマンドを使用してリストアする方法がありましたので実装した内容についてまとめます。

作業手順

作業の流れてしてはこちらの手順で行います。

  1. リストア時に必要なコマンド
  2. クラスター設定値を取得
  3. リストアするシェルスクリプトを作成
  4. リストアを実施

1. リストア時に必要なコマンド

クラスターをリストアする際はredshift restore-from-cluster-snapshotコマンドを使用します。helpを使用して実行時に指定するパラメータについて確認してみます。

$ aws redshift restore-from-cluster-snapshot help
...
SYNOPSIS
            restore-from-cluster-snapshot
          --cluster-identifier <value>
          --snapshot-identifier <value>
          [--snapshot-cluster-identifier <value>]
          [--port <value>]
          [--availability-zone <value>]
          [--allow-version-upgrade | --no-allow-version-upgrade]
          [--cluster-subnet-group-name <value>]
          [--publicly-accessible | --no-publicly-accessible]
          [--owner-account <value>]
          [--hsm-client-certificate-identifier <value>]
          [--hsm-configuration-identifier <value>]
          [--elastic-ip <value>]
          [--cluster-parameter-group-name <value>]
          [--cluster-security-groups <value>]
          [--vpc-security-group-ids <value>]
          [--preferred-maintenance-window <value>]
          [--automated-snapshot-retention-period <value>]
          [--manual-snapshot-retention-period <value>]
          [--kms-key-id <value>]
          [--node-type <value>]
          [--enhanced-vpc-routing | --no-enhanced-vpc-routing]
          [--additional-info <value>]
          [--iam-roles <value>]
          [--maintenance-track-name <value>]
          [--snapshot-schedule-identifier <value>]
          [--number-of-nodes <value>]
          [--cli-input-json | --cli-input-yaml]
          [--generate-cli-skeleton <value>]
          [--cli-auto-prompt <value>]
...
       --availability-zone (string)
          The Amazon EC2 Availability Zone in which to restore the cluster.

          Default: A random, system-chosen Availability Zone.

          Example: us-east-2a

リストア実行時には、作成するクラスター名と取得元となるスナップショットの2つを指定することでできそうです。 しかし、パラメータ値を指定しない場合はデフォルト値が適用されてしまいます。リストア後も同一の設定で使用したいので設定が必要な項目についてリストア対象のクラスター設定値を確認します。

2. クラスター設定値を取得

クラスターの設定値を確認するにはredshift describe-clustersコマンドを使用します。

$ aws redshift describe-clusters --cluster-identifier リストア対象クラスター名
{
    "Clusters": [
        {
            "ClusterIdentifier": "リストア対象クラスター名",
            "NodeType": "dc2.large",
            "ClusterStatus": "available",
            "ClusterAvailabilityStatus": "Available",
            "MasterUsername": "root",
            "DBName": "dev",
            "Endpoint": {
                "Address": "*******.redshift.amazonaws.com",
                "Port": 5439
            },
            "ClusterCreateTime": "2020-12-02T00:06:20.341000+00:00",
            "AutomatedSnapshotRetentionPeriod": 1,
            "ManualSnapshotRetentionPeriod": -1,
            "ClusterSecurityGroups": [],
            "VpcSecurityGroups": [
                {
                    "VpcSecurityGroupId": "sg-****************",
                    "Status": "active"
                }
            ],
            "ClusterParameterGroups": [
                {
                    "ParameterGroupName": "*****-redshift-stack-redshiftclusterparametergroup-***",
                    "ParameterApplyStatus": "in-sync"
                }
            ],
            "ClusterSubnetGroupName": "*****-redshift-stack-redshiftclustersubnetgroup-***",
            "VpcId": "vpc-****************",
            "AvailabilityZone": "ap-northeast-1a",
            "PreferredMaintenanceWindow": "sun:00:00-sun:00:30",
            "PendingModifiedValues": {},
            "ClusterVersion": "1.0",
            "AllowVersionUpgrade": true,
            "NumberOfNodes": 1,
            "PubliclyAccessible": true,
            "Encrypted": false,
            "RestoreStatus": {
                "Status": "completed",
                "CurrentRestoreRateInMegaBytesPerSecond": 0.0,
                "SnapshotSizeInMegaBytes": 0,
                "ProgressInMegaBytes": 0,
                "ElapsedTimeInSeconds": 17,
                "EstimatedTimeToCompletionInSeconds": 0
            },
            "ClusterPublicKey": "***",
            "ClusterNodes": [
                {
                    "NodeRole": "SHARED",
                    "PrivateIPAddress": "**.***.**.*",
                    "PublicIPAddress": "**.***.**.*"
                }
            ],
            "ClusterRevisionNumber": "21556",
            "Tags": [],
            "EnhancedVpcRouting": false,
            "IamRoles": [],
            "MaintenanceTrackName": "current",
            "DeferredMaintenanceWindows": [],
            "NextMaintenanceWindowStartTime": "2020-12-06T00:00:00+00:00"
        }
    ]
}

設定値を表示できました。この出力結果をjsonファイル(parameter.json)として保存します。

3. リストアするシェルスクリプトを作成

リストア時に必要なコマンドと、設定値がわかりましたのでリストアするためのシェルファイル(make_cluster_from_shapshot.sh)を作成します。

ファイルの処理としては以下の3つです。

  1. リストア元のスナップショット名を変数に代入
  2. jsonから必要なパラメータをjqコマンドを使用し取得
  3. パラメーターを指定してリストアを実施

make_cluster_from_shapshot.sh

# スナップショット名
SNAPSHOT_IDENTIFIER="リストア元スナップショット名"

# 設定値json読み込み
file_name="parameter.json"
parameter_json=$(cat ${file_name})
# 設定取得
CLUSTER_IDENTIFIER=`echo ${parameter_json} | jq -r ".Clusters[].ClusterIdentifier"`
NODE_TYPE=`echo ${parameter_json} | jq -r ".Clusters[].NodeType"`
PORT=`echo ${parameter_json} | jq -r ".Clusters[].Endpoint.Port"`
AVAILAVILITY_ZONE=`echo ${parameter_json} | jq -r ".Clusters[].AvailabilityZone"`
CLUSTER_SUBNET_GROUP_NAME=`echo ${parameter_json} | jq -r ".Clusters[].ClusterSubnetGroupName"`
CLUSTER_PARAMETER_GROUP_NAME=`echo ${parameter_json} | jq -r ".Clusters[].ClusterParameterGroups[].ParameterGroupName"`
VPC_SECURITY_GROUP_IDS=`echo ${parameter_json} | jq -r ".Clusters[].VpcSecurityGroups[].VpcSecurityGroupId"`
PREFERRED_MAINTENANCE_WINDOW=`echo ${parameter_json} | jq -r ".Clusters[].PreferredMaintenanceWindow"`
AUTOMATED_SNAPSHOT_RETENTION_PERIOD=`echo ${parameter_json} | jq -r ".Clusters[].AutomatedSnapshotRetentionPeriod"`
NUMBER_OF_NODES=`echo ${parameter_json} | jq -r ".Clusters[].NumberOfNodes"`
IAM_ROLES=`echo ${parameter_json} | jq -r ".Clusters[].IamRoles"`
ALLOW_VERSION_UPGRADE=true
PUBLICLY_ACCESSIBLE=true

# Redshiftリストア実施
aws redshift restore-from-cluster-snapshot \
 --cluster-identifier $CLUSTER_IDENTIFIER \
 --snapshot-identifier $SNAPSHOT_IDENTIFIER \
 --port $PORT \
 --availability-zone $AVAILAVILITY_ZONE \
 --"allow-version-upgrade" \
 --cluster-subnet-group-name $CLUSTER_SUBNET_GROUP_NAME \
 --"publicly-accessible" \
 --cluster-parameter-group-name $CLUSTER_PARAMETER_GROUP_NAME \
 --vpc-security-group-ids $VPC_SECURITY_GROUP_IDS \
 --preferred-maintenance-window $PREFERRED_MAINTENANCE_WINDOW \
 --automated-snapshot-retention-period $AUTOMATED_SNAPSHOT_RETENTION_PERIOD \
 --node-type $NODE_TYPE \
 --iam-roles $IAM_ROLES \
 --number-of-nodes $NUMBER_OF_NODES

4. リストアを実施

リストア実施前に、現状のクラスターを削除します。削除時にスナップショットの作成が行われないように--skip-final-cluster-snapshotを追加して実施します。

$ aws redshift delete-cluster --skip-final-cluster-snapshot --cluster-identifier リストア対象のクラスター名

{
    "Cluster": {
        "ClusterIdentifier": "リストア対象のクラスター名",
        "NodeType": "dc2.large",
        "ClusterStatus": "deleting",
        "ClusterAvailabilityStatus": "Modifying",
        "MasterUsername": "root",
        "DBName": "dev",
...

削除が完了しましたら、先ほど作成したシェルファイルを実行します。

$ bash 201202_restore_redshift.sh 
{
    "Cluster": {
        "ClusterIdentifier": "クラスター名",
        "NodeType": "dc2.large",
        "ClusterStatus": "creating",
        "ClusterAvailabilityStatus": "Modifying",
        "MasterUsername": "root",
        "DBName": "dev",
...

クラスターの作成が開始されました!

まとめ

Redshiftクラスターのリストアを行うシェルファイルを作成しました。リストアは定期的に必要になるのでシェルファイルとしてまとめることができたので良かったです。同じような問題点を抱えている方の助けになれば幸いです。

参考URL