Cloud SQLを自動停止および自動起動できるようスケジュール設定する

こんにちは、香田です。

今回はCloud SQLを自動停止および自動起動できるようスケジュール設定する方法について紹介していきます。

スケジュール設定するにあたって、Pub/Sub、Cloud Function、Cloud Schedulerを使用し自動停止、自動起動する流れとなります。

Cloud SQLの作成

はじめに自動停止、自動起動させるCloud SQLを作成していきます。

Cloud Functionよりスケジュール対象としてフィルタリングできるよう、ラベルにschedule-instance=trueと設定します。

gcloud beta sql instances create postgres-12-n2b8a \
--database-version=POSTGRES_12 \
--tier=db-f1-micro \
--region=asia-northeast1 \
--labels=env=dev,schedule-instance=true

Pub/Subの作成

次にCloud Functionのトリガーで利用するPub/Subを作成していきます。

自動停止用のトピックを作成します。

gcloud pubsub topics create stop-sql-database-instance-topic

自動起動用のトピックを作成します。

gcloud pubsub topics create start-sql-database-instance-topic

Cloud Functionの作成

Cloud Functionで利用する実行環境はPython3.9を利用します。事前にPython 開発環境を作成していきます。

作業ディレクトリを作成します。

mkdir work
cd work

venv仮想環境を初期化します。

python -m venv venv
source venv/bin/activate

Cloud Fucntionで利用する為、Google API クライアント ライブラリをインストールします。

pip install google-api-python-client
pip freeze > requirements.txt

下記のコードをコピーし、main.pyという名前で保存します。

import json
import os
import base64
import googleapiclient.discovery

sqladmin = googleapiclient.discovery.build('sqladmin', 'v1beta4')
project = os.getenv('GCP_PROJECT')


def get_data(event):
    if 'data' in event:
        data = json.loads(base64.b64decode(event['data']).decode('utf-8'))
    else:
        raise RuntimeError('No data in event')
    return data


def get_label(data):
    if 'label' in data:
        label = data['label']
    else:
        raise RuntimeError('No label in data')
    return label


def stop_sql_database_instance(event, context):
    print("EVENT", event)
    data = get_data(event)
    label = get_label(data)
    key = label.split('=')[0]
    val = label.split('=')[1]

    instances = sqladmin.instances().list(project=project).execute()
    if 'items' in instances:
        for instance in instances['items']:
            if key in instance['settings']['userLabels']:
                if val == instance['settings']['userLabels'][key]:
                    name = instance['name']
                    activation_policy = 'NEVER'
                    data = {"settings": {"activationPolicy": activation_policy}}
                    sqladmin.instances().patch(
                        project=project,
                        instance=name,
                        body=data).execute()
                    print(
                        'Stop sql database instance name {name}'.format(name=name))


def start_sql_database_instance(event, context):
    print("EVENT", event)
    data = get_data(event)
    label = get_label(data)
    key = label.split('=')[0]
    val = label.split('=')[1]

    instances = sqladmin.instances().list(project=project).execute()
    if 'items' in instances:
        for instance in instances['items']:
            if key in instance['settings']['userLabels']:
                if val == instance['settings']['userLabels'][key]:
                    name = instance['name']
                    activation_policy = 'ALWAYS'
                    data = {"settings": {"activationPolicy": activation_policy}}
                    sqladmin.instances().patch(
                        project=project,
                        instance=name,
                        body=data).execute()
                    print(
                        'Start sql database instance name {name}'.format(name=name))

Cloud Functionのデプロイ

自動停止用のCloud Functionをデプロイします。

gcloud functions deploy stop_sql_database_instance \
--trigger-topic stop-sql-database-instance-topic \
--runtime python39 \
--region asia-northeast1 \
--set-env-vars GCP_PROJECT=$(gcloud config get-value project)

自動起動用のCloud Functionをデプロイします。

gcloud functions deploy start_sql_database_instance \
--trigger-topic start-sql-database-instance-topic \
--runtime python39 \
--region asia-northeast1 \
--set-env-vars GCP_PROJECT=$(gcloud config get-value project)

Cloud Schedulerの作成

Pub/Subを呼び出すためにCloud Scheduler ジョブを作成していきます。

自動停止用のジョブを作成します。下記では19時になったらPub/Subが呼び出されます。

gcloud beta scheduler jobs create pubsub stop-sql-database-instance \
--schedule '00 19 * * *' \
--topic stop-sql-database-instance-topic \
--message-body '{"label":"schedule-instance=true"}' \
--time-zone 'Asia/Tokyo'

自動起動用のジョブを作成します。下記では9時になったらPub/Subが呼び出されます。

gcloud beta scheduler jobs create pubsub start-sql-database-instance \
--schedule '00 09 * * *' \
--topic start-sql-database-instance-topic \
--message-body '{"label":"schedule-instance=true"}' \
--time-zone 'Asia/Tokyo'

Cloud Schedulerの実行

作成したジョブを実行し確認する場合、GCPコンソール画面の[Cloud Scheduler]より[今すぐ実行]にて確認できます。

作成した自動停止ジョブ、自動起動ジョブをそれぞれ実行し問題なければ成功です。

クリーンアップ

アカウントが課金されないよう下記で作成したリソースは削除可能です。

Cloud Schedulerの削除

gcloud beta scheduler jobs delete stop-sql-database-instance
gcloud beta scheduler jobs delete start-sql-database-instance

Cloud Functionの削除

gcloud functions delete stop_sql_database_instance --region asia-northeast1
gcloud functions delete start_sql_database_instance --region asia-northeast1

Pub/Subの削除

gcloud pubsub topics delete stop-sql-database-instance-topic
gcloud pubsub topics delete start-sql-database-instance-topic

Cloud SQLの削除

gcloud beta sql instances delete postgres-12-n2b8a

さいごに

Cloud SQLを自動停止および自動起動できるようスケジュール設定する方法いかがでしたでしょうか。

Cloud SQLを自動停止および自動起動する上で本記事が参考になれば幸いです。

最後までご覧いただきありがとうございます。

SNSでもご購読できます。