Stuck Updating Lambda@Edge using Cross-Region References in AWS CDK
This is a personal note on getting stuck with an Exports cannot be updated error when trying to update Lambda@Edge. It happened when I built an S3 + CloudFront + cognito-at-edge architecture using cross-region stacks (us-east-1 / ap-northeast-1) and crossRegionReferences: true in AWS CDK.
Background
I was in a situation where a separate API backend already existed, and I wanted to quickly build a prototype frontend application for it.
- Streamlit is subtle for fine interactions.
- Next.js is too heavy (an AgentCore environment was already running experimentally).
So, I decided to build a minimal SPA with React + Vite. I used Cognito for authentication and CloudFront + S3 for static hosting. To be able to spin it up and tear it down quickly, I codified the various stacks with AWS CDK.
cognito-at-edge
When integrating Cognito authentication into a static site on CloudFront + S3, instead of having the login flow on the SPA side, it's convenient to intercept requests with Lambda@Edge and perform Cognito authentication checks. cognito-at-edge is an npm package that wraps this implementation.
By attaching Lambda@Edge to CloudFront's Viewer Request event, you can check the authentication state before accessing the content in S3.
HowItHappened
StackSplitting

There is a restriction that Lambda@Edge and CloudFront ACM certificates can only be deployed in us-east-1 because they are global services.
Lambda@Edge functions must be created in the US East (N. Virginia) Region. — Restrictions on Edge Functions
On the other hand, there are cases where you want to place S3 or Cognito in ap-northeast-1 due to the location of app data (data residency, etc.). (Although I did this without thinking too deeply this time).
As a result, it became the following 3-stack architecture:
EdgeStack: us-east-1 (Lambda@Edge, WAF WebACL)DomainStack: us-east-1 (ACM Certificate, Route 53 Hosted Zone)AppStack: ap-northeast-1 (S3, Cognito, CloudFront distribution)
// bin/app.ts (Outline) // 1. Deploy Lambda@Edge to us-east-1 const edgeStack = new EdgeStack(app, "EdgeStack", { env: { region: "us-east-1", account: config.env.account }, crossRegionReferences: true, }); // 2. Deploy Certificate / Hosted Zone to us-east-1 // (ACM for CloudFront must be in us-east-1) const domainStack = new DomainStack(app, "DomainStack", { env: { region: "us-east-1", account: config.env.account }, config, crossRegionReferences: true, }); // 3. Deploy S3 / Cognito / CloudFront to ap-northeast-1 new AppStack(app, "ClientAppStack", { env: config.env, // ap-northeast-1 crossRegionReferences: true, edgeLambdaVersionArn: pinnedEdgeLambdaVersionArn || edgeStack.authFunctionVersionArn, webAclArn: edgeStack.webAclArn, config, domainStack, });
By setting crossRegionReferences: true, CDK automatically generates cross-region references (cdk-exports-* stacks) internally via SSM Parameter Store.
TheProblem
After running the development environment, I needed to update the processing script of cognito-at-edge.
At this time, when attaching Lambda@Edge to CloudFront, you must specify the version ARN ($LATEST is not allowed).
You must specify a version of the Lambda@Edge function. You can't use $LATEST. — Restrictions on Edge Functions
When I tried to export the updated version and reference it, the deployment failed with the following error.
❌ EdgeStack failed: Error: The stack named EdgeStack failed creation, it may need to be manually deleted from the AWS console: ROLLBACK_COMPLETE: Export EdgeStack:ExportsOutputFnGetAttXXXXXXXX cannot be updated as it is in use by ClientAppStack
Export EdgeStack:ExportsOutputFnGetAtt... cannot be updated as it is in use by stack ClientAppStack
This occurs because CDK automatically generates an intermediate stack (cdk-exports-*) with export values to realize inter-stack references for crossRegionReferences: true. As a CloudFormation specification, an export value imported by another stack cannot be updated or deleted.
You can't modify or remove an output value that is referenced by another stack. — AWS CloudFormation Documentation
Every time you update a Lambda function, a new version is published, and its ARN changes as an export value. However, as long as AppStack imports that value, the export value cannot be changed. It falls into a deadlock state every time you deploy.
After some research, I found similar issues reported:
Solution
The root cause is that "AppStack directly references the output of EdgeStack via CloudFormation Export." Breaking this dependency by pinning with CDK Context solves the issue temporarily.
PintheARNwithCDKContext
Allow the Lambda version ARN to be passed from the outside via CDK context (cdk.json or --context flag), removing the direct reference between stacks.
// bin/app.ts // Get fixed ARN from context (fallback to dynamic reference if it doesn't exist) const pinnedEdgeLambdaVersionArn = app.node.tryGetContext( "edgeLambdaVersionArn", ) as string | undefined; new AppStack(app, "ClientAppStack", { env: config.env, crossRegionReferences: true, // If there is a pinned ARN, use it and don't have an Export dependency on EdgeStack edgeLambdaVersionArn: pinnedEdgeLambdaVersionArn || edgeStack.authFunctionVersionArn, // ... });
When pinning in cdk.json:
{ "context": { "edgeLambdaVersionArn": "arn:aws:lambda:us-east-1:123456789012:function:AuthFunction:42" } }
Or specify directly during cdk deploy:
cdk deploy ClientAppStack \ --context edgeLambdaVersionArn=arn:aws:lambda:us-east-1:123456789012:function:AuthFunction:42
Deployment Procedure (When Updating):
- Deploy
EdgeStackand check the new version ARN. - Set that ARN in the context and deploy
AppStack(ClientAppStack).
With this order, you can switch the Import dependency to the context value before deploying the stack that imports the Export value.
Cross-RegionCoordinationUsingSSMParameterStore
There is also a pattern of passing values using SSM Parameter Store manually without relying on CDK's auto-generated stacks with crossRegionReferences: true.
// EdgeStack side: Write ARN to us-east-1 import * as ssm from "aws-cdk-lib/aws-ssm"; new ssm.StringParameter(this, "EdgeLambdaVersionArnParam", { parameterName: "/myapp/edge-lambda-version-arn", stringValue: authFunctionVersion.functionArn, });
// AppStack side: Read SSM in us-east-1 from ap-northeast-1 // * Since cross-region SSM references are not directly supported in CDK, // execute `aws ssm get-parameter --region us-east-1` in the deployment script // and pass it via context, or use a custom resource. // Custom resource example (AwsCustomResource) import { AwsCustomResource, AwsCustomResourcePolicy, PhysicalResourceId, } from "aws-cdk-lib/custom-resources"; const getParam = new AwsCustomResource(this, "GetEdgeLambdaArn", { onUpdate: { service: "SSM", action: "getParameter", parameters: { Name: "/myapp/edge-lambda-version-arn" }, region: "us-east-1", physicalResourceId: PhysicalResourceId.of(Date.now().toString()), }, policy: AwsCustomResourcePolicy.fromSdkCalls({ resources: AwsCustomResourcePolicy.ANY_RESOURCE, }), }); const versionArn = getParam.getResponseField("Parameter.Value");
However, reading SSM via a custom resource also uses Lambda internally, so there is overhead. For prototype purposes, simply pinning the context should be sufficient.
IShouldn'tHaveMadeItCross-RegionintheFirstPlace
For a prototype architecture, if I had unified all stacks in us-east-1, this problem wouldn't have occurred. This time, I vaguely decided to "put the app data in ap-northeast-1," but there was no need to separate regions at a stage where there were no strict data residency requirements.
CDK'scrossRegionReferencesisConvenientbutHasPitfalls
crossRegionReferences: true easily realizes cross-region references, but you will get stuck if you use it for resources whose Export values can change frequently (like Lambda version ARNs). I should have considered externalizing frequently changing values to context or parameter store from the beginning.
ReferenceLinks
- Restrictions on Edge Functions - AWS Documentation
- AWS CloudFormation Outputs - AWS Documentation
- cognito-at-edge - npm
- CDK crossRegionReferences - AWS CDK Documentation
- AWS CDK Custom Resources (AwsCustomResource) - AWS Documentation
- Implementing ACM and CloudFront cross-region references with official AWS CDK functions - DevelopersIO