top of page
検索
  • 執筆者の写真mon

クロスアカウントでCodeCommit リポジトリの変更を通知する

はじめに

あるシステムにおいて、CodeCommitのあるAWSアカウントから別のアカウントのCodePipelineを起動したいという要件がありました。


別のアカウントのリポジトリを参照してCodePipelineを起動するには、主に「別アカウントのリポジトリの変更を検知してパイプラインを起動する」と「パイプラインから別アカウントのリポジトリリソースの参照」が必要になります。

この記事ではEventBridgeを使って、アカウントをまたいで通知する方法について説明します。


この記事のゴール

この記事のゴールは、CodeCommitのmasterブランチに変更が加わったら別アカウントでそれを検知できるところまでです。

クロスアカウントでのCodePipelineの実行については次の機会にでも説明します。


リポジトリアカウントの環境を作る

以降はアカウントは以下のように呼びます

  • リポジトリアカウント : CodeCommitのRepositoryがある方のアカウント

  • パイプラインアカウント : CodePipelineがある方のアカウント

リポジトリアカウント側で以下のCFn(CloudFormation)テンプレートを使って

  • CodeCommit リポジトリ

  • Event Rule

を作成します。さらに、Eventの内容や状態を確認するためにCloudWatch Logsへも書き込むように構成します。

(CloudWatch Logsは確認用なので不要になったら削除して良いです)

AWSTemplateFormatVersion: '2010-09-09'

Parameters:
  # イベント通知先のAWSアカウントID
  ExternalAccountId:
    Type: String
  TargetBranchName:
    Type: String
Resources:
  # リポジトリ
  Repo:
    DeletionPolicy: Retain
    Type: AWS::CodeCommit::Repository
    Properties:
      RepositoryName: "Repo"

  # 流れているイベントを確認するためのLogGroup
  # 不要になったら削除してOK
  EventDebugLogGroup:
    Type: AWS::Logs::LogGroup
    Properties:
      LogGroupName: !Sub "/aws/events/${AWS::StackName}-EventDebugLog"
  # RuleからLogsに書き込むためのポリシー
  EventDebugLogGroupPolicy:
    Type: AWS::Logs::ResourcePolicy
    Properties:
      PolicyName: !Sub "${AWS::StackName}-EventDebugLogGroupPolicy"
      PolicyDocument: !Sub |
          {
            "Version": "2012-10-17",
            "Statement": [
              {
                "Effect": "Allow",
                "Principal": {
                  "Service": [
                    "events.amazonaws.com",
                    "delivery.logs.amazonaws.com"
                  ]
                },
                "Action": [
                  "logs:CreateLogStream",
                  "logs:PutLogEvents"
                ],
                "Resource": "*"
              }
            ]
          }

  # CodeCommitからのイベントで起動するRuleのRole
  CodeCommitBranchEventRuleRole:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Version: 2012-10-17
        Statement:
          - Effect: Allow
            Principal:
              Service:
                - events.amazonaws.com
                - delivery.logs.amazonaws.com
            Action: sts:AssumeRole
      Path: /
      Policies:
        # 別アカウントのEventBusにイベントを送信する
        - PolicyName: default
          PolicyDocument:
            Version: 2012-10-17
            Statement:
              - Effect: Allow
                Action: events:PutEvents
                Resource: !Sub arn:aws:events:${AWS::Region}:${ExternalAccountId}:event-bus/default

  # CloudWatchEventの実行ルール
  CodeCommitBranchEventRule:
    Type: AWS::Events::Rule
    Properties:
      Name: !Sub "${AWS::StackName}-CodeCommitBranchEventRule"
      EventPattern:
        source:
          - aws.codecommit
        detail-type:
          - CodeCommit Repository State Change
        resources:
          - !Sub "arn:aws:codecommit:${AWS::Region}:${AWS::AccountId}:${Repo.Name}"
        detail:
          event:
            - referenceCreated
            - referenceUpdated
          referenceType:
            - branch
          referenceName:
            - !Ref TargetBranchName
      Targets:
        - Arn: !Sub arn:aws:events:${AWS::Region}:${ExternalAccountId}:event-bus/default
          RoleArn: !GetAtt CodeCommitBranchEventRuleRole.Arn
          Id: external
        # 動作確認用CloudWatch Logs出力
        - Arn: !GetAtt EventDebugLogGroup.Arn
          Id: log-debug

CFn Stackが作成されたら EventBridgeでRuleが作成されていることを確認します。

(余談ですが、AWSとしてはアカウントIDは秘匿すべき情報ではないというアナウンスをしていてもなんとなく隠したい気持ちになります)


リポジトリにソースをPushする

CodeCommitリポジトリのmasterブランチに変更をpushして、CloudWatch Logsにイベントが記録されることを確認します。

(この時点でTargetに指定しているパイプラインアカウントのEventBusにもメッセージは送ろうとしていますが、まだパイプラインアカウント側で許可していないのでエラーになっていることがモニタリングで記録されているはずです)


パイプラインアカウントの環境を作る

パイプラインアカウント側で以下のCFn(CloudFormation)テンプレートを使って

  • Event Rule

を作成します。リポジトリアカウントと同様に、Eventの内容や状態を確認するためにCloudWatch Logsへも書き込むように構成します。

(こちらもCloudWatch Logsは確認用なので不要になったら削除して良いです)

AWSTemplateFormatVersion: '2010-09-09'

Parameters:
  # リポジトリののAWSアカウントID
  RepositoryAccountId:
    Type: String
  # リポジトリ名
  RepositoryName:
    Type: String
  # 変更を検知するCodeCommitのブランチ名
  TargetBranchName:
    Type: String

Resources:

  # EventBusがリポジトリアカウントからのメッセージを受信することを許可
  EventBusPolicy:
    Type: AWS::Events::EventBusPolicy
    Properties:
      StatementId: default
      Statement:
        Effect: Allow
        Principal:
          AWS: !Sub arn:aws:iam::${RepositoryAccountId}:root
        Action: events:PutEvents
        Resource: !Sub arn:aws:events:${AWS::Region}:${AWS::AccountId}:event-bus/default

  # 流れているイベントを確認するためのLogGroup
  # 不要になったら削除してOK
  EventDebugLogGroup:
    Type: AWS::Logs::LogGroup
    Properties:
      LogGroupName: !Sub "/aws/events/${AWS::StackName}-EventDebugLog"
  # RuleからLogsに書き込むためのポリシー
  EventDebugLogGroupPolicy:
    Type: AWS::Logs::ResourcePolicy
    Properties:
      PolicyName: !Sub "${AWS::StackName}-EventDebugLogGroupPolicy"
      PolicyDocument: !Sub |
          {
            "Version": "2012-10-17",
            "Statement": [
              {
                "Effect": "Allow",
                "Principal": {
                  "Service": [
                    "events.amazonaws.com",
                    "delivery.logs.amazonaws.com"
                  ]
                },
                "Action": [
                  "logs:CreateLogStream",
                  "logs:PutLogEvents"
                ],
                "Resource": "*"
              }
            ]
          }

  # CloudWatchEventの実行ルール
  CodeCommitBranchEventRule:
    Type: AWS::Events::Rule
    Properties:
      Name: !Sub "${AWS::StackName}-CodeCommitBranchEventRule"
      EventPattern:
        source:
          - aws.codecommit
        detail-type:
          - CodeCommit Repository State Change
        resources:
          - !Sub "arn:aws:codecommit:${AWS::Region}:${RepositoryAccountId}:${RepositoryName}"
        detail:
          event:
            - referenceCreated
            - referenceUpdated
          referenceType:
            - branch
          referenceName:
            - !Ref TargetBranchName
      Targets:
        # 動作確認用CloudWatch Logs出力
        - Arn: !GetAtt EventDebugLogGroup.Arn
          Id: log-debug

CFn Stackが作成されたら EventBridgeでRuleが作成されていることを確認します。


確認

再度リポジトリに変更をpushします。

パイプラインアカウントのRuleのターゲットに指定したCloudWatch Logsにメッセージが到達していることを確認します。


ちなみに、リポジトリアカウントのLogsのメッセージとパイプラインアカウントのメッセージは当たり前なのですが同じですね。

また、私の評価した環境ではそれぞれのログの記録時刻は同時でした。

これでリポジトリの変更イベントを別のアカウントで検出することができました。

後はパイプラインアカウント側のRuleのTriggerで好きな処理を起動することができます。

次回はCodePipelineの起動までいってみたいと思います。



閲覧数:27回0件のコメント

最新記事

すべて表示

データ状態によりSQLを異常終了させたい

はじめに 夜間バッチのデータ更新等では、入力テーブルが0件などのデータの状態によってSQLを継続実行せず、エラー終了したいケースがあります。 出力テーブルが0件で作成されると、後続の参照処理大きな障害を引き起こしかねないケースで、中断することで前日状態を維持したい場合です。 例えば、全件洗いがえのマスター系データが障害により0件で連携されたなど、夜間バッチの障害では時々出会う事象です。 前提 SQ

bottom of page