Logo

dev-resources.site

for different kinds of informations.

Config AWS Cloudwatch Application Signals Transaction Search with CDK

Published at
1/11/2025
Categories
awsapplicationsignals
cdk
cloudwatch
transactionsearch
Author
johanneskonings
Author
15 person written this
johanneskonings
open
Config AWS Cloudwatch Application Signals Transaction Search with CDK

Use case

You want to use AWS Cloudwatch Application Signals Transaction Search and your IaC is based on AWS CDK.

Setup

This is how the Transaction Search page looks like, if it's not yet configured:

application signals transaction search without config

And like this in the x-ray settings:

application signals transaction search without config x-ray

The AWS documentation outlines the steps to enable Transaction Search functionality here: https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/CloudWatch-Transaction-Search-getting-started.html#w24aac24c21c13b9

While the documentation provides AWS CLI commands, we can implement the same configuration using AWS CDK Custom Resources for infrastructure as code.

The whole configuration looks like this:

    const { account, region } = Stack.of(this);

      // https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/CloudWatch-Transaction-Search-getting-started.html#w24aac24c21c13b9
      const applicationSignalsTransactionSearchLogsResourcePolicy =
        new AwsCustomResource(
          this,
          "ApplicationSignalsTransactionSearchLogsResourcePolicy",
          {
            onCreate: {
              service: "@aws-sdk/client-cloudwatch-logs",
              action: "PutResourcePolicy",
              parameters: {
                policyName:
                  "ApplicationSignalsTransactionSearchLogsResourcePolicy",
                policyDocument: JSON.stringify({
                  Version: "2012-10-17",
                  Statement: [
                    {
                      Sid: "TransactionSearchXRayAccess",
                      Effect: "Allow",
                      Principal: {
                        Service: "xray.amazonaws.com",
                      },
                      Action: ["logs:PutLogEvents", "logs:CreateLogStream"],
                      Resource: [
                        `arn:aws:logs:${region}:${account}:log-group:aws/spans:*`,
                        `arn:aws:logs:${region}:${account}:log-group:/aws/application-signals/data:*`,
                      ],
                      Condition: {
                        ArnLike: {
                          "aws:SourceArn": `arn:aws:xray:${region}:${account}:*`,
                        },
                        StringEquals: {
                          "aws:SourceAccount": account,
                        },
                      },
                    },
                  ],
                }),
              },
              physicalResourceId: PhysicalResourceId.of(
                "ApplicationSignalsTransactionSearchLogsResourcePolicy",
              ),
            },
            policy: AwsCustomResourcePolicy.fromSdkCalls({
              resources: AwsCustomResourcePolicy.ANY_RESOURCE,
            }),
          },
        );
      const applicationSignalsTransactionSearchXraySegmentDestination =
        new AwsCustomResource(
          this,
          "ApplicationSignalsTransactionSearchXraySegmentDestination",
          {
            onCreate: {
              service: "@aws-sdk/client-xray",
              action: "UpdateTraceSegmentDestination",
              parameters: {
                Destination: "CloudWatchLogs",
              },
              physicalResourceId: PhysicalResourceId.of(
                "ApplicationSignalsTransactionSearchXraySegmentDestination",
              ),
            },
            installLatestAwsSdk: true,
            policy: AwsCustomResourcePolicy.fromStatements([
              new PolicyStatement({
                effect: Effect.ALLOW,
                actions: ["logs:PutRetentionPolicy"],
                resources: [
                  `arn:aws:logs:${region}:${account}:log-group:aws/spans:log-stream:`,
                ],
              }),
              new PolicyStatement({
                effect: Effect.ALLOW,
                actions: ["xray:UpdateTraceSegmentDestination"],
                resources: ["*"],
              }),
            ]),
          },
        );
      applicationSignalsTransactionSearchXraySegmentDestination.node.addDependency(
        applicationSignalsTransactionSearchLogsResourcePolicy,
      );
      const applicationSignalsTransactionSearchXrayIndexRule =
        new AwsCustomResource(
          this,
          "ApplicationSignalsTransactionSearchXrayIndexRule",
          {
            onCreate: {
              service: "@aws-sdk/client-xray",
              action: "UpdateIndexingRule",
              parameters: {
                Name: "Default",
                Rule: {
                  Probabilistic: {
                    DesiredSamplingPercentage: 100,
                  },
                },
              },
              physicalResourceId: PhysicalResourceId.of(
                "ApplicationSignalsTransactionSearchXrayIndexRule",
              ),
            },
            installLatestAwsSdk: true,
            policy: AwsCustomResourcePolicy.fromSdkCalls({
              resources: AwsCustomResourcePolicy.ANY_RESOURCE,
            }),
          },
        );
      NagSuppressions.addResourceSuppressions(
        [
          applicationSignalsTransactionSearchXraySegmentDestination,
          applicationSignalsTransactionSearchLogsResourcePolicy,
          applicationSignalsTransactionSearchXrayIndexRule,
        ],
        [
          {
            id: "AwsSolutions-IAM5",
            reason: "CDK managed policy",
          },
        ],
        true,
      );
    }

Enter fullscreen mode Exit fullscreen mode

It contains the following steps:

  1. Update the Cloudwatch Logs Resource Policy
  2. Update the x-ray settings

Update the Cloudwatch Logs Resource Policy

The documentation here is a little bit misleading. The shown condition arn:partition:logs:region:account-id:* should be arn:partition:xray:region:account-id:*. Also the action logs:PutLogEvents should be logs:PutLogEvents and logs:CreateLogStream.

 const applicationSignalsTransactionSearchLogsResourcePolicy =
        new AwsCustomResource(
          this,
          "ApplicationSignalsTransactionSearchLogsResourcePolicy",
          {
            onCreate: {
              service: "@aws-sdk/client-cloudwatch-logs",
              action: "PutResourcePolicy",
              parameters: {
                policyName:
                  "ApplicationSignalsTransactionSearchLogsResourcePolicy",
                policyDocument: JSON.stringify({
                  Version: "2012-10-17",
                  Statement: [
                    {
                      Sid: "TransactionSearchXRayAccess",
                      Effect: "Allow",
                      Principal: {
                        Service: "xray.amazonaws.com",
                      },
                      Action: ["logs:PutLogEvents", "logs:CreateLogStream"],
                      Resource: [
                        `arn:aws:logs:${region}:${account}:log-group:aws/spans:*`,
                        `arn:aws:logs:${region}:${account}:log-group:/aws/application-signals/data:*`,
                      ],
                      Condition: {
                        ArnLike: {
                          "aws:SourceArn": `arn:aws:xray:${region}:${account}:*`,
                        },
                        StringEquals: {
                          "aws:SourceAccount": account,
                        },
                      },
                    },
                  ],
                }),
              },
              physicalResourceId: PhysicalResourceId.of(
                "ApplicationSignalsTransactionSearchLogsResourcePolicy",
              ),
            },
            policy: AwsCustomResourcePolicy.fromSdkCalls({
              resources: AwsCustomResourcePolicy.ANY_RESOURCE,
            }),
          },
        );

Enter fullscreen mode Exit fullscreen mode

Update the x-ray settings

The 2 API calls for x-ray are nearly straight forward. Only the comamnds UpdateTraceSegmentDestination and UpdateIndexingRule requires the newest SDK version, because it's introduced in version: https://github.com/aws/aws-sdk-js-v3/releases/tag/v3.698.0

 const applicationSignalsTransactionSearchXraySegmentDestination =
        new AwsCustomResource(
          this,
          "ApplicationSignalsTransactionSearchXraySegmentDestination",
          {
            onCreate: {
              service: "@aws-sdk/client-xray",
              action: "UpdateTraceSegmentDestination",
              parameters: {
                Destination: "CloudWatchLogs",
              },
              physicalResourceId: PhysicalResourceId.of(
                "ApplicationSignalsTransactionSearchXraySegmentDestination",
              ),
            },
            installLatestAwsSdk: true,
            policy: AwsCustomResourcePolicy.fromStatements([
              new PolicyStatement({
                effect: Effect.ALLOW,
                actions: ["logs:PutRetentionPolicy"],
                resources: [
                  `arn:aws:logs:${region}:${account}:log-group:aws/spans:log-stream:`,
                ],
              }),
              new PolicyStatement({
                effect: Effect.ALLOW,
                actions: ["xray:UpdateTraceSegmentDestination"],
                resources: ["*"],
              }),
            ]),
          },
        );
      applicationSignalsTransactionSearchXraySegmentDestination.node.addDependency(
        applicationSignalsTransactionSearchLogsResourcePolicy,
      );
      const applicationSignalsTransactionSearchXrayIndexRule =
        new AwsCustomResource(
          this,
          "ApplicationSignalsTransactionSearchXrayIndexRule",
          {
            onCreate: {
              service: "@aws-sdk/client-xray",
              action: "UpdateIndexingRule",
              parameters: {
                Name: "Default",
                Rule: {
                  Probabilistic: {
                    DesiredSamplingPercentage: 100,
                  },
                },
              },
              physicalResourceId: PhysicalResourceId.of(
                "ApplicationSignalsTransactionSearchXrayIndexRule",
              ),
            },
            installLatestAwsSdk: true,
            policy: AwsCustomResourcePolicy.fromSdkCalls({
              resources: AwsCustomResourcePolicy.ANY_RESOURCE,
            }),
          },
        );

Enter fullscreen mode Exit fullscreen mode

Result

After some minutes the Transaction Search is visible in the Management Console.

application signals transaction search enabled in x-ray settings

application signals transaction search enabled in cloudwatch

cdk Article's
30 articles in total
Favicon
Invoking Private API Gateway Endpoints From Step Functions
Favicon
Automating Cross-Account CDK Bootstrapping Using AWS Lambda
Favicon
Deploy de NextJS utilizando CDK
Favicon
Config AWS Cloudwatch Application Signals Transaction Search with CDK
Favicon
[Solved] AWS Resource limit exceeded
Favicon
Create a cross-account glue Job using AWS CDK
Favicon
Enabling Decorators for Lambda Functions with CDK in an Nx Monorepo
Favicon
Run vs code on a private AWS ec2 instance without ssh (with AWS CDK examples)
Favicon
Config AWS Cloudwatch Application Signals for NodeJs Lambda with CDK
Favicon
Deploying a Simple Static Website on AWS with CDK and TypeScript
Favicon
AWS Architectural Diagrams on a Commit Base: Using AWS PDK Diagram Plugin with Python
Favicon
AWS CDK Aspects specifications have changed
Favicon
Relative Python imports in a Dockerized lambda function
Favicon
Building Scalable Infrastructure with AWS CDK: A Developerโ€™s Guide to Best Practices
Favicon
API Gateway integration with AWS Services.
Favicon
DevSecOps with AWS- IaC at scale - Building your own platform โ€“ Part 3 - Pipeline as a Service
Favicon
AWS Cloud Development Kit (CDK) vs. Terraform
Favicon
Query your EventBridge Scheduled Events in DynamoDB
Favicon
AWS CDK context validation
Favicon
How to combine SQS and SNS to implement multiple Consumers (Part 2)
Favicon
Serverless Code-Signing (EV) with KMS and Fargate
Favicon
How to build an API with Lambdas, API Gateway and deploy with AWS CDK
Favicon
The Journey of CDK.dev: From Static Site to Bluesky
Favicon
Create an Asset Store with a Custom Domain using AWS CDK, Route53, S3 and CloudFront
Favicon
Crafting a Scalable Node.js API: Insights from My RealWorld Project with Express, Knex, and AWS CDK
Favicon
Techniques to Save Costs Using AWS Lambda Functions with CDK
Favicon
Deploy a Docker Image to ECS with Auto Scaling Using AWS CDK in Minutes
Favicon
AWS CDK + Localstack (API Gateway, Lambda, SQS, DynamoDB,TypeScript)
Favicon
Simplifying Cloud Infrastructure with AWS CDK
Favicon
Effortless Debugging: AWS CDK TypeScript Projects in VSCode

Featured ones: