A/B deployment using Lambda@Edge trigger in Viewer request for two CloudFront Distributions (PLEASE HELP)

0

I'm trying to create an A/B deployment following an outdated guide and am having some issues trying to recreate it for my use case. This is the model I am trying to duplicate. Enter image description here

I've created 3 lamdba functions to recreate it. One for Viewer request, Origin Request, and Origin Response. I'll post them in a moment. The issue I'm having is that my created CF Distros using s3 buckets doesn't use OAI, so I'm not sure how to reference the two origins with the code. I appreciate all of your time and resources!

Enter image description here

Enter image description here

**VIEWER REQUEST **

'use strict';

const sourceCoookie = 'X-Source';
const sourceMain = 'abc1.s3-website-us-east-1.amazonaws.com';
const sourceExperiment = 'abc2.s3-website-us-east-1.amazonaws.com';
const experimentTraffic = 0.5;

// Viewer request handler
exports.handler =  (event, context, callback) => {
    const request = event.Records[0].cf.request;
    const headers = request.headers;

    // Look for source cookie
    if ( headers.cookie ) {
        for (let i = 0; i < headers.cookie.length; i++) {        
            if (headers.cookie[i].value.indexOf(sourceCoookie) >= 0) {
                console.log('Source cookie found. Forwarding request as-is');
                // Forward request as-is
                callback(null, request);
                return;
            }         
        }       
    }

    console.log('Source cookie has not been found. Throwing dice...');
    const source = ( Math.random() < experimentTraffic ) ? sourceExperiment : sourceMain;
    console.log(`Source: ${source}`)

    // Add Source cookie
    const cookie = `${sourceCoookie}=${source}`
    console.log(`Adding cookie header: ${cookie}`);
    headers.cookie = headers.cookie || [];
    headers.cookie.push({ key:'Cookie', value: cookie });

    // Forwarding request
    callback(null, request);
};

**ORIGIN REQUEST **

'use strict';

const sourceCoookie = 'X-Source';
const sourceMain = 'abc1.s3-website-us-east-1.amazonaws.com';
const sourceExperiment = 'abc2.s3-website-us-east-1.amazonaws.com';
const experimentBucketName = 'abc2.s3-website-us-east-1.amazonaws.com';
const experimentBucketRegion = 'us-east-1';

// Origin Request handler
exports.handler = (event, context, callback) => {
    const request = event.Records[0].cf.request;
    const headers = request.headers;

    const source = decideSource(headers);

    // If Source is Experiment, change Origin and Host header
    if ( source === sourceExperiment ) {
        console.log('Setting Origin to experiment bucket');
        // Specify Origin
        request.origin = {
            s3: {
                authMethod: 'origin-access-identity',
                domainName: experimentBucketName,
                path: '',
                region: experimentBucketRegion    
            }
        };

        // Also set Host header to prevent “The request signature we calculated does not match the signature you provided” error
        headers['host'] = [{key: 'host', value: experimentBucketName }];
    }
    // No need to change anything if Source was Main or undefined
    
    callback(null, request);
};

**ORIGIN RESPONSE **

'use strict';

const sourceCoookie = 'X-Source';
const sourceMain = 'abc.s3-website-us-east-1.amazonaws.com';
const sourceExperiment = 'abc2.s3-website-us-east-1.amazonaws.com';
const cookiePath = '/';

// Origin Response handler
exports.handler =  (event, context, callback) => {
    const request = event.Records[0].cf.request;
    const requestHeaders = request.headers;
    const response = event.Records[0].cf.response;    

    const sourceMainCookie = `${sourceCoookie}=${sourceMain}`;
    const sourceExperimenCookie = `${sourceCoookie}=${sourceExperiment}`;    

    // Look for Source cookie
    // A single cookie header entry may contains multiple cookies, so it looks for a partial match
    if (requestHeaders.cookie) {
        for (let i = 0; i < requestHeaders.cookie.length; i++) {    
            // ...ugly but simple enough for now   
            if (requestHeaders.cookie[i].value.indexOf(sourceExperimenCookie) >= 0) {
                console.log('Experiment Source cookie found');
                setCookie(response, sourceExperimenCookie);
                callback(null, response);
                return;
            }
            if (requestHeaders.cookie[i].value.indexOf(sourceMainCookie) >= 0) {
                console.log('Main Source cookie found');
                setCookie(response, sourceMainCookie);
                callback(null, response);
                return;
            }            
        }
    }
    
    // If request contains no Source cookie, do nothing and forward the response as-is
    console.log('No Source cookie found');
    callback(null, response);
}

// Add set-cookie header (including path)
const setCookie = function(response, cookie) {
    const cookieValue = `${cookie}; Path=${cookiePath}`;
    console.log(`Setting cookie ${cookieValue}`);
    response.headers['set-cookie'] = [{ key: "Set-Cookie", value: cookieValue }];    
}
1 Antwort
0

Hi

You should set the authMethod to none since you are not using OAI.

As per Documentation

authMethod (read/write) (Amazon S3 origins only)
If you're using an origin access identity (OAI), set this field to origin-access-identity. If you aren't using an OAI, set it to none.
profile picture
EXPERTE
beantwortet vor 10 Monaten
  • Thanks, I actually caught that and changed it. It still isn't working the way I wanted though. What else could be the issue?

Du bist nicht angemeldet. Anmelden um eine Antwort zu veröffentlichen.

Eine gute Antwort beantwortet die Frage klar, gibt konstruktives Feedback und fördert die berufliche Weiterentwicklung des Fragenstellers.

Richtlinien für die Beantwortung von Fragen