Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Lambda@Edge not logging on cloudfront request

As explained in the Docs , I set up Lambda@edge for cloudfront trigger of Viewer Response.

The lambda function code :

'use strict';

exports.handler = (event, context, callback) => {
    console.log('----EXECUTED------');

    const response = event.Records[0].cf.response;      
    console.log(event.Records[0].cf_response);

    callback(null, response);
};

I have set up trigger appropriately for the Viewer Response event.

Now when I make a request through cloudfront, it must be logged in cloudwatch, but it doesn't.
If I do a simple Test Lambda Function (using Button), it is logged properly.

What might be the issue here ?

like image 352
formatkaka Avatar asked Sep 30 '17 13:09

formatkaka


People also ask

How does Lambda edge work with CloudFront?

Lambda@Edge lets you run Node. js and Python Lambda functions to customize content that CloudFront delivers, executing the functions in AWS locations closer to the viewer. The functions run in response to CloudFront events, without provisioning or managing servers.

How do I add edge lambda to CloudFront?

In the Designer section of the page, choose CloudFront, as shown in the following image. Scroll down to the Configure triggers section of the page, then choose Deploy to Lambda@Edge. On the Deploy to Lambda@Edge page, under Configure CloudFront trigger, enter the following information: Distribution.

How do you get logs from Lambda edge?

You can access the log files using the CloudWatch console or the CloudWatch Logs API. Lambda creates CloudWatch Logs log streams in the AWS Regions closest to the location where the function is executed. The log group name is formatted as: /aws/lambda/us-east-1 .

Can CloudFront connect to Lambda?

Fronting your Lambda Function URL endpoints with CloudFront allows you to cache content closer to the viewer by leveraging the globally distributed content distribution network. You could define custom domain names, turn on HTTPS delivery over TLS.


4 Answers

When you deploy Lambda@Edge function, It is deployed to all edge cache regions across the world with their version Replica of the Lambda Edge function. Regional edge caches are a subset of the main AWS regions and edge locations.

When a user requests to the nearest pop/edge, the lambda associated with the edge cache region will get called. All logs of Lambda associated with those regions will in their edge cache region CloudWatch logs.

For example:

If a user is hitting us-east-1 region then its associated logs will be in us-east-1.

To know exactly where (on which region) your function is logging, you can run this AWS CLI script:

FUNCTION_NAME=function_name_without_qualifiers
for region in $(aws --output text  ec2 describe-regions | cut -f 3) 
do
    for loggroup in $(aws --output text  logs describe-log-groups --log-group-name "/aws/lambda/us-east-1.$FUNCTION_NAME" --region $region --query 'logGroups[].logGroupName')
    do
        echo $region $loggroup
    done
done

on which you have to replace "function_name_without_qualifiers" with the name of your lambda@edge. Link

Hope it helps.

like image 77
Kannaiyan Avatar answered Oct 25 '22 17:10

Kannaiyan


For those who have also searched for logs and couldn't find them with the script provided by @Kannaiyan.

TL;DR

Use this IAM Role for your Lambda function

{
"Version": "2012-10-17",
"Statement": [
    {
        "Effect": "Allow",
        "Action": "logs:CreateLogGroup",
        "Resource": "arn:aws:logs:*:*:*"
    },
    {
        "Effect": "Allow",
        "Action": [
            "logs:CreateLogStream",
            "logs:PutLogEvents"
        ],
        "Resource": [
            "arn:aws:logs:*:*:log-group:*:*"
        ]
    }
  ]
}

====

Make sure you have correct IAM role. If you created a Lambda first and then deployed it to Lambda@Edge, automatically generated IAM Role will only have permissions enough to log data in a single region into the log group named after the Lambda function, whilst using Lambda@Edge means it'll try to log data in different regions into the "/aws/lambda/." log group. Therefore it is necessary to change the IAM Role to allow creation of log group and write access there in different regions. In the TL;DR section, I provided the sample IAM Role, but make sure to narrow down the access to the specific list of log groups in production

like image 22
Yevhenii Hordashnyk Avatar answered Oct 25 '22 18:10

Yevhenii Hordashnyk


According to AWS Documentation for Lambda@Edge Functions:

When you check for the log files, be aware that log files are stored in the Region closest to the location where the function is executed. So if you visit a website from, for example, London, you must change the Region to view the CloudWatch Logs for the London Region.

like image 9
captainblack Avatar answered Oct 25 '22 18:10

captainblack


Following on from @yevhenii-hordashnyk's answer, if you're using "Serverless" framework, by default it creates a IAM user with logging permissions for the execution region only, and it is locked to the application name (which does not work for Edge functions because they are prefixed by the region of the installed function, thus requiring different permissions).

You have to specify a custom role, and apply that role to your function as per https://www.serverless.com/framework/docs/providers/aws/guide/iam

Note the following snippet uses * instead of - Ref: 'AWS::Region', as well as additional edgelambda.amazonaws.com service in Trust Relationships.

        AssumeRolePolicyDocument:
          Version: '2012-10-17'
          Statement:
            - Effect: Allow
              Principal:
                Service:
                  - lambda.amazonaws.com
                  - edgelambda.amazonaws.com
              Action: sts:AssumeRole

        Policies:
          - PolicyName: myPolicyName
            PolicyDocument:
              Version: '2012-10-17'
              Statement:
                - Effect: Allow # note that these rights are given in the default policy and are required if you want logs out of your lambda(s)
                  Action:
                    - logs:CreateLogGroup
                    - logs:CreateLogStream
                    - logs:PutLogEvents
                  Resource:
                    - 'Fn::Join':
                      - ':'
                      -
                        - 'arn:aws:logs'
                        - '*'
                        - Ref: 'AWS::AccountId'
                        - 'log-group:/aws/lambda/*:*:*'

By default it does add the `AWSLambdaVPCAccessExecutionRole` policy to the lambda role, but I do not know why it does not create the Log Stream. Maybe I've missed something, but after doing the above, it works now.
like image 1
Daryl Teo Avatar answered Oct 25 '22 18:10

Daryl Teo