You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何配置CloudWatch将CreateLogGroup消息发送至EventBridge?

问题:CloudTrail部署报错,无法转发CloudWatch CreateLogGroup事件到EventBridge

我需要让CloudWatch将CreateLogGroup事件发送至EventBridge,已知该需求需通过CloudTrail转发,但部署CloudFormation模板时持续报错:

AWS::CloudTrail::Trail - "Invalid request provided: Incorrect S3 bucket policy is detected for bucket"

原CloudFormation模板:

AWSTemplateFormatVersion: '2010-09-09'
Outputs:
  HelloFunction:
    Value:
      Ref: HelloFunction
  WatcherFunction:
    Value:
      Ref: WatcherFunction
  WatcherTrailBucket:
    Value:
      Ref: WatcherTrailBucket
Parameters:
  MemorySizeDefault:
    Default: '512'
    Type: String
  RuntimeVersion:
    Default: '3.8'
    Type: String
  TimeoutDefault:
    Default: '5'
    Type: String
Resources:
  HelloFunction:
    Properties:
      Code:
        ZipFile: |
          def handler(event, context):
              print (event)
      Handler: index.handler
      MemorySize:
        Ref: MemorySizeDefault
      Role:
        Fn::GetAtt:
        - HelloFunctionRole
        - Arn
      Runtime:
        Fn::Sub: python${RuntimeVersion}
      Timeout:
        Ref: TimeoutDefault
    Type: AWS::Lambda::Function
  HelloFunctionRole:
    Properties:
      AssumeRolePolicyDocument:
        Statement:
        - Action: sts:AssumeRole
          Effect: Allow
          Principal:
            Service: lambda.amazonaws.com
        Version: '2012-10-17'
      Policies:
      - PolicyDocument:
          Statement:
          - Action:
            - logs:CreateLogGroup
            - logs:CreateLogStream
            - logs:PutLogEvents
            Effect: Allow
            Resource: '*'
          Version: '2012-10-17'
        PolicyName:
          Fn::Sub: hello-function-role-policy-${AWS::StackName}
    Type: AWS::IAM::Role
  WatcherFunction:
    Properties:
      Code:
        ZipFile: |
          def handler(event, context):
              print (event)
      Handler: index.handler
      MemorySize:
        Ref: MemorySizeDefault
      Role:
        Fn::GetAtt:
        - WatcherFunctionRole
        - Arn
      Runtime:
        Fn::Sub: python${RuntimeVersion}
      Timeout:
        Ref: TimeoutDefault
    Type: AWS::Lambda::Function
  WatcherFunctionRole:
    Properties:
      AssumeRolePolicyDocument:
        Statement:
        - Action: sts:AssumeRole
          Effect: Allow
          Principal:
            Service: lambda.amazonaws.com
        Version: '2012-10-17'
      Policies:
      - PolicyDocument:
          Statement:
          - Action:
            - logs:CreateLogGroup
            - logs:CreateLogStream
            - logs:PutLogEvents
            Effect: Allow
            Resource: '*'
          Version: '2012-10-17'
        PolicyName:
          Fn::Sub: watcher-function-role-policy-${AWS::StackName}
    Type: AWS::IAM::Role
  WatcherEventRule:
    Type: AWS::Events::Rule
    Properties:
      EventPattern:
        source:
          - aws.logs
        detail-type:
          - "AWS API Call via CloudTrail"
        detail:
          eventName:
            - CreateLogGroup
      Targets:
      - Id:
          Fn::Sub: watcher-event-rule-${AWS::StackName}
        Arn:
          Fn::GetAtt:
          - WatcherFunction
          - Arn
      State: ENABLED
  WatcherEventRulePermission:
    Type: AWS::Lambda::Permission
    Properties:
      Action: lambda:InvokeFunction
      Principal: events.amazonaws.com
      FunctionName:
        Ref: WatcherFunction
      SourceArn:
        Fn::GetAtt:
        - WatcherEventRule
        - Arn
  WatcherTrailBucket:
    Type: AWS::S3::Bucket
  WatcherTrailBucketPolicy:
    DependsOn:
    - WatcherTrailBucket
    Type: AWS::S3::BucketPolicy
    Properties:
      Bucket:
         Ref: WatcherTrailBucket
      PolicyDocument:
        Version: '2012-10-17'
        Statement:
          - Effect: Allow
            Principal:
              Service: cloudtrail.amazonaws.com
            Action: s3:GetBucketAcl
            Resource: "*"
            Condition: {}
          - Effect: Allow
            Principal:
              Service: cloudtrail.amazonaws.com
            Action: s3:PutObject
            Resource: "*"
            Condition:
              StringEquals:
                s3:x-amz-acl: bucket-owner-full-control
  WatcherTrail:
    Type: AWS::CloudTrail::Trail
    Properties:
      EventSelectors:
        - ReadWriteType: All
      IsLogging: true
      S3BucketName:
        Ref: WatcherTrailBucket
      IsLogging: true
      S3KeyPrefix: logs/

修复方案

问题点说明

  1. S3桶策略Resource通配符不合法:CloudTrail要求桶策略必须明确指定目标桶的ARN,不能使用"*",否则会触发权限校验错误。
  2. Trail资源重复配置IsLogging:模板中WatcherTrail资源里写了两次IsLogging: true,属于冗余配置,需要移除其中一个。
  3. 缺少账户ID验证条件:为了安全性,桶策略应添加条件限制只有当前AWS账户的CloudTrail能写入该桶。

修改后的完整模板

AWSTemplateFormatVersion: '2010-09-09'
Outputs:
  HelloFunction:
    Value:
      Ref: HelloFunction
  WatcherFunction:
    Value:
      Ref: WatcherFunction
  WatcherTrailBucket:
    Value:
      Ref: WatcherTrailBucket
Parameters:
  MemorySizeDefault:
    Default: '512'
    Type: String
  RuntimeVersion:
    Default: '3.8'
    Type: String
  TimeoutDefault:
    Default: '5'
    Type: String
Resources:
  HelloFunction:
    Properties:
      Code:
        ZipFile: |
          def handler(event, context):
              print (event)
      Handler: index.handler
      MemorySize:
        Ref: MemorySizeDefault
      Role:
        Fn::GetAtt:
        - HelloFunctionRole
        - Arn
      Runtime:
        Fn::Sub: python${RuntimeVersion}
      Timeout:
        Ref: TimeoutDefault
    Type: AWS::Lambda::Function
  HelloFunctionRole:
    Properties:
      AssumeRolePolicyDocument:
        Statement:
        - Action: sts:AssumeRole
          Effect: Allow
          Principal:
            Service: lambda.amazonaws.com
        Version: '2012-10-17'
      Policies:
      - PolicyDocument:
          Statement:
          - Action:
            - logs:CreateLogGroup
            - logs:CreateLogStream
            - logs:PutLogEvents
            Effect: Allow
            Resource: '*'
          Version: '2012-10-17'
        PolicyName:
          Fn::Sub: hello-function-role-policy-${AWS::StackName}
    Type: AWS::IAM::Role
  WatcherFunction:
    Properties:
      Code:
        ZipFile: |
          def handler(event, context):
              print (event)
      Handler: index.handler
      MemorySize:
        Ref: MemorySizeDefault
      Role:
        Fn::GetAtt:
        - WatcherFunctionRole
        - Arn
      Runtime:
        Fn::Sub: python${RuntimeVersion}
      Timeout:
        Ref: TimeoutDefault
    Type: AWS::Lambda::Function
  WatcherFunctionRole:
    Properties:
      AssumeRolePolicyDocument:
        Statement:
        - Action: sts:AssumeRole
          Effect: Allow
          Principal:
            Service: lambda.amazonaws.com
        Version: '2012-10-17'
      Policies:
      - PolicyDocument:
          Statement:
          - Action:
            - logs:CreateLogGroup
            - logs:CreateLogStream
            - logs:PutLogEvents
            Effect: Allow
            Resource: '*'
          Version: '2012-10-17'
        PolicyName:
          Fn::Sub: watcher-function-role-policy-${AWS::StackName}
    Type: AWS::IAM::Role
  WatcherEventRule:
    Type: AWS::Events::Rule
    Properties:
      EventPattern:
        source:
          - aws.logs
        detail-type:
          - "AWS API Call via CloudTrail"
        detail:
          eventName:
            - CreateLogGroup
      Targets:
      - Id:
          Fn::Sub: watcher-event-rule-${AWS::StackName}
        Arn:
          Fn::GetAtt:
          - WatcherFunction
          - Arn
      State: ENABLED
  WatcherEventRulePermission:
    Type: AWS::Lambda::Permission
    Properties:
      Action: lambda:InvokeFunction
      Principal: events.amazonaws.com
      FunctionName:
        Ref: WatcherFunction
      SourceArn:
        Fn::GetAtt:
        - WatcherEventRule
        - Arn
  WatcherTrailBucket:
    Type: AWS::S3::Bucket
  WatcherTrailBucketPolicy:
    DependsOn:
    - WatcherTrailBucket
    Type: AWS::S3::BucketPolicy
    Properties:
      Bucket:
         Ref: WatcherTrailBucket
      PolicyDocument:
        Version: '2012-10-17'
        Statement:
          - Effect: Allow
            Principal:
              Service: cloudtrail.amazonaws.com
            Action: s3:GetBucketAcl
            Resource: !Sub "arn:aws:s3:::${WatcherTrailBucket}"
            Condition:
              StringEquals:
                aws:SourceAccount: !Ref AWS::AccountId
          - Effect: Allow
            Principal:
              Service: cloudtrail.amazonaws.com
            Action: s3:PutObject
            Resource: !Sub "arn:aws:s3:::${WatcherTrailBucket}/logs/*"
            Condition:
              StringEquals:
                s3:x-amz-acl: bucket-owner-full-control
                aws:SourceAccount: !Ref AWS::AccountId
  WatcherTrail:
    Type: AWS::CloudTrail::Trail
    Properties:
      EventSelectors:
        - ReadWriteType: All
          IncludeManagementEvents: true
          DataResources: []
      IsLogging: true
      S3BucketName:
        Ref: WatcherTrailBucket
      S3KeyPrefix: logs/

关键修改说明

  • 桶策略Resource:将"*"替换为具体的桶ARN(!Sub "arn:aws:s3:::${WatcherTrailBucket}")和桶内路径ARN(!Sub "arn:aws:s3:::${WatcherTrailBucket}/logs/*")。
  • 添加SourceAccount条件:通过aws:SourceAccount: !Ref AWS::AccountId限制只有当前账户的CloudTrail能访问桶,提升安全性。
  • 移除重复的IsLogging:删除Trail资源中重复的IsLogging: true配置。
  • 完善EventSelectors:显式添加IncludeManagementEvents: true确保管理事件(如CreateLogGroup)被捕获。

内容的提问来源于stack exchange,提问作者Justin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.05 04:21:49