Skip to content
This repository was archived by the owner on Oct 9, 2021. It is now read-only.

Commit 1fcf64f

Browse files
committed
v3.0.0
1 parent 83d1ea7 commit 1fcf64f

File tree

1,095 files changed

+274589
-587
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

1,095 files changed

+274589
-587
lines changed

CHANGELOG.md

+6
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,12 @@
22
CHANGELOG
33
=========
44

5+
3.0.0
6+
=====
7+
* Introduces Cognito User Pools for authentication along with newer looking UI.
8+
* Adds API Gateway IAM Authorization
9+
* Provides support for workshop to run in all regions that are currently supporting Lambda and API Gateway services.
10+
511
2.0.0
612
=====
713
* Introduces multi-region stack support for workshop to run in any of the 5 existing regions that have API Gateway and Lambda.
1.14 KB
Binary file not shown.
1.37 KB
Binary file not shown.

CloudFormation/CreateZombieWorkshop.json

+248-24
Original file line numberDiff line numberDiff line change
@@ -14,25 +14,40 @@
1414

1515
"Mappings": {
1616
"AllowedRegions": {
17-
"us-west-2": {
18-
"S3Endpoint": "https://s3-us-west-2",
19-
"S3ContentsBucket": "aws-zombie-workshop-us-west-2"
17+
"us-west-2": {
18+
"S3Endpoint": "https://s3-us-west-2",
19+
"S3ContentsBucket": "aws-zombie-workshop-us-west-2",
20+
"CognitoRegion": "us-west-2"
2021
},
21-
"us-east-1": {
22-
"S3Endpoint": "https://s3",
23-
"S3ContentsBucket": "aws-zombie-workshop-us-east-1"
22+
"us-east-1": {
23+
"S3Endpoint": "https://s3",
24+
"S3ContentsBucket": "aws-zombie-workshop-us-east-1",
25+
"CognitoRegion": "us-east-1"
2426
},
2527
"eu-west-1": {
26-
"S3Endpoint": "https://s3-eu-west-1",
27-
"S3ContentsBucket": "aws-zombie-workshop-eu-west-1"
28+
"S3Endpoint": "https://s3-eu-west-1",
29+
"S3ContentsBucket": "aws-zombie-workshop-eu-west-1",
30+
"CognitoRegion": "eu-west-1"
2831
},
29-
"eu-central-1": {
30-
"S3Endpoint": "https://s3-eu-central-1",
31-
"S3ContentsBucket": "aws-zombie-workshop-eu-central-1"
32+
"eu-central-1": {
33+
"S3Endpoint": "https://s3-eu-central-1",
34+
"S3ContentsBucket": "aws-zombie-workshop-eu-central-1",
35+
"CognitoRegion": "us-east-1"
3236
},
33-
"ap-northeast-1": {
34-
"S3Endpoint": "https://s3-ap-northeast-1",
35-
"S3ContentsBucket": "aws-zombie-workshop-ap-northeast-1"
37+
"ap-northeast-1": {
38+
"S3Endpoint": "https://s3-ap-northeast-1",
39+
"S3ContentsBucket": "aws-zombie-workshop-ap-northeast-1",
40+
"CognitoRegion": "ap-northeast-1"
41+
},
42+
"ap-southeast-1": {
43+
"S3Endpoint": "https://s3-ap-southeast-1",
44+
"S3ContentsBucket": "aws-zombie-workshop-ap-southeast-1",
45+
"CognitoRegion": "us-east-1"
46+
},
47+
"ap-southeast-2": {
48+
"S3Endpoint": "https://s3-ap-southeast-2",
49+
"S3ContentsBucket": "aws-zombie-workshop-ap-southeast-2",
50+
"CognitoRegion": "us-east-1"
3651
}
3752
}
3853
},
@@ -55,8 +70,8 @@
5570
"Version": "2012-10-17",
5671
"Statement": [{
5772
"Effect": "Allow",
58-
"Principal": {"Service": ["lambda.amazonaws.com", "apigateway.amazonaws.com"]},
59-
"Action": ["sts:AssumeRole"]
73+
"Principal": {"Service": ["lambda.amazonaws.com", "apigateway.amazonaws.com"], "Federated": "cognito-identity.amazonaws.com"},
74+
"Action": ["sts:AssumeRole", "sts:AssumeRoleWithWebIdentity"]
6075
}]
6176
},
6277
"Path": "/",
@@ -104,6 +119,16 @@
104119
"Action": ["apigateway:*"],
105120
"Resource": ["*", "arn:aws:apigateway:*::/*"]
106121
},
122+
{
123+
"Effect": "Allow",
124+
"Action": [
125+
"mobileanalytics:PutEvents",
126+
"cognito-sync:*",
127+
"cognito-identity:*",
128+
"cognito-idp:*"
129+
],
130+
"Resource": ["*"]
131+
},
107132
{
108133
"Effect": "Allow",
109134
"Action": ["iam:*"],
@@ -138,16 +163,39 @@
138163
"DependsOn": ["ZombieLabLambdaRole","CreateIAMUsers"]
139164
},
140165

166+
"APIinvokePolicy": {
167+
"Type": "AWS::IAM::Policy",
168+
"Properties": {
169+
"Roles": [{ "Ref" : "ZombieLabLambdaRole" }],
170+
"PolicyName": { "Fn::Join": ["-", [{"Ref": "AWS::StackName"}, "apiinvokepolicy"]]},
171+
"PolicyDocument": {
172+
"Statement": [
173+
{
174+
"Effect": "Allow",
175+
"Action": ["execute-api:invoke"],
176+
"Resource": [
177+
{ "Fn::Join" : ["", ["arn:aws:execute-api:", { "Ref" : "AWS::Region" }, ":", { "Ref" : "AWS::AccountId" }, ":", { "Fn::GetAtt": ["CreateAPIGateway", "RestApiID"]}, "/ZombieWorkshopStage/zombie/POST/message" ]]},
178+
{ "Fn::Join" : ["", ["arn:aws:execute-api:", { "Ref" : "AWS::Region" }, ":", { "Ref" : "AWS::AccountId" }, ":", { "Fn::GetAtt": ["CreateAPIGateway", "RestApiID"]}, "/ZombieWorkshopStage/zombie/GET/message" ]]},
179+
{ "Fn::Join" : ["", ["arn:aws:execute-api:", { "Ref" : "AWS::Region" }, ":", { "Ref" : "AWS::AccountId" }, ":", { "Fn::GetAtt": ["CreateAPIGateway", "RestApiID"]}, "/ZombieWorkshopStage/zombie/POST/talkers" ]]},
180+
{ "Fn::Join" : ["", ["arn:aws:execute-api:", { "Ref" : "AWS::Region" }, ":", { "Ref" : "AWS::AccountId" }, ":", { "Fn::GetAtt": ["CreateAPIGateway", "RestApiID"]}, "/ZombieWorkshopStage/zombie/GET/talkers" ]]}
181+
]
182+
}
183+
]
184+
}
185+
},
186+
"DependsOn": ["ZombieLabLambdaRole", "CreateAPIGateway"]
187+
},
188+
141189
"S3BucketPolicy": {
142190
"Type": "AWS::S3::BucketPolicy",
143191
"Properties": {
144192
"Bucket": {"Ref" : "S3BucketForWebsiteContent"},
145193
"PolicyDocument": {
146194
"Statement":[{
147-
"Action":["s3:GetObject"],
148-
"Effect":"Allow",
149-
"Resource": { "Fn::Join" : ["", ["arn:aws:s3:::", { "Ref" : "S3BucketForWebsiteContent" } , "/*" ]]},
150-
"Principal": "*"
195+
"Action":["s3:GetObject"],
196+
"Effect":"Allow",
197+
"Resource": { "Fn::Join" : ["", ["arn:aws:s3:::", { "Ref" : "S3BucketForWebsiteContent" } , "/*" ]]},
198+
"Principal": "*"
151199
}]
152200
}
153201
}
@@ -203,6 +251,81 @@
203251
}
204252
},
205253

254+
"UsersDynamoDBTable": {
255+
"Type": "AWS::DynamoDB::Table",
256+
"Properties": {
257+
"TableName": { "Fn::Join": ["-", [{"Ref": "AWS::StackName"}, "users"]]},
258+
"AttributeDefinitions": [
259+
{
260+
"AttributeName": "userid",
261+
"AttributeType": "S"
262+
},
263+
{
264+
"AttributeName": "phone",
265+
"AttributeType": "S"
266+
},
267+
{
268+
"AttributeName": "slackuser",
269+
"AttributeType": "S"
270+
},
271+
{
272+
"AttributeName": "slackteamdomain",
273+
"AttributeType": "S"
274+
}
275+
],
276+
"KeySchema": [
277+
{
278+
"AttributeName": "userid",
279+
"KeyType": "HASH"
280+
}
281+
],
282+
"ProvisionedThroughput": {
283+
"ReadCapacityUnits": 5,
284+
"WriteCapacityUnits": 5
285+
},
286+
"GlobalSecondaryIndexes": [
287+
{
288+
"IndexName": { "Fn::Join": ["-", [{"Ref": "AWS::StackName"}, "phoneindex"]]},
289+
"KeySchema": [
290+
{
291+
"AttributeName": "phone",
292+
"KeyType": "HASH"
293+
}
294+
],
295+
"Projection": {
296+
"NonKeyAttributes": ["confirmed", "camp"],
297+
"ProjectionType": "INCLUDE"
298+
},
299+
"ProvisionedThroughput": {
300+
"ReadCapacityUnits": 5,
301+
"WriteCapacityUnits": 5
302+
}
303+
},
304+
{
305+
"IndexName": { "Fn::Join": ["-", [{"Ref": "AWS::StackName"}, "slackindex"]]},
306+
"KeySchema": [
307+
{
308+
"AttributeName": "slackuser",
309+
"KeyType": "HASH"
310+
},
311+
{
312+
"AttributeName": "slackteamdomain",
313+
"KeyType": "RANGE"
314+
}
315+
],
316+
"Projection": {
317+
"NonKeyAttributes": ["confirmed", "camp"],
318+
"ProjectionType": "INCLUDE"
319+
},
320+
"ProvisionedThroughput": {
321+
"ReadCapacityUnits": 5,
322+
"WriteCapacityUnits": 5
323+
}
324+
}
325+
]
326+
}
327+
},
328+
206329
"S3BucketForWebsiteContent": {
207330
"Type": "AWS::S3::Bucket",
208331
"Properties": {
@@ -248,6 +371,45 @@
248371
]
249372
},
250373

374+
"CognitoTriggerBuild": {
375+
"Type": "AWS::Lambda::Function",
376+
"Properties": {
377+
"Handler": "index.handler",
378+
"Role": { "Fn::GetAtt": ["ZombieLabLambdaRole", "Arn"] },
379+
"Code": {
380+
"S3Bucket": { "Ref" : "S3BucketForWebsiteContent" },
381+
"S3Key": "cognitoTriggerBuild.zip"
382+
},
383+
"Runtime": "nodejs4.3",
384+
"Timeout": "120"
385+
},
386+
"DependsOn": [
387+
"ZombieLabLambdaRole",
388+
"S3BucketForWebsiteContent",
389+
"PutWebsiteFilesInS3"
390+
]
391+
},
392+
393+
"CreateCognitoTrigger": {
394+
"Type": "Custom::CreateCognitoTrigger",
395+
"Properties": {
396+
"ServiceToken": { "Fn::GetAtt": ["CognitoTriggerBuild", "Arn"] },
397+
"region": { "Ref": "AWS::Region" },
398+
"CognitoRegion": { "Fn::FindInMap" : [ "AllowedRegions", { "Ref" : "AWS::Region" }, "CognitoRegion"]},
399+
"LambdaFunctionBucket": { "Fn::FindInMap" : [ "AllowedRegions", { "Ref" : "AWS::Region" }, "S3ContentsBucket"]},
400+
"StackName": { "Ref": "AWS::StackName" },
401+
"IamRole": { "Fn::GetAtt": ["ZombieLabLambdaRole", "Arn"] }
402+
},
403+
"DependsOn": [
404+
"S3BucketForWebsiteContent",
405+
"ZombieLabLambdaRole",
406+
"PutWebsiteFilesInS3",
407+
"WriteMessagesToDynamoDB",
408+
"GetMessagesFromDynamoDB",
409+
"MessagesDynamoDBTable"
410+
]
411+
},
412+
251413
"CreateAPIGateway": {
252414
"Type": "Custom::CreateAPIGateway",
253415
"Properties": {
@@ -291,6 +453,48 @@
291453
]
292454
},
293455

456+
"CognitoPoolsFunction": {
457+
"Type": "AWS::Lambda::Function",
458+
"Properties": {
459+
"Handler": "cognito.handler",
460+
"Role": { "Fn::GetAtt" : ["ZombieLabLambdaRole", "Arn"] },
461+
"Code": {
462+
"S3Bucket": { "Ref": "S3BucketForWebsiteContent" },
463+
"S3Key": "cognito.zip"
464+
},
465+
"Runtime": "nodejs4.3",
466+
"Timeout": "300",
467+
"MemorySize": "1536"
468+
},
469+
"DependsOn": [
470+
"ZombieLabLambdaRole",
471+
"S3BucketForWebsiteContent",
472+
"PutWebsiteFilesInS3",
473+
"CreateAPIGateway"
474+
]
475+
},
476+
477+
"CreateCognitoPools": {
478+
"Type": "Custom::CognitoPoolsFunction",
479+
"Properties": {
480+
"ServiceToken": { "Fn::GetAtt": ["CognitoPoolsFunction", "Arn"] },
481+
"region": { "Ref": "AWS::Region" },
482+
"CognitoRegion": { "Fn::FindInMap" : [ "AllowedRegions", { "Ref" : "AWS::Region" }, "CognitoRegion"]},
483+
"cognitoRoleARN": { "Fn::GetAtt": ["ZombieLabLambdaRole", "Arn"] },
484+
"bucket": { "Ref": "S3BucketForWebsiteContent" },
485+
"constantsFile": "S3/assets/js/constants.js",
486+
"StackName": { "Ref": "AWS::StackName" }
487+
},
488+
"DependsOn": [
489+
"S3BucketForWebsiteContent",
490+
"ZombieLabLambdaRole",
491+
"PutWebsiteFilesInS3",
492+
"WriteMessagesToDynamoDB",
493+
"GetMessagesFromDynamoDB",
494+
"MessagesDynamoDBTable"
495+
]
496+
},
497+
294498
"WriteMessagesToDynamoDB": {
295499
"Type": "AWS::Lambda::Function",
296500
"Properties": {
@@ -369,7 +573,7 @@
369573
" context.fail(new Error('DynamoDB Error: ' + err));\n",
370574
" } else {\n",
371575
" console.log(data);\n",
372-
" context.done(null, {Satus: 'Success'});\n",
576+
" context.done(null, {Status: 'Success'});\n",
373577
" }\n",
374578
"\n",
375579
" });\n",
@@ -380,7 +584,7 @@
380584
"Runtime": "nodejs",
381585
"Timeout": "10"
382586
},
383-
"DependsOn" : "TalkersDynamoDBTable"
587+
"DependsOn" : ["TalkersDynamoDBTable","ZombieLabLambdaRole"]
384588
},
385589

386590
"GetTalkersFromDynamoDB": {
@@ -440,7 +644,7 @@
440644
"Runtime": "nodejs",
441645
"Timeout": "10"
442646
},
443-
"DependsOn" : "TalkersDynamoDBTable"
647+
"DependsOn" : ["TalkersDynamoDBTable", "ZombieLabLambdaRole"]
444648
},
445649

446650
"CreateIAMUsers": {
@@ -492,6 +696,22 @@
492696
"Value": { "Ref": "MessagesDynamoDBTable" },
493697
"Description": "Table name of the newly created Messages DynamoDB table that will contain chat messages."
494698
},
699+
"DynamoDBTalkersTableName": {
700+
"Value": { "Ref": "TalkersDynamoDBTable" },
701+
"Description": "Table name of the newly created Talkers DynamoDB table that will contain metadata about survivors who are typing."
702+
},
703+
"DynamoDBUsersTableName": {
704+
"Value": { "Ref": "UsersDynamoDBTable" },
705+
"Description": "Table name of the newly created Users DynamoDB table that will contain records about registered users for the app."
706+
},
707+
"DynamoDBUsersSlackIndex": {
708+
"Value": { "Fn::Join": ["-", [{"Ref": "AWS::StackName"}, "slackindex"]]},
709+
"Description": "Name of the Slack index associated with the newly created Users DynamoDB table."
710+
},
711+
"DynamoDBUsersPhoneIndex": {
712+
"Value": { "Fn::Join": ["-", [{"Ref": "AWS::StackName"}, "phoneindex"]]},
713+
"Description": "Name of the Phone index associated with the newly created Users DynamoDB table."
714+
},
495715
"Bucket": {
496716
"Value": { "Ref": "S3BucketForWebsiteContent" },
497717
"Description": "The S3 bucket which contains the chat web app contents."
@@ -520,6 +740,10 @@
520740
"Value": { "Fn::GetAtt": ["GetMessagesFromDynamoDB", "Arn"] },
521741
"Description": "The ARN for the Get Messages Lambda function"
522742
},
743+
"ApiID": {
744+
"Value": { "Fn::GetAtt": ["CreateAPIGateway", "RestApiID"]},
745+
"Description": "The unique ID for your API Gateway API."
746+
},
523747
"IamUsersPassword": {
524748
"Value": { "Fn::GetAtt": ["CreateIAMUsers", "IamPassword"]},
525749
"Description": "The password for your IAM users",
@@ -552,7 +776,7 @@
552776
},
553777
"BucketCopiedContentsFrom": {
554778
"Value": { "Fn::FindInMap" : [ "AllowedRegions", { "Ref" : "AWS::Region" }, "S3ContentsBucket"]},
555-
"Description": "This is the local region AWS bucket where your files were copied from."
779+
"Description": "This is the local region AWS bucket where your files were copied from."
556780
}
557781
}
558782
}

0 commit comments

Comments
 (0)