RDS, Redshiftの起動停止スクリプト(検証環境用)

2015.08.24

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

西澤です。RDS、Redshiftは素晴らしいサービスですが、EC2インスタンスのように停止ができない為、一時的に課金を止める為には削除するより他ありません。ただ、スナップショットを作っておいて、Identifierを変えずにLaunchすれば、同じEndpointで再利用することができます。多くの方もそうされているとは思いますが、これをスクリプト化しておけば、停止/起動とほぼ同様に扱うことが可能ですので、今回はこれをAWS CLIでやってみたいと思います。

RDSの起動停止スクリプト

特にRDSは、AWS Management Consoleからリストアを行う際、Security Groupの指定ができないので、起動するのを待ってから設定変更をする必要があります。AWS CLIを利用すれば、リストア時にSecurity Groupを指定することが可能です。

botocore1.2.7から、RDSスナップショットからのリストア時にVPC Security Groupの指定はできなくなっている為、--vpc-security-group-idsオプションを指定している下記スクリプトは動作しません。VPC Security Groupを変更する場合には、RDSインスタンス起動後に修正する必要があります。

#!/bin/bash
export AWS_DEFAULT_REGION=us-west-2
RDS_IDENTIFIER=rds-instance
RDS_INSTANCE_CLASS=db.t1.micro
AZ=us-west-2a
DB_SUBNET_GROUP=default
STORAGE_TYPE=gp2
VPC_SECURITY_GROUP=sg-xxxxxxxx

function rds_status() {
  aws rds describe-db-instances \
    --db-instance-identifier ${RDS_IDENTIFIER} \
    --query "DBInstances[].{DBInstanceIdentifier:DBInstanceIdentifier,DBInstanceStatus:DBInstanceStatus}" \
    --output table
}

case $1 in
  start)
    LAST_RDS_SNAPSHOT=$(aws rds describe-db-snapshots \
      --query "reverse(sort_by(DBSnapshots,&SnapshotCreateTime))[?DBInstanceIdentifier==\`${RDS_IDENTIFIER}\`]|[0].[DBSnapshotIdentifier]" \
      --output text)
    aws rds restore-db-instance-from-db-snapshot \
      --db-instance-identifier ${RDS_IDENTIFIER} \
      --db-snapshot-identifier ${LAST_RDS_SNAPSHOT} \
      --db-instance-class ${RDS_INSTANCE_CLASS} \
      --availability-zone ${AZ} \
      --db-subnet-group-name ${DB_SUBNET_GROUP} \
      --no-multi-az \
      --no-publicly-accessible \
      --storage-type ${STORAGE_TYPE} \
      --vpc-security-group-ids ${VPC_SECURITY_GROUP}
    rds_status
    ;;
  stop)
    RDS_SNAPSHOT_NAME=${RDS_IDENTIFIER}-$(date +'%Y%m%d-%H%M%S')
    aws rds delete-db-instance \
      --db-instance-identifier ${RDS_IDENTIFIER} \
      --no-skip-final-snapshot \
      --final-db-snapshot-identifier ${RDS_SNAPSHOT_NAME}
    rds_status
    ;;
  status)
    rds_status
    ;;
  *)
    echo "Usage: $0 {start|stop|status}"
    ;;
esac

ポイントは指定したDB Instance Identifierの最新のSnapshotをJMESPATH(--queryオプション)で拾って来るところです。このような指定ができると手作業を減らすことができますね。静的に指定しているオプションやスキップしているオプションもありますので、必ず公式ドキュメントもご確認ください。

Redshiftの起動停止スクリプト

Redshiftもほぼ同じようにスクリプト化することができました。これで検証の度に、環境を再作成する煩わしさから解放され、一度利用した環境を確実に再利用することができますね。ちなみに前のものもそうですが、Credentialは事前に指定されている前提です。

#!/bin/bash
export AWS_DEFAULT_REGION=us-west-2
REDSHIFT_IDENTIFIER=rs-cluster
AZ=us-west-2a
REDSHIFT_CLUSTER_SUBNET_GROUP=default
REDSHIFT_CLUSTER_PARAMETER_GROUP=default.redshift-1.0
VPC_SECURITY_GROUP=sg-xxxxxxxx

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 \
      --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} \
      --availability-zone ${AZ} \
      --cluster-subnet-group-name ${REDSHIFT_CLUSTER_SUBNET_GROUP} \
      --no-publicly-accessible \
      --cluster-parameter-group-name ${REDSHIFT_CLUSTER_PARAMETER_GROUP} \
      --vpc-security-group-ids ${VPC_SECURITY_GROUP}
    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-identifier ${REDSHIFT_SNAPSHOT_NAME}
    redshift_status
    ;;
  status)
    redshift_status
    ;;
  *)
    echo "Usage: $0 {start|stop|status}"
    ;;
esac

こちらも同様に、静的に指定しているオプションやスキップしているオプションがあります。必ず公式ドキュメントをご確認ください。

まとめ

従量課金のクラウドサービスですが、インフラをコード化できるメリットを最大限に生かしたいところです。GUI作業はミスの元になりますので、些細なことでもスクリプトにしておけば、作業効率を上げることができます。今回ご紹介したスクリプトは、エラー処理を含めていませんし、古いスナップショットのハウスキーピングも入れていません。リストアはそれなりに時間がかかりますので、本番環境で自動化を行う場合には、十分な検証が必要になると思いますが、AWSを触れ始めたばかりの方の参考になれば嬉しいです。