redshiftの停止・再起動スクリプトを作ってみた

# redshiftの料金を節約したい
redshiftは大量データを高速で集計できるため、非常に重宝。
が、いかんせんお値段が結構（DC2ノードで2.6万円/月ほど）する。
手っ取り早い削減方法はリザーブドインスタンスの契約だが、1年間～の契約のため
様々な事情でオンデマンド契約にせざるを得ないケースが考えられる。
例）
・1年間も使うっけ？
・3年契約だと7割引だけど、そんなに長期間契約できない！

#停止→再起動のスクリプトを書いてみた
オンデマンドの場合、稼働時間で料金発生するなら、
必要な時だけ稼働させれば良いじゃない！ってことで、
Bashスクリプトを作成。
#スクリプト
```bash

#!/bin/bash


######### 使い方 ###########################################################
#
# 1. 最後のスナップショットからクラスタを復元するとき　$ bash redshift_start start
# 2. クラスタを停止するとき（スナップショットを取得後）$ bash redshift_start stop
# 3. クラスタのステータスを確認するとき             $ bash redshift_start status
#
############################################################################


########## ↓設定パラメーター一覧 ###############################################
#####
###
##
#

##### デフォルトリージョン
export AWS_DEFAULT_REGION=ap-northeast-1

#### Redshiftクラスタ名
REDSHIFT_IDENTIFIER=your_redshift_cluster

#### PORT番号
PORT=5439

#### ゾーン（アベイラビティゾーン）
AZ=ap-northeast-1a

#### クラスターサブネットグループ
REDSHIFT_CLUSTER_SUBNET_GROUP=your-protect-var-redshiftsubnet

#### パラメーターグループ名
REDSHIFT_CLUSTER_PARAMETER_GROUP=your_redshift_cluster

#### セキュリティグループID # セキュリティグループ名で指定する場合は、不要
VPC_SECURITY_GROUP_IDS=sg-xxxxxxxx

#### セキュリティグループ名 # セキュリティグループIDで指定する場合は、不要
CLUSTER_SECURITY_GROUPS=your-sec-redshift

#### 自動スナップショットの保持期間 停止・削除を終えた場合の措置
AUTOMATED_SNAPSHOT_RETENTION_RERIOD=4

#### 手動スナップショットの保持期間
MANUAL_SNAPSHOT_RETENTION_RERIOD=4

#### メンテナンスウィンドウの時間 UTC基準
MAINTENANCE_WINDOW=sat:18:00-sat:18:30

#### RedshiftのIAM_ROLE
IAM_ROLES=arn:aws:iam::xxxxxxxx:role/role-xxxxxxxx

#
##
###
######
########## ↑設定パラメーター一覧 ###############################################


############### 直接記述するパラメーター ##############################
####
#### バージョンUPグレード　: 許可 　　      --allow-version-upgrade
#### パブリックアクセス可能か：いいえ　      --no-publicly-accessible
#### 拡張されたVPCルーティング可能か：いいえ --no-enhanced-vpc-routing
####
#######################################################################


######## ここから関数本体 ############################################
######## 下記では、セキュリティグループID（VPC_SECURITY_GROUP_IDS）で指定しているため、セキュリティグループ名は指定していない

function redshift_status() {
  aws redshift describe-clusters \
    --cluster-identifier ${REDSHIFT_IDENTIFIER} \
    --query "Clusters[].{ClusterIdentifier:ClusterIdentifier,ClusterStatus:ClusterStatus,RestoreStatus:RestoreStatus.Status}" \
    --output table
}
 
case $1 in
  start)
    LAST_REDSHIFT_SNAPSHOT=$(aws redshift describe-cluster-snapshots \
      --snapshot-type manual \
      --query "reverse(sort_by(Snapshots,&SnapshotCreateTime))[?ClusterIdentifier==\`${REDSHIFT_IDENTIFIER}\`]|[0].[SnapshotIdentifier]" \
      --output text)

    aws redshift restore-from-cluster-snapshot \
      --cluster-identifier ${REDSHIFT_IDENTIFIER} \
      --snapshot-identifier ${LAST_REDSHIFT_SNAPSHOT} \
      --port ${PORT} \
      --availability-zone ${AZ} \
      --allow-version-upgrade \
      --cluster-subnet-group-name ${REDSHIFT_CLUSTER_SUBNET_GROUP} \
      --no-publicly-accessible \
      --cluster-parameter-group-name ${REDSHIFT_CLUSTER_PARAMETER_GROUP} \
      --automated-snapshot-retention-period ${AUTOMATED_SNAPSHOT_RETENTION_RERIOD} \
      --manual-snapshot-retention-period ${MANUAL_SNAPSHOT_RETENTION_RERIOD} \
      --vpc-security-group-ids ${VPC_SECURITY_GROUP_IDS} \
      --preferred-maintenance-window ${MAINTENANCE_WINDOW} \
      --no-enhanced-vpc-routing \
      --iam-roles ${IAM_ROLES} 
    redshift_status
    ;;

  stop)
    REDSHIFT_SNAPSHOT_NAME=${REDSHIFT_IDENTIFIER}-$(date +'%Y%m%d-%H%M%S')
    aws redshift delete-cluster \
      --cluster-identifier ${REDSHIFT_IDENTIFIER} \
      --no-skip-final-cluster-snapshot \
      --final-cluster-snapshot-retention-period ${MANUAL_SNAPSHOT_RETENTION_RERIOD} \
      --final-cluster-snapshot-identifier ${REDSHIFT_SNAPSHOT_NAME}
    redshift_status
    ;;

  status)
    redshift_status
    ;;
  *)
    echo "Usage: $0 {start|stop|status}"
    ;;
esac

```

#注意点
- AWS CLIは、最新版を確認するほうがよい
    - 上記スクリプトはVer 1.16.109で作成
    - 参考サイト（AWS CLI Command Refrence）で、オプション内容を確認
    - 場合によってはCLIのUPDATEが必要
- クラスター復元時、マニュアルスナップショットの期限設定オプションが効かない
    - 対象のオプションは、manual-snapshot-retention-period \<value\>
    - valueに-1以外の数値を設定しても、復元後クラスタの手動スナップショット保持期間が-1に
    - AWSに問い合わせたところ、不具合とのこと（2019年2月時点）
    - 現状では、対策は2つ
        - modify-cluster-snapshotを利用して変更
        - delete-clusterのオプションで、最終スナップショットの保持期間を指定<br>※上記スクリプトではこちらを利用


#参考サイト
- AWS CLI Command Refrence
    - [クラスターを確認 describe-clusters](https://docs.aws.amazon.com/cli/latest/reference/redshift/describe-clusters.htmll)
    - [クラスターを削除 delete-cluster](https://docs.aws.amazon.com/cli/latest/reference/redshift/delete-cluster.html)
    - [クラスターを復元 restore-from-cluster-snapshot](https://docs.aws.amazon.com/cli/latest/reference/redshift/restore-from-cluster-snapshot.html)
- DevelopersIO
    - [RDS, Redshiftの起動停止スクリプト(検証環境用)](https://dev.classmethod.jp/cloud/aws/rds-redshift-start-stop/)