1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

[AWS, CloudFormation] Amazon Connect 階層グループ更新イベントの自動同期方法 🚀

Last updated at Posted at 2025-04-16

1. イントロダクション

1.1 ソリューション概要と利点

Amazon Connect の階層グループ(ユーザー階層グループ)の変更を自動的に検知し、その情報を S3 に保存する機構です
まるで「階層グループの変化を嗅ぎ分ける優秀な番犬」のような存在🐶
よくあるアーキテクチャですがCloudFormation の記述含めご説明します

主な利点

利点 説明
リアルタイム同期 階層グループの変更を即座に検知し、S3に反映
データの永続化 重要な階層情報を安全にS3に保存
自動化 人手を介さずに自動的に同期処理を実行
監査性 変更履歴をS3に保存することで、監査証跡として活用可能
コスト効率 サーバーレスアーキテクチャにより、運用コストを最小化

2. アーキテクチャ解説

2.1 全体フロー

[Amazon Connect] → [CloudTrail] → [EventBridge] → [Lambda] → [S3]

2.2 各コンポーネントの役割

コンポーネント 役割 特徴
Amazon Connect 階層グループの管理 コールセンターの組織構造を管理
CloudTrail API呼び出しの記録 すべてのAPIアクションをログとして記録
EventBridge イベントルーティング 特定のイベントを検知してLambdaをトリガー
Lambda 処理実行 階層情報を取得しS3に保存
S3 データ保存 階層情報をJSON形式で保存

実際の使用イメージとしてはバックエンドAPIが適宜S3の階層グループを参照しに行き、最新の情報を取得できるといったものです

2.3 データフローの詳細

  1. イベント発生

    • Amazon Connectで階層グループの変更が発生
    • 変更操作(作成/更新/削除)が実行される
  2. イベント検知

    • CloudTrailがAPI呼び出しを記録
    • EventBridgeが特定のイベントパターンを検知
  3. 処理実行

    • Lambda関数がトリガーされる
    • 最新の階層グループ情報を取得
  4. データ保存

    • 取得した情報をJSON形式でS3に保存

3. 実装手順

connect-hierarchy-sync.yml
AWSTemplateFormatVersion: 2010-09-09
Description: "Lambda Function Stack For Amazon Connect Hierarchy Sync Stack"

# -------------------------------------
# Metadata
# -------------------------------------
Metadata:
  AWS::CloudFormation::Interface:
    ParameterGroups:
      - Label:
          default: "Project Configuration"
        Parameters:
          - ProjectName
          - Environment
      - Label:
          default: "Lambda Configuration"
        Parameters:
          - LambdaArchiveBucketName
          - LambdaArchiveBucketObjectKey
          - LambdaHandler
          - LambdaMemorySize
          - LambdaTimeout
          - LambdaRuntime
      - Label:
          default: "EventBridge Configuration"
        Parameters:
          - EventBridgeRuleName
          - ConnectInstanceId
      - Label:
          default: "S3 Configuration"
        Parameters:
          - ConnectHierarchyBucketName
          - ECSTaskRoleArn

# -------------------------------------
# Input parameters
# -------------------------------------
Parameters:
  ProjectName:
    Description: "Enter the project name. (ex: your-project-name)"
    Type: String
    MinLength: 1
    ConstraintDescription: "ProjectName must be enter."
    Default: your-project-name
  Environment:
    Description: "Select the environment."
    Type: String
    AllowedValues:
      - dev
      - stg
      - prd
    ConstraintDescription: "Environment must be select."
  LambdaArchiveBucketName:
    Description: "Enter the S3 bucket name for storing Lambda function deployment package. (ex: your-project-name-<environment>-lambda-function-archive)"
    Type: String
  LambdaArchiveBucketObjectKey:
    Description: "Enter the Lambda function package file (zip) object key of the Lambda archive bucket. (ex: connect-hierarchy-sync/lambda_function.zip)"
    Type: String
  LambdaHandler:
    Description: "Enter the Lambda function name for Connect hierarchy sync. (ex: lambda_function.lambda_handler)"
    Type: String
    Default: lambda_function.lambda_handler
  LambdaMemorySize:
    Description: "Enter the Lambda function memory size (MiB). (default: 128)"
    Type: Number
    Default: 128
    MinValue: 128
    MaxValue: 512
  LambdaTimeout:
    Description: "Enter the Lambda function timeout second. (default: 60)"
    Type: Number
    Default: 60
  LambdaRuntime:
    Description: "Select the Lambda function runtime. (default: python3.13)"
    Type: String
    AllowedValues:
      - python3.13
    Default: python3.13
    ConstraintDescription: "Runtime must be select."
  EventBridgeRuleName:
    Description: "Enter the EventBridge rule name for Connect hierarchy sync. (ex: notice-connect-hierarchy-sync-your-project-name-<environment>)"
    Type: String
  ConnectInstanceId:
    Description: "Enter the Amazon Connect Instance ID."
    Type: String
  ConnectHierarchyBucketName:
    Description: "Enter the S3 bucket name for storing Amazon Connect hierarchy group data. (ex: your-project-name-<environment>-connect-hierarchy-sync)"
    Type: String
  ECSTaskRoleArn:
    Description: "Specify the IAM Role ARN required to run the application. (ex: arn:aws:iam::012345678910:role/ECSTaskRole)"
    Type: String

# -------------------------------------
# Resources
# -------------------------------------
Resources:
  # -------------------------------------
  # IAM
  # -------------------------------------
  LambdaFunctionRolePolicy:
    DeletionPolicy: Retain
    UpdateReplacePolicy: Retain
    Type: AWS::IAM::ManagedPolicy
    Properties:
      ManagedPolicyName: !Sub LambdaToConnectAndS3Access-${Environment}
      PolicyDocument:
        Version: 2012-10-17
        Statement:
          - Effect: Allow
            Action: logs:CreateLogGroup
            Resource: !Sub arn:aws:logs:${AWS::Region}:${AWS::AccountId}:*
          - Effect: Allow
            Action:
              - logs:CreateLogStream
              - logs:PutLogEvents
            Resource: !Sub arn:aws:logs:${AWS::Region}:${AWS::AccountId}:log-group:/aws/lambda/${ProjectName}-${Environment}-connect-hierarchy-sync:*
          - Effect: Allow
            Action:
              - connect:ListUserHierarchyGroups
            Resource: !Sub arn:aws:connect:${AWS::Region}:${AWS::AccountId}:instance/${ConnectInstanceId}
          - Effect: Allow
            Action:
              - s3:PutObject
            Resource: !Sub arn:aws:s3:::${ConnectHierarchyBucketName}/*
  LambdaFunctionRole:
    DeletionPolicy: Retain
    UpdateReplacePolicy: Retain
    Type: AWS::IAM::Role
    Properties:
      RoleName: !Sub LambdaToConnectAndS3Role-${Environment}
      AssumeRolePolicyDocument:
        Version: 2012-10-17
        Statement:
          - Effect: Allow
            Principal:
              Service: lambda.amazonaws.com
            Action: sts:AssumeRole
      Path: /
      ManagedPolicyArns:
        - !Ref LambdaFunctionRolePolicy

  # -------------------------------------
  # Lambda
  # -------------------------------------
  LambdaFunction:
    Type: AWS::Lambda::Function
    Properties:
      Code:
        S3Bucket: !Ref LambdaArchiveBucketName
        S3Key: !Ref LambdaArchiveBucketObjectKey
      Description: "This function syncs Amazon Connect hierarchy data to S3."
      Environment:
        Variables:
          CONNECT_INSTANCE_ID: !Ref ConnectInstanceId
          S3_BUCKET_NAME: !Ref ConnectHierarchyBucketName
      FunctionName: !Sub ${ProjectName}-${Environment}-connect-hierarchy-sync
      Handler: !Ref LambdaHandler
      MemorySize: !Ref LambdaMemorySize
      PackageType: Zip
      Timeout: !Ref LambdaTimeout
      Role: !GetAtt LambdaFunctionRole.Arn
      Runtime: !Ref LambdaRuntime
  LambdaFunctionPermission:
    Type: AWS::Lambda::Permission
    Properties:
      Action: lambda:InvokeFunction
      FunctionName: !GetAtt LambdaFunction.Arn
      Principal: events.amazonaws.com
      SourceArn: !GetAtt ConnectHierarchyRule.Arn

  # -------------------------------------
  # EventBridge
  # -------------------------------------
  ConnectHierarchyRule:
    Type: AWS::Events::Rule
    Properties:
      Name: !Ref EventBridgeRuleName
      Description: "Amazon Connect の階層グループ変更時に指定する Lambda 関数をトリガー"
      EventPattern:
        source:
          - aws.connect
        detail-type:
          - AWS API Call via CloudTrail
        detail:
          eventSource:
            - connect.amazonaws.com
          eventName:
            - CreateUserHierarchyGroup
            - UpdateUserHierarchyGroupName
            - DeleteUserHierarchyGroup
          requestParameters:
            InstanceId:
              - !Ref ConnectInstanceId
      Targets:
        - Arn: !GetAtt LambdaFunction.Arn
          Id: Lambda
        - Arn: !GetAtt EventBridgeLogGroup.Arn
          Id: CloudWatchLogs

  # -------------------------------------
  # CloudWatchLogs LogGroup
  # -------------------------------------
  EventBridgeLogGroup:
    DeletionPolicy: Retain
    UpdateReplacePolicy: Retain
    Type: AWS::Logs::LogGroup
    Properties:
      LogGroupName: !Sub /aws/events/eventbridge/${EventBridgeRuleName}
      RetentionInDays: 30
      Tags:
        - Key: ProjectName
          Value: !Ref ProjectName
        - Key: Environment
          Value: !Ref Environment 
  EventBridgeLogGroupPolicy:
    Type: AWS::Logs::ResourcePolicy
    Properties:
      PolicyName: !Sub EventBridgeLogGroupPolicy-${Environment}
      PolicyDocument: !Sub |
        {
          "Version": "2012-10-17",
          "Statement": [
            {
              "Sid": "EventBridgeToCloudWatchLogs",
              "Effect": "Allow",
              "Principal": {
                "Service": "events.amazonaws.com"
              },
              "Action": [
                "logs:CreateLogStream",
                "logs:PutLogEvents"
              ],
              "Resource": "${EventBridgeLogGroup.Arn}"
            }
          ]
        }

  # -------------------------------------
  # S3
  # -------------------------------------
  ConnectHierarchyBucket:
    Type: AWS::S3::Bucket
    DeletionPolicy: Retain
    UpdateReplacePolicy: Retain
    Properties:
      BucketName: !Ref ConnectHierarchyBucketName
      BucketEncryption:
        ServerSideEncryptionConfiguration:
          - ServerSideEncryptionByDefault:
              SSEAlgorithm: AES256
      PublicAccessBlockConfiguration:
        BlockPublicAcls: true
        BlockPublicPolicy: true
        IgnorePublicAcls: true
        RestrictPublicBuckets: true
      Tags:
        - Key: ProjectName
          Value: !Ref ProjectName
        - Key: Environment
          Value: !Ref Environment
  ConnectHierarchyBucketPolicy:
    Type: AWS::S3::BucketPolicy
    Properties:
      Bucket: !Ref ConnectHierarchyBucket
      PolicyDocument:
        Version: "2012-10-17"
        Statement:
          - Effect: Deny
            Principal: "*"
            Action: "s3:*"
            Resource: 
              - !Sub ${ConnectHierarchyBucket.Arn}
              - !Sub ${ConnectHierarchyBucket.Arn}/*
            Condition:
              Bool:
                "aws:SecureTransport": false
          - Effect: Allow
            Principal:
              AWS: !Ref ECSTaskRoleArn
            Action:
              - s3:GetObject
            Resource: !Sub ${ConnectHierarchyBucket.Arn}/*

3.1 CloudFormation テンプレートの解説

重要なパラメータ

パラメータ名 説明
ProjectName プロジェクト名
Environment 環境(dev/stg/prd)
ConnectInstanceId Amazon ConnectインスタンスID
ConnectHierarchyBucketName 階層情報保存用S3バケット名

主要なリソース定義

リソース 説明 重要な設定
LambdaFunctionRole Lambda実行用IAMロール ConnectとS3へのアクセス権限
LambdaFunction Lambda関数定義 メモリ128MB、タイムアウト60秒
ConnectHierarchyRule EventBridgeルール 階層グループ変更イベントの検知
ConnectHierarchyBucket S3バケット 暗号化とパブリックアクセス制限

3.2 Lambda 関数のコード解説

# 主要な処理ロジック
def lambda_handler(event, context):
    try:
        # 1. Connectから階層グループ情報を取得
        response = connect.list_user_hierarchy_groups(
            InstanceId=CONNECT_INSTANCE_ID
        )
        
        # 2. 階層グループ名を抽出
        hierarchy_groups = []
        for group in response["UserHierarchyGroupSummaryList"]:
            hierarchy_groups.append(group["Name"])
        
        # 3. S3にJSON形式で保存
        s3.put_object(
            Bucket=S3_BUCKET_NAME,
            Key=S3_HIERARCHY_GROUPS_KEY,
            Body=json.dumps({"name": hierarchy_groups}, default=str, ensure_ascii=False),
            ContentType="application/json"
        )
        
        return {"statusCode": 200}
        
    except Exception as e:
        return {
            "statusCode": 500,
            "body": json.dumps({"error": str(e)}, default=str, ensure_ascii=False)
        }

今回は階層グループ名のみを取得していますが、別の Amazon Connect API を使用すれば大体の情報は取得できると思います

5. セキュリティのベストプラクティス

セキュリティ対策 実装内容 効果
IAMロール 最小権限の原則 必要な権限のみ付与
S3暗号化 サーバーサイド暗号化 データの保護
パブリックアクセス制限 バケットポリシー 不正アクセスの防止
セキュアトランスポート HTTPS強制 通信の暗号化

6. まとめ

「階層グループの番犬」として、組織の構造変化を確実に記録し、必要な時にすぐに参照できる状態を維持しますU^ェ^U
まるで優秀な番犬が、家の出入りを記録するように、階層グループの変更を確実に記録していくのです・・・U・x・U

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?