Skip to content

Commit 334d3b3

Browse files
author
James Prendergast
committed
Change the lab to be self-paced
1 parent 1e852c0 commit 334d3b3

16 files changed

+767
-363
lines changed

Makefile

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
TAGS:="purpose=lab project=lambda-edge-ab"
2+
EDGE_STACK = lambda-edge-dist
3+
# ORIGIN_STACK = lambda-edge-origins
4+
CLOUDFRONT_TEMPLATE = cloudfront-template.yml
5+
# ORIGIN_TEMPLATE = ../content/origin-template.yml
6+
# OAI:=$(shell aws cloudformation describe-stacks --stack-name $(EDGE_STACK) --region us-east-1 --query 'Stacks[0].Outputs[?OutputKey==`OaiS3CanonicalUserId`].OutputValue[]' --output text)
7+
# RAND:=$$RANDOM
8+
# include rand.mk
9+
# ORIGIN_A:=ab-test-a-$(RAND)
10+
# ORIGIN_B:=ab-test-b-$(RAND)
11+
# DISTROBUCKET:=aws-sam-cli-managed-default-samclisourcebucket-$(RAND)
12+
# DISTRIBUTION_ID:=$(shell aws cloudformation describe-stacks --stack-name $(EDGE_STACK) --region us-east-1 --query 'Stacks[0].Outputs[?OutputKey==`DistributionID`].OutputValue[]' --output text)
13+
14+
.PHONY: deploy-clicktracker upload-origin upload-index invalidate-cache clean package deploy-distribution deploy-origins teardown-origins setup reset
15+
16+
# rand.mk:
17+
# @echo "RAND:=$$RANDOM" > rand.mk
18+
19+
# test:
20+
# @echo $(RAND)
21+
22+
upload-index:
23+
aws s3api put-object --bucket $(ORIGIN_A) --content-type text/html --cache-control max-age=60 --key index.html --body ./content/origin-a/index.html
24+
aws s3api put-object --bucket $(ORIGIN_B) --content-type text/html --cache-control max-age=60 --key index.html --body ./content/origin-b/index.html
25+
26+
# invalidate-cache:
27+
# aws cloudfront create-invalidation --distribution-id $(DISTRIBUTION_ID) --paths "/*"
28+
29+
# distrobucket:
30+
# aws s3api create-bucket --bucket $(DISTROBUCKET) --acl private --region us-east-1
31+
# aws s3api put-bucket-policy --bucket $(DISTROBUCKET) --policy '{ "Version": "2008-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Service": "serverlessrepo.amazonaws.com" }, "Action": "s3:GetObject", "Resource": "arn:aws:s3:::$(DISTROBUCKET)/*" } ] }'
32+
33+
deploy:
34+
sam deploy --template-file $(CLOUDFRONT_TEMPLATE) --tags $(TAGS) --stack-name $(EDGE_STACK) -g
35+
36+
# deploy-origins:
37+
# sam deploy --template-file $(ORIGIN_TEMPLATE) --tags $(TAGS) --stack-name $(ORIGIN_STACK) --parameter-overrides "OriginAccessIdentity=$(OAI) OriginA=$(ORIGIN_A).s3.ap-southeast-2.amazonaws.com OriginB=$(ORIGIN_B).s3.ap-southeast-2.amazonaws.com"
38+
39+
# ../edge-functions/src/origins_config.js:
40+
# @echo "module.exports = {\n a:'$(ORIGIN_A)',\n b:'$(ORIGIN_B)'\n};\n" > $@
41+
42+
teardown-origins:
43+
aws s3 rb s3://$(ORIGIN_A) --force
44+
aws s3 rb s3://$(ORIGIN_B) --force
45+
aws cloudformation wait stack-delete-complete --stack-name $(ORIGIN_STACK)
46+
47+
setup: deploy-distribution
48+
@echo "LAB SET UP"
49+
50+
reset: teardown-origins invalidate-cache
51+
@echo "LAB RESET"

README.md

Lines changed: 542 additions & 129 deletions
Large diffs are not rendered by default.

cloudfront-template.yml

Lines changed: 148 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,148 @@
1+
AWSTemplateFormatVersion: '2010-09-09'
2+
Transform: AWS::Serverless-2016-10-31
3+
Description: A/B testing using cloudfront and lambda@edge
4+
5+
Resources:
6+
7+
OriginAccessIdentity:
8+
Type: AWS::CloudFront::CloudFrontOriginAccessIdentity
9+
Properties:
10+
CloudFrontOriginAccessIdentityConfig:
11+
Comment: Origin Access Identity for lambda@edge dev lab
12+
13+
LogBucket:
14+
Type: "AWS::S3::Bucket"
15+
16+
CFDistribution:
17+
Type: AWS::CloudFront::Distribution
18+
Properties:
19+
DistributionConfig:
20+
Logging:
21+
Bucket: !GetAtt LogBucket.DomainName
22+
IncludeCookies: true
23+
Enabled: true
24+
DefaultRootObject: index.html
25+
Comment: 'AB testing Cloudfront distribution'
26+
Origins:
27+
- Id: s3
28+
DomainName: !GetAtt OriginABucket.DomainName
29+
S3OriginConfig:
30+
OriginAccessIdentity: !Join [ "/", [ origin-access-identity, cloudfront, !Ref OriginAccessIdentity ]]
31+
DefaultCacheBehavior:
32+
TargetOriginId: s3
33+
ForwardedValues:
34+
QueryString: false
35+
Cookies:
36+
Forward: whitelist
37+
WhitelistedNames:
38+
- pool
39+
ViewerProtocolPolicy: redirect-to-https
40+
DefaultTTL: 30
41+
MinTTL: 0
42+
AllowedMethods:
43+
- HEAD
44+
- GET
45+
CachedMethods:
46+
- HEAD
47+
- GET
48+
SmoothStreaming: false
49+
Compress: true
50+
51+
OriginABucket:
52+
Type: AWS::S3::Bucket
53+
Properties:
54+
BucketName: !Join
55+
- "-"
56+
- - "ab-testing-origin-a"
57+
- !Select
58+
- 0
59+
- !Split
60+
- "-"
61+
- !Select
62+
- 2
63+
- !Split
64+
- "/"
65+
- !Ref "AWS::StackId"
66+
AccessControl: Private
67+
Tags:
68+
- Key: purpose
69+
Value: lab
70+
- Key: project
71+
Value: lambda-edge-ab
72+
73+
OriginBBucket:
74+
Type: AWS::S3::Bucket
75+
Properties:
76+
BucketName: !Join
77+
- "-"
78+
- - "ab-testing-origin-b"
79+
- !Select
80+
- 0
81+
- !Split
82+
- "-"
83+
- !Select
84+
- 2
85+
- !Split
86+
- "/"
87+
- !Ref "AWS::StackId"
88+
AccessControl: Private
89+
Tags:
90+
- Key: purpose
91+
Value: lab
92+
- Key: project
93+
Value: lambda-edge-ab
94+
95+
OriginAAccessBucketPolicy:
96+
Type: AWS::S3::BucketPolicy
97+
Properties:
98+
Bucket:
99+
Ref: OriginABucket
100+
PolicyDocument:
101+
Version: '2008-10-17'
102+
Id: PolicyForCloudFrontPrivateContentA
103+
Statement:
104+
- Sid: '1'
105+
Effect: Allow
106+
Principal:
107+
CanonicalUser: !GetAtt OriginAccessIdentity.S3CanonicalUserId
108+
Action: s3:GetObject
109+
Resource:
110+
- !Join [ "", [ "arn:aws:s3:::", !Ref OriginABucket, "/*"]]
111+
112+
OriginBAccessBucketPolicy:
113+
Type: AWS::S3::BucketPolicy
114+
Properties:
115+
Bucket:
116+
Ref: OriginBBucket
117+
PolicyDocument:
118+
Version: '2008-10-17'
119+
Id: PolicyForCloudFrontPrivateContentA
120+
Statement:
121+
- Sid: '1'
122+
Effect: Allow
123+
Principal:
124+
CanonicalUser: !GetAtt OriginAccessIdentity.S3CanonicalUserId
125+
Action: s3:GetObject
126+
Resource:
127+
- !Join [ "", [ "arn:aws:s3:::", !Ref OriginBBucket, "/*"]]
128+
129+
Outputs:
130+
CFDistribution:
131+
Description: Cloudfront Distribution Domain Name
132+
Value: !GetAtt CFDistribution.DomainName
133+
134+
DistributionID:
135+
Description: Cloudfront Distribution ID
136+
Value: !Ref CFDistribution
137+
138+
BucketADomain:
139+
Description: Regional Domian name of the A bucket
140+
Value: !GetAtt OriginABucket.RegionalDomainName
141+
142+
BucketBDomain:
143+
Description: Regional Domian name of the A bucket
144+
Value: !GetAtt OriginBBucket.RegionalDomainName
145+
146+
LogBucketDomain:
147+
Description: Regional Domian name of the log bucket
148+
Value: !GetAtt LogBucket.RegionalDomainName

edge-functions/src/common.js

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
exports.parseCookies = (headers) => {
2+
const parsedCookie = {};
3+
if (headers.cookie) {
4+
headers.cookie[0].value.split(';').forEach((cookie) => {
5+
if (cookie) {
6+
const parts = cookie.split('=');
7+
parsedCookie[parts[0].trim()] = parts[1].trim();
8+
}
9+
});
10+
}
11+
return parsedCookie;
12+
};

edge-functions/src/originrequest.js

Lines changed: 1 addition & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2,23 +2,11 @@
22

33
// the S3 origins that correspond to content for Pool A and Pool B
44
const origins = require('./origins_config.js');
5+
const parseCookies = require('./common.js').parseCookies;
56

67
// the `pool` cookie determines which origin to route to
78
const cookieName = 'pool';
89

9-
const parseCookies = (headers) => {
10-
const parsedCookie = {};
11-
if (headers.cookie) {
12-
headers.cookie[0].value.split(';').forEach((cookie) => {
13-
if (cookie) {
14-
const parts = cookie.split('=');
15-
parsedCookie[parts[0].trim()] = parts[1].trim();
16-
}
17-
});
18-
}
19-
return parsedCookie;
20-
}
21-
2210
// changes request origin depending on value of the `pool` cookie
2311
exports.handler = (event, context, callback) => {
2412
const request = event.Records[0].cf.request;

edge-functions/src/originresponse.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
'use strict';
22

33
// the S3 origins that correspond to content for Pool A and Pool B
4-
const origins = require('./origins_config.js');
4+
const originconfig = require('./origins_config.js');
5+
const origins = originconfig.origins;
56

67
//returns a set-cookie header based on where the content was served from
78
exports.handler = (event, context, callback) => {

edge-functions/src/viewerrequest.js

Lines changed: 1 addition & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4,18 +4,7 @@
44
const cookieName = 'pool';
55

66
//returns cookies as an associative array, given a CloudFront request headers array
7-
const parseCookies = (headers) => {
8-
const parsedCookie = {};
9-
if (headers.cookie) {
10-
headers.cookie[0].value.split(';').forEach((cookie) => {
11-
if (cookie) {
12-
const parts = cookie.split('=');
13-
parsedCookie[parts[0].trim()] = parts[1].trim();
14-
}
15-
});
16-
}
17-
return parsedCookie;
18-
}
7+
const parseCookies = require('./common.js').parseCookies;
198

209
// returns either 'a' or 'b', with a default probability of 1:1
2110
const choosePool = (chance = 2) => Math.floor(Math.random()*chance) === 0 ? 'b' : 'a';

resources/access_denied.png

121 KB
Loading
Loading

resources/origin-a-bucket-empty.png

283 KB
Loading

resources/s3_origin_bucketslist.png

131 KB
Loading
208 KB
Loading

samconfig.toml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
version = 0.1
2+
[default]
3+
[default.deploy]
4+
[default.deploy.parameters]
5+
stack_name = "lambda-edge-dist2"
6+
s3_bucket = "aws-sam-cli-managed-default-samclisourcebucket-1882ei3cfmxkc"
7+
s3_prefix = "lambda-edge-dist2"
8+
region = "us-east-1"
9+
capabilities = "CAPABILITY_IAM"
10+

setup/Makefile

Lines changed: 0 additions & 51 deletions
This file was deleted.

0 commit comments

Comments
 (0)