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.

@aws-cdk/aws-cloudfront: Unable to deploy with EdgeFunction

See original GitHub issue

I can successfully deploy a CloudFront distribution using the CDK. However, as soon as I try to add a Lambda@Edge function to this, my deployment fails.

Reproduction Steps

Here is the Typescript code I used to deploy:

import * as cdk from '@aws-cdk/core';
import * as cdkCertificateManager from '@aws-cdk/aws-certificatemanager';
import * as cdkCloudfront from '@aws-cdk/aws-cloudfront';
import * as cdkLambda from '@aws-cdk/aws-lambda';
import * as cdkOrigins from '@aws-cdk/aws-cloudfront-origins';
import * as cdkRoute53 from '@aws-cdk/aws-route53';
import * as cdkRoute53Targets from '@aws-cdk/aws-route53-targets';

import { CustomStackProps } from '@resilientplc/hubble-cdk-utils';

import { CDK_UTILS } from '../config/config';

import { CfProps } from './cf-props';

export class CfConstruct extends cdk.Construct {
  constructor(
    stack: cdk.Stack,
    {
      stage,
      env,
      tags,
      customProps: { hostedZoneId, hostedZoneDomainName, certificateArn, vpcName, graphQlEndpoint, apiR53RecordName, hubbleAlertsS3BucketName }
    }: CustomStackProps<CfProps>
  ) {
    super(stack, 'CloudFrontConstruct');

    const lambdaAtEdgeFunction = new cdkCloudfront.experimental.EdgeFunction(this, 'LambdaAtEdgeFunction', {
      runtime: cdkLambda.Runtime.NODEJS_12_X,
      code: cdkLambda.Code.fromAsset('.build/request-routing-lambda'),
      handler: 'request-routing-lambda.requestRoutingLambda'
    });

    const distribution = new cdkCloudfront.Distribution(this, 'CloudFrontDist', {
      comment: `${CDK_UTILS.resourceName('cloudfront')}: CloudFront distribution for GraphQL endpoint`,
      domainNames: [`${apiR53RecordName}.${hostedZoneDomainName}`],
      certificate: cdkCertificateManager.Certificate.fromCertificateArn(this, 'Certificate', certificateArn),
      minimumProtocolVersion: cdkCloudfront.SecurityPolicyProtocol.TLS_V1,
      priceClass: cdkCloudfront.PriceClass.PRICE_CLASS_100,
      defaultBehavior: {
        allowedMethods: cdkCloudfront.AllowedMethods.ALLOW_ALL,
        cachePolicy: new cdkCloudfront.CachePolicy(this, 'CloudFrontCachePolicy', {
          cachePolicyName: CDK_UTILS.resourceName('cloudfront-cache-policy'),
          headerBehavior: cdkCloudfront.CacheHeaderBehavior.allowList('Authorization'),
          defaultTtl: cdk.Duration.seconds(0),
          minTtl: cdk.Duration.seconds(0),
          maxTtl: cdk.Duration.seconds(1)
        }),
        edgeLambdas: [
          {
            eventType: cdkCloudfront.LambdaEdgeEventType.ORIGIN_REQUEST,
            functionVersion: lambdaAtEdgeFunction.currentVersion
          }
        ],
        origin: new cdkOrigins.HttpOrigin(cdk.Fn.select(2, cdk.Fn.split('/', graphQlEndpoint)), {
          originPath: '',
          originSslProtocols: [cdkCloudfront.OriginSslPolicy.TLS_V1, cdkCloudfront.OriginSslPolicy.TLS_V1_1, cdkCloudfront.OriginSslPolicy.TLS_V1_2]
        }),
        originRequestPolicy: new cdkCloudfront.OriginRequestPolicy(this, 'CloudFrontOriginRequestPolicy', {
          originRequestPolicyName: CDK_UTILS.resourceName('cloudfront-origin-request-policy'),
          headerBehavior: cdkCloudfront.OriginRequestHeaderBehavior.allowList('Origin', 'Access-Control-Request-Method', 'Access-Control-Request-Headers'),
          queryStringBehavior: cdkCloudfront.OriginRequestQueryStringBehavior.all(),
          cookieBehavior: cdkCloudfront.OriginRequestCookieBehavior.all()
        }),
        viewerProtocolPolicy: cdkCloudfront.ViewerProtocolPolicy.HTTPS_ONLY
      }
    });

    const zone = cdkRoute53.HostedZone.fromHostedZoneAttributes(this, 'R53HostedZone', { hostedZoneId, zoneName: hostedZoneDomainName });

    new cdkRoute53.ARecord(this, 'ARecord', {
      zone,
      recordName: apiR53RecordName,
      target: cdkRoute53.RecordTarget.fromAlias(new cdkRoute53Targets.CloudFrontTarget(distribution))
    });
  }
}

What did you expect to happen?

I expected it to deploy without errors.

What actually happened?

The deployment failed with the following errors:

cf (users-api-cf-dev): deploying...
[0%] start: Publishing 45b7ed524ce2b119dd4f2b8642ae8bfaf0df45bc6bd705072ae4ee6d1a999241:current
[100%] success: Published 45b7ed524ce2b119dd4f2b8642ae8bfaf0df45bc6bd705072ae4ee6d1a999241:current
users-api-cf-dev: creating CloudFormation changeset...
 0/7 | 13:11:30 | UPDATE_IN_PROGRESS   | AWS::CloudFormation::Stack               | users-api-cf-dev User Initiated
 1/7 | 13:11:57 | UPDATE_IN_PROGRESS   | AWS::CDK::Metadata                       | cf/CDKMetadata/Default (CDKMetadata) 
 1/7 | 13:11:57 | CREATE_IN_PROGRESS   | AWS::IAM::Role                           | cf/Custom::CrossRegionStringParameterReaderCustomResourceProvider/Role (CustomCrossRegionStringParameterReaderCustomResourceProviderRole71CD6825) 
 1/7 | 13:11:57 | CREATE_IN_PROGRESS   | AWS::IAM::Role                           | cf/Custom::CrossRegionStringParameterReaderCustomResourceProvider/Role (CustomCrossRegionStringParameterReaderCustomResourceProviderRole71CD6825) Resource creation Initiated
 1/7 | 13:11:58 | UPDATE_COMPLETE      | AWS::CDK::Metadata                       | cf/CDKMetadata/Default (CDKMetadata) 
 2/7 | 13:12:16 | CREATE_COMPLETE      | AWS::IAM::Role                           | cf/Custom::CrossRegionStringParameterReaderCustomResourceProvider/Role (CustomCrossRegionStringParameterReaderCustomResourceProviderRole71CD6825) 
 3/7 | 13:12:18 | CREATE_IN_PROGRESS   | AWS::Lambda::Function                    | cf/Custom::CrossRegionStringParameterReaderCustomResourceProvider/Handler (CustomCrossRegionStringParameterReaderCustomResourceProviderHandler65B5F33A) 
 3/7 | 13:12:19 | CREATE_IN_PROGRESS   | AWS::Lambda::Function                    | cf/Custom::CrossRegionStringParameterReaderCustomResourceProvider/Handler (CustomCrossRegionStringParameterReaderCustomResourceProviderHandler65B5F33A) Resource creation Initiated
 3/7 | 13:12:19 | CREATE_COMPLETE      | AWS::Lambda::Function                    | cf/Custom::CrossRegionStringParameterReaderCustomResourceProvider/Handler (CustomCrossRegionStringParameterReaderCustomResourceProviderHandler65B5F33A) 
 3/7 | 13:12:21 | CREATE_IN_PROGRESS   | Custom::CrossRegionStringParameterReader | cf/CloudFrontConstruct/LambdaAtEdgeFunction/ArnReader/Default (CloudFrontConstructLambdaAtEdgeFunctionArnReader5C1A0822) 
 3/7 | 13:12:27 | CREATE_IN_PROGRESS   | Custom::CrossRegionStringParameterReader | cf/CloudFrontConstruct/LambdaAtEdgeFunction/ArnReader/Default (CloudFrontConstructLambdaAtEdgeFunctionArnReader5C1A0822) Resource creation Initiated
 3/7 | 13:12:27 | CREATE_FAILED        | Custom::CrossRegionStringParameterReader | cf/CloudFrontConstruct/LambdaAtEdgeFunction/ArnReader/Default (CloudFrontConstructLambdaAtEdgeFunctionArnReader5C1A0822) Failed to create resource. ParameterNotFound: null
    at Request.extractError (/var/runtime/node_modules/aws-sdk/lib/protocol/json.js:52:27)
    at Request.callListeners (/var/runtime/node_modules/aws-sdk/lib/sequential_executor.js:106:20)
    at Request.emit (/var/runtime/node_modules/aws-sdk/lib/sequential_executor.js:78:10)
    at Request.emit (/var/runtime/node_modules/aws-sdk/lib/request.js:688:14)
    at Request.transition (/var/runtime/node_modules/aws-sdk/lib/request.js:22:10)
    at AcceptorStateMachine.runTo (/var/runtime/node_modules/aws-sdk/lib/state_machine.js:14:12)
    at /var/runtime/node_modules/aws-sdk/lib/state_machine.js:26:10
    at Request.<anonymous> (/var/runtime/node_modules/aws-sdk/lib/request.js:38:9)
    at Request.<anonymous> (/var/runtime/node_modules/aws-sdk/lib/request.js:690:12)
    at Request.callListeners (/var/runtime/node_modules/aws-sdk/lib/sequential_executor.js:116:18)
        new CustomResource (/Users/anjum/Documents/workspace/resilient/users-api/node_modules/@aws-cdk/core/lib/custom-resource.js:30:25)
        \_ EdgeFunction.createCrossRegionArnReader (/Users/anjum/Documents/workspace/resilient/users-api/node_modules/@aws-cdk/aws-cloudfront/lib/experimental/edge-function.js:255:26)
        \_ EdgeFunction.createCrossRegionFunction (/Users/anjum/Documents/workspace/resilient/users-api/node_modules/@aws-cdk/aws-cloudfront/lib/experimental/edge-function.js:232:30)
        \_ new EdgeFunction (/Users/anjum/Documents/workspace/resilient/users-api/node_modules/@aws-cdk/aws-cloudfront/lib/experimental/edge-function.js:43:20)
        \_ new CfConstruct (/Users/anjum/Documents/workspace/resilient/users-api/.build/stacks/cf/cf-construct.js:35:38)
        \_ new CfStack (/Users/anjum/Documents/workspace/resilient/users-api/.build/stacks/cf/cf-stack.js:28:9)
        \_ Object.<anonymous> (/Users/anjum/Documents/workspace/resilient/users-api/.build/stacks/stacks.js:52:1)
        \_ Module._compile (internal/modules/cjs/loader.js:774:30)
        \_ Object.Module._extensions..js (internal/modules/cjs/loader.js:785:10)
        \_ Module.load (internal/modules/cjs/loader.js:641:32)
        \_ Function.Module._load (internal/modules/cjs/loader.js:556:12)
        \_ Function.Module.runMain (internal/modules/cjs/loader.js:837:10)
        \_ internal/main/run_main_module.js:17:11
 3/7 | 13:12:28 | UPDATE_ROLLBACK_IN_P | AWS::CloudFormation::Stack               | users-api-cf-dev The following resource(s) failed to create: [CloudFrontConstructLambdaAtEdgeFunctionArnReader5C1A0822]. 
...

Environment

  • CDK CLI Version : 1.91.0
  • Framework Version: 1.91.0
  • Node.js Version: v12.4.0
  • OS : macOS Big Sur Version 11.2.3 (20D91)
  • Language (Version): Typescript (4.2.2)

Other

I have also raised this as a question in the slack channel: https://cdk-dev.slack.com/archives/C018XT6REKT/p1615987569068600


This is 🐛 Bug Report

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Comments:26 (7 by maintainers)

github_iconTop GitHub Comments

1reaction
peterwoodworthcommented, Jul 8, 2021

Ping me if you want to discuss this further! I’ll be closing this issue now since the original issue has been resolved.

1reaction
njlynchcommented, Mar 19, 2021

If I remove the --exclusively flag then will they all be deployed rather only the one we specify via the cf name directly after cdk deploy?

If you specify the stack, but remove the --exclusively flag, then the stack you specify, and all stacks which are necessary to deploy the stack you specified, will be deployed.

We have some stacks in there that pass along their exported stack variables to other stacks.

If Stack A exports a variable and Stack B consumes it, then Stack B is dependent on Stack A. If you deploy Stack B, Stack A will be automatically deployed (without the exclusively flag); if you deploy Stack A, Stack B will not be deployed.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Restrictions on edge functions - Amazon CloudFront
To associate an edge function with a CloudFront distribution, the function and distribution must be owned by the same AWS account. Combining CloudFront ......
Read more >
class EdgeFunction (construct) · AWS CDK
Implements IConstruct , IConstruct , IDependable , IResource , IVersion , IConnectable , IGrantable , IFunction. A Lambda@Edge function.
Read more >
aws-cdk-lib.aws_cloudfront module
Amazon CloudFront is a web service that speeds up distribution of your static and dynamic web content, such as .html, .css, .js, and...
Read more >
interface LambdaFunctionAssociationProperty · AWS CDK
Java, software.amazon.awscdk.services.cloudfront.CfnDistribution. ... A complex type that contains a Lambda@Edge function association.
Read more >
aws-cdk/aws-cloudfront-origins module - AWS Documentation
We will only store essential cookies at this time, because we were unable to save your cookie preferences. If you want to change...
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