-
Notifications
You must be signed in to change notification settings - Fork 3.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[lambda] Lambda@Edge support #1575
Comments
Hello, is there any workaround we can use to deploy lambda@edge with aws-cdk? Can it use sam module with https://github.com/awslabs/serverless-application-model/tree/master/examples/2016-10-31/lambda_edge ? Or can we trigger shell command after regular lambda deployment to deploy it to the edge and get the version? |
I'm not sure if you can use the AutoPublishAlias feature of SAM from CDK, but recently I did discover it's pretty easy to create a cfn custom resource that implements that functionality (it's really just making a call to PublishVersion and UpdateAlias, if you care about that) - perhaps something like this would be worth adding to the construct library? To actually setup the Lambda@Edge function associations, I haven't tried it yet, but perhaps we can use https://github.com/awslabs/aws-cdk/blob/521570a7c3a3788ce313f310ccb35bd1484ad2f5/docs/src/aws-construct-lib.rst#access-the-aws-cloudformation-layer for this, at least until proper support is added to the L2 construct. |
@lordpython Thanks a lot for your answer. Do you have any examples with custom resource and described |
These are just the Lambda API calls, documented here https://docs.aws.amazon.com/lambda/latest/dg/API_PublishVersion.html and https://docs.aws.amazon.com/lambda/latest/dg/API_UpdateAlias.html (and you should pretty easily be able to find documentation for them in each languages SDK, eg boto3 docs for PublishVersion are here https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/lambda.html#Lambda.Client.publish_version) |
So I was able to solve my task with this way. My requirements were mainly that I want to have bucket in a different region than us-east-1, so I need to pass the lambda version somehow to another region First definitions: const cdk = require('@aws-cdk/cdk');
const lambda = require('@aws-cdk/aws-lambda');
const s3 = require('@aws-cdk/aws-s3');
const cfr = require('@aws-cdk/aws-cloudfront');
const iam = require('@aws-cdk/aws-iam');
const cf = require('@aws-cdk/aws-cloudformation');
const r53 = require('@aws-cdk/aws-route53');
const sha256 = require('sha256-file');
const CF_HOSTED_ZONE_ID = 'Z2FDTNDATAQYW2';
const LAMBDA_OUTPUT_NAME = 'LambdaOutput';
const LAMBDA_EDGE_STACK_NAME = 'stack-name';
const DOMAIN_NAME = 'example.com';
const CERTIFICATE_ARN = 'arn:aws:acm:us-east-1:<aid>:certificate/<cert>';
const app = new cdk.App(); Then the edge lambda stack itself: class LambdaStack extends cdk.Stack {
constructor(parent, id, props) {
super(parent, id, props);
const override = new lambda.Function(this, 'your-lambda', {
runtime: lambda.Runtime.NodeJS810,
handler: 'index.handler',
code: lambda.Code.asset('./lambda'),
role: new iam.Role(this, 'AllowLambdaServiceToAssumeRole', {
assumedBy: new iam.CompositePrincipal(
new iam.ServicePrincipal('lambda.amazonaws.com'),
new iam.ServicePrincipal('edgelambda.amazonaws.com'),
),
managedPolicyArns: ['arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole']
})
});
// this way it updates version only in case lambda code changes
const version = override.addVersion(':sha256:' + sha256('./lambda/index.js'));
// the main magic to easily pass the lambda version to stack in another region
new cdk.CfnOutput(this, LAMBDA_OUTPUT_NAME, {
value: cdk.Fn.join(":", [
override.functionArn,
version.functionVersion
])
});
}
} Then cloud front definition: class StaticSiteStack extends cdk.Stack {
constructor(parent, id, props) {
super(parent, id, props);
const lambdaProvider = new lambda.SingletonFunction(this, 'Provider', {
uuid: 'f7d4f730-4ee1-11e8-9c2d-fa7ae01bbebc',
code: lambda.Code.asset('./cfn'),
handler: 'stack.handler',
timeout: 60,
runtime: lambda.Runtime.NodeJS810,
});
// to allow aws sdk call inside the lambda
lambdaProvider.addToRolePolicy(
new iam.PolicyStatement()
.allow()
.addAction('cloudformation:DescribeStacks')
.addResource(`arn:aws:cloudformation:*:*:stack/${LAMBDA_EDGE_STACK_NAME}/*`)
);
// This basically goes to another region to edge stack and grabs the version output
const stackOutput = new cf.CustomResource(this, 'StackOutput', {
lambdaProvider,
properties: {
StackName: LAMBDA_EDGE_STACK_NAME,
OutputKey: LAMBDA_OUTPUT_NAME,
// just to change custom resource on code update
LambdaHash: sha256('./lambda/index.js')
}
});
const bucket = new s3.Bucket(this, 'bucket', {
publicReadAccess: true // not really sure I need this permission actually
});
const origin = {
domainName: bucket.domainName,
id: 'origin1',
s3OriginConfig: {}
};
// CloudFrontWebDistribution will simplify a lot,
// but it doesn't support lambdaFunctionAssociations in any way :(
const distribution = new cfr.CfnDistribution(this, 'WebSiteDistribution', {
distributionConfig: {
aliases: ['site.example.com', '*.site.example.com'],
defaultCacheBehavior: {
allowedMethods: ['GET', 'HEAD'],
cachedMethods: ['GET', 'HEAD'],
defaultTtl: 60,
maxTtl: 60,
targetOriginId: origin.id,
viewerProtocolPolicy: cfr.ViewerProtocolPolicy.RedirectToHTTPS,
forwardedValues: {
cookies: {
forward: 'none'
},
queryString: false
},
lambdaFunctionAssociations: [
{
eventType: 'viewer-request',
lambdaFunctionArn: stackOutput.getAtt('Output')
}
]
},
defaultRootObject: 'index.html',
enabled: true,
httpVersion: cfr.HttpVersion.HTTP2,
origins: [
origin
],
priceClass: cfr.PriceClass.PriceClass100,
viewerCertificate: {
acmCertificateArn: CERTIFICATE_ARN,
sslSupportMethod: cfr.SSLMethod.SNI
}
},
tags: [{
key: 'stack',
value: this.name
}]
});
const zone = new r53.HostedZoneProvider(this, {
domainName: DOMAIN_NAME
}).findAndImport(this, 'MyPublicZone');
new r53.AliasRecord(this, 'BaseRecord', {
recordName: 'site',
zone: zone,
target: {
asAliasRecordTarget: () => ({
hostedZoneId: CF_HOSTED_ZONE_ID,
dnsName: distribution.distributionDomainName
})
}
});
new r53.AliasRecord(this, 'StarRecord', {
recordName: '*.site',
zone: zone,
target: {
asAliasRecordTarget: () => ({
hostedZoneId: CF_HOSTED_ZONE_ID,
dnsName: distribution.distributionDomainName
})
}
});
new cdk.CfnOutput(this, 'Bucket', {
value: `s3://${bucket.bucketName}`
});
new cdk.CfnOutput(this, 'CfDomain', {
value: distribution.distributionDomainName
});
new cdk.CfnOutput(this, 'CfId', {
value: distribution.distributionId
});
// to reverify it was really updated to a proper version
new cdk.CfnOutput(this, 'LambdaEdge', {
value: stackOutput.getAtt('Output')
});
}
} Then stack creation const ls = new LambdaStack(app, LAMBDA_EDGE_STACK_NAME, {
env: {
region: 'us-east-1'
}
});
new StaticSiteStack(app, 'cf-stack').addDependency(ls);
app.run(); To test that it works:
exports.handler = (event, context, callback) => {
console.log("REQUEST", JSON.stringify(event));
const status = '200';
const headers = {
'content-type': [{
key: 'Content-Type',
value: 'application/json'
}]
};
const body = JSON.stringify(event, null, 2);
return callback(null, {status, headers, body});
};
exports.handler = (event, context) => {
console.log("REQUEST RECEIVED:\n" + JSON.stringify(event));
const aws = require("aws-sdk");
const response = require('cfn-response');
const {RequestType, ResourceProperties: {StackName, OutputKey}} = event;
if (RequestType === 'Delete') {
return response.send(event, context, response.SUCCESS);
}
const cfn = new aws.CloudFormation({region: 'us-east-1'});
cfn.describeStacks({StackName}, (err, {Stacks}) => {
if (err) {
console.log("Error during stack describe:\n", err);
return response.send(event, context, response.FAILED, err);
}
const Output = Stacks[0].Outputs
.filter(out => out.OutputKey === OutputKey)
.map(out => out.OutputValue)
.join();
response.send(event, context, response.SUCCESS, {Output});
});
}; don't forget to add published an article https://lanwen.ru/posts/aws-cdk-edge-lambda/ |
I would give this a try to integrate into CDK (I mean the @rix0rrr @RomainMuller |
This declaration is required for deploying custom resources as lamdba association, which by itself is required to deploy a lambda@edge for a stack which is in a different region as 'us-east-1'. Relates to aws#1575
This declaration is required for deploying custom resources as lamdba association, which by itself is required to deploy a lambda@edge for a stack which is in a different region as 'us-east-1'. Relates to aws#1575
This declaration is required for deploying custom resources as lamdba association, which by itself is required to deploy a lambda@edge for a stack which is in a different region as 'us-east-1'. Relates to aws#1575
This declaration is required for deploying custom resources as lamdba association, which by itself is required to deploy a lambda@edge for a stack which is in a different region as 'us-east-1'. Relates to aws#1575
This declaration is required for deploying custom resources as lamdba association, which by itself is required to deploy a lambda@edge for a stack which is in a different region as 'us-east-1'. Relates to aws#1575
* feat(cloudfront): define lambda@edge as resolvable resource This declaration is required for deploying custom resources as lamdba association, which by itself is required to deploy a lambda@edge for a stack which is in a different region as 'us-east-1'. Relates to #1575 * test: simplified test case by just test resources required for the case * feat: allow to create a version from an arn This commit allows to reference a lambda from a different region and use that as function association. * refactor: resolve conflicts * refactor: update based on review * refactor: use version arn as function arn * Fixing package.json * Fix tests
Hi @KnisterPeter, thanks for your work, since the 2 PRs are already merged, is there a guide or doc to indicate how to create a lambda@edge function effectively with CDK? |
@PinkyJie Not really, the two PRs are basic work to get it going. Basicly export a concrete version of the edge function from the us stack and import that version in your regional stack. Then put it in front of cloudfront. The work I've done was to add all typings so a lambda function could be connected with cloudfront. |
@KnisterPeter Thanks for the explanation, I'm using the solution from #1575 (comment) now, and it works like a charm, just wondering if there's more efficient solution after the 2 PRs. |
@PinkyJie Just no need to use the basic |
I'm having a super hard time using CDK with Lambda@Edge. I have one stack that deploys a lambda. I have another stack that deploys a Cloudfront distribution where I want to use the Lambda as a Viewer Request event lambda. I can get everything to deploy once. However, I run into issues when I've change my lambda's code and want to redeploy. The problem is the same issue that is affecting Lambda layer redeployments: #1972 (comment) |
Using SSM seems like a simpler solution indeed:
And to get it in a stack in another region:
|
Related to #572 |
P.S. const distribution = new cloudfront.CloudFrontWebDistribution(
this,
'MyWebsiteCloudFront',
{
originConfigs: [
{
s3OriginSource: {
s3BucketSource: bucket,
},
behaviors: [
{
isDefaultBehavior: true,
lambdaFunctionAssociations: [
{
eventType: cloudfront.LambdaEdgeEventType.VIEWER_REQUEST,
lambdaFunction: authLambdaVersion,
},
],
},
],
},
],
loggingConfig: {},
viewerCertificate: cloudfront.ViewerCertificate.fromAcmCertificate(
acmCertificate,
{
aliases: [DOMAIN],
}
),
}
); |
Hi all. I also faced a problem using Regards |
@kinbald I'm not sure there's a workaround for that behavior. In my experience I've had to wait 24 hours, and then I can destroy the stack. The behavior's the same with any Lambda@Edge function, even when created via the console. |
@blimmer Sure, more a product issue. Just thinking that as we wait for WebDistribution deployment, could be interesting to wait for lambda replicas deletion (e.g. creating a proper type of lambda for edge). |
Looking at the CDK code this is not well demonstrated in a way that the sub-stack is hidden from the user of the resource. See aws/aws-cdk#1575 for better tracking of CDK support for lambda at edge cross regions.
@jtomaszewski how to get authLambdaVersion when this function was created inanother stack ? |
In your lambda stack you store the version ARN in SSM Parameter store: [...]
// Export ARN with version
new StringParameter(this, 'edge-lambda-arn', {
parameterName: '/exampleproject/example-parameter',
description: 'CDK parameter stored for cross region Edge Lambda',
stringValue: yourFunction.currentVersion.functionArn
}) And in your CloudFront stack you get the parameter and instantiate a Version object with the ARN (note the region in AwsCustomResource): [...]
const lambdaParameter = new AwsCustomResource(this, 'GetParameter', {
policy: AwsCustomResourcePolicy.fromStatements([
new iam.PolicyStatement({
effect: iam.Effect.ALLOW,
actions: ['ssm:GetParameter*'],
resources: [
this.formatArn({
service: 'ssm',
region: 'us-east-1',
resource: `parameter/exampleproject/example-parameter'`
})
]
})
]),
onUpdate: {
// will also be called for a CREATE event
service: 'SSM',
action: 'getParameter',
parameters: {
Name: '/exampleproject/example-parameter'
},
region: 'us-east-1',
physicalResourceId: PhysicalResourceId.of(Date.now().toString()) // Update physical id to always fetch the latest version
}
})
[...]
lambdaFunctionAssociations: [
{
eventType: LambdaEdgeEventType.VIEWER_REQUEST,
lambdaFunction: lambda.Version.fromVersionArn(
this,
'cf-lambda',
lambdaParameter.getResponseField('Parameter.Value')
)
}
]
[...] |
We have an ongoing effort of redesigning the CloudFront module. To that end, we are currently in the middle of an RFC and we would love feedback from all interested parties. Specifically, checkout the |
@iliapolo is there any ongoing effort on IMO the CDK should take care of deploying the Lambda@Edge functions to I think this is a prime example of how a CDK construct can abstract from technical details and make our lives easier. |
I might miss something, but why not simply rading back the version ARN in the CloudFront stack using SSM: const versionArn = ssm.StringParameter.fromStringParameterAttributes(this, 'MyValue', {
parameterName: '/exampleproject/example-parameter',
}).stringValue; EDIT: I missed something: SSM can only access parameters in the same region. For cross-region/account, an IAM user (or group) that can assume a role in the target region/account with permission to access the parameter in that region/account is required. Hence the custom resource. |
Yes, the Lambda@Edge support for the redesign of CloudFront (the Simple example: const myFunc = new lambda.Function(...);
new cloudfront.Distribution(this, 'myDist', {
defaultBehavior: {
origin: new origins.S3Origin(myBucket),
edgeLambdas: [
{
functionVersion: myFunc.currentVersion,
eventType: cloudfront.LambdaEdgeEventType.VIEWER_REQUEST,
}
],
},
}); |
@njlynch thanks. It is quite tedious to deploy Lambda edge functions to regions other than My findings are that you need:
import * as cdk from '@aws-cdk/core';
import * as lambda from '@aws-cdk/aws-lambda';
import * as iam from '@aws-cdk/aws-iam';
import * as ssm from '@aws-cdk/aws-ssm';
import { ServicePrincipals, ManagedPolicies } from 'cdk-constants';
interface EdgeLambdaStackProps extends cdk.StackProps {
lambdaFunctionArnParameterName: string;
}
export class EdgeLambdaStack extends cdk.Stack {
constructor(scope: cdk.Construct, id: string, props: EdgeLambdaStackProps) {
super(scope, id, props);
if (props.env?.region !== 'us-east-1') {
throw new Error("The stack contains Lambda@Edge functions and must be deployed in 'us-east-1'");
}
const { lambdaFunctionArnParameterName } = props
const { managedPolicyArn } = iam.ManagedPolicy.fromAwsManagedPolicyName(
ManagedPolicies.AWS_LAMBDA_BASIC_EXECUTION_ROLE
);
const ssrLambda = new lambda.Function(this, 'EdgeLambdaFunction', {
runtime: lambda.Runtime.NODEJS_12_X,
code: '../some-dir/my-handler',
handler: 'index.handler',
role: new iam.Role(this, 'EdgeLambdaServiceRole', {
assumedBy: new iam.CompositePrincipal(
new iam.ServicePrincipal(ServicePrincipals.LAMBDA),
new iam.ServicePrincipal(ServicePrincipals.EDGE_LAMBDA)
),
managedPolicies: [
{
managedPolicyArn,
},
],
}),
});
const { functionArn } = ssrLambda.currentVersion;
new ssm.StringParameter(this, 'LambdaFunctionArnParameter', {
parameterName: lambdaFunctionArnParameterName,
stringValue: functionArn,
});
}
} In the stack that contains the CloudFront distribution, S3 buckets etc. (to be deployed in another region):
import * as cdk from '@aws-cdk/core';
import * as lambda from '@aws-cdk/aws-lambda';
import * as s3 from '@aws-cdk/aws-s3';
import * as s3deploy from '@aws-cdk/aws-s3-deployment';
import * as cloudfront from '@aws-cdk/aws-cloudfront';
import * as acm from '@aws-cdk/aws-certificatemanager';
import * as cr from '@aws-cdk/custom-resources';
import * as iam from '@aws-cdk/aws-iam';
interface WebStackProps extends cdk.StackProps {
lambdaFunctionArnParameterName: string;
domainName: string;
certificate: acm.ICertificate;
}
export class WebStack extends cdk.Stack {
public readonly siteBucket: s3.IBucket;
constructor(scope: cdk.Construct, id: string, props: WebStackProps) {
super(scope, id, props);
const { lambdaFunctionArnParameterName, domainName, certificate } = props;
const bucket = new s3.Bucket(this, 'Bucket');
const bucketOai = new cloudfront.OriginAccessIdentity(this, 'BucketOai');
bucket.grantRead(bucketOai);
const egdeLambdaFunctionArn = new SsmParameterReader(this, 'LambdaFunctionArnReader', {
parameterName: lambdaFunctionArnParameterName,
region: 'us-east-1',
}).stringValue;
const distribution = new cloudfront.CloudFrontWebDistribution(this, 'Distribution', {
originConfigs: [
{
s3OriginSource: {
s3BucketSource: bucket,
originAccessIdentity: bucketOai,
},
behaviors: [
{
defaultTtl: cdk.Duration.seconds(0),
minTtl: cdk.Duration.seconds(0),
maxTtl: cdk.Duration.seconds(0),
forwardedValues: {
cookies: {
forward: 'all',
},
queryString: true,
},
lambdaFunctionAssociations: [
{
eventType: cloudfront.LambdaEdgeEventType.ORIGIN_REQUEST,
lambdaFunction: lambda.Version.fromVersionArn(this, 'EdgeLambdaFunctionArn', egdeLambdaFunctionArn),
},
],
isDefaultBehavior: true,
},
],
},
],
viewerCertificate: cloudfront.ViewerCertificate.fromAcmCertificate(certificate, {
securityPolicy: cloudfront.SecurityPolicyProtocol.TLS_V1_2_2018,
aliases: [domainName, `www.${domainName}`],
}),
});
new s3deploy.BucketDeployment(this, 'DeployNextJsStaticAssets', {
sources: [
s3deploy.Source.asset('../some-dir', {
exclude: ['my-handler'], // don't upload handler code to S3
}),
],
destinationBucket: bucket,
});
}
}
interface SsmParameterReaderProps {
parameterName: string;
region: string;
}
// https://stackoverflow.com/a/59774628/6058505
export class SsmParameterReader extends cdk.Construct {
private reader: cr.AwsCustomResource;
get stringValue(): string {
return this.getParameterValue();
}
constructor(scope: cdk.Construct, name: string, props: SsmParameterReaderProps) {
super(scope, name);
const { parameterName, region } = props;
const customResource = new cr.AwsCustomResource(scope, `${name}CustomResource`, {
policy: cr.AwsCustomResourcePolicy.fromStatements([
new iam.PolicyStatement({
effect: iam.Effect.ALLOW,
actions: ['ssm:GetParameter*'],
resources: [
cdk.Stack.of(this).formatArn({
service: 'ssm',
region,
resource: 'parameter',
resourceName: parameterName.replace(/^\/+/, ''), // remove leading '/', since formatArn() will add one
}),
],
}),
]),
onUpdate: {
service: 'SSM',
action: 'getParameter',
parameters: {
Name: parameterName,
},
region,
physicalResourceId: cr.PhysicalResourceId.of(Date.now().toString()), // Update physical id to always fetch the latest version
},
});
this.reader = customResource;
}
private getParameterValue(): string {
return this.reader.getResponseField('Parameter.Value');
}
} Ideally, we could drop an instance of an (imaginary) |
Thanks @asterikx (and all others who have contributed work-arounds and solutions to this so far)! I think the request for a construct that enables requesting Lambda functions cross-region is reasonable given the complexity of the above work-arounds. I have created #9862 to track this request. Given the long history of this issue, and the multiple side-threads that have since come up, I am going to close this issue out in favor of the above to track the cross-region-specific piece. If you have been following this issue and have a use case or need for requesting Lambda functions cross-region, please go 👍 #9862 so we can track priority of this request. |
DRAFT PR - Looking for early-stages feedback This PR creates a construct (`EdgeFunction`) for Lambda@Edge functions. CloudFront requires that a function be in us-east-1 to be used with Lambda@Edge, even if the logical distribution is created via another region. The initial goal of this construct is to make it easier to request and work with a function in us-east-1 when the primary stack is in another region. In the future, this can be extended to validate other Lambda@Edge restrictions. See https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/lambda-requirements-limits.html and #9833 for more information on those limitations. DRAFT -- What exists does work and has been successfully deployed with a CloudFront distribution based in eu-west-1, but all of the normal Lambda functionality (e.g., permissions) has not been verified to work yet. Some open questions: 1. Where does this belong? There are circular dependency issues with `custom-resources` that prevents this from being in `aws-lambda`. `aws-cloudfront` seems possibly the next-best thing, but I can also see an argument for moving this into its own module. 2. Does this approach (creating a new stack and using SSM + an AWS custom resource) make sense, or should another approach be taken? 3. I intentionally didn't extend from `FunctionBase` in order to override most of the methods there to redirect to the delegate function; it's not clear (yet) that this will work and/or is a good idea. Feedback welcome. Thanks to @asterikx for the inspiration and consolidated writeup in #1575. fixes #9862
DRAFT PR - Looking for early-stages feedback This PR creates a construct (`EdgeFunction`) for Lambda@Edge functions. CloudFront requires that a function be in us-east-1 to be used with Lambda@Edge, even if the logical distribution is created via another region. The initial goal of this construct is to make it easier to request and work with a function in us-east-1 when the primary stack is in another region. In the future, this can be extended to validate other Lambda@Edge restrictions. See https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/lambda-requirements-limits.html and #9833 for more information on those limitations. Some open questions: 1. Is there a more clever way to "refresh" the SSM parameter reader when the underlying function changes? 2. How to make this and `edgeArn` play nicely together? Thanks to @asterikx for the inspiration and consolidated writeup in #1575. fixes #9862
DRAFT PR - Looking for early-stages feedback This PR creates a construct (`EdgeFunction`) for Lambda@Edge functions. CloudFront requires that a function be in us-east-1 to be used with Lambda@Edge, even if the logical distribution is created via another region. The initial goal of this construct is to make it easier to request and work with a function in us-east-1 when the primary stack is in another region. In the future, this can be extended to validate other Lambda@Edge restrictions. See https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/lambda-requirements-limits.html and #9833 for more information on those limitations. Some open questions: 1. Is there a more clever way to "refresh" the SSM parameter reader when the underlying function changes? 2. How to make this and `edgeArn` play nicely together? Thanks to @asterikx for the inspiration and consolidated writeup in #1575. fixes #9862
DRAFT PR - Looking for early-stages feedback This PR creates a construct (`EdgeFunction`) for Lambda@Edge functions. CloudFront requires that a function be in us-east-1 to be used with Lambda@Edge, even if the logical distribution is created via another region. The initial goal of this construct is to make it easier to request and work with a function in us-east-1 when the primary stack is in another region. In the future, this can be extended to validate other Lambda@Edge restrictions. See https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/lambda-requirements-limits.html and #9833 for more information on those limitations. Some open questions: 1. Is there a more clever way to "refresh" the SSM parameter reader when the underlying function changes? 2. How to make this and `edgeArn` play nicely together? Thanks to @asterikx for the inspiration and consolidated writeup in #1575. fixes #9862
This PR creates a construct (`EdgeFunction`) for Lambda@Edge functions. CloudFront requires that a function be in us-east-1 to be used with Lambda@Edge, even if the logical distribution is created via another region. The initial goal of this construct is to make it easier to request and work with a function in us-east-1 when the primary stack is in another region. In the future, this can be extended to validate other Lambda@Edge restrictions. See https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/lambda-requirements-limits.html and #9833 for more information on those limitations. Thanks to @asterikx for the inspiration and consolidated writeup in #1575. Related changes: * When updating the CloudFront README, I noticed that the `Distribution` sub-section hadn't been updated when it was flipped from Experimental to Dev Preview. * A minor docstring fix for Lambda. fixes #9862 ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
It would be great to have a L2 construct providing Lambda@Edge support. Though it's not clear to me what the best way to add this would be, since whereas most other event sources have a method on the resource (i.e. such as
topic.subscribeLambda(...)
), Lambda@Edge associations are made between a lambda function and a specific behavior of a distribution, and the individual behaviors are not exposed by the L2 construct (you end up with a CloudFrontDistribution object, but no way to reference individual behaviors of that distribution).Adding support for Lambda@Edge would probably also require adding better support for Lambda function versions (it would be great to just be able to use something like AutoPublishAlias from SAM).
The text was updated successfully, but these errors were encountered: