Help us understand the problem. What is going on with this article?

SORACOM LTE-M ButtonでChaosMonkey

More than 1 year has passed since last update.

はじめに

タイトルそのままですが、SORACOM LTE-M Buttonをクリックすることで、ChaosMonkey的にランダムにEC2インスタンスを落とすようにしてみました。
一応障害テストにも使えますが、「押すなよ押すなよ」的な使い方に最適かと思われます。

実装

 クリック時の動作

シングルクリックで1インスタンス、ダブルクリックで2インスタンス、ロングクリックで3インスタンスがterminateされます。
実装によっては、ロングクリックで全消し、というバルスボタンを作ることも可能です。

ボタンのセットアップ

ボタンを1Clickサービスに登録してアクションを紐づけるところまでは、こちらのエントリに詳しく書かれています。
https://dev.classmethod.jp/soracom/setup-soracom-ltem-button-by-android/

こちらのエントリでは、SMSを送信するアクションを選択していますが、今回は以下で実装するLambdaを選択します。

AWS Lambdaの実装

Javaで書いてありますが、このような実装になります。

public class ChaosMonkeyButton implements RequestHandler<ClickEvent, String> {

  AmazonEC2 ec2;

  public ChaosMonkeyButton() {
    ec2 = AmazonEC2ClientBuilder.standard().withRegion(Regions.US_EAST_2).build();
  }

  @Override
  public String handleRequest(ClickEvent input, Context context) {

    DescribeInstancesResult describeInstances = ec2.describeInstances();

    //terminateするインスタンス数をクリックタイプによって変える
    int terminateNum = input.deviceEvent.buttonClicked.clickType.ordinal() + 1;
    context.getLogger().log("terminateNum:" + terminateNum);

    //インスタンスリストからランダムにterminate対象を取り出す
    List<Instance> terminateList = describeInstances.getReservations().stream()
        .flatMap(res -> res.getInstances().stream()).filter(this::isRunning)
        .collect(Collectors.collectingAndThen(Collectors.toList(), collected -> {
          Collections.shuffle(collected);
          return collected.stream();
        })).limit(terminateNum).collect(Collectors.toList());

    if (terminateList.isEmpty() == false) {
      //インスタンスをterminate
      List<String> idList = terminateList.stream().map(t -> t.getInstanceId()).collect(Collectors.toList());
      idList.stream().forEach(i -> {
        context.getLogger().log("terminate " + i);
        ec2.terminateInstances(new TerminateInstancesRequest().withInstanceIds(i));
      });
    } else {
      context.getLogger().log("There are no running instances");
    }

    return "OK";
  }

  private boolean isRunning(Instance instance) {
    return InstanceStateName.Running.toString().equals(instance.getState().getName());
  }
}

ソースコードやビルドスクリプトは以下に置いておきます。リクエストは1Clickボタンで共通なので、Javaの方であれば簡単にカスタマイズできると思います。
https://github.com/c9katayama/soracom-lte-m-button-lambda

動作確認

先輩、システム構築終わりました!!
スクリーンショット 2018-11-03 9.56.14.png

おー、よくできたね。どれどれ ポチー(ロングクリック)
15411830590660.jpg

ギャーーー!
スクリーンショット 2018-11-03 9.56.48.png

おわりに

今回は、EC2を落とすという使い方でしたが、SORACOM LTE-M ButtonはLambdaを直接叩けるので、適切にLambdaにロールを割り当てることで、自分のAWS環境のリソースをボタンクリックで変化させることができます。
例えばセキュリティグループを一瞬開けるとか、IAMに権限を一時的に付与するといった、承認を得て作業するようなシチュエーションの場合に、ハンコを押す感覚で上司が操作できるのは面白いかなと思いました。
またボタンの場合、認証はハードウェアに内蔵されたeSIMに任せることができます。このため、例えばボタンを押す人を変える場合も、AWSのクレデンシャルやその他の認証情報を人に渡す必要がなく、複数人で利用するようなユースケースでは便利に使えるケースもありそうです。

c9katayama
毎日SIMを焼いています。 短編SIM小説「SIM City」を年一回更新中。 「AWSクラウドデザインパターン」など執筆
http://d.hatena.ne.jp/c9katayama/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした