CloudWatchの再起動アクションをCloudFormationから作成してみた

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

ご機嫌いかがでしょうか、豊崎です。大阪オフィスからポストしております。

今回はCloudWatchの再起動アクションをCloudFormationから作成してみました。いくつか発見がありましたので書いていきたいと思います。

調べてみた

CloudFormationでCloudWatchを作成する際は以下のように記述する模様です。

{
   "Type" : "AWS::CloudWatch::Alarm",
   "Properties" : {
      "ActionsEnabled" : Boolean,
      "AlarmActions" : [ String, ... ],
      "AlarmDescription" : String,
      "AlarmName" : String,
      "ComparisonOperator" : String,
      "Dimensions" : [ Dimension, ... ],
      "EvaluateLowSampleCountPercentile" : String,
      "EvaluationPeriods" : Integer,
      "ExtendedStatistic" : String,
      "InsufficientDataActions" : [ String, ... ],
      "MetricName" : String,
      "Namespace" : String,
      "OKActions" : [ String, ... ],
      "Period" : Integer,
      "Statistic" : String,
      "Threshold" : Double,
      "TreatMissingData" : String,
      "Unit" : String
   }
}

ハイライトされている行がAlarmのアクションを記述する行になります。

AlarmActions

このアラームが ALARM 以外の状態から ALARM 状態に遷移するときに実行されるアクションのリスト。各アクションを Amazon リソースネーム (ARN) として指定します。

AWS::CloudWatch::Alarm

さて、ARNで指定するとありますが、「CloudWatchの再起動アクション」のARNをどう指定するかわかりませんでした。。

AWSの公式ドキュメントを調べるとCloudWatchの各アクション(Start,Stop,reboot,Recover)に対応するARNについて記載がありました。

arn:aws:swf:us-east-1:customer-account:action/actions/AWS_EC2.InstanceId.Reboot/1.0

注記  EC2ActionsAccess IAM ロールを作成するには、Amazon EC2 または CloudWatch コンソールを使用して少なくとも 1 つの再起動アラームを作成する必要があります。この IAM ロールが作成された後は、AWS CLI を使用して再起動アラームを作成できます。

CloudWatch リソースへのアクセス権限の管理の概要

上記によると、「arn:aws:swf:us-east-1:customer-account:action/actions/AWS_EC2.InstanceId.Reboot/1.0」が再起動(reboot)用のARNとなるようです。

作成するには少なくとも1つの再起動アクションを実行するアラームを作成する必要があると書いてありますので手動でアラームを1つ作成してみましょう。

AWSマネジメントコンソールにログインしCloudWatchのダッシュボードからアラームを作っていきます。

アラームを作る

それでは早速AWSマネジメントコンソール>CloudWatchダッシュボードからアラームの作成をクリックします。

次に適当なメトリクスを選んでいきます(CloudWatchアクション用のARN(IAMRole)を作成するためなので任意のものでOKです)

ここではStatusCheckFailedを選びましたが、なんでもよいです。選択して次にすすみます。

次の画面で必要な箇所の設定を行ったら、アクションの設定をしていきます。

デフォルトで表示されているSNSのアクションは削除して、EC2アクションを追加しましょう。「このインスタンスの再起動」を選択してアラームの作成を行いましょう。

作成されたCloudWatch Alarmを選択して履歴をみてみましょう。

alarmActionsの箇所に「arn:aws:swf:ap-northeast-1:XXXXXXXXXXXX:action/actions/AWS_EC2.InstanceId.Reboot/1.0」と表示されているのが確認できます。

それではCloudFormationの「AlarmActions」に、このARNに指定していきましょう。

{
  "createdAlarm": {
    "namespace": "AWS/EC2",
    "alarmArn": "arn:aws:cloudwatch:ap-northeast-1:XXXXXXXXXXXX:alarm:demo-reboot",
    "alarmConfigurationUpdatedTimestamp": "2018-03-27T01:01:29.011+0000",
    "threshold": 1,
    "dimensions": [
      {
        "name": "InstanceId",
        "value": "i-XXXXXXXXXXXX"
      }
    ],
    "metricName": "StatusCheckFailed",
    "period": 300,
    "okactions": [],
    "alarmActions": [
      "arn:aws:swf:ap-northeast-1:XXXXXXXXXXXX:action/actions/AWS_EC2.InstanceId.Reboot/1.0"
    ],
    "insufficientDataActions": [],
    "evaluationPeriods": 3,
    "datapointsToAlarm": 3,
    "comparisonOperator": "GreaterThanOrEqualToThreshold",
    "treatMissingData": "ignore",
    "stateValue": "INSUFFICIENT_DATA",
    "alarmName": "demo-reboot",
    "alarmDescription": "demo-reboot",
    "statistic": "Average",
    "actionsEnabled": true,
    "stateUpdatedTimestamp": "2018-03-27T01:01:29.011+0000"
  },
  "version": "1.0",
  "type": "Create"
}

書いてみた

以下がCloudWatchの再起動アクションをCloudFormationで書いたものです。

{
  "AWSTemplateFormatVersion": "2010-09-09",
  "Resources": {
    "Inctance1StatusCheckFaild" : {
      "Type" : "AWS::CloudWatch::Alarm",
      "Properties" : {
        "ActionsEnabled" : true,
        "AlarmActions" : [ "arn:aws:sns:ap-northeast-1:XXXXXXXXXXXX:demo-sns", "arn:aws:swf:ap-northeast-1:XXXXXXXXXXXX:action/actions/AWS_EC2.InstanceId.Reboot/1.0" ],
        "AlarmDescription" : "demo-reboot-alarm-CPUUtilization",
        "AlarmName" : "demo-reboot-alarm-CPUUtilization",
        "ComparisonOperator" : "GreaterThanOrEqualToThreshold",
        "Dimensions" : [
          {
            "Name" : "InstanceId",
            "Value" : "i-XXXXXXXXXXXX"
          }
        ],
        "EvaluationPeriods" : 3,
        "MetricName" : "CPUUtilization",
        "Namespace" : "AWS/EC2",
        "OKActions" : [ "arn:aws:sns:ap-northeast-1:XXXXXXXXXXXX:demo-sns" ],
        "Period" : 60,
        "Statistic" : "Maximum",
        "Threshold" : 80,
        "TreatMissingData" : "missing"
     }
   }
  }
}

しっかり作成されました。再起動アクションもしっかり設定されています。

今回はCPUの高負荷をトリガーに再起動を行う設定としているので、EC2のCPUに負荷を与えた状態でしばらく様子をみてみます。 (雑にyesコマンドで高負荷にしてます)

$ vmstat 1
procs -----------memory---------- ---swap-- -----io---- --system-- -----cpu-----
 r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st
 5  0      0 844092  10020 103412    0    0     0     0  255  269 99  1  0  0  0
 4  0      0 844092  10020 103412    0    0     0     0  255  268 98  2  0  0  0
 ・
 ・
 <略>
 ・
 ・
 4  0      0 844092  10020 103412    0    0     0     0  309  331 99  1  0  0  0
 4  0      0 844092  10020 103412    0    0     0     0  253  259 99  1  0  0  0

Broadcast message from root@ip-10-0-3-12
	(unknown) at 1:40 ...

The system is going down for reboot NOW!
Control-Alt-Delete pressed
 5  0      0 845272  10020 103464    0    0    60     0  279  451 87  2  0  0 12
Connection to 13.230.44.56 closed by remote host.
Connection to 13.230.44.56 closed.
$

しっかり再起動されました。

さいごに

CloudWatchのアクションはARNで指定する必要があることを知りませんでした。そしてよくみてみるとSimpleWorkFlowのARNのように見えますね。SWFダッシュボードからは作成された内容がみれなかったのですが裏側で利用されているんでしょうか?おもしろいですね。

この記事が誰かのお役に経てば幸いです。