SSM Run Commandで定期的にカスタムメトリクスを配信する

SSM Run Commandsでカスタムメトリクスを定期的に配信する

SSM Run CommandとPutMetricData APIで、定期的にカスタムメトリクスを配信する構成

SSM Run Commandを使用して、定期的にCloudWatchにカスタムメトリクスを配信する構成をご紹介します。

CloudWatchにカスタムメトリクスをプッシュする方法は、以下の2通りあります。

統合 CloudWatch エージェントまたは API を使用して、カスタムメトリクスを CloudWatch にプッシュできます。

カスタムメトリクスを CloudWatch にプッシュするにはどうすればよいですか?

今回はSSM Run Commandを使用して、定期的(30分間隔)にPutMetricData APIを呼び出し、カスタムメトリクスを配信します。

なおCloudWatch Agentのインストールおよびメトリクス配信については、以下のページをご確認ください。

あわせて読みたい
LinuxにCloudWatch Agentをインストールしてデータ収集 【LinuxインスタンスにCloudWatch Agentをインストールして、ログとメトリクスを収集する構成】 CloudWatch Agentを使用することによって、ログやメトリクスを収集する...
あわせて読みたい
WindowsにCloudWatch Agentをインストールしてデータ収集 【WindowsインスタンスにCloudWatch Agentをインストールして、ログとメトリクスを収集する構成】 CloudWatch Agentを使用することによって、ログやメトリクスを収集す...

構築する環境

Diagram of Delivering custom metrics by SSM Run Command.

今回の構成では、プライベートサブネットの中から、以下の3種類のサービスにアクセスするために、VPCエンドポイントを設置します。

  • SSM用: Run Commandで定期的にインスタンスにPutMetricData APIを実行させるため
  • S3用:Run Commandの実行結果をS3バケットに保存するため
  • CloudWatch用:PutMetricData APIでカスタムメトリクスを配信するため

今回の構成でカスタムメトリクスとして配信する内容ですが、カスタムメトリクスを CloudWatch にプッシュするにはどうすればよいですか?で紹介されている特定ポートの接続数を実際に実施したいと思います。

環境構築用のCloudFormationテンプレートファイル

上記の構成をCloudFormationで構築します。
以下のURLにCloudFormationテンプレートを配置します。

https://github.com/awstut-an-r/awstut-dva/tree/main/02/001

テンプレートファイルのポイント解説

今回の環境を構成するための、各テンプレートファイルのポイントを取り上げます。

IAMロールでSSM・S3・CloudWatchにアクセスするための権限を付与する

ポイントはインスタンスにアタッチするIAMロールです。

Resources:
  InstanceRole:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Version: 2012-10-17
        Statement:
          - Effect: Allow
            Action: sts:AssumeRole
            Principal:
              Service:
                - ec2.amazonaws.com
      Policies:
        - PolicyName: PermitPutMetricData
          PolicyDocument:
            Version: 2012-10-17
            Statement:
              - Effect: Allow
                Action:
                  - cloudwatch:PutMetricData
                Resource: "*"
        - PolicyName: DeliverLogPolicy
          PolicyDocument:
            Version: 2012-10-17
            Statement:
              - Effect: Allow
                Action:
                  - s3:GetObject
                  - s3:PutObject
                  - s3:PutObjectAcl
                  - s3:ListBucket
                Resource:
                  - !Sub "arn:aws:s3:::${SSMLogBucket}"
                  - !Sub "arn:aws:s3:::${SSMLogBucket}/*"
      ManagedPolicyArns:
        - arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore
Code language: YAML (yaml)

今回の構成において、3サービスと連携する上で必要となる権限を、IAMロールを作成して与えます。SSMはAWS管理ポリシーAmazonSSMManagedInstanceCoreで、CloudWatchおよびS3はインラインポリシーで賄います。

SSM Run Commandで定期的にPutMetricData APIを呼び出してカスタムメトリクスに配信する

SSM関連付けを確認します。

Resources:
  RunShellScriptAssociation:
    Type: AWS::SSM::Association
    Properties:
      AssociationName: !Sub ${Prefix}-run-shellscript-association
      Name: AWS-RunShellScript
      OutputLocation:
        S3Location:
          OutputS3BucketName: !Ref SSMLogBucket
          OutputS3KeyPrefix: shellscript-association-log
      Parameters:
        commands:
          - "port=443"
          - "total_conn=$(netstat -an | grep $port | wc -l)"
          - "instance_id=$(ec2-metadata -i | cut -d ' ' -f 2)"
          - "aws cloudwatch put-metric-data --namespace 'totalconn' --metric-name $port --dimensions Instance=$instance_id --value $total_conn --region ap-northeast-1"
          - "echo `date` instance_id=$instance_id, port=$port, total_conn=$total_conn"
      ScheduleExpression: cron(0/30 * * * ? *)
      #ScheduleExpression: rate(30 minutes)
      Targets:
        - Key: InstanceIds
          Values:
            - !Ref Instance
      WaitForSuccessTimeoutSeconds: !Ref WaitForSuccessTimeoutSeconds
Code language: YAML (yaml)

SSM Run Commandの実行は、AWS::SSM::Associationリソースを定義することで実現することができます。
今回、PutMetricData APIの呼び出しは、AWS CLIから実行します。AWS CLIからカスタムメトリクスに配信するために、定期的に実行する処理を、シェルスクリプトとして定義します。シェルスクリプトを実行するために実行するべきSSMドキュメントはAWS-RunShellScriptです。Parametersプロパティ内のcommandsプロパティに必要なコマンドを定義します。コマンドはカスタムメトリクスを CloudWatch にプッシュするにはどうすればよいですか?を参考にしました。最後のechoコマンドはS3バケットに出力する実行ログです。
SSM Run Commandの定期的な実行はScheduleExpressionプロパティで設定できます。記法は関連付のための cron および rate 式に詳しいのですが、cron形式、またはrate形式で実行するタイミングを指定できます。
SSM Run Commandにおける定期実行には注意点があります。それは最短の実行間隔に関する制限です。

関連付けは、次の cron 式をサポートします。1/2、1、2、4、8、または 12 時間ごと。毎日または毎週の特定の時間。

関連付けは、30 分以上 31 日未満の間隔の rate 式をサポートします。 

関連付のための cron および rate 式

つまり最短が30分間隔ということになります。そのため今回も30分ごとに実施するように設定します。

SSM・S3・CloudWatch用のVPCエンドポイント

3サービス用のVPCエンドポイントを作成します。今回の構成では、インスタンスはプライベートサブネット内に設置されているため、VPC外のリソースにアクセスするための経路として使用します。
以下がアクセス先とサービス名の関係です。

  • S3:s3
  • SSM:ssm, ec2messages, ssmmessages
  • CloudWatch:monitoring

SSM用とCloudWatch用のエンドポイントはインターフェース型、S3用はゲートウェイ型で作成します。

環境構築

CloudFormationを使用して、本環境を構築し、実際の挙動を確認します。

CloudFormationスタックを作成し、スタック内のリソースを確認する

CloudFormationスタックを作成します。
スタックの作成および各スタックの確認方法については、以下のページをご確認ください。

あわせて読みたい
CloudFormationのネストされたスタックで環境を構築する 【CloudFormationのネストされたスタックで環境を構築する方法】 CloudFormationにおけるネストされたスタックを検証します。 CloudFormationでは、スタックをネストす...

各スタックのリソースを確認した結果、今回作成された主要リソースの情報は以下の通りです。

  • インスタンスのID:i-080d5cb0109464241
  • S3バケットの名前:dva-02-001
  • カスタムメトリクスの名前空間:totalconn

SSM Run Commandの実行状況を確認する

AWS Management Consoleから設定状況を確認します。

Schedule the execution of the SSM Run Command.

「Schedule expression」の項目に、30分ごと(毎時0分および30分)に実行する旨の記述があります。

次に実行されたSSM Run Commandを確認します。

SSM Run Command has been executed periodically.

ご覧の通り、初回のみ中途半端な時間ですが、2回目以降はスケジュール通りのタイミングに実行されていることがわかります。

S3バケットにアクセスし、SSM Run Commandの実行ログを確認します。

SSM Run Command logs are saved for each execution.

各フォルダにはシェルスクリプトの実行結果(stdout.txt)が設置されています。

The SSM Run Command log is output to stdout.txt.

先述のechoコマンドの中身が出力されていることがわかります。

Sun Jan 9 10:01:01 UTC 2022 instance_id=i-080d5cb0109464241, port=443, total_conn=2
Code language: plaintext (plaintext)

カスタムメトリクスの配信状況を確認する

最後にメトリクスを確認します。
AWS Management Consoleにて、以下にアクセスします。

CloudWatch > メトリクス > 全てのメトリクス > totalconn

Graph creation with custom metrics delivered by SSM Run Command.

上記の通り、メトリクスが配信され、グラフが作成されました。
SSMドキュメントが定期的に実行され、CloudWatchにメトリクスを配信できていることがわかります。

まとめ

SSM Run Command使用して、定期的(30分/回)にPutMetricData APIを呼び出し、カスタムメトリクスを配信することができました。