是否可以在不同的帐户中创建规则?

Is it possible to create a rule in a different account?

我正在尝试使用 CDK 在不同的帐户中创建事件总线规则:

// Getting source bus ARN
const sourceBusArn = Stack.of(this).formatArn({
  region: this.region,
  service: 'events',
  account: Config.sourceAccount,
  resource: 'event-bus',
  resourceName: Config.sourceBusName,
});

// Retrieving source bus
const sourceBus = EventBus.fromEventBusArn(this, 'SourceBus', sourceBusArn);

// creating rule to forward source bus events to target buses
new Rule(this, 'CrossAccountSourceRule', {
  eventPattern: Config.eventPattern,
  eventBus: sourceBus,
  targets: [new EventBusTarget(targetBus)],
});

这里 Config.sourceAccount 是一个外部账户,不同于正在执行的 CDK。 Config.sourceBusName 总线存在于该账户中,并且具有允许从外部账户创建规则的策略同一组织。

但尝试创建规则会引发异常 Event bus <bus-in-external-account> does not exist. Status Code: 400。是否可以像这样或任何其他方式在不同的帐户中创建规则?

找到解决方案。当从源帐户而不是 EventBus.fromEventBusArn 导入总线时,使用 EventBus.fromEventBusAttributes - 但有一个转折:将源总线 ARN 作为总线名称和总线 ARN 传递:

// Getting source bus ARN
const sourceBusArn = Stack.of(this).formatArn({
  region: this.region,
  service: 'events',
  account: Config.sourceAccount,
  resource: 'event-bus',
  resourceName: Config.sourceBusName,
});

// Retrieving source bus. Pass ARN both as name and Arn props.
const sourceCoreBus = EventBus.fromEventBusAttributes(this, 'SourceCoreBus', {
  eventBusName: sourceBusArn,
  eventBusArn: sourceBusArn,
  eventBusPolicy: '',
});

// creating rule to forward source bus events to target buses
new Rule(this, 'CrossAccountSourceRule', {
  eventPattern: Config.eventPattern,
  eventBus: sourceBus,
  targets: [new EventBusTarget(targetBus)],
});

这将在外部帐户中创建规则。不要忘记您尝试访问的总线必须具有所需的权限策略,例如

{
   "Version":"2012-10-17",
   "Statement":[
      {
         "Effect":"Allow",
         "Principal":{
            "AWS":"<id-of-account-that-creates-rules>"
         },
         "Action":[
            "events:DescribeEventBus",
            "events:PutRule",
            "events:PutTargets",
            "events:DeleteRule",
            "events:RemoveTargets",
            "events:DisableRule",
            "events:EnableRule",
            "events:TagResource",
            "events:UntagResource",
            "events:DescribeRule",
            "events:ListTargetsByRule",
            "events:ListTagsForResource"
         ],
         "Resource":[
            "arn:aws:events:us-west-2:<id-of-source-account>:rule/<bus-name>",
            "arn:aws:events:us-west-2:<id-of-source-account>:rule/<bus-name>/*"
         ]
      }
   ]
}

更新: 一点解释。上述解决方案之所以有效,是因为在底层规则构造使用了级别 1 CfnRule construct. And one of its props EventBusName can be either bus name or ARN。因此,当传递 ARN 而不是名称时 - 它就这样使用。生成的 CloudFormation 模板如下所示(相关片段):

  "CrossAccountSourceRuleAF67328": {
   "Type": "AWS::Events::Rule",
   "Properties": {
    "EventBusName": {
     "Fn::Join": [
      "",
      [
       "arn:",
       {
        "Ref": "AWS::Partition"
       },
       ":events:",
       {
        "Ref": "AWS::Region"
       },
       ":1234567890:event-bus/bus-name"
      ]
     ]
    },