Skip to content
This repository was archived by the owner on Jan 14, 2025. It is now read-only.

Commit 0d2a573

Browse files
committed
2 parents 00b2335 + 559f1a0 commit 0d2a573

Some content is hidden

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

62 files changed

+1033
-714
lines changed

MultiRegion/1_API/README.md

Lines changed: 39 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# Building the Wild Rydes Backend Components Layer
22

33
In this module, you will deploy backend application components to AWS. These
4-
backend components include several AWS Lambda functions, two API Gateway Endpoints and two
4+
backend components include several AWS Lambda functions, two API Gateway Endpoints and
55
DynamoDB tables. You will also create the IAM polices and roles required by
66
these components.
77

@@ -22,11 +22,6 @@ The following objects will be used as you create the resources in the console fo
2222
from DynamoDB using the `tickets-get.js` and `health-check.js` Lambda functions
2323
* `wild-rydes-dynamodb-post.json` - This is the policy needed in order to write
2424
to DynamoDB using the `tickets-post.js` Lambda function
25-
* `wild-rydes-dynamodb-replication.json` - This is the policy needed in order
26-
to use DynambDB Streams to replicate to a second region using the `tickets-replicate.js`
27-
Lambda function
28-
* `tickets-replicate.js` Lambda function to replicate new DynamoDB records to our
29-
failover region
3025
* `health-check.js` - Lambda function for checking the status of our application health
3126
* `tickets-get.js` - Lambda function triggered by API Gateway to put application data
3227
into DynamoDB
@@ -36,9 +31,9 @@ The following objects will be used as you create the resources in the console fo
3631
There are several steps needed to deploy the API and Lambda functions via the
3732
console. The basic steps are:
3833

39-
1. Create the appropriate IAM policies and roles our four AWS Lambda functions
34+
1. Create the appropriate IAM policies and roles our AWS Lambda functions
4035
2. Create the required Amazon DynamoDB table
41-
3. Create the four AWS Lambda functions
36+
3. Create the needed AWS Lambda functions
4237
4. Create the Amazon API Gateway for the region you are currently deploying
4338
5. Testing to ensure our backend components are all working as expected
4439

@@ -67,16 +62,15 @@ Name your policy `TicketGetPolicy` and click **Create policy**
6762

6863
![Create Policy Editor](images/create-policy-2.png)
6964

70-
Now repeat these exact same steps two more times in order to create the
71-
following two additional polices that will be needed during the workshop.
65+
Now repeat these exact same steps one more time in order to create the
66+
following additional policy that will be needed during the workshop.
7267

7368
**Download policy**: [TicketPostPolicy](wild-rydes-dynamodb-post.json)
7469

75-
**Download policy**: [TicketReplicatePolicy](wild-rydes-dynamodb-replication.json)
7670

77-
Next you will create the three roles that correspond to the three polices that
71+
Next you will create the three roles that correspond to the polices that
7872
were just created. Each of these roles will be used by a different Lambda
79-
function thereby limiting the permissions of each function. This follows an
73+
function thereby limiting the permissions of each function. This follows the
8074
AWS Best Practice of granting [least privilege](http://docs.aws.amazon.com/IAM/latest/UserGuide/best-practices.html#grant-least-privilege).
8175

8276
In the Console, select the **IAM** service and choose **Roles** from the left,
@@ -98,9 +92,8 @@ On the next screen, enter `TicketGetRole` for the Role Name and select **Create
9892

9993
![Choose Role Final](images/create-role-final.png)
10094

101-
Repeat the same steps two more times, this time creating the role for
102-
`TicketPostRole` and `TicketReplicateRole` and attaching
103-
the corresponding policy you created earlier.
95+
Repeat the same steps one more time, this time creating the role for
96+
`TicketPostRole` and attaching the corresponding policy you created earlier.
10497

10598
## 2. Create the DynamoDB Table
10699

@@ -122,23 +115,20 @@ That’s all that is required for now to set up the table.
122115

123116
![DymamoDB Create SXRTickets](images/dynamodb-create-sxrtickets.png)
124117

125-
## 3. Create Four Lambda functions
118+
## 3. Create Three Lambda functions
126119

127-
Next, you will create four Lambda functions. First, navigate to **Lambda** in
120+
Next, you will create three Lambda functions. First, navigate to **Lambda** in
128121
the console (again ensuring you are still in the correct region) and click
129-
**Create a function**
122+
**Create a function** Ensure you choose **Author from scratch**
130123

131124
![Create Lambda function](images/create-lambda-function.png)
132125

133-
Next select “Author from scratch”
134-
135-
![Lambda author from scratch](images/lambda-author-scratch.png)
126+
Change the runtime to `Node.js 6.10`. ('Node.js 8.10' should work but it
127+
has not been tested)
136128

137129
Name your first function `TicketGetFunction` and assign the role with the **matching**
138-
name you created previously to it and click **Create function**
139-
140-
On the next screen, ensure the runtime is `Node.js 6.10`. If it isn’t, simply
141-
select it.
130+
name you created previously to it and click **Create function** and move on to the main
131+
Lambda interface.
142132

143133
For the Handler, enter `tickets-get.handler` and then paste the following code into the
144134
editor you see on your screen:
@@ -154,21 +144,21 @@ your function will not work - case matters*
154144

155145
Once everything is set correctly, click **Save** near the top center of the screen.
156146

157-
We still need to create three more lambda functions. All of them use `Node.js 6.10`
147+
**IMPORTANT NOTE** When editing the Lambda code using the console, it is VERY important that
148+
your file name match the 'Handler Name' in the table below. You must rename the file from
149+
the defaut of index.js or your function will not work! For example, if your handler name is
150+
*tickets-get.handler* then your Lambda file name should be *tickets-get.js*
151+
152+
We still need to create two more lambda functions. All of them use `Node.js 6.10`
158153
as the runtime. Repeat the same steps you used above. The table below provides the
159-
information needed for all four functions. Note that you have already done the first one.
154+
information needed for all three functions. Note that you have already done the first one.
160155

161156
| Function Name | Handler Name | Execution Role | Env Var Key | Env Var Value |
162157
| --------------------- | --------------------- | ------------------------------- | ------------- | -------------- |
163158
| [TicketGetFunction](tickets-get.js) | tickets-get.handler | TicketGetRole | TABLE_NAME | SXRTickets |
164159
| [TicketPostFunction](tickets-post.js) | tickets-post.handler | TicketPostRole | TABLE_NAME | SXRTickets |
165-
| [TicketReplicateFunction](tickets-replicate.js) | tickets-replicate.handler | TicketReplicateRole | TABLE_NAME | SXRTickets |
166-
| TicketReplicateFunction | | | TARGET_REGION | ap-southeast-1 |
167160
| [SXRHealthCheckFunction](health-check.js) | health-check.handler | TicketGetRole | TABLE_NAME | SXRTickets |
168161

169-
Note that `TicketReplicateFunction` has two variables - make sure you enter both.
170-
Also note that proper capitalization matters with `Environment Variables`. Improper
171-
case will cause issues later in the workshop.
172162

173163
## 4. Create API Gateway Endpoint
174164

@@ -287,8 +277,6 @@ files within. You will see several files - here are descriptions of each:
287277
to retrieve tickets from DynamoDB
288278
* `tickets-post.js` – This is the Node.js code required by our second Lambda function
289279
to create new tickets in DynamoDB
290-
* `tickets-replicate.js` – This is the Node.js code that replicates dynamodb data to
291-
another region.
292280
* `health-check.js` - Lambda function for checking the status of our application health
293281

294282

@@ -341,9 +329,9 @@ You can do this using the following CLI command. Note that you must replace
341329

342330
aws cloudformation package \
343331
--region eu-west-1 \
344-
--template-file wild-rydes-api.yaml \
345-
--output-template-file wild-rydes-api-output.yaml \
346-
--s3-bucket [bucket_name_you_created_above]
332+
--template-file wild-rydes-api-primary-region.yaml \
333+
--output-template-file wild-rydes-api-primary-region-output.yaml \
334+
--s3-bucket [eu_west_bucket_name_you_created_above]
347335

348336
**IMPORTANT** DO NOT deploy any resources to Singapore during your initial pass
349337
on Module 1. You will come back in Module 3 and then deploy the same components
@@ -354,11 +342,13 @@ convenience.
354342

355343
aws cloudformation package \
356344
--region ap-southeast-1 \
357-
--template-file wild-rydes-api.yaml \
358-
--output-template-file wild-rydes-api-output.yaml \
359-
--s3-bucket [bucket_name_you_created_above]
345+
--template-file wild-rydes-api-failover-region.yaml \
346+
--output-template-file wild-rydes-api-failover-region-output.yaml \
347+
--s3-bucket [ap_southeast_bucket_name_you_created_above]
360348

361-
If all went well, you should get a success message and instructions to deploy your new template.
349+
If all went well, you should get a success message and instructions to deploy your new template.
350+
Follow those instructions. *NOTE: You will need to add '--capabilities CAPABILITY_IAM' to the*
351+
*command in order to successfully deploy*
362352

363353
## 3. Deploy a stack of resources
364354

@@ -373,8 +363,8 @@ Go ahead and run the following CLI command:
373363

374364
aws cloudformation deploy \
375365
--region eu-west-1 \
376-
--template-file wild-rydes-api-output.yaml \
377-
--stack-name wild-rydes-api \
366+
--template-file wild-rydes-api-primary-region-output.yaml \
367+
--stack-name wild-rydes-api-primary \
378368
--capabilities CAPABILITY_IAM
379369

380370
**IMPORTANT** DO NOT deploy any resources to Singapore during your initial pass
@@ -386,8 +376,8 @@ convenience.
386376

387377
aws cloudformation deploy \
388378
--region ap-southeast-1 \
389-
--template-file wild-rydes-api-output.yaml \
390-
--stack-name wild-rydes-api \
379+
--template-file wild-rydes-api-failover-region-output.yaml \
380+
--stack-name wild-rydes-api-failover \
391381
--capabilities CAPABILITY_IAM
392382

393383

@@ -408,6 +398,9 @@ our `TicketGetFunction` Lambda function and the `POST` method calling our `Ticke
408398
Lambda function. You can also see that an empty DynamoDB table was set up as well as IAM
409399
roles to allow our functions to speak to DynamoDB.
410400

401+
TODO: Instructions for setting up DynamoDB global table. MUST DO THIS BEFORE NEXT STEP. CANT HAVE DATA IN TABLE BEFORE SETTING UP GLOBAL REPLOICATION
402+
403+
411404
You can confirm that your API is working by copying your API URL and appending `/ticket`
412405
to it before navigating to it into your browser. It should return the following:
413406

91.8 KB
Loading
-18.2 KB
Loading
Lines changed: 185 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,185 @@
1+
AWSTemplateFormatVersion: '2010-09-09'
2+
Transform: AWS::Serverless-2016-10-31
3+
Description: SXR API Stack for failover region.
4+
5+
Resources:
6+
7+
TicketServiceAPI:
8+
Type: AWS::Serverless::Api
9+
Properties:
10+
StageName: prod
11+
DefinitionBody:
12+
swagger: 2.0
13+
info:
14+
title:
15+
Ref: AWS::StackName
16+
paths:
17+
"/ticket":
18+
get:
19+
responses: {}
20+
x-amazon-apigateway-integration:
21+
uri:
22+
Fn::Sub: arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${TicketGetFunction.Arn}/invocations
23+
passthroughBehavior: "when_no_match"
24+
httpMethod: "POST"
25+
type: "aws_proxy"
26+
post:
27+
responses: {}
28+
x-amazon-apigateway-integration:
29+
uri:
30+
Fn::Sub: arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${TicketPostFunction.Arn}/invocations
31+
passthroughBehavior: "when_no_match"
32+
httpMethod: "POST"
33+
type: "aws_proxy"
34+
options:
35+
consumes:
36+
- "application/json"
37+
produces:
38+
- "application/json"
39+
responses:
40+
'200':
41+
description: "200 response"
42+
headers:
43+
Access-Control-Allow-Origin:
44+
type: "string"
45+
Access-Control-Allow-Methods:
46+
type: "string"
47+
Access-Control-Allow-Headers:
48+
type: "string"
49+
x-amazon-apigateway-integration:
50+
responses:
51+
default:
52+
statusCode: "200"
53+
responseParameters:
54+
method.response.header.Access-Control-Allow-Methods: "'POST,GET,OPTIONS'"
55+
method.response.header.Access-Control-Allow-Headers: "'Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token'"
56+
method.response.header.Access-Control-Allow-Origin: "'*'"
57+
requestTemplates:
58+
application/json: "{\"statusCode\": 200}"
59+
passthroughBehavior: "when_no_match"
60+
type: "mock"
61+
"/health":
62+
get:
63+
responses: {}
64+
x-amazon-apigateway-integration:
65+
uri:
66+
Fn::Sub: arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${HealthFunction.Arn}/invocations
67+
passthroughBehavior: "when_no_match"
68+
httpMethod: "POST"
69+
type: "aws_proxy"
70+
options:
71+
consumes:
72+
- "application/json"
73+
produces:
74+
- "application/json"
75+
responses:
76+
'200':
77+
description: "200 response"
78+
headers:
79+
Access-Control-Allow-Origin:
80+
type: "string"
81+
Access-Control-Allow-Methods:
82+
type: "string"
83+
Access-Control-Allow-Headers:
84+
type: "string"
85+
x-amazon-apigateway-integration:
86+
responses:
87+
default:
88+
statusCode: "200"
89+
responseParameters:
90+
method.response.header.Access-Control-Allow-Methods: "'POST,GET,OPTIONS'"
91+
method.response.header.Access-Control-Allow-Headers: "'Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token'"
92+
method.response.header.Access-Control-Allow-Origin: "'*'"
93+
requestTemplates:
94+
application/json: "{\"statusCode\": 200}"
95+
passthroughBehavior: "when_no_match"
96+
type: "mock"
97+
swagger: '2.0'
98+
99+
TicketGetFunction:
100+
Type: AWS::Serverless::Function
101+
Properties:
102+
Handler: tickets-get.handler
103+
Runtime: nodejs6.10
104+
FunctionName: TicketGetFunction
105+
Policies:
106+
- AWSLambdaDynamoDBExecutionRole #managed policy
107+
- Version: '2012-10-17' # Policy Document
108+
Statement:
109+
- Effect: Allow
110+
Action:
111+
- dynamodb:Scan
112+
- dynamodb:GetItem
113+
Resource: "*"
114+
Environment:
115+
Variables:
116+
TABLE_NAME: SXRTickets
117+
Events:
118+
GetResource:
119+
Type: Api
120+
Properties:
121+
Path: /ticket
122+
Method: get
123+
RestApiId: !Ref TicketServiceAPI
124+
125+
TicketPostFunction:
126+
Type: AWS::Serverless::Function
127+
Properties:
128+
Handler: tickets-post.handler
129+
Runtime: nodejs6.10
130+
FunctionName: TicketPostFunction
131+
Policies:
132+
- AWSLambdaDynamoDBExecutionRole #managed policy
133+
- Version: '2012-10-17' # Policy Document
134+
Statement:
135+
- Effect: Allow
136+
Action:
137+
- dynamodb:PutItem
138+
Resource: "*"
139+
Environment:
140+
Variables:
141+
TABLE_NAME: SXRTickets
142+
Events:
143+
GetResource:
144+
Type: Api
145+
Properties:
146+
Path: /ticket
147+
Method: post
148+
RestApiId: !Ref TicketServiceAPI
149+
150+
HealthFunction:
151+
Type: AWS::Serverless::Function
152+
Properties:
153+
Handler: health-check.handler
154+
Runtime: nodejs6.10
155+
FunctionName: SXRHealthCheckFunction
156+
Policies:
157+
- AWSLambdaDynamoDBExecutionRole #managed policy
158+
- Version: '2012-10-17' # Policy Document
159+
Statement:
160+
- Effect: Allow
161+
Action:
162+
- dynamodb:Scan
163+
- dynamodb:GetItem
164+
Resource: "*"
165+
Environment:
166+
Variables:
167+
TABLE_NAME: SXRTickets
168+
Events:
169+
GetResource:
170+
Type: Api
171+
Properties:
172+
Path: /health
173+
Method: get
174+
RestApiId: !Ref TicketServiceAPI
175+
176+
Outputs:
177+
ApiUrl:
178+
Description: URL of your API endpoint
179+
Value: !Join
180+
- ''
181+
- - https://
182+
- !Ref TicketServiceAPI
183+
- '.execute-api.'
184+
- !Ref 'AWS::Region'
185+
- '.amazonaws.com/prod/'

0 commit comments

Comments
 (0)