Cloud Intelligence™Cloud Intelligence™

Cloud Intelligence™

CloudWatch Agent automatisiert ausrollen – mit Systems Manager und EventBridge

By Nikhil PawarMar 28, 20247 min read

Diese Seite ist auch in English, Español, Français, Italiano, 日本語 und Português verfügbar.

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:

  1. 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.
  2. 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.
  3. Automation Document im Systems Manager erstellen — Mit CloudFormation bauen wir ein Custom Runbook, das den CloudWatch Agent installiert und konfiguriert.
  4. 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.
  5. EventBridge-Regel erstellen — CloudFormation legt eine EventBridge-Regel an, die EC2-Instance-Events mit Status "running" filtert und die SSM-Automation auslöst.
  6. 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:

  1. Die zugewiesene Rolle der Ziel-Instanz ermitteln und die Managed Policy CloudWatchAgentServer an die Instanz-Rolle anhängen.
  2. Den CloudWatch Agent auf der Ziel-Instanz installieren.
  3. 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.