こんにちは、プラットフォーム技術部の佐藤です。

以前の記事で「AWS CLIでRDSをこまめに止めてコスト削減」という記事を掲載しました。私のプロジェクトでも実践したいと思ったのですが、悲しいことにAWS CLIを定期的に実行できるような常時起動サーバーがありません。

そんなときに、Lambda と CloudWatch を使用してスケジュールされた間隔でインスタンスを起動および停止するという記事を見かけました。これと同じ方法でRDSの停止もおこなえるのではないかと思い、少々乱暴ではありますが「動いているRDSインスタンス一覧を取得して全て止める。」というLambda関数を作ってみようと思いたちました。

ただ、Lambdaで動かすコードを直接書いて動作確認するのはなかなか大変です。いったんローカル環境で開発してAWS環境にアップロードするという方法を試してみました。

実はローカルで開発してみようと思い立ったのはaws-sam-localやpython-lambda-localを知ったことがきっかけだったのですが、今回やろうとすることはAWS CLIで実行する内容を単純にBoto3を使ったPythonコードで作り替えるだけなので、そこまで大掛かりなことは必要ありませんでした。

ですので、aws-sam-localを使ってバリバリ開発できるような方には、物足りない内容かと思います。
AWS CLI代わりの処理をLambda関数で作ってみたいなと思いつつ、普段はIDEなどあまり馴染みのない方へのご参考になればと思います。

開発環境の準備

予め準備済みのもの

ローカルの開発環境としてはWindows 10 Proで、IDEはVisual Studio Codeを使いました。Lambda実行環境にはPython 3.7を採用します。なお、Python実行環境構築にはPipenvを使います。 以下は既にインストール済みでPATHが通っているものとして始めます。

  • Python 3.7.2 X86_64
  • Visual Studio Code

開発用のフォルダーはC:\myProjectを作成して始めます。

Visual Studio CodeにPython拡張をインストール

Python – Visual Studio MarketplaceからPython拡張をインストールします。以下の例では拡張をダウンロードし、コマンドラインでインストールしていますが、Visual Studio Codeの画面操作でもインストール可能です。

Pipenvモジュールのインストール

pipコマンドでPipenvモジュールをインストールします。

Pipenv用環境変数設定

この後作成するPipenv環境は、プロジェクトフォルダーの下に作成したいので、環境変数にPIPENV_VENV_IN_PROJECT=trueを設定しておきます。

Pipenv環境作成

プロジェクトフォルダーにPipenv環境を作成、Python用SDKであるBoto3モジュールをインストールします。ちなみにbotoとは「アマゾンカワイルカ」の英名。洒落たネーミングですよね。

Visual Studio Codeの起動と環境設定

プロジェクトフォルダーでVisual Studio Codeを起動します。

起動すると左ペインにmyProjectが表示されますが、まだPipenv関連のファイルだけが存在している状態になっています。プロジェクトフォルダーの下にLambda関数用のstopDBInstancesフォルダーを作って、更にfunction.pyを新規作成します。
Lambda関数用フォルダーとファイルを新規作成

function.pyを作成するとPythonと認識し「pylintがない」というエラーが表示されます。ここでは追加設定不要なようにpylintを素直にインストールしますが、お好みのLinterをインストールしてください。
Linter未インストールの警告

また、これから作成するコードをローカル実行するにはアクセスキーの設定が必要になりますが、Lambda関数内には記載したくないので環境変数で設定します。Visual Studio Codeでは.envファイルを作成するとそのワークスペースでの環境変数を設定することができます。伏字にしますがこんな感じで(Administrator権限です)。

デバッグしつつ製造開始

まずはDBクラスターの一覧を取得

Boto3のドキュメントでRDSのAPIを眺めてみると、describe_db_instances()でインスタンスの一覧を取得できそうです。インスタンス停止はstop_db_instances()、クラスター停止はstop_db_clusters()といったところでしょうか。

まずは動いているDBクラスターの一覧を取得してみようと以下のコードを用意しました。最後の2行はLambdaとしては不要ですが、ローカルデバッグしやすいように記述しています。

では早速デバッグ実行してみましょう。

経過をみたいのでforループにブレークポイントを設定しています。メニューの[Debug]->[Start Debugging]から開始します。ブレークポイントで停止したら確認しつつF10キーで先に進めます。「順調にdbclustersに追加されていっているなぁ」と眺めていましたが、あらまぁException発生です。
DBClusterIdentifierキーでのException

DBClusterIdentifierというキーでエラーですと出ていますので、左ペインのVariablesでdb構造体を確認してみます。
DBClusterIdentifierキー値の確認
db_describe_instances()ではRDSやAurora関係なく一覧を取得してくるのですが、RDSインスタンスにはDBClusterIdentifier値が存在しないのでエラーになっているようです。

RDSインスタンスはクラスターとは別の方法で止める必要があるので別のリストに積んでいくことにします。DBClusterIdentifier値が取得できない場合はインスタンスと判断して別リストに保存していくようにしてみました。

再びデバッグ実行してみると、これでavailableなステータスになっているDBクラスターとDBインスタンスの一覧が取得できていることがわかります。が、listだと既出のIDが出現してもそのまま追加されて格好悪いことがわかりました。
DBクラスターとインスタンスの一覧

なので、重複を排除してくれるsetに変更します。メソッドもappendからaddに変わってこんなコードになります。

デバッグ実行してVariablesを確認してみると値が重複せず格納できていることが確認できました。
DBクラスターとインスタンスの一覧(重複排除)

クラスター、インスタンスの停止処理を追加

一覧は取得できたので、クラスターはstop_db_cluster()で、インスタンスはstop_db_instance()でそれぞれ停止する処理を追加します。

実行してみて、availableなステータスのインスタンスが停止されれば成功です。
DBクラスターとインスタンスの停止処理実行

AWSにアップロード

動作するLambda関数は出来上がりました。AWSのWebコンソール画面でコピー&ペーストしてもよいのですが、折角ですのでlambda-uploaderを使って登録してみましょう。

lambda-uploaderモジュールのインストール

統合ターミナルからpipenvコマンドでインストールします。

lambda-uploader用設定

stopDBInstancesフォルダーの中にlambda.jsonとして以下にようなファイルを作成します。

roleに定義しているlambda_start_stop_rdsですが、以下のようなインラインポリシーをもったroleを予め作成してあります。今回の関数では厳密にはStart権限までは不要です。またアカウントID部分は適宜修正してください。

アップロード実行

pipenv shellコマンドで環境切り替え後、lambda-uploaderでLambda関数をアップロードします。

AWS管理コンソールで確認すると、無事アップロードされていることが確認できます。
アップロードされたLambda関数

定期実行用のCloudWatchイベントルール作成

今回は毎晩21時に停止処理を実行するCloudWatchのイベントルールを作成しました。
定期実行用CloudWatchイベントルール

これでAWS CLI実行環境もたない人のためのRDSの停止処理が完成です!

今となってはLambdaでシェルも実行できるようになったので「AWS CLI直接実行すればいいじゃん」という声も聞こえそうですが、そこそこ複雑でデバッグ環境が欲しくなるような処理を作る場合には有用な手段かと思います。

今回はVisual Studio Codeですが、EclipseやPyCharm、WingIDE等でも同様のことができると思いますので、何か参考になる部分があれば喜ばしく思います。

 

この記事が気に入ったら
いいね!しよう

最新情報をお届けします

Twitter で「株式会社アークシステム」をフォローしよう!

Visual Studio CodeでRDS停止のLambda関数作ってみるhttps://devlog.arksystems.co.jp/wp-content/uploads/2019/03/assistant-director-behind-the-scene-board-1893526.jpghttps://devlog.arksystems.co.jp/wp-content/uploads/2019/03/assistant-director-behind-the-scene-board-1893526-150x150.jpgksatoプラットフォーム技術部クラウド利用技術開発環境・ツールAWS,Python,Lambda,Amazon RDS,Visual Studio Codeこんにちは、プラットフォーム技術部の佐藤です。 以前の記事で「AWS CLIでRDSをこまめに止めてコスト削減」という記事を掲載しました。私のプロジェクトでも実践したいと思ったのですが、悲しいことにAWS CLIを定期的に実行できるような常時起動サーバーがありません。 そんなときに、Lambda と CloudWatch を使用してスケジュールされた間隔でインスタンスを起動および停止するという記事を見かけました。これと同じ方法でRDSの停止もおこなえるのではないかと思い、少々乱暴ではありますが「動いているRDSインスタンス一覧を取得して全て止める。」というLambda関数を作ってみようと思いたちました。 ただ、Lambdaで動かすコードを直接書いて動作確認するのはなかなか大変です。いったんローカル環境で開発してAWS環境にアップロードするという方法を試してみました。 実はローカルで開発してみようと思い立ったのはaws-sam-localやpython-lambda-localを知ったことがきっかけだったのですが、今回やろうとすることはAWS CLIで実行する内容を単純にBoto3を使ったPythonコードで作り替えるだけなので、そこまで大掛かりなことは必要ありませんでした。 ですので、aws-sam-localを使ってバリバリ開発できるような方には、物足りない内容かと思います。 AWS CLI代わりの処理をLambda関数で作ってみたいなと思いつつ、普段はIDEなどあまり馴染みのない方へのご参考になればと思います。 開発環境の準備 予め準備済みのもの ローカルの開発環境としてはWindows 10 Proで、IDEはVisual Studio Codeを使いました。Lambda実行環境にはPython 3.7を採用します。なお、Python実行環境構築にはPipenvを使います。 以下は既にインストール済みでPATHが通っているものとして始めます。Python 3.7.2 X86_64 Visual Studio Code開発用のフォルダーはC:\myProjectを作成して始めます。Visual Studio CodeにPython拡張をインストール Python - Visual Studio MarketplaceからPython拡張をインストールします。以下の例では拡張をダウンロードし、コマンドラインでインストールしていますが、Visual Studio Codeの画面操作でもインストール可能です。Pipenvモジュールのインストール pipコマンドでPipenvモジュールをインストールします。Pipenv用環境変数設定 この後作成するPipenv環境は、プロジェクトフォルダーの下に作成したいので、環境変数にPIPENV_VENV_IN_PROJECT=trueを設定しておきます。 Pipenv環境作成 プロジェクトフォルダーにPipenv環境を作成、Python用SDKであるBoto3モジュールをインストールします。ちなみにbotoとは「アマゾンカワイルカ」の英名。洒落たネーミングですよね。Visual Studio Codeの起動と環境設定 プロジェクトフォルダーでVisual Studio Codeを起動します。起動すると左ペインにmyProjectが表示されますが、まだPipenv関連のファイルだけが存在している状態になっています。プロジェクトフォルダーの下にLambda関数用のstopDBInstancesフォルダーを作って、更にfunction.pyを新規作成します。function.pyを作成するとPythonと認識し「pylintがない」というエラーが表示されます。ここでは追加設定不要なようにpylintを素直にインストールしますが、お好みのLinterをインストールしてください。また、これから作成するコードをローカル実行するにはアクセスキーの設定が必要になりますが、Lambda関数内には記載したくないので環境変数で設定します。Visual Studio Codeでは.envファイルを作成するとそのワークスペースでの環境変数を設定することができます。伏字にしますがこんな感じで(Administrator権限です)。デバッグしつつ製造開始 まずはDBクラスターの一覧を取得 Boto3のドキュメントでRDSのAPIを眺めてみると、describe_db_instances()でインスタンスの一覧を取得できそうです。インスタンス停止はstop_db_instances()、クラスター停止はstop_db_clusters()といったところでしょうか。 まずは動いているDBクラスターの一覧を取得してみようと以下のコードを用意しました。最後の2行はLambdaとしては不要ですが、ローカルデバッグしやすいように記述しています。では早速デバッグ実行してみましょう。 経過をみたいのでforループにブレークポイントを設定しています。メニューの->から開始します。ブレークポイントで停止したら確認しつつF10キーで先に進めます。「順調にdbclustersに追加されていっているなぁ」と眺めていましたが、あらまぁException発生です。DBClusterIdentifierというキーでエラーですと出ていますので、左ペインのVariablesでdb構造体を確認してみます。db_describe_instances()ではRDSやAurora関係なく一覧を取得してくるのですが、RDSインスタンスにはDBClusterIdentifier値が存在しないのでエラーになっているようです。 RDSインスタンスはクラスターとは別の方法で止める必要があるので別のリストに積んでいくことにします。DBClusterIdentifier値が取得できない場合はインスタンスと判断して別リストに保存していくようにしてみました。再びデバッグ実行してみると、これでavailableなステータスになっているDBクラスターとDBインスタンスの一覧が取得できていることがわかります。が、listだと既出のIDが出現してもそのまま追加されて格好悪いことがわかりました。なので、重複を排除してくれるsetに変更します。メソッドもappendからaddに変わってこんなコードになります。デバッグ実行してVariablesを確認してみると値が重複せず格納できていることが確認できました。クラスター、インスタンスの停止処理を追加 一覧は取得できたので、クラスターはstop_db_cluster()で、インスタンスはstop_db_instance()でそれぞれ停止する処理を追加します。実行してみて、availableなステータスのインスタンスが停止されれば成功です。AWSにアップロード 動作するLambda関数は出来上がりました。AWSのWebコンソール画面でコピー&ペーストしてもよいのですが、折角ですのでlambda-uploaderを使って登録してみましょう。 lambda-uploaderモジュールのインストール 統合ターミナルからpipenvコマンドでインストールします。lambda-uploader用設定 stopDBInstancesフォルダーの中にlambda.jsonとして以下にようなファイルを作成します。roleに定義しているlambda_start_stop_rdsですが、以下のようなインラインポリシーをもったroleを予め作成してあります。今回の関数では厳密にはStart権限までは不要です。またアカウントID部分は適宜修正してください。アップロード実行 pipenv shellコマンドで環境切り替え後、lambda-uploaderでLambda関数をアップロードします。AWS管理コンソールで確認すると、無事アップロードされていることが確認できます。定期実行用のCloudWatchイベントルール作成 今回は毎晩21時に停止処理を実行するCloudWatchのイベントルールを作成しました。これでAWS CLI実行環境もたない人のためのRDSの停止処理が完成です! 今となってはLambdaでシェルも実行できるようになったので「AWS CLI直接実行すればいいじゃん」という声も聞こえそうですが、そこそこ複雑でデバッグ環境が欲しくなるような処理を作る場合には有用な手段かと思います。 今回はVisual Studio Codeですが、EclipseやPyCharm、WingIDE等でも同様のことができると思いますので、何か参考になる部分があれば喜ばしく思います。ARK Solution Development Division Developers Blog.