Functions(サーバーレス)で時刻をトリガーとしてVSIを自動起動/停止する(VPC Gen1 VSI編)


クラウドの課金を節約する手段として、業務時間外に仮想サーバーを停止しておきたいというニーズはよくあると思います。時刻をトリガーとしてサーバーレスのプログラムを起動し、そのプログラムから仮想サーバーを起動または停止するAPIを発行してやればよさそうです。
IBM CloudにはFunctionsというサーバーレス環境があるので、これを使ってVPC(Gen1)のVSI(IBM Cloudの仮想サーバー)を起動/停止してみます。
作業の流れは次のとおりです。言語はPythonを使用します。

  1. VSIを起動/停止するプログラムの作成
  2. サーバーレス環境にプログラム(アクション)をデプロイ
  3. サービスIDの作成とAPIキーの取得
  4. アクションの動作確認
  5. 時刻トリガーの登録と、アクションとの関連付け
  6. トリガーの動作の確認

1. VSIを起動/停止するプログラムの作成

Functionsのアクションはmain関数で実装することになっています。以下に今回作成したプログラムのmainの部分を掲載します。全体はこちらに置いておきます。
APIキーや起動・停止したいインスタンス名、起動・停止の指示等はパラメータからdictで受け取ることにしてあります。

def main(dict):
    api = dict['api']
    reg = dict['region']
    ver = dict['version']
    vpc = dict['vpc']
    act = dict['action']
    vsi = dict['instance']

    con = http.client.HTTPSConnection(f"{reg}.iaas.cloud.ibm.com")
    hdr = {
        'Content-Type': 'application/json',
        'Cache-Control': 'no-cache',
        'Accept': 'application/json',
        'Authorization': get_token(api),
        'cache-control': 'no-cache'
    }

    res = json.loads(fetch_instances(con, ver, hdr, vpc))
    instances = res['instances']

    res = "NOT FOUND"
    for instance in instances:
        if instance['name'] == vsi:
            id = instance['id']
            res = create_action(con, ver, hdr, id, act)
    return res

REST APIのリファレンスはこちらにあります。
インスタンス一覧の取得はList all instances、インスタンスの起動・停止はCreate an instance actionが参考にます。
現在VPCにはGen1とGen2があり、微妙に異なるので要注意です。今回はGen1の方を対象にしています。

2. サーバーレス環境にプログラム(アクション)をデプロイ

ダッシュボードのGUIで登録する方法、ibmcloud CLIを使う方法等がありますが、ここではダッシュボードのGUIを使用することにします。
Functionsのダッシュボードから「作成の開始」→「アクションの作成」でアクション名を指定し、ランタイムとしてPython 3を選択します。

コードの画面にプログラムを貼り付けて保存します。

パラメーターの画面で、プログラムに渡すパラメータを定義します。

ここでは"us-south"リージョンの"vpc-dal-gen1-takeyan"というVPCに作成した"dal01take01"という名前のVSIを"start"するように設定しています。versionはVPC用REST APIのバージョンで、APIリファレンスのコマンドサンプルを参照して指定しました。
apiではこのVSIを起動・停止する権限を持っているユーザーIDかサービスIDのAPIキーを指定します。次章でサービスIDを作成してAPIキーを取得する方法を整理しておきます。

3. サービスIDの作成とAPIキーの取得

サービスIDはIAMの機能のひとつで、クラウドサービスへのアクセス・ポリシーとAPIキーを紐付けます。このAPIキーでIAMの認証を受けてトークンを取得し、このトークンを伴ってサービスにアクセスすると、アクセス・ポリシーに従ってアクセスが許可または拒否されます。
サービスIDはダッシュボード右上のプルダウンメニューから「管理」→「アクセス(IAM)」を選択してIAMのダッシュボードを開き、画面左側のメニューから「サービスID」を選択して「サービスID」の画面に移動し、そこで「作成」を選択して作成します。

今回は、アクセス・ポリシーとして「リソース・グループ」=すべてのリソース・グループ、「サービス」=VPC Infrastructure、「リソース・タイプ」=Virtual Server for VPC、「プラットフォーム・アクセス」=エディターという条件を選択してサービスIDを作成しました。


サービスIDを作成したら、APIキーを作成します。このAPIキーを前章のapiの値として使用します。

4. アクションの動作確認

アクションの「コード」の画面で「起動」をクリックします。

アクションのコードに登録したPythonプログラムは、mainの中でVSIの起動または停止を要求するREST APIをコールして、その応答を返り値にセットしていました。その返り値が「結果:」のところに表示されています。
Create an instance actionにはREST APIコールの正常応答のサンプルが掲載されています。このサンプルどおりの返り値が返ってきており、アクションが正常に実行されたことがわかります。

5. 時刻トリガーの登録と、アクションとの関連付け

毎週月~金の9時にスタートするトリガーを作成します。
トリガーは、Functionsのダッシュボードから「トリガー」→「作成」→「トリガーの作成」→「Periodic」とたどって「トリガーの接続」の画面を開き、ここでトリガー名を指定し要件にあったタイミングを選択します。タイミングはUTC曜日およびUTC時間で指定しますが、トリガーが発生する次回の時刻は日本時間で確認できます。

作成したトリガーをアクションに関連づけます。

作成済のアクションを「既存の選択」のプルダウンリストから選択して、トリガーとアクションが関連付けられます。

6. トリガーの動作の確認

トリガーの実行結果は「モニター」の画面で確認することができます。
アクティビティー・サマリーのトリガー名(ここでは0800weekdayと1800weekday)と、その右にある棒グラフで成功と失敗の回数がわかります。またアクティビティー・ログで実行履歴とログの詳細が確認できます。

ここまでVPC Gen1のVSIを定時に自動で起動・停止するために必要なFunctions関連のプログラミングと設定をひととおり体験してみました。

以上です。