DVA

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

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

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

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

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

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

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

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

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

構築する環境

AWS認定アソシエイト3資格対策~ソリューションアーキテクト、デベロッパー、SysOpsアドミニストレーター~ | 平山毅, 堀内康弘, 福垣内孝造, 岡智也, 池田大, 原江梨佳, 澤田拓也, 原俊太郎, 仲村勇亮, 上村祐輝, 鳥谷部昭寛 | 工学 | Kindleストア | Amazon
Amazonで平山毅, 堀内康弘, 福垣内孝造, 岡智也, 池田大, 原江梨佳, 澤田拓也, 原俊太郎, 仲村勇亮, 上村祐輝, 鳥谷部昭寛のAWS認定アソシエイト3資格対策~ソリューションアーキテクト、デベロッパー、SysOpsアドミニストレーター~。アマゾンならポイント還元本が多数。一度購入いただいた電子書籍は、K...
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テンプレートを配置します。

awstut-dva/02/001 at main · awstut-an-r/awstut-dva
Contribute to awstut-an-r/awstut-dva development by creating an account on GitHub.

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

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

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スタックを作成します。
スタックの作成および各スタックの確認方法については、以下のページをご確認ください。

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

  • インスタンスの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回目以降はスケジュール通りのタイミングに実行されていることがわかります。

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

SSM Run Command logs are saved for each execution.

先述の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を呼び出し、カスタムメトリクスを配信することができました。

タイトルとURLをコピーしました