Foto von Alexander+Supertramp auf Shutterstock
In diesem Blogbeitrag automatisieren wir die Installation und Konfiguration des CloudWatch Agent auf EC2-Instanzen (Linux) für eigene Memory-Metriken vollständig – über ein Automation-Runbook im Systems Manager. Mit einem Custom Runbook automatisieren wir Installation und Konfiguration des CloudWatch Agent; AWS EventBridge stößt den Vorgang ohne manuellen Eingriff an.

Grundlegendes Architekturdiagramm
Überblick zur Automatisierung
Für diese Automatisierung nutzen wir ein AWS-CloudFormation-Template, das die nötigen Ressourcen bereitstellt und folgende Schritte abdeckt:
- IAM-Rolle für AWS Systems Manager zur Ausführung des Automation Document anlegen — Der Systems Manager benötigt eine Execution Role, um das Runbook in Ihrem Namen auf den Ziel-EC2-Instanzen auszuführen, sowie Berechtigungen für die EC2-Instanzen, damit diese Metriken an CloudWatch schreiben dürfen.
- CloudWatch-Agent-Konfigurationsdatei im Systems Manager Parameter Store ablegen — Das CloudFormation-Template lädt die individuelle CloudWatch-Konfigurationsdatei in den Parameter Store. Die Instanzen holen sich diese Datei dort ab, um den CloudWatch Agent zu konfigurieren.
- Automation Document im Systems Manager erstellen — Mit CloudFormation bauen wir ein Custom Runbook, das den CloudWatch Agent installiert und konfiguriert.
- IAM-Rolle für die EventBridge-Regel zum Aufruf der Systems Manager Automation anlegen — EventBridge benötigt eine Invoke Role, um den Automatisierungs-Workflow im Systems Manager zur Installation und Konfiguration des CloudWatch Agent anzustoßen.
- EventBridge-Regel erstellen — CloudFormation legt eine EventBridge-Regel an, die EC2-Instance-Events mit Status "running" filtert und die SSM-Automation auslöst.
- Optional (SQS Dead Letter Queue erstellen) — Eine Standard-SQS-Queue, die als SQS Dead Letter Queue für die EventBridge-Regel dient und Fehlerdetails der EventBridge-Trigger erfasst.
CloudFormation-Template
AWSTemplateFormatVersion: '2010-09-09'
Description: A template to create an AWS Systems Manager Automation Document that installs Amazon CloudWatch agent, sets up necessary permissions, and configures CloudWatch agent to publish memory metrics to CloudWatch and trigger SSM automation with eventbridge rule
Resources:
SsmAutomationRole:
Type: AWS::IAM::Role
Properties:
Description: IAM role for AWS Systems Manager to execute automation document
AssumeRolePolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Principal:
Service: ssm.amazonaws.com
Action: sts:AssumeRole
Condition:
StringEquals:
aws:SourceAccount: !Sub ${AWS::AccountId}
ArnLike:
aws:SourceArn: !Sub arn:${AWS::Partition}:ssm:*:${AWS::AccountId}:automation-execution/*
ManagedPolicyArns:
- !Sub arn:${AWS::Partition}:iam::aws:policy/service-role/AmazonSSMAutomationRole
Path: /
Policies:
- PolicyName: SsmMemMetricIamPolicy
PolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Action:
- iam:GetRole
- iam:GetInstanceProfile
- iam:GetPolicy
- iam:AttachRolePolicy
- iam:ListInstanceProfiles
- ec2:DescribeInstances
Resource: '*'
CloudWatchAgentConfigFile:
Type: AWS::SSM::Parameter
Properties:
Name: CloudwatchAgentConfigForMemoryMetricsLinux.json
Description: Store CloudWatch Agent configuration file as AWS Systems Manager Parameter
Type: String
Value: |
{
"agent": {
"metrics_collection_interval": 60,
"run_as_user": "cwagent"
},
"metrics": {
"append_dimensions": {
"InstanceId": "${aws:InstanceId}"
},
"metrics_collected": {
"mem": {
"measurement": [\
"mem_used_percent"\
],
"metrics_collection_interval": 60
}
}
}
}
SystemManagersMemoryMetricsRunbook:
Type: AWS::SSM::Document
Properties:
DocumentFormat: YAML
DocumentType: Automation
Name: CloudwatchAgent_Install_Configure_MemoryMetrics_OnEC2Linux
Content:
description: Install CloudWatch Agent, Add permissions to target instances and configure CloudWatch agent to publish metrics
schemaVersion: '0.3'
assumeRole: !Sub ${SsmAutomationRole.Arn}
parameters:
InstanceId:
type: String
description: Select instances
mainSteps:
- name: Attach_CloudWatchAgent_ServerPolicy_to_instance_role
action: aws:executeScript
onFailure: Abort
isCritical: true
timeoutSeconds: 600
description: |
## Find the attached role, attach CloudWatchAgentServer managed policy to the role
inputs:
Runtime: python3.8
Handler: attach_cloudwatch_agent_managed_policy
InputPayload:
InstanceIds: '{{InstanceId}}'
Script: |
import boto3
ec2_client = boto3.client('ec2')
iam_client = boto3.client('iam')
current_session = boto3.session.Session()
current_region = current_session.region_name
partition = current_session.get_partition_for_region(current_region)
cloudwatchagent_policy_arn = f'arn:{partition}:iam::aws:policy/CloudWatchAgentServerPolicy'
def attach_cloudwatch_agent_managed_policy(event,context):
instance_id = event['InstanceIds']
response = ec2_client.describe_instances(InstanceIds=[instance_id])
iam_role = response['Reservations'][0]['Instances'][0]['IamInstanceProfile']['Arn']
role_name=iam_role.split('/')[-1]
iam_client.attach_role_policy(RoleName=role_name, PolicyArn=cloudwatchagent_policy_arn)
- name: Install_cloudWatchAgent_onTargetInstance
action: aws:runCommand
onFailure: Abort
inputs:
Parameters:
action:
- Install
installationType:
- Uninstall and reinstall
name:
- AmazonCloudWatchAgent
DocumentName: AWS-ConfigureAWSPackage
InstanceIds:
- '{{InstanceId}}'
- name: Configure_CloudWatchAgen_onTargetInstance
action: aws:runCommand
inputs:
DocumentName: AmazonCloudWatch-ManageAgent
InstanceIds:
- '{{InstanceId}}'
Parameters:
action: configure
mode: ec2
optionalConfigurationSource: ssm
optionalConfigurationLocation: CloudwatchAgentConfigForMemoryMetricsLinux.json
optionalRestart: 'yes'
AutomationIAMRole:
Type: AWS::IAM::Role
Properties:
RoleName: Amazon_EventBridge_Invoke_Start_Automation_Execution
AssumeRolePolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Principal:
Service: events.amazonaws.com
Action: sts:AssumeRole
ManagedPolicyArns:
- arn:aws:iam::aws:policy/service-role/AmazonSSMAutomationRole # AmazonSSMAutomationRole managed policy
EventRule:
Type: AWS::Events::Rule
Properties:
EventBusName: default
EventPattern:
source:
- aws.ec2
detail-type:
- EC2 Instance State-change Notification
detail:
state:
- running
Name: cloudwatch-install-configure-rule
State: ENABLED
Targets:
- Id: cloudwatch-ssm-document
#Arn: >-
# arn:aws:ssm:us-east-1:XXXXXXXXXXX:automation-definition/CloudwatchAgent_Install_Configure_MemoryMetrics_OnEC2Linux
#arn:${Partition}:ssm:${Region}:${Account}:document/${DocumentName}
Arn: !Sub arn:${AWS::Partition}:ssm:${AWS::Region}:${AWS::AccountId}:automation-definition/CloudwatchAgent_Install_Configure_MemoryMetrics_OnEC2Linux
RoleArn: !Sub ${AutomationIAMRole.Arn}
InputTransformer:
InputPathsMap:
instance: $.detail.instance-id
InputTemplate: '{"InstanceId":[<instance>]}'
DeadLetterConfig:
Arn: !Sub ${SQSQueue.Arn}
SQSQueue:
Type: AWS::SQS::Queue
Properties:
MaximumMessageSize: 262144 #integer value from 1,024 bytes (1 KiB) to 262,144 bytes (256 KiB). The default value is 262,144 (256 KiB).
MessageRetentionPeriod: 345600 # 4 Days
QueueName: DLQ-for-event-bridge
Outputs:
SsmAutomationRoleName:
Description: Name of the SSM Automation IAM Role
Value: !Ref SsmAutomationRole
IAMRoleArn:
Description: ARN of the created IAM role
Value: !GetAtt AutomationIAMRole.Arn
IAMRoleName:
Description: Name of the created IAM role
Value: !Ref AutomationIAMRole
AutomationIAMRoleArn:
Description: EventBridge Invokation role name to Start Automation Execution
Value: !GetAtt AutomationIAMRole.Arn
SQSQueueArn:
Description: SQS Queue to capture EventBridge execution errors
Value: SQSQueue.Arn
Schritte:
1. Den oben gezeigten CloudFormation-Stack über die CLI oder die Konsole anlegen:

Schritt 1
2. Bereitgestelltes Systems Manager Automation Document prüfen: Das Custom Document umfasst 3 Schritte:
- Die zugewiesene Rolle der Ziel-Instanz ermitteln und die Managed Policy CloudWatchAgentServer an die Instanz-Rolle anhängen.
- Den CloudWatch Agent auf der Ziel-Instanz installieren.
- Den CloudWatch Agent so konfigurieren, dass er Metriken an CloudWatch sendet.

Schritt 2
3. Amazon-EventBridge-Regel überprüfen:

Schritt 3
Event Pattern — Über das folgende Event Pattern werden eingehende Events mit Status "running" gefiltert.
Event
{
"detail-type": ["EC2 Instance State-change Notification"],
"source": ["aws.ec2"],
"detail": {
"state": ["running"]
}
}
Die EventBridge Input Transformation nutzt den unten gezeigten Input Transformer, um die ID der Ziel-Instanz zu extrahieren.
Input transformer
Input path
{
"instance": "$.detail.instance-id"
}
Input template
{
"InstanceId":[<instance>]
}
4. Neue Instanz erstellen:
- Auf der Test-EC2-Instanz muss der AWS Systems Manager Agent (SSM Agent) installiert sein, damit der Systems Manager mit ihr kommunizieren kann. Außerdem brauchen die EC2-Instanzen Netzwerkzugriff auf die öffentlichen Systems Manager Service Endpoints oder auf AWS PrivateLink VPC Endpoints für Systems Manager. (Hinweis: Ich habe das Amazon-Linux-2023-AMI verwendet und es in der Default-VPC gestartet.)
- Legen Sie eine Rolle "EC2ssmCoreRole" mit der AWS Managed Policy "AmazonSSMManagedInstanceCore" an, damit der Systems Manager die EC2-Instanz verwalten kann. Erstellen Sie ein Instance Profile und weisen Sie die Rolle dem Instance Profile zu. Starten Sie anschließend eine Test-Instanz (t2.micro). Für den Start der Test-Instanz habe ich das folgende CloudFormation-Beispiel-Template verwendet.
AWSTemplateFormatVersion: 2010-09-09
Description: CloudFormation template to create EC2 instance with SSM role
Parameters:
LatestAmiId:
Type: 'AWS::SSM::Parameter::Value<AWS::EC2::Image::Id>'
Default: '/aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-gp2'
Resources:
EC2Role:
Type: AWS::IAM::Role
Properties:
RoleName: EC2ssmCoreRole
Description: IAM role to allow Systems Manager to manage the EC2 instance
AssumeRolePolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Principal:
Service: ec2.amazonaws.com
Action: sts:AssumeRole
ManagedPolicyArns:
- arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore
EC2InstanceProfile:
Type: AWS::IAM::InstanceProfile
Properties:
Roles:
- !Ref EC2Role
InstanceProfileName: EC2ssmCoreRole
EC2Instance:
Type: AWS::EC2::Instance
Properties:
ImageId: !Ref LatestAmiId
InstanceType: t2.micro
IamInstanceProfile: !Ref EC2InstanceProfile
Tags:
- Key: Name
Value: "Test-instance"
- Key: Env
Value: "test-environment"
Outputs:
EC2ssmCoreRoleName:
Description: Name of the SSM Automation IAM Role
Value: !Ref EC2Role
EC2ssmCoreRoleArn:
Description: ARN of the created IAM role
Value: !GetAtt EC2Role.Arn
EC2InstanceId:
Description: Instance Id
Value: !Ref EC2Instance
5. Prüfen Sie, ob die EventBridge-Regel ausgelöst wurde, sobald die Instanz in den Status "running" wechselte und der Systems Manager die Automation gestartet sowie den CloudWatch Agent auf der EC2-Instanz installiert und für das Senden von Memory-Metriken konfiguriert hat.
6. Ausführung der Systems Manager Automation prüfen — Sobald die Instanz in den Status "running" wechselt, löst dies die EventBridge-Regel aus, die das Systems Manager Automation Document startet.

Schritt 6
7. Status und Fortschritt der Automation-Ausführung prüfen — sie führt 3 Schritte aus:
- Die CloudWatch Agent Server Policy an die Instanz-Rolle anhängen
- Den CloudWatch Agent auf der Ziel-Instanz installieren
- Den CloudWatch Agent konfigurieren, indem die Konfigurationsdatei aus dem Systems Manager Parameter Store geladen wird, damit eigene Memory-Metriken gesendet werden.

Schritt 7

Schritt 7
8. Stellen Sie sicher, dass der CloudWatch Agent installiert und so konfiguriert ist, dass er eigene Memory-Metriken an CloudWatch sendet.

Schritt 8
Fazit — Wir haben gezeigt, wie sich Installation und Konfiguration des CloudWatch Agent für neu gestartete EC2-Instanzen vollständig automatisieren lassen und wie eigene Memory-Metriken über Systems Manager Automation und AWS EventBridge ohne manuellen Eingriff an CloudWatch übermittelt werden.