CloudAutomatorでSQSを利用せずジョブの数珠つなぎを実現する

Cloud Automatorのアドベントカレンダー2017年の10日目を担当します。

Cloud Automatorとは

Cloud Automatorでは、AWSのリソースを操作するための内容を「ジョブ」と呼ばれる単位でWeb上の操作画面からGUIで登録し、日時指定やHTTPリクエストをトリガーにして実行させることが可能なサービスです。
https://cloudautomator.com/

ジョブの連続実行

これまでCloud Automatorでは、複数のジョブを連続して実行させるためには、AmazonSQSを利用して数珠つなぎ状態にする方法をサポートしていました。(マニュアル:「ジョブを数珠つなぎにして複数のジョブを連携する」参照)
しかしこれは、SQSを事前に準備する必要があり、少々手間でした。

スクリーンショット.png


2017年10月に、「Webhook後処理」という機能(マニュアル:「Webhook後処理」参照)がリリースされました。ざっくり言うと、ジョブの実行後にその結果を任意のURLにPOSTリクエストで受け取ることが可能になります。
今回はこの機能を利用して、 SQSを使わずに Cloud Automatorのジョブを連続実行させてみます。

スクリーンショット 2017-12-10 22.26.24.png

サンプル:EC2インスタンスのインスタンスタイプの変更

ここでは、先ほどのSQSを使ったインスタンスタイプを変更するための一連ジョブを、HTTPトリガーとWebhook後処理で置き換える例を示します。

例えばマネージメントコンソール上で、EC2のインスタンスタイプを手動で変更&起動したい場合は

  1. 該当のインスタンスを「停止」にする(→完全に停止するまでしばらく待つ)
  2. インスタンスタイプを変更する
  3. インスタンスを起動する

これらの操作が必要になりますが、ここで地味に面倒なのが、インスタンスが完全に停止するまで待たないと、インスタンスタイプが変更できないことです。Cloud Automatorを利用すると、これら一連の作業をジョブとして登録&連続実行させることで、不毛な停止待ち時間もすべてCloud Automatorがハンドリングしてくれます。

👉 STEP1: インスタンス起動ジョブを登録

連続するジョブを作成する際は、最後のジョブから登録していくと手間が少なくて済みます。(2017年12月現在)
まずは、 運用ジョブ > ジョブの追加 メニューから、新規にジョブを作成します。

step1.png

項目 設定値
トリガー HTTPトリガー
アクション EC2:インスタンスを起動
AWSアカウント ※CloudAutomatorに登録しているAWSアカウントを指定
インスタンス 該当のインスタンスを指定(タグの指定でもOK)
リソースの終了ステータスをチェックする ※ここはチェックしてもしなくてもどちらでもOK
後処理 ※必要に応じて(指定しなくてもOK)
ジョブ名 「インスタンス起動ジョブ」など任意の名前

このような形で登録します。

登録完了後は、 運用ジョブ > 運用ジョブ一覧 メニューから、先ほど作成したジョブの詳細画面を開いて、以下の情報をメモします。

step1_2.png

👉 STEP2: インスタンスタイプ変更ジョブの登録

次に、インスタンスタイプの変更ジョブを登録していきます。STEP1と同じように、ジョブの新規登録画面から、以下のように登録します。

項目 設定値
トリガー HTTPトリガー
アクション EC2:インスタンスタイプを変更
AWSアカウント ※CloudAutomatorに登録しているAWSアカウントを指定
インスタンス 該当のインスタンスを指定(タグの指定でもOK)
インスタンスタイプ ※変更したいタイプを指定
後処理 ※新規に後処理を作成して指定(後述)
ジョブ名 「インスタンスタイプ変更ジョブ」など任意の名前

🔰 後処理の指定
後処理の指定箇所で、「後処理を新たに作成する」ボタンを押して、作成画面を開きます。
step2_1.png

ここで、サービスには Webhook を選択し、先ほどメモしておいた「インスタンス起動ジョブ」の、 HTTPトリガーのURL と、 HTTPヘッダーのAuth情報 を入力し、判別しやすい後処理名を入力して登録します。
step2_2.png

後処理作成後、今作成した後処理を「成功時」の後処理に指定します。
step2_3.png

以上の情報で「インスタンスタイプ変更」のジョブを作成します。
STEP1と同様に、作成したジョブの詳細画面を開き、 HTTPトリガーのURLHTTPヘッダーのAuth情報 を再度メモします。

👉 STEP3: インスタンス停止ジョブの作成

これで最後です。STEP2と同様に、ジョブの作成画面で次のように登録します。

項目 設定値
トリガー ※利用したいトリガーを指定
アクション EC2:インスタンスを停止
AWSアカウント ※CloudAutomatorに登録しているAWSアカウントを指定
インスタンス 該当のインスタンスを指定(タグの指定でもOK)
リソースの終了ステータスをチェックする ※ここは必ずチェックしてください
後処理 ※新規に後処理を作成して指定(後述)
ジョブ名 「インスタンス停止ジョブ」など任意の名前

【⚠️注意事項】
「リソースの終了ステータスをチェックする」にチェックを入れることで、インスタンスが完全に停止するのを待ってから、指定した後処理が実施されるようになります。チェックを入れないと、インスタンスが停止準備の状態のままインスタンスタイプ変更のジョブが実行されてしまい、ジョブがエラー終了してしまうのでご注意ください。

🔰 後処理の指定
STEP2と同様に、新規に後処理を作成します。
サービスには Webhook を選択し、先ほどメモしておいた「インスタンスタイプ変更ジョブ」の、 HTTPトリガーのURL と、 HTTPヘッダーのAuth情報 を入力し、判別しやすい後処理名を入力して登録し、ジョブ作成画面上「成功時」の後処理に、作成した後処理を指定してジョブを作成します。

以上で終了です。

まとめ

インスタンスタイプの変更処理などは、自動化しようとすると、インスタンスが完全に停止したことをハンドリングするのが地味に大変だったりしますが、これらはすべてCloud Automator側で判断してくれるため大変便利です。

Cloud Automator上で「インスタンスの停止・変更・再起動」を行うためには、SQSで各ジョブ間を繋ぐ方法しかありませんでしたが、Webhook後処理の登場によって、その作業がかなり簡略化できるようになりました。
・・・とは言っても、後処理を毎回作成するのも大変ではあります。そのため、これらの作業すらも不要になるような便利な機能のリリースが、今後予定されています。
詳しくはサービスのロードマップページを参照してください。
https://cloudautomator.com/roadmap/

続きを読む

Amazon ConnectとCloud Automatorを接続して、電話からAWSを操作してみる

2008年当時、私たちはAWSが出てきたので「サーバー購入禁止令」を引きましたが、今度はConnectのおかげて「電話購入禁止令」が出せそうです! このAmazon Connect、「コンタクトセンターのクラウドサービス」と銘打たれていますが、コンタクトセンターだけでなく様々なアプリケーションとの連携も可能です。今日は「Cloud … 続きを読む

AWS Step FunctionsでRedshift準備完了まで待機する

目的

AWSでサーバーインスタンス起動系などのリクエストをすると数分待つことになります。
対象や実現方法は色々考えられますが、今回はRedshiftを起動し、使える状態になるまで待機する部分をAWS Step Functionsで実装してみます。

概要

  • チュートリアルのターゲットをRedshiftに変えて実際にやってみたという内容です。
  • LambdaはPython3.6で記述します。

手順

  • 実行用のロールや環境設定は省略します

Redshift起動Lambdaを作成

createRedshiftCluster という名前でLambda Functionを作成します。
パラメータはハードコーディングになっています。(記事用にシンプルにするためです 汗)

createRedshiftCluster
import boto3

def lambda_handler(event, context):
    redshift = boto3.client('redshift')
    redshift.create_cluster(
        ClusterIdentifier='test-cluster',
        DBName='dev',
        Port=5439,
        MasterUsername='testuser',
        MasterUserPassword='myPassword1234',
        VpcSecurityGroupIds=['sg-abcdef12'], 
        ClusterSubnetGroupName='csg1',
        NodeType='dc2.large',
        ClusterType='single-node',
        PubliclyAccessible=True,
        EnhancedVpcRouting=False)
    event['result'] = 'SUCCESS'
    return event

Redshift起動完了確認Lambdaを作成

waitRedshift という名前でLambda Functionを作成します。
WaiterAPIを利用しますがここではリトライはしません。(MaxAttempts=1は1回実行して実行中なら再試行しません)
StepFunctions側でリトライを制御します。
エラー処理は微妙かもしれません。現物合わせです。
起動中ならCREATING、準備完了なら RUNNING を返すようにしてあります。

waitRedshift
import boto3
import botocore

def lambda_handler(event, context):
    redshift = boto3.client('redshift')
    waiter = redshift.get_waiter('cluster_available')
    try:
        waiter.wait(
            ClusterIdentifier='test-cluster',
            WaiterConfig={
                'Delay': 3,
                'MaxAttempts': 1})
        event['result'] = 'RUNNING'
    except botocore.exceptions.WaiterError as e:
        if not hasattr(e, 'last_response'):
            raise e
        if 'Error' in e.last_response:
            raise e
        event['result'] = 'CREATING'
    return event

全体の流れをStepFunctionsで作成

PrepareRedshift という名前でStepFunctionsを作成します。
上記で作成した lambda:createRedshiftCluster を実行し、20秒待ち。
lambda:waitRedshiftで完了チェックし、まだなら再度20秒待ち。これを繰り返します。
APIコール部分はリトライも記述してあります。

PrepareRedshift
{
  "Comment": "Create and Wait for Redshift Cluster",
  "StartAt": "CreateCluster",
  "States": {
    "CreateCluster": {
      "Type": "Task",
      "Resource": "arn:aws:lambda:us-east-1:123456789012:function:createRedshiftCluster",
      "Next": "Wait",
      "Retry": [
        {
          "ErrorEquals": ["States.ALL"],
          "IntervalSeconds": 5,
          "MaxAttempts": 3,
          "BackoffRate": 2.0
        }
      ]
    },
    "Wait": {
      "Type": "Wait",
      "Seconds" : 20,
      "Next": "CheckStatus"
    },
    "CheckStatus": {
      "Type": "Task",
      "Resource": "arn:aws:lambda:us-east-1:123456789012:function:waitRedshift",
      "Next": "IsRunning",
      "Retry": [
        {
          "ErrorEquals": ["States.ALL"],
          "IntervalSeconds": 5,
          "MaxAttempts": 3,
          "BackoffRate": 2.0
        }
      ]
    },
    "IsRunning": {
      "Type": "Choice",
      "Choices": [
        {
          "Variable": "$.result",
          "StringEquals": "RUNNING",
          "Next": "Success"
        },
        {
          "Variable": "$.result",
          "StringEquals": "CREATING",
          "Next": "Wait"
        }
      ],
      "Default": "Abort"
    },
    "Abort": {
      "Type": "Fail"
    },
    "Success": {
      "Type": "Succeed"
    }
  }
}

記述について

素晴らしい機能ですが、Amazon States Language なる言語(?)で記述する必要があります。
あとフロー中の変数取り回しができるのですが、 $.var のような記述でこれはJsonPathというようです。
ちょっと大変ですが、ひと通り目を通しておいたほうが良さそうです。
ビジュアライズしてくれるのでそこはホッとします。

表示例:(Endがつながっていませんが大丈夫です :sweat_drops:

image.png

実行結果

マネージメントコンソールから実行すると実行中、実行終了のステップに着色されていきます。
今回は4分ほどで成功しました。

image.png

まとめ

Redshiftクラスタが操作可能になるまで待機する、というパーツはできました。(※エラー処理とかテストとか全然できてませんが :smile:
現実的には、処理の起動トリガーをどうするか、後続処理を実装する等、システムとして組み立てることになると思います。
プロジェクトとしては、いわゆるビジネスロジック(古い表現かも)部分に時間を掛けたいはずですよね。
今回のような準備処理は時間をかけず、サラリと実現するためのツールが Cloud Automatorですねー

続きを読む

Cloud Automatorでt2.nanoインスタンスの価値を絞り出す

概要・目的

  • EC2のインスタンスファミリ、t2ファミリは低コストラインナップが特徴です
  • t2ファミリは「CPUクレジット残高」によってパフォーマンスが変動する仕組みが独特です
  • t2ファミリの中でも、特に価格の安いt2.nanoを、Cloud Automatorを利用して活用する方法を紹介します

前置き

t2のリリース

  • 2017年11月30日、t2に「Unlimited」という機能がリリースされました

  • 従来はCPUクレジットを使い果たすと処理パフォーマンスが低下し、CPUクレジットの回復を待つ、またはインスタンスのSTOP→STARTによって初期CPUクレジットにリセットするしかありませんでした
  • 「Unlimited」機能を有効にすれば、追加料金を支払うことでパフォーマンス低下を回避することができます(CPUクレジットを追加購入しているイメージでしょうか)
  • パフォーマンス低下状態から回復したい、でもインスタンスを停止できない、そんなシーンではとても有効な機能です

T2 Unlimitedの追加料金

  • 「T2 Unlimited」、良いリリースだと思うのですが、追加料金はどうなっているのでしょうか
  • LinuxではvCPU時間あたり0.05ドル と記述があります。リーズナブルに見えます(実際リーズナブルだとも思います)
  • しかし、今回ターゲットとするt2.nanoのインスタンス料金は 1時間あたり $0.0058 (us-east1) です。一桁違います
  • 適用局面は違いますが、0.05ドルあれば8時間イケるともいえます

結論

  • (少々強引ですが)止めてもいいシステムならやっぱりSTOP→STARTが手っ取り早い

本題

  • 前置きが長くなりましたが、やりたいことは、CPUクレジットを使い切ったインスタンスを自動的にSTOP→STARTして初期CPUクレジットを獲得するです
  • 当然ながら短時間なら停止しても問題のないシステムが対象です
  • 実際のところ、t2.nanoのCPUクレジット枯渇時は停止しているようなものと考えて差し支えないと思います
  • つまり、t2.nanoを採用している時点で停止は覚悟の上ということです(知らんけど)

動作の仕組み

  • CloudWatchAlarmでCPUクレジット低下を検知
  • AmazonSNS経由でCloud Automatorの EC2 STOP ジョブを起動
  • EC2 STOP ジョブが完了するまでCloud Automatorは待機してくれます)
  • EC2 STOP ジョブの正常完了時アクションで EC2 STARTジョブを起動(Cloud Automatorはジョブ同士を数珠つなぎで起動できるのです)
  • EC2 START ジョブの完了時アクションで管理者へメール通知

参考

  • この仕組みは(停止しても問題のない)個人サイトで実際に動作しています
  • 仕組み導入前後の様子をCloudWatchのグラフで紹介します

導入前

  • CPUクレジットを使い果たして復活する様子がありません

image.png

導入後

  • CPUクレジットを使い果たす前にSTOP→STARTすることで初期CPUクレジットを獲得して復活しています

image.png

最後に

t2ファミリはクセが強いので使いドコロの見極めは必要ですが、上手くつかえばコストを抑えた運用が可能ですね。
T2 Unlimitedのリリースでさらに利用バリエーションが広がり、活用シーンも増えるのではないでしょうか。
今回はちょっとかわったCloud Automatorの利用方法を紹介いたしました。

続きを読む