awslabs / aws-solutions-constructs

The AWS Solutions Constructs Library is an open-source extension of the AWS Cloud Development Kit (AWS CDK) that provides multi-service, well-architected patterns for quickly defining solutions
https://docs.aws.amazon.com/solutions/latest/constructs/
Apache License 2.0
1.23k stars 246 forks source link

[aws-cloudfront-s3] invalid function name #981

Closed chris-feist closed 1 year ago

chris-feist commented 1 year ago

I'm trying to use the aws-cloudfront-s3 deployment with the aws-s3-deployment to upload assets directly to the bucket. Everything works fine until I try to use the deployment lib to add the assets to the bucket.

Reproduction Steps

import { CloudFrontToS3 } from '@aws-solutions-constructs/aws-cloudfront-s3';
import { App, Stack, aws_s3_deployment as s3Deploy } from 'aws-cdk-lib';

export class MyStack extends Stack {
  constructor(app: App) {
    super(app, 'my-stack');

    const {
      s3Bucket,
      cloudFrontWebDistribution,
    } = new CloudFrontToS3(this, 'distribution', {
      bucketProps: {
        cors: [
          {
            allowedHeaders: ['*'],
            allowedMethods: ['GET'] as any,
            allowedOrigins: ['*'],
            maxAge: 3600,
          },
        ],
      },
    });

    // This resource causes the error. Commented out everything deploys fine
    new s3Deploy.BucketDeployment(this, this.createResourceName('assets'), {
      sources: [s3Deploy.Source.asset(path.join(__dirname, './dist'))],
      destinationBucket: s3Bucket,
      // distribution: cloudFrontWebDistribution,
    });
  }
}

Error Log

Resource handler returned message: "1 validation error detected: Value 'Custom::CDKBucketDeployment8693BB64968944B69AAFB0CC9EB8756C' at 'functionName' failed to satisfy constraint: Member must satisfy regular expression pattern: (arn:(aws[a-zA-Z-]*)?:lambda:)?([a-z]{2}((-gov)|(-iso(b?)))?-[a-z]+-\d{1}:)?(\d{12}:)?(function:)?([a-zA-Z0-9-_\.]+)(:(\$LATEST|[a-zA-Z0-9-_]+))? (Service: Lambda, Status Code: 400, Request ID: b25b4a00-d8aa-4020-8907-335d90162a32)" (RequestToken: 49312c9b-14dc-c9c4-6030-241ad5933215, HandlerErrorCode: GeneralServiceException)

Environment

Other

I've also tried changing the Construct ID's but that doesn't seem to get around the issue either


This is :bug: Bug Report

biffgaut commented 1 year ago

Thanks for the heads up around this. I was successful launching the code below:

import { CloudFrontToS3 } from '@aws-solutions-constructs/aws-cloudfront-s3';
import { App, Stack, aws_s3_deployment as s3Deploy } from 'aws-cdk-lib';

import * as s3 from 'aws-cdk-lib/aws-s3';

export class Issue981Stack extends Stack {
  constructor(app: App) {
    super(app, 'my-stack');

    const {
      s3Bucket,
      cloudFrontWebDistribution,
    } = new CloudFrontToS3(this, 'distribution', {
      bucketProps: {
        cors: [
          {
            allowedHeaders: ['*'],
            allowedMethods: ['GET'] as any,
            allowedOrigins: ['*'],
            maxAge: 3600,
          },
        ],
      },
    });

    new s3Deploy.BucketDeployment(this, "some-id", {
      sources: [s3Deploy.Source.asset('./website-dist')],
      destinationBucket: s3Bucket as s3.IBucket,
      distribution: cloudFrontWebDistribution
    });
  }
}

The error indicates that at some point the Custom Resource supporting the BucketDeployment is trying to refer to an S3 bucket with an invalid name. I'm not sure what you function createResourceName does, I would look there. Also, I needed to force the BucketDeploymentProps to believe that s3Bucket was an IBucket - your code doesn't perform that cast, is there anything omitted that account for the difference?

chris-feist commented 1 year ago

It looks like I had a custom Lambda aspect that was setting the function name based on the Construct node ID. In most cases its a friendly name, but with this specific resource, its set automatically by aws-cdk-lib. Thanks for the help! I really appreciate it 👍