-
Notifications
You must be signed in to change notification settings - Fork 27
Logging to AWS CloudWatch
How to Configure Logging to AWS CloudWatch Using CloudFormation for API Gateway or EventBridge
In this article, we'll walk through how to configure logging from Salesforce to AWS CloudWatch using either API Gateway or EventBridge as the integration mechanism. Both options allow you to send logs generated by RFLIB to AWS, providing a flexible and scalable way to store, monitor, and analyze your log data using the AWS CloudWatch service.
AWS CloudWatch offers powerful monitoring capabilities, and by sending logs from Salesforce to CloudWatch, you can:
- Centralize all your log data for streamlined monitoring and troubleshooting.
- Trigger alerts and notifications based on your logs.
- Gain insights into system performance and application behavior.
There are two main ways to set up logging from Salesforce to AWS:
-
EventBridge-Based Integration: This method uses Amazon EventBridge, which is ideal for event-driven logging. EventBridge offers an event bus to link with the
Log Event
Platform Event, which means all events in Log Monitor will be stored in CloudWatch. -
API Gateway-Based Integration: In this approach, API Gateway acts as an intermediary for sending logs via HTTP callouts from Salesforce. This method provides greater control over security configurations and is available in all AWS regions. Similar to archiving logs in Big Objects, there is a Log Setting that allows for configuring a specific log level for the log submission.
Both integrations rely on AWS CloudFormation templates to set up the necessary AWS infrastructure for logging, including the Lambda function and security policies required to process log events from Salesforce. The following sections outline the key steps for both approaches, with the assumption that you have already deployed your CloudFormation stack using the provided templates.
When using EventBridge, your setup involves routing Salesforce events through an Event Bus to a Lambda function, which processes the logs and sends them to CloudWatch.
- Deploy the CloudFormation Stack: Use the CloudFormation template for EventBridge to set up the Lambda function, IAM roles, and other necessary AWS resources.
To dispatch a Salesforce Platform Event to an AWS Lambda function, you'll need to set up the Salesforce Event Relay. This involves several steps:
-
Set Up Named Credentials:
- Start by setting up the Named Credentials to access your AWS account. Note that Salesforce documentation uses the legacy version of Named Credentials for this setup, and the URL is case-sensitive (e.g.,
arn:aws:US-WEST-2:XXXXXXXXXXXX
). - For a detailed description of the setup, see Salesforce’s Help Page.
- Start by setting up the Named Credentials to access your AWS account. Note that Salesforce documentation uses the legacy version of Named Credentials for this setup, and the URL is case-sensitive (e.g.,
-
Create a Platform Event Channel:
-
This cannot be done in Salesforce Setup and requires a REST API tool, such as Salesforce Workbench, Salesforce Inspector Reloaded, or Postman.
-
Sample Request to Create a Platform Event Channel:
POST /services/data/v61.0/tooling/sobjects/PlatformEventChannel HTTP/1.1 Host: yourInstance.salesforce.com Authorization: Bearer <access_token> Content-Type: application/json { "FullName": "AWS_EventBridge__chn", "Metadata": { "channelType": "event", "label": "AWS EventBridge Channel" } }
- Replace
v61.0
with your API version. - Replace
yourInstance.salesforce.com
with your Salesforce instance. - Replace
<access_token>
with your session's access token.
- Replace
-
You can follow the Salesforce guide here for more details.
-
-
Add a Channel Member:
-
A Channel Member links the Platform Event to the Channel. Use a REST API tool to send the configuration payload.
-
Sample Request to Add a Channel Member:
POST /services/data/v61.0/tooling/sobjects/PlatformEventChannelMember HTTP/1.1 Host: yourInstance.salesforce.com Authorization: Bearer <access_token> Content-Type: application/json { "FullName": "AWS_EventBridge_chn_rflib_Log_Event_e", "Metadata": { "eventChannel": "AWS_EventBridge__chn", "selectedEntity": "rflib_Log_Event__e" } }
- Replace
<EventChannelId>
with the ID of the Event Channel created in the previous step. - Replace other placeholders as described above.
- Replace
-
See the Salesforce documentation for more details.
-
-
Complete the Event Relay Wizard:
- Now that the prerequisites are in place, go to Setup > Event Relay, click on New, and follow the wizard's steps.
After completing the above, Salesforce's Event Relay will be set up but deactivated by default. Now, let’s switch over to the AWS Console to configure EventBridge.
Once your AWS Lambda function is deployed, the next step is to create an EventBridge rule that triggers your Lambda function when Salesforce events are sent to the Event Bus. Here's how to configure the rule via the AWS Console:
-
Navigate to EventBridge:
- In the AWS Management Console, search for EventBridge and navigate to the dashboard.
-
Activate the Partner Event Source:
- Salesforce creates a partner event source in Amazon EventBridge in pending status after you create an event relay.
- Associate the event bus with the partner event source in EventBridge so that the event source is ready to receive events from Salesforce.
- Detailed steps can be found in the Salesforce documentation.
-
Create a New Rule:
- On the left panel, select Rules and click the Create Rule button.
-
Define the Rule:
- Enter a name for your rule (e.g.,
SalesforceEventToLambda
). - Choose the Event Bus where Salesforce events will be sent. If you’re using a custom event bus, select it.
- Enter a name for your rule (e.g.,
-
Set Up the Event Pattern:
- Under Event Source, select Event Pattern to trigger Lambda based on specific conditions (e.g., all events or filtered events).
-
Set Lambda as the Target:
- Scroll down to the Select Target section.
- From the drop-down, select Lambda function, then select your deployed Lambda function.
-
Create the Rule:
- After configuring the event pattern and selecting the Lambda target, click Create to save the rule.
Once the rule is created, Salesforce events that match the pattern will trigger your Lambda function.
- Go back to Salesforce and activate the Event Relay.
- Verify that events are being sent to AWS by checking the logs in CloudWatch.
- Deploy the CloudFormation Stack: In the AWS Console, set up API Gateway, Lambda function, and security policies using the CloudFormation template for API Gateway.
- Record Outputs: After the successful execution of the CloudFormation template, record the outputs for the API Gateway URL and the API Execution Role ARN.
Salesforce will authenticate API requests using Named Credentials. You have two options:
- IAM RolesAnywhere (Recommended, Secure, More Complex, May Incur Additional Costs)
- STS Access Key and Secret (Simpler, Less Secure)
-
Generate a CSR in Salesforce:
- Navigate to Setup > Certificate and Key Management.
- Click Create CA-Signed Certificate.
- Enter a label (e.g.,
SalesforceCSR
). - Click Generate Certificate Signing Request to download the
.csr
file.
-
Set Up AWS Private CA:
- In AWS, navigate to AWS Certificate Manager Private Certificate Authority.
-
Create a Private Root CA:
- Choose Root CA.
- For Key Algorithm, select ECDSA P256.
- Complete the setup by providing necessary details.
- IMPORTANT: Be aware of the costs associated with running a Private CA.
-
Sign the Salesforce CSR Using AWS Private CA:
- Use the AWS CLI to sign the CSR and retrieve the certificate.
aws acm-pca issue-certificate \ --certificate-authority-arn <PRIVATE_ROOT_CA_ARN> \ --csr fileb://<RELATIVE_PATH_TO_CSR_FILE> \ --signing-algorithm SHA256WITHECDSA \ --validity Value=365,Type="DAYS"
-
Replace
<PRIVATE_ROOT_CA_ARN>
and<RELATIVE_PATH_TO_CSR_FILE>
with your values. -
Retrieve the certificate:
aws acm-pca get-certificate \ --certificate-authority-arn <PRIVATE_ROOT_CA_ARN> \ --certificate-arn <CERTIFICATE_ARN>
- The command returns a JSON result with "Certificate" and "CertificateChain".
-
Prepare the Certificate for Salesforce:
- Copy the value of the "Certificate" property into a text file.
- Replace all
\n
characters with actual line breaks to format the certificate correctly. - Ensure the certificate begins with
-----BEGIN CERTIFICATE-----
and ends with-----END CERTIFICATE-----
. - Save the text file with a
.crt
extension.
-
Import the Certificate into Salesforce:
- In Salesforce, go back to Certificate and Key Management.
- Click Import from Keystore.
- Upload the certificate file (
.crt
).
-
Configure AWS RolesAnywhere:
- Navigate to AWS IAM > RolesAnywhere.
-
Create a Trust Anchor:
- Click Create trust anchor.
- Trust anchor type: Choose AWS Private CA.
- Certificate Authority ARN: Enter the ARN of the Private CA you created earlier.
-
Name: Provide a name for the trust anchor (e.g.,
SalesforceTrustAnchor
). - Tags: (Optional) Add tags as needed.
- Click Create trust anchor.
-
Create an IAM Role with Trust Relationship:
-
In AWS IAM, navigate to Roles and click Create role.
-
Trusted Entity Type: Choose Custom trust policy.
-
Define the Trust Relationship Policy:
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Service": "rolesanywhere.amazonaws.com" }, "Action": [ "sts:AssumeRole", "sts:TagSession", "sts:SetSourceIdentity" ], "Condition": { "ArnEquals": { "aws:SourceArn": "arn:aws:rolesanywhere:<region>:<account_id>:trust-anchor/<trust_anchor_id>" } } } ] }
- Replace
<region>
,<account_id>
, and<trust_anchor_id>
with your specific details. - This policy ensures that only AWS RolesAnywhere with the correct trust anchor can assume the role.
- Replace
-
Attach Policies to the Role:
-
Sample Policy for Lambda Invocation:
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": "lambda:InvokeFunction", "Resource": "arn:aws:lambda:<region>:<account_id>:function:<lambda_function_name>" }, { "Effect": "Allow", "Action": "execute-api:Invoke", "Resource": "arn:aws:execute-api:<region>:<account_id>:<api_gateway_id>/*" } ] }
- Replace
<region>
,<account_id>
,<lambda_function_name>
, and<api_gateway_id>
with your values.
- Replace
-
-
Review and Create Role:
- Provide a role name (e.g.,
SalesforceLambdaRole
). - Add descriptions and tags as needed.
- Click Create role.
- Provide a role name (e.g.,
-
-
Create a Profile in AWS RolesAnywhere:
- In AWS IAM RolesAnywhere, navigate to Profiles and click Create profile.
-
Name: Enter a name (e.g.,
SalesforceProfile
). - Trust Anchor: Select the trust anchor created in Step 6.
- IAM Role: Select the IAM role created in Step 7.
- Duration: Set the session duration as needed.
- Enabled: Ensure the profile is enabled.
- Tags: (Optional) Add tags as needed.
- Click Create profile.
-
Create External Credential in Salesforce:
- Navigate to Setup > External Credentials.
- Click New External Credential.
-
Label: Enter a name (e.g.,
AWSLambdaExternalCredential
). - Authentication Protocol: Select AWS Signature Version 4.
-
AWS Service: Enter
execute-api
. -
AWS Region: Enter your AWS region (e.g.,
us-west-2
). - Access Key and Secret Key: Leave these fields empty (since authentication is based on the certificate).
- AWS Header Date Format: Leave as default.
- Click Save.
-
Create a Principal:
- Under the External Credential, click New Principal.
- Principal Type: Select AWS IAM Role.
- Principal ARN: Enter the ARN of the IAM Role created in Step 7.
- Certificate: Select the certificate imported in Step 5.
-
Name: Provide a name for the principal (e.g.,
RFLIB_PRINCIPAL
). - Click Save.
-
Create Named Credential in Salesforce:
- Navigate to Setup > Named Credentials.
- Click New Named Credential.
-
Label: Enter a name (e.g.,
AWSLambdaNamedCredential
). -
URL: Enter the base URL of your API Gateway (e.g.,
https://<api_id>.execute-api.<region>.amazonaws.com/prod
). - External Credential: Select the External Credential created in Step 9.
- Generate Authorization Header: Ensure this is checked.
- Allow Formulas in HTTP Header: Check this option if needed.
- Certificate: Select the certificate imported earlier.
- Click Save.
-
Provide Access to Named Credentials Through Permission Set:
- Create a Permission Set that grants access to the Named and External Credentials.
- Assign the Permission Set to any user requiring access to the API Gateway.
-
Create an IAM User:
-
Go to the AWS IAM Console and select Add User.
-
User Name: Enter a name for the user (e.g.,
SalesforceLambdaUser
). -
Access Type: Select Programmatic access.
-
Permissions:
-
Attach existing policies directly or create a new policy.
-
Sample Policy:
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": "lambda:InvokeFunction", "Resource": "arn:aws:lambda:<region>:<account_id>:function:<lambda_function_name>" }, { "Effect": "Allow", "Action": "execute-api:Invoke", "Resource": "arn:aws:execute-api:<region>:<account_id>:<api_gateway_id>/*" } ] }
-
Replace
<region>
,<account_id>
,<lambda_function_name>
, and<api_gateway_id>
with your values.
-
-
Review and Create User.
-
Download Credentials: Save the Access Key and Secret Key.
-
-
Create External Credential in Salesforce:
- In Salesforce, navigate to Setup > External Credentials and click New External Credential.
-
Label: Enter a name (e.g.,
AWSLambdaExternalCredential
). - Authentication Protocol: Select AWS Signature Version 4.
-
AWS Service: Enter
execute-api
. -
AWS Region: Enter your AWS region (e.g.,
us-west-2
). - Access Key: Enter the Access Key from the IAM User.
- Secret Key: Enter the Secret Key from the IAM User.
-
Additional Status Codes for Token Refresh: Enter
403
. - Click Save.
-
Create Named Credential in Salesforce:
- Navigate to Setup > Named Credentials and click New Named Credential.
-
Label: Enter a label (e.g.,
RFLIB HTTP Callout Log
). -
Name: The name must be set to
RFLIB_HTTP_CALLOUT_LOG
-
URL: Enter the base URL of your API Gateway (e.g.,
https://<api_id>.execute-api.<region>.amazonaws.com/prod
). - External Credential: Select the External Credential created in Step 2.
- Generate Authorization Header: Ensure this is checked.
- Click Save.
-
Provide Access to Named Credentials Through Permission Set:
- Create a Permission Set that grants access to the Named and External Credentials.
- Assign the Permission Set to any user requiring access to the API Gateway.
In Salesforce, go to Setup > Custom Settings, and complete the following steps:
- Click on the Manage link next to "Logger Settings".
- Click the Edit button to change the Default Organization Level Values.
- Update the value of the HTTP Callout Log Level to either "INFO", "WARN", "ERROR", or "FATAL". Note that the logging level should be the same or higher thank the Log Event Reporting Level. Log Events must match both configured levels to be sent out.
- Click on the Save button to activate the new settings.
-
Test the Integration:
- Send test logs from Salesforce to AWS.
- Verify that logs appear in AWS CloudWatch as expected.
-
Monitor and Troubleshoot:
- Use AWS CloudWatch to monitor logs in the RFLIB Log Group. Note that there will be one log stream per Org set up.
- Set up alerts or notifications based on log data if needed.
By following these detailed steps, you can successfully configure logging from Salesforce to AWS CloudWatch using either EventBridge or API Gateway. This integration allows you to leverage AWS's powerful monitoring tools to gain deeper insights into your Salesforce application's performance and behavior.
Note: Always ensure that you understand the costs associated with AWS services like AWS Private CA and AWS RolesAnywhere. Consult AWS pricing documentation and consider the security requirements of your organization when choosing between IAM RolesAnywhere and STS Access Key and Secret for authentication.
If you have any questions or need further assistance with any part of the setup process, feel free to reach out for help by opening an issue.