SSM Run CommandとPutMetricData APIで、定期的にカスタムメトリクスを配信する構成
SSM Run Commandを使用して、定期的にCloudWatchにカスタムメトリクスを配信する構成をご紹介します。
CloudWatchにカスタムメトリクスをプッシュする方法は、以下の2通りあります。
統合 CloudWatch エージェントまたは API を使用して、カスタムメトリクスを CloudWatch にプッシュできます。
カスタムメトリクスを CloudWatch にプッシュするにはどうすればよいですか?
今回はSSM Run Commandを使用して、定期的(30分間隔)にPutMetricData APIを呼び出し、カスタムメトリクスを配信します。
なおCloudWatch Agentのインストールおよびメトリクス配信については、以下のページをご確認ください。
構築する環境
今回の構成では、プライベートサブネットの中から、以下の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スタックを作成します。
スタックの作成および各スタックの確認方法については、以下のページをご確認ください。
各スタックのリソースを確認した結果、今回作成された主要リソースの情報は以下の通りです。
- インスタンスのID:i-080d5cb0109464241
- S3バケットの名前:dva-02-001
- カスタムメトリクスの名前空間:totalconn
SSM Run Commandの実行状況を確認する
AWS Management Consoleから設定状況を確認します。
「Schedule expression」の項目に、30分ごと(毎時0分および30分)に実行する旨の記述があります。
次に実行されたSSM Run Commandを確認します。
ご覧の通り、初回のみ中途半端な時間ですが、2回目以降はスケジュール通りのタイミングに実行されていることがわかります。
S3バケットにアクセスし、SSM Run Commandの実行ログを確認します。
各フォルダにはシェルスクリプトの実行結果(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
上記の通り、メトリクスが配信され、グラフが作成されました。
SSMドキュメントが定期的に実行され、CloudWatchにメトリクスを配信できていることがわかります。
まとめ
SSM Run Command使用して、定期的(30分/回)にPutMetricData APIを呼び出し、カスタムメトリクスを配信することができました。