Redshift クラスタの一時停止機能を定時刻にLambdaから実行する

2020.04.16

こんにちは、データアナリティクス事業本部の下地です。

先月、Redshiftのアップデートでクラスターを一時停止する機能が追加されました!アップデートについて弊社ブログでも取り上げさせてもらってます。

このアップデートにより使用しない時間帯にRedshiftクラスターを一時停止し費用を抑えることが容易になりました(これまでは停止ではなく削除する必要があったためスナップショットを取得し、実行時にスナップショットから立ち上げる必要がありました)。さらに、ユーザーで決めた時間にクラスターを停止・再起動する機能も追加されておりますのでとても便利です。

今回はRedshiftクラスターを運用する際に、基本的には夜間帯は環境を一時停止したいが「不定期で夜間帯に起動し続ける必要がある」場合に対応するために、Redshiftクラスターのタグ情報に基づいてクラスターを停止(または続行)するLambdaの実装を行いCloudWatch Eventsから実行する機能を作成します。

全体像

作成する全体像としては図のような手順になります。

  1. CloudWatch Eventsにより定時刻にLambdaを実行
  2. Redshiftの指定のタグ値を取得
  3. タグ値によって処理(停止、続行)を行う
  4. 処理内容をSNS通知する

作成手順

Redshift, SNS, Lambda, CloudWatch Eventsの設定を行います。

Redshiftタグ値の設定

Redshiftクラスターのタグ値を設定します。今回はstop_flgを分岐に使用するキーとして作成します(特定のタグ値の処理を確認するために別のタグ値も別途作成しています)。

  • stop_flg: true -> Redshiftクラスター停止
  • stop_flg: false -> Redshiftクラスター続行

SNSの設定

プログラム実行後にemail通知を飛ばすようにSNSの設定を行います。

トピックを作成後にプロトコルをEmailに選択したサブスクリプションを設定しました。

Lambdaの設定

今回「python3.6」を使用し作成しました。記述したコードを載せます。

import boto3
import os

REGION         = "使用するregion名"
CLUSTERNAME    = "クラスター名"
sns_arn        = "snsのarn"
KEYNAME        = "取得するタグ値のキーワード"
STOPKeyword    = "環境を停止する文字列"
NOTSTOPKeyword = "環境を継続する文字列"

def lambda_handler(event, context):
    # TODO implement
    client = boto3.client('redshift', region_name = REGION)
    sns_client = boto3.client("sns", region_name = REGION)
    reds = client.describe_clusters(ClusterIdentifier = CLUSTERNAME)
    name_tag = [x['Value'] for x in reds['Clusters'][0]['Tags'] if x['Key'] == KEYNAME]
    
    if name_tag[0] == STOPKeyword:
        response = client.pause_cluster(ClusterIdentifier=CLUSTERNAME)
        request = {"TopicArn": sns_arn,"Subject": "検証環境を停止しました","Message": "検証環境を停止しました"}
    elif name_tag[0] == NOTSTOPKeyword:
        request = {"TopicArn": sns_arn,"Subject": "検証環境は停止してません。","Message": "検証環境は停止してません。"}
    sns_client.publish(**request)

IAM policyの設定

動作に必要なポリシーを作成します。今回、必要なのはredshiftの”詳細の読み取り機能,pause機能"と"SNSのpublish"機能です。この3つの機能について下記のように指定します。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": [
                "redshift:DescribeClusters",
                "redshift:PauseCluster"
            ],
            "Resource": "arn:aws:redshift:[REGION名]:[アカウント番号]:cluster:[CLUSTERNAME名]"
        },
        {
            "Sid": "VisualEditor1",
            "Effect": "Allow",
            "Action": "sns:Publish",
            "Resource": "*"
        }
    ]
}

CloudWatch Eventsの設定

起動時刻と先ほど作成したLambda関数を指定します。

時間の指定はcron方式で毎日12:00に実行するように設定します00 3 * * ? *。cronはUTC時刻になっていますので日本時間に合わせる必要があります(12:00に実行する場合は3:00に設定)。

定時刻前後の推移

CloudWatch Evnetsで設定した時間前後のRedshiftの状態を示します。

イベント発生前

イベント発生後

イベント発生前後で Available -> ModifyingになることとSNSに登録したEmailに停止した内容のメールが飛ぶのを確認しました。

まとめ

Redshiftアップデートで実装された一時停止機能を利用して、クラスターの特定タグ値に基づいて処理(一時停止または起動状態)する実装を行いました。不定期で夜間帯に使用したい場合の運用において対応出来るかなと思います。同じようにRedshiftを使用している方々の運用の助けになれば幸いです。

 

参考URL