question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

(logs): Log Group ARN has extra `:*`

See original GitHub issue

What is the problem?

The logGroupArn attribute for a LogGroup L2 construct has an extra :* at the end of the ARN. While this matches the behavior of CloudFormation’s Arn attribute for an AWS::Logs::LogGroup, it does not match the documented structure for a Log Group. This breaks integration with other services, such as the creation of an AWS::WAFv2::LoggingConfiguration, which requires the ARN of the Log Group without :*.

Reproduction Steps

Build the following constructs within a Stack. (Sorry for the length; building a Web ACL is noisy)

import * as wafv2 from "aws-cdk-lib/aws-wafv2";
import * as logs from "aws-cdk-lib/aws-logs";

const acl = new waf.CfnWebACL(this, "ACL", {
  scope: "REGIONAL",
  defaultAction: {
    allow: {},
  },
  visibilityConfig: {
    sampledRequestsEnabled: true,
    cloudWatchMetricsEnabled: true,
    metricName: "SampleACLMetric",
  },
  rules: [
    {
      name: "RuleWithAWSManagedRules",
      priority: 0,
      overrideAction: {
        none: {},
      },
      statement: {
        managedRuleGroupStatement: {
          vendorName: "AWS",
          name: "AWSManagedRulesCommonRuleSet",
          excludedRules: [],
        },
      },
      visibilityConfig: {
        sampledRequestsEnabled: true,
        cloudWatchMetricsEnabled: true,
        metricName: "SampleAWSManagedRulesMetric",
      },
    },
  ],
});

const aclLogGroup = new logs.LogGroup(this, "ACLLogs", {
  // WAFv2 Log Groups must begin with `aws-waf-logs`. Including the ACL's
  // ID hopefully prevents name conflicts.
  logGroupName: `aws-waf-logs-${acl.attrId}`,
});

const logConfig = new wafv2.CfnLoggingConfiguration(scope, "WebAclLogging", {
  logDestinationConfigs: [aclLogGroup.logGroupArn],
  resourceArn: acl.attrArn,
});

What did you expect to happen?

The AWS::WAFv2::LoggingConfiguration resource should create successfully, referencing the logGroupArn attribute directly.

The LogGroup construct should provide the ARN in the format specified by the documentation, including

What actually happened?

The AWS::WAFv2::LoggingConfiguration resource failed to create with the error:

Resource handler returned message: "Error reason: The ARN isn’t valid. A valid ARN begins with arn: and includes other information separated by colons or slashes., field: LOG_DESTINATION, parameter: arn:aws:logs:us-east-1:1234657890:log-group:aws-waf-logs-foo:*

The LogGroup.logGroupArn had an :* that was not documented as part of the ARN according to most documentation for the ARN of a Log Group.

CDK CLI Version

2.3.0 (build beaa5b2)

Framework Version

No response

Node.js Version

v14.18.2

OS

Linux

Language

Typescript

Language Version

No response

Other information

It may be more viable to fix this in other L2 constructs that need a log group than it is to fix it in the LogGroup construct itself at this point (and it doesn’t seem that L2 constructs for the Web ACL logging configuration exist yet).

A workaround is to construct the ARN manually (with adjustments if the Log Group is in another account/region):

// The `.logGroupArn` attribute of `LogGroup` contains a `:*` at the end,
// which causes conflicts with the Web ACL Logging Configuration
const logGroupArn = Stack.of(this).formatArn({
  arnFormat: ArnFormat.COLON_RESOURCE_NAME,
  service: "logs",
  resource: "log-group",
  resourceName: aclLogGroup.logGroupName,
});

Issue Analytics

  • State:open
  • Created 2 years ago
  • Reactions:12
  • Comments:12 (4 by maintainers)

github_iconTop GitHub Comments

6reactions
ryancastlecommented, Jan 27, 2022

Workaround example in CDKv2

const logGroup = new LogGroup(this, 'LogGroup', {
  logGroupName: `aws-waf-logs-firewall`,
  retention: RetentionDays.SIX_MONTHS,
  removalPolicy: RemovalPolicy.DESTROY,
});

const logDestination = Fn.select(0, Fn.split('*', logGroup.logGroupArn));
4reactions
aidbalcommented, May 20, 2022

Hi @comcalvi, thanks for linking me the PR.

I agree that there was a need to patch the bug which caused incorrect permissions.

I think that your patch created another bug (the one I mentioned) unintentionally.

And it’s not about mixing L1 and L2, I can easily break your bug fix by only using L2 constructs (explained at the end)

Why the bug fix is not complete

Here you guys check if the arn has :* attached, if so, you replace it with empty string.

However, you don’t put into the consideration that the ARN might be a token and so your regex might not find anything.

I think the better approach there would have been to check if it’s a token. If so, don’t append any :*. If not, search for :* and replace it with empty string, then append :* at the end.

I think this makes the most sense as the LogGroupArn in AWS Console shows up with :* at the end:

AWS Console LogGroup ARN

Meaning the user expects the ARN of the LogGroup to always be the one with :* attached in the end. Thus, any CloudFormation values (i.e. Tokens), referring to LogGroupArn, will always represent the value with :* at the end (at least to the customer’s eyes). No need to append any additional values.

Breaking your bug fix with L2 only

If you don’t fix this bug and say that it only affects it when L1 and L2 are mixed together, I can easily create L2 Log group and get the ARN from that:

const logGroupL2 = new LogGroup(this, "LogGroupL2")

const stateMachine = new StateMachine(this, "StateMachine", {
  ...
  logs: {
    destination: LogGroup.fromLogGroupArn(this, "LogGroupFromArn", logGroupL2.logGroupArn)
    level: LogLevel.ALL
  }
})

This results in the following CloudFormation code:

              "CloudWatchLogsLogGroup": {
                "LogGroupArn": {
                  "Fn::Join": [
                    "",
                    [
                      {
                        "Fn::GetAtt": [
                          "LogGroupL255E4F451",
                          "Arn"
                        ]
                      },
                      ":*"
                    ]
                  ]
                }
              }

No L1 construct being mixed in, but still breaks your bug fix.

Read more comments on GitHub >

github_iconTop Results From Across the Web

AWS::Logs::LogGroup - AWS CloudFormation
The Amazon Resource Name (ARN) of the AWS KMS key to use when encrypting log data. ... Log group data is always encrypted...
Read more >
aws.cloudwatch.LogGroup - Pulumi
The ARN of the KMS Key to use when encrypting log data. Please note, after the AWS KMS CMK is disassociated from the...
Read more >
Python CloudWatch Logging — watchtower documentation
Watchtower is a log handler for Amazon Web Services CloudWatch Logs. ... you can see the log output in your AWS console under...
Read more >
CloudWatch Logs - AWS CDK Workshop
The first thing to do is to go and look at the logs of our hit counter AWS Lambda function. ... Select the...
Read more >
Amazon Web Services log source parameters for ... - IBM
If you want to collect AWS Route 53 logs from Amazon CloudWatch logs, ... If you enabled Assume an IAM Role, the Assume...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found