-
Notifications
You must be signed in to change notification settings - Fork 0
/
feed.xml
567 lines (391 loc) · 33.2 KB
/
feed.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="3.6.2">Jekyll</generator><link href="http://localhost:4000/feed.xml" rel="self" type="application/atom+xml" /><link href="http://localhost:4000/" rel="alternate" type="text/html" /><updated>2018-07-26T00:50:18+10:00</updated><id>http://localhost:4000/</id><title type="html">Headly’s blog of things</title><subtitle>A blog mostly about techie things</subtitle><entry><title type="html">Using Windows10 for development - WLS</title><link href="http://localhost:4000/developing-on-windows" rel="alternate" type="text/html" title="Using Windows10 for development - WLS" /><published>2017-07-26T10:00:00+10:00</published><updated>2017-07-26T10:00:00+10:00</updated><id>http://localhost:4000/developing-on-windows</id><content type="html" xml:base="http://localhost:4000/developing-on-windows"><p>Once upon a time I use to develop using a windows machine..</p>
<p>After encountering many annoying issues when trying to setup my local dev environment sometimes taking days attempting to resolve proxy and issues with NPM packages that weren’t designed or tested on windows.</p>
<p>I then moved to the darkside after seeing a coworker join the team and within minutes have his environment setup and running.. on a Mac..</p>
<p>Since then I have been using Ubuntu/Mac operating systems</p>
<p>Recently I rebuilt my home desktop and so also upgraded my old windows duel boot windows7/Ubuntu combo to windows10/Ubuntu and since then have hardly booted into ubuntu</p>
<p>The reason?</p>
<p>Windows subsystem for Linux - WLS</p>
<p>This layer allows the running of binary executables natively meaning that you can run a Linux distro.</p>
<h2 id="installingenabling-wsl">Installing/Enabling WSL</h2>
<p>To enable WSL go to<br />
<code class="highlighter-rouge">Control Panel &gt; Programs &gt; Turn Windows features on or off</code>
Then enable tick “Windows Subsystem for Linux”</p>
<p>You then get prompted to restart, once your back up and running head over to the windows store and install the ubuntu “App” <a href="https://www.microsoft.com/en-au/p/ubuntu/9nblggh4msv6">Ubuntu</a></p>
<p>Once installed perform a windows search for “Ubuntu” and select the app
A terminal will open and your now in a ubuntu bash shell!</p>
<h3 id="configure">Configure</h3>
<p>Now that bash is installed you have to get the most out of it</p>
<h4 id="installing-zsh">Installing <a href="https://en.wikipedia.org/wiki/Z_shell">Zsh</a></h4>
<p>Zsh has a crap ton of nice features ontop of the default bash shell</p>
<p>In the bash command line run
<code class="highlighter-rouge">sudo apt-get install zsh</code></p>
<p>This installs the Z_shell. In order to default to zsh on load edit the users <code class="highlighter-rouge">~/.bashrc</code> file and add the following lines</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>if test -t 1; then
exec zsh
fi
</code></pre></div></div>
<h4 id="installing-oh-my-zsh">Installing <a href="https://github.com/robbyrussell/oh-my-zsh">Oh-My-Zsh</a></h4>
<p>In order to make the most of zsh you want to use <a href="https://github.com/robbyrussell/oh-my-zsh">Oh-My-Zsh</a> which is a framework to help manage and install plugins/themes for zsh</p>
<p>To install run
<code class="highlighter-rouge">sh -c "$(curl -fsSL https://raw.githubusercontent.com/robbyrussell/oh-my-zsh/master/tools/install.sh)"</code></p>
<p>Once installed check out the <a href="https://github.com/robbyrussell/oh-my-zsh/wiki">wiki</a> to see the available themes and plugins.</p>
<p>One plugin I like is <a href="https://github.com/zsh-users/zsh-autosuggestions">autosuggestion</a></p>
<p>Using your previous history it suggests possible commands that you may want to run as you type</p>
<h4 id="installing-cmder-and-configure-to-use-base">Installing <a href="https://github.com/cmderdev/cmder">cmder</a> and configure to use base</h4>
<p>Cmder is console emulator because well the default windows one is.. crap</p>
<p>Download the latest <a href="https://github.com/cmderdev/cmder/releases/">release</a></p>
<p>Press Win + Alt + T to open the tasks menu
Create a new task clicking +</p>
<p>Give it the name “bash::ubuntu”
Give it an icon “/icon %USERPROFILE%\software\cmder\os_ubuntu_alt.ico” changing the path to whatever image you want</p>
<p>And set the command to run to be <code class="highlighter-rouge">%windir%\system32\bash.exe ~ -cur_console:p</code>
Save and press ctrl + t and select your new task</p>
<p>It will now be running the zsh shell.</p>
<p>So far I have only used it lightly however so far it seem’s to be doing the job but only time will tell</p></content><author><name>Joshua</name></author><category term="Windows" /><summary type="html">Once upon a time I use to develop using a windows machine..</summary></entry><entry><title type="html">Creating a CRUD API with AWS lambda and dynamoDB</title><link href="http://localhost:4000/aws-serverless-crud" rel="alternate" type="text/html" title="Creating a CRUD API with AWS lambda and dynamoDB" /><published>2017-07-25T22:00:00+10:00</published><updated>2017-07-25T22:00:00+10:00</updated><id>http://localhost:4000/aws-serverless-crud</id><content type="html" xml:base="http://localhost:4000/aws-serverless-crud"><h2 id="intro">Intro</h2>
<p>The last few lambda functions I have created have been very basic in nature as they returned simple responses with no error handling or other integrations needed.</p>
<p>So I thought I should try creating a slightly more complex CRUD API that links to a dynamoDB table to store a users information and skills.</p>
<p>To implement this I used the following:</p>
<ul>
<li><a href="https://serverless.com/">Serverless</a></li>
<li>DynamoDb</li>
<li>AWS Lambda</li>
<li>Node 4.3.2</li>
</ul>
<h2 id="creating-the-dynamodb-table">Creating the dynamoDB table</h2>
<p>First up I needed to create a database for our api/functions to store the data in.</p>
<p>To provision the dynamoDb table I added the following into my serverless.yml file.</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>resources:
Resources:
usersTable:
Type: AWS::DynamoDB::Table
Properties:
TableName: user-skills-CRUD-usersTable-${opt:stage}
KeySchema:
- AttributeName: userId
KeyType: HASH
AttributeDefinitions:
- AttributeName: userId
AttributeType: S
ProvisionedThroughput:
ReadCapacityUnits: 1
WriteCapacityUnits: 1
DynamoDBIamPolicy:
Type: AWS::IAM::Policy
DependsOn: usersTable
Properties:
PolicyName: lambda-dynamodb
PolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Action:
- dynamodb:GetItem
- dynamodb:PutItem
- dynamodb:ListTables
- dynamodb:DeleteItem
- dynamodb:Query
- dynamodb:UpdateItem
Resource: arn:aws:dynamodb:*:*:table/user-skills-CRUD*
Roles:
- Ref: IamRoleLambdaExecution
</code></pre></div></div>
<p>This will create a table with the name “user-skills-CRUD-usersTable-${opt:stage}” where the “opt:stage” variable is replaced with the stage that I am deploying too. This allowed me to have different tables for each of my different environments.</p>
<p>The DynamoDBIamPolicy section is used by serverless to create a policy with the permissions defined and assigns it to the lambda functions. Without this the functions would not be able to access the table.</p>
<p>I also define the key of the table to be the userId which is a string as it will be a GUID.</p>
<h2 id="endpoints">Endpoints</h2>
<p>Now that I have the database table setup and the permissions all ready to go it’s now time to define the endpoints and the lambda functions that they will map to.</p>
<p>As part of this API I wanted to implement the following endpoints:</p>
<ul>
<li>(POST) /users - Create a user</li>
<li>(PUT) /users/{userId} - Update the users details</li>
<li>(DELETE) /users/{userId} - Delete the user</li>
<li>(GET) /users/{userId} - Read the users details</li>
</ul>
<p>To provision the endpoints in the gateway I added the following into my serverless.yml file</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>functions:
getUser:
handler: index.getUser
events:
- http:
path: users/{userId}
method: get
environment:
usersTableName: user-skills-CRUD-usersTable-${opt:stage}
deleteUser:
handler: index.deleteUser
events:
- http:
path: users/{userId}
method: delete
environment:
usersTableName: user-skills-CRUD-usersTable-${opt:stage}
createUser:
handler: index.createUser
events:
- http:
path: users
method: post
environment:
usersTableName: user-skills-CRUD-usersTable-${opt:stage}
updateUser:
handler: index.updateUser
events:
- http:
path: users/{userId}
method: put
environment:
usersTableName: user-skills-CRUD-usersTable-${opt:stage}
</code></pre></div></div>
<p>This will create the four endpoints and also inject the table name as an environment variable into the function. Unfortunately while serverless does offer a service wide environment variable I was unable to get this to work and was forced to repeat this in each individual function which makes it slightly less clean :(</p>
<p>The variable “{userId}” in the paths will be added to the event object that is passed into the lambda function. So can be accessed like “event.pathParameters.userId”</p>
<h2 id="functions">Functions</h2>
<p>Now that everything is mapped it was time to actually start writing the code behind the functions.</p>
<p>To get started I wanted to wire up the database for local development. Locally I ran dynamoDB using docker the container can be found <a href="https://hub.docker.com/r/deangiberson/aws-dynamodb-local/">here</a></p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>const AWS = require('aws-sdk');
let dynamoDb;
//Set dynamoDbEndpoint if it exists
if (process.env.dynamoDbEndpoint) {
console.log('*** Manually setting dynamoDb config');
dynamoDb = new AWS.DynamoDB({accessKeyId: 'headly48', secretAccessKey: '123', region: 'us-west-2', endpoint: new AWS.Endpoint(process.env.dynamoDbEndpoint)});
} else {
dynamoDb = new AWS.DynamoDB();
}
</code></pre></div></div>
<p>So in the index.js file I added the above code which creates a new dynamoDB with my local endpoint otherwise it defaults to using my AWS configured settings.</p>
<p>So if I want to call the createUser function against my local DB I ran the following in the command line</p>
<p><code class="highlighter-rouge">node -e 'process.env.dynamoDbEndpoint = "http://192.168.99.100:8000"; require("./index.js").createUser(}, null, function (blah, res) {console.log(res)})'</code></p>
<p>Now that’s sorted I created a userService class which is responsible for making the calls to the database.</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>class UserService {
constructor (dynamoDb, tableName) {
this.dynamoDb = dynamoDb;
this.tableName = tableName;
}
}
</code></pre></div></div>
<p>And initialized it in the index.js by passing in the dbConnection and tableName</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>let userService = new UserService(dynamoDb, process.env.usersTableName);
</code></pre></div></div>
<p>Now I just needed to create the createUser function in my index.js.</p>
<p>This function first validates the users email is present and then makes a call to the userService which returns a promise. If the user has been successfully saved then it will return the userId in the body with a httpStatus of 201 else returns a 500.</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>module.exports.createUser = (event, context, callback) =&gt; {
let requestBody = JSON.parse(event.body);
if(!requestBody.email) {
return callback(null, {statusCode: 400, body: JSON.stringify({error: 'Please provide users email'})});
}
userService.createUser(requestBody).then(function (user) {
callback(null, {statusCode: 201, body: JSON.stringify(user)});
}).catch(function (error) {
console.log('Error creating user. ' + error);
callback(error);
});
};
</code></pre></div></div>
<p>Below is the createUser function in the userService. It generates a userId and creates the param to pass to dynamoDb and returns a promise.</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>createUser(userDetails) {
let userId = uuidGenerator.v4();
var params = {
TableName: this.tableName,
Item: {
userId: { S: userId},
email: {S: userDetails.email}
}
};
if (userDetails.skills) {
params.Item.skills = {SS: userDetails.skills}
}
return this.dynamoDb.putItem(params).promise().then(function (data) {
console.log('Created user ' + userId);
return {userId: userId};
});
}
</code></pre></div></div>
<p>Next the getUser function in the index.js.</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>module.exports.getUser = (event, context, callback) =&gt; {
if (!event.pathParameters.userId || !uuidvalidator(event.pathParameters.userId)) {
return callback(null, {statusCode: 400, body: JSON.stringify({error: 'UserId is invalid'})});
}
userService.getUser(event.pathParameters.userId).then(function (data) {
if (!data || Object.keys(data).length === 0) {
callback(null, {statusCode: 404, body: {message: 'User does not exist'}});
} else {
callback(null, {statusCode: 200, body: JSON.stringify(data)});
}
}).catch(function (error) {
callback(JSON.stringify({error: error}));
});
};
</code></pre></div></div>
<p>And the userService function it calls</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>getUser (userId) {
var params = {
TableName: this.tableName,
Key: { // a map of attribute name to AttributeValue for all primary key attributes
userId: { S: userId}
},
AttributesToGet: [
'userId',
'email',
'skills'
]
};
return this.dynamoDb.getItem(params).promise().then(function (data) {
let user = {};
user.userId = data.Item.userId.S;
user.skills = data.Item.skills.SS;
return user;
});
}
</code></pre></div></div>
<p>Next the updateUser function in the index.js</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>module.exports.updateUser = (event, context, callback) =&gt; {
if (!event.pathParameters.userId || !uuidvalidator(event.pathParameters.userId)) {
return callback(null, {statusCode: 400, body: JSON.stringify({error: 'UserId is invalid'})});
}
let requestBody = JSON.parse(event.body);
if(!requestBody.email) {
return callback(null, {statusCode: 400, body: JSON.stringify({error: 'Please provide users email'})});
}
userService.updateUser(event.pathParameters.userId, requestBody).then(function () {
callback(null, {statusCode: 204});
}).catch(function (error) {
console.log('Error creating user. ' + error);
callback(error);
});
};
</code></pre></div></div>
<p>And the function in the userService</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>updateUser (userId, userDetails) {
var params = {
TableName: this.tableName,
Key: { // a map of attribute name to AttributeValue for all primary key attributes
userId: { S: userId}
},
AttributeUpdates: {}
};
if (userDetails.email) {
params.AttributeUpdates.email = {
Action: 'PUT',
Value: {S: userDetails.email}
}
}
if (userDetails.skills) {
params.AttributeUpdates.skills = {
Action: 'PUT',
Value: {SS: userDetails.skills}
}
}
return this.dynamoDb.updateItem(params).promise();
}
</code></pre></div></div>
<p>Finally is the deleteUser function</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>module.exports.deleteUser = (event, context, callback) =&gt; {
let requestBody = JSON.parse(event.body);
if (!event.pathParameters.userId || !uuidvalidator(event.pathParameters.userId)) {
return callback(null, {statusCode: 400, body: JSON.stringify({error: 'UserId is invalid'})});
}
userService.deleteUser(event.pathParameters.userId).then(function () {
callback(null, {statusCode: 204});
}).catch(function (error) {
console.log('Error creating user. ' + error);
callback(error);
});
};
</code></pre></div></div>
<p>And the function in the userService</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>deleteUser(userId) {
var params = {
TableName: this.tableName,
Key: {
userId: { S: userId}
}
};
return this.dynamoDb.deleteItem(params).promise();
}
</code></pre></div></div>
<h2 id="deploying">Deploying</h2>
<p>Now for the fun part :D.
Deploying to AWS which is as simple as running the command</p>
<p><code class="highlighter-rouge">serverless deploy --stage dev</code></p>
<p><img src="assets/posts/2018-07-25-aws-serverless-crud/1.jpg" alt="" /></p>
<p>As I have used the stage var in the serverless.yml file I now have to include the stage manually which is a little annoying and it would be nice if serverless picked up the default opts.</p>
<h2 id="summary">Summary</h2>
<p>It seemed fairly straightforward to get everything connected and working. It did take some time to workout the permissions that needed to be set and also setting environment variables/tableName was very fiddly and so ended up keeping it simple rather then constantly redeploying to see if changes to the service wide env variables fixed the issue of not being picked up correctly.</p>
<p>The postman collection to test the endpoints can be found <a href="https://www.getpostman.com/collections/34d0ceaf9a0b6d66922b">here</a>
To see the full code and more commands to run locally checkout my <a href="https://github.com/headly48/blog-samples/tree/master/user-skills-CRUD">Github</a></p></content><author><name>Joshua</name></author><category term="AWS" /><category term="dynamoDB" /><category term="lambda" /><summary type="html">Intro</summary></entry><entry><title type="html">Serverless - Making lambda deployments easy</title><link href="http://localhost:4000/aws-serverless-deployments" rel="alternate" type="text/html" title="Serverless - Making lambda deployments easy" /><published>2017-07-25T21:00:00+10:00</published><updated>2017-07-25T21:00:00+10:00</updated><id>http://localhost:4000/aws-serverless-deployments</id><content type="html" xml:base="http://localhost:4000/aws-serverless-deployments"><p>In my last post I worked on my first lambda function and went through the process of manually setting up the function, gateway and roles. While this works it does slow down development considerably and I can see it quickly becoming a pain in the arse especially when dealing with different environment’s when releasing changes.</p>
<p>In comes <a href="https://serverless.com/">Serverless</a> which is a framework to help you develop and deploy serverless architectures in AWS. It’s built on Node.js and currently only supports python and node runtime environment’s however the others are in the works.</p>
<p>It sounds fairly decent so thought I’d try it out by switching the lorem-lipsum function I created in my last post to use it.</p>
<p>First up I installed the framework using npm following the instructions <a href="https://www.npmjs.com/package/serverless">here</a></p>
<p>Once installed I created the serverless.yml file with the following settings</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>service: lorem-lipsum-serverless
frameworkVersion: "=1.2.1"
provider:
name: aws
runtime: nodejs4.3
memorySize: 128
functions:
getLoremIpsum:
handler: handler.getLoremIpsum
events:
- http:
path: lorem
method: get
</code></pre></div></div>
<p>With this file i’m creating the http endpoint ‘/lorem’ which is mapped to the function getLoremIpsum which is below</p>
<p><img src="assets/posts/2018-07-25-aws-serverless-deployments/1.jpg" alt="" /></p>
<p>I’v now got the mappings and function but before I can deploy I need to create an AWS user that has all the permissions required to create and delete the stacks.</p>
<p>I added the json that I used to create the 6 policy’s that I have added to my user <a href="https://github.com/headly48/blog-samples/tree/master/lorem-lipsum-serverless/policys">here</a> once done I set my awscli to use the user I just created.</p>
<p>I’v now got my mappings, the function and all the permissions I need so now time to deploy it!</p>
<p>This is as easy as running the command <code class="highlighter-rouge">serverless deploy</code></p>
<p><img src="assets/posts/2018-07-25-aws-serverless-deployments/2.jpg" alt="" /></p>
<p>And the result</p>
<p><img src="assets/posts/2018-07-25-aws-serverless-deployments/3.jpg" alt="" /></p>
<p>Hmm but now I wanted to make a change to the function to return a different response. After making the code changes and re-running the command it has been updated</p>
<p><img src="assets/posts/2018-07-25-aws-serverless-deployments/4.jpg" alt="" /></p>
<p>By default when running <code class="highlighter-rouge">serverless deploy</code> it stages it as dev so now that the response is all good I wish to deploy it to prod</p>
<p><code class="highlighter-rouge">serverless deploy --stage prod</code></p>
<p><img src="assets/posts/2018-07-25-aws-serverless-deployments/5.jpg" alt="" /></p>
<p>I now have two different environments so that I can make code changes to dev and test them without effecting prod.</p>
<p>After running <code class="highlighter-rouge">serverless deploy</code> again my dev env reflects the changes</p>
<p><img src="assets/posts/2018-07-25-aws-serverless-deployments/6.jpg" alt="" /></p>
<p>While the prod env is still returning the same response as what I deployed earlier.</p>
<p>Once finished It’s just as easy to tear down and delete all traces of the stack by running the command</p>
<p><code class="highlighter-rouge">serverless remove</code></p>
<p><img src="assets/posts/2018-07-25-aws-serverless-deployments/7.jpg" alt="" /></p>
<p>While this was a fairly simple and small test the serverless framework does appear to do the job in helping to deploy the stacks with different stages and i’ll be using it in the future :D.</p>
<p>The sample code can be found <a href="https://github.com/headly48/blog-samples/tree/master/lorem-lipsum-serverless">here</a></p></content><author><name>Joshua</name></author><category term="AWS" /><category term="serverless" /><category term="lambda" /><summary type="html">In my last post I worked on my first lambda function and went through the process of manually setting up the function, gateway and roles. While this works it does slow down development considerably and I can see it quickly becoming a pain in the arse especially when dealing with different environment’s when releasing changes.</summary></entry><entry><title type="html">AWS - Creating my first lambda function</title><link href="http://localhost:4000/aws-first-lambda" rel="alternate" type="text/html" title="AWS - Creating my first lambda function" /><published>2017-07-25T20:00:00+10:00</published><updated>2017-07-25T20:00:00+10:00</updated><id>http://localhost:4000/aws-first-lambda</id><content type="html" xml:base="http://localhost:4000/aws-first-lambda"><p>Since creating my AWS account a few days ago i have been dying to try out there lambda functions and thought I should create a very simple rest endpoint that will return a lorem lipsum message.</p>
<h2 id="creating-the-function">Creating the function</h2>
<p>To get started I created a very basic index.js file in a new project with a function handler that will be called by aws.</p>
<p><img src="assets/posts/2018-07-25-aws-first-lambda/first.jpg" alt="" /></p>
<p>To keep it simple I used the lorem-ipsum node module available <a href="https://www.npmjs.com/package/lorem-ipsum">here</a> which i pulled down using a package.json file and npm</p>
<p><img src="assets/posts/2018-07-25-aws-first-lambda/second.jpg" alt="" /></p>
<p>I then created a zip folder containing the index.js file and also its dependencies in the node_modules subfolder.</p>
<p>I did run into an issue when zipping these folders where it created a folder wrapping these files in the artifact and as such when uploading and testing in AWS I received errors saying the handler does not exist.</p>
<h2 id="mapping-the-lambda-function">Mapping the lambda function</h2>
<p>Now that I had created the artifact it was time to login to the AWS console and go to the lambda <a href="https://console.aws.amazon.com/lambda/home?#/create/configure-function">dashboard</a> to create the lambda and map it to the function that I just created.</p>
<p>Below is the configurations I used when configuring the new lambda</p>
<p><img src="assets/posts/2018-07-25-aws-first-lambda/third.jpg" alt="" /></p>
<p>Once done you should be able to test it out and if all works out well see the response :D</p>
<p><img src="assets/posts/2018-07-25-aws-first-lambda/fourth.jpg" alt="" /></p>
<h2 id="creating-the-gateway">Creating the gateway</h2>
<p>Now that I had a function running I wanted to be able to trigger it and get the response using a rest call. This was setup by using the AWS <a href="https://console.aws.amazon.com/apigateway/home">gateway</a>.</p>
<p>First up I created an api and then created a get method to the lambda created above</p>
<p><img src="assets/posts/2018-07-25-aws-first-lambda/fifth.jpg" alt="" /></p>
<p>Once the method is created I tested it out within the gateway and all looks good</p>
<p><img src="assets/posts/2018-07-25-aws-first-lambda/six.jpg" alt="" /></p>
<p>The final step is to deploy the gateway API. At first I missed this step and was stuck wondering why I was receiving error’s when trying to hit the same endpoint that was displayed when testing.</p>
<p><img src="assets/posts/2018-07-25-aws-first-lambda/7.jpg" alt="" /></p>
<p>Once done I was able to successfully hit the endpoint using postman and see the generated Lipsum text.</p>
<p>While I used the AWS console to manually configure the different components since it was my first time. Next time I would use their aws-cli and cloudformation to try and do it all automatically enabling quicker changes and updates to the function.</p>
<p>The code can be found <a href="https://github.com/headly48/blog-samples/tree/master/lorem-lipsum-lambda">here</a></p></content><author><name>Joshua</name></author><category term="AWS" /><category term="serverless" /><category term="lambda" /><summary type="html">Since creating my AWS account a few days ago i have been dying to try out there lambda functions and thought I should create a very simple rest endpoint that will return a lorem lipsum message.</summary></entry><entry><title type="html">The second coming of “Hello world”</title><link href="http://localhost:4000/hello-world" rel="alternate" type="text/html" title="The second coming of "Hello world"" /><published>2017-07-24T20:00:00+10:00</published><updated>2017-07-24T20:00:00+10:00</updated><id>http://localhost:4000/hello-world</id><content type="html" xml:base="http://localhost:4000/hello-world"><p>After having a pretty big hiatus I thought it was about time I give the whole blogging thing another crack, Fingers crossed this time sticks!</p>
<p>I thought I may as well also take the opportunity to try out a different solution for generating the blog.</p>
<p>Previously I used a combination of buster/ghost to host a local blog server and then generate the assets from this which turned out to be a tad annoying.</p>
<p>Now I trying out using the jenkell/jasper2 combo. Instead of having to run a server jenkell generates the static assets directly keeping it more simple so it just works.</p>
<p>I created this new one by</p>
<ol>
<li>Cloning the repo https://github.com/jekyller/jasper2</li>
<li>Changing the destination property in the _config.yml to equal “../headly48.github.io/”</li>
<li>Running the cmd “bundle install” to pull down the required gem dependencies</li>
<li>Running the cmd “bundle exec jekyll serve” to generate the required static assets in the folder “../headly48.github.io/” and also to preview the site</li>
</ol>
<p>And now if you can read this then pushing the generated folder to the git pages repo..</p>
<p>Until next time</p></content><author><name>Joshua</name></author><category term="Getting started" /><summary type="html">After having a pretty big hiatus I thought it was about time I give the whole blogging thing another crack, Fingers crossed this time sticks!</summary></entry></feed>