Important: Change Data Capture does not support relationships at the time this post was written (08/2021). This means you will only be able to sync up beyond your object unless you implement some tricks using Process Builder and Apex. That's out of the scope of this post and we are going to see it in a different one because requires some extra steps and knowledge.
To start listening on specific object go to Setup -> Integrations -> Change Data Capture. Move the object you want to the right.
# Commands to deploy this through SAM CLI
# sam build
# sam deploy --no-confirm-changeset
AWSTemplateFormatVersion: 2010-09-09
Description: >-
app flow lambda + s3 + SQS
Transform:
- AWS::Serverless-2016-10-31
Parameters:
Environment:
Type: String
Description: Environment name. Example, dev,staging,testing, etc
Globals:
Function:
Runtime: nodejs12.x
Timeout: 30
MemorySize: 128
Resources:
MyLambda:
Type: AWS::Serverless::Function
DependsOn:
- "MyQueue"
Properties:
Handler: src/handlers/my.handler
Description: Sync up lambda
Environment:
Variables:
QueueURL:
Ref: "MyQueue"
MyBucket: !Sub "${AWS::AccountId}-${Environment}-my-bucket"
Role:
Fn::GetAtt:
- "MyLambdaRole"
- "Arn"
Tags:
Name: !Sub "${Environment}-my-lambda"
MyLambdaRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Statement:
- Effect: Allow
Action: "sts:AssumeRole"
Principal:
Service:
- "lambda.amazonaws.com"
Version: "2012-10-17"
ManagedPolicyArns:
- arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole
Policies:
- PolicyName: AccessOnMyQueue
PolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Action: "sqs:SendMessage"
Resource:
- Fn::GetAtt:
- "MyQueue"
- "Arn"
- PolicyName: AccessToS3Notifications
PolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Action:
- 's3:GetBucketNotification'
Resource: !Sub 'arn:aws:s3:::${AWS::AccountId}-${Environment}-my-bucket'
- PolicyName: AccessOnS3Objects
PolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Action:
- "s3:GetObject"
Resource: !Sub 'arn:aws:s3:::${AWS::AccountId}-${Environment}-my-bucket/*'
MyBucket:
Type: AWS::S3::Bucket
DependsOn:
- MyLambda
Properties:
BucketName: !Sub "${AWS::AccountId}-${Environment}-my-bucket"
NotificationConfiguration:
LambdaConfigurations:
- Event: 's3:ObjectCreated:*'
Function: !GetAtt MyLambda.Arn
LifecycleConfiguration:
Rules:
- Id: ExpirationInDays
Status: 'Enabled'
ExpirationInDays: 3
- Id: NoncurrentVersionExpirationInDays
Status: 'Enabled'
NoncurrentVersionExpirationInDays: 3
MyBucketPolicy:
Type: AWS::S3::BucketPolicy
DependsOn: MyBucket
Properties:
Bucket: !Ref MyBucket
PolicyDocument:
Version: '2008-10-17'
Statement:
- Effect: Allow
Principal:
Service: appflow.amazonaws.com
Action:
- s3:PutObject
- s3:AbortMultipartUpload
- s3:ListMultipartUploadParts
- s3:ListBucketMultipartUploads
- s3:GetBucketAcl
- s3:PutObjectAcl
Resource:
- !Sub "arn:aws:s3:::${AWS::AccountId}-${Environment}-my-bucket"
- !Sub "arn:aws:s3:::${AWS::AccountId}-${Environment}-my-bucket/*"
MyQueue:
Type: AWS::SQS::Queue
Properties:
QueueName: !Sub "${Environment}-my-queue.fifo"
FifoQueue: true
ContentBasedDeduplication: true
RedrivePolicy:
deadLetterTargetArn:
Fn::GetAtt:
- "MyDeadLetterQueue"
- "Arn"
maxReceiveCount: 2
MyDeadLetterQueue:
Type: AWS::SQS::Queue
Properties:
QueueName: !Sub "${Environment}-my-queue-dlq.fifo"
FifoQueue: true
MessageRetentionPeriod: 1209600 # 14 days (the max supported)
MyQueuePolicy:
DependsOn:
- "MyQueue"
Type: AWS::SQS::QueuePolicy
Properties:
PolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: Allow
Principal:
Service:
- "events.amazonaws.com"
- "sqs.amazonaws.com"
Action:
- "sqs:SendMessage"
- "sqs:GetQueueUrl"
- "sqs:DeleteMessage"
- "sqs:ReceiveMessage"
Resource:
Fn::GetAtt:
- "MyQueue"
- "Arn"
Queues:
- Ref: "MyQueue"
# AppFlow flow to connect SFDC and AWS
MyAppFlow:
Type: AWS::AppFlow::Flow
Properties:
FlowName: !Sub "${Environment}-my-app-flow"
Description: Flow to sync up with Salesforce
TriggerConfig:
TriggerType: Event
SourceFlowConfig:
ConnectorType: Salesforce
ConnectorProfileName: !Sub "${Environment}-my-connection" # the name of the Oauth connection created in AWS console
SourceConnectorProperties:
Salesforce:
Object: Account__ChangeEvent
EnableDynamicFieldUpdate: false
IncludeDeletedRecords: true
DestinationFlowConfigList:
- ConnectorType: S3
DestinationConnectorProperties:
S3:
BucketName: !Ref MyBucket
S3OutputFormatConfig:
AggregationConfig:
AggregationType: None
PrefixConfig:
PrefixFormat: MINUTE
PrefixType: FILENAME
FileType: JSON
Tasks:
- TaskType: Filter
ConnectorOperator:
Salesforce: PROJECTION
SourceFields:
- Name
- TaskType: Map
SourceFields:
- Name
TaskProperties:
- Key: SOURCE_DATA_TYPE
Value: Name
- Key: DESTINATION_DATA_TYPE
Value: Name
DestinationField: Name
Photo by Mark Fletcher-Brown on Unsplash