<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:cc="http://cyber.law.harvard.edu/rss/creativeCommonsRssModule.html">
    <channel>
        <title><![CDATA[Stories by Randika Rathugamage on Medium]]></title>
        <description><![CDATA[Stories by Randika Rathugamage on Medium]]></description>
        <link>https://medium.com/@randika?source=rss-2677501c4d0e------2</link>
        <image>
            <url>https://cdn-images-1.medium.com/fit/c/150/150/2*9M0t9T6KysPPe4_T_I4VmQ.png</url>
            <title>Stories by Randika Rathugamage on Medium</title>
            <link>https://medium.com/@randika?source=rss-2677501c4d0e------2</link>
        </image>
        <generator>Medium</generator>
        <lastBuildDate>Thu, 04 Jun 2026 20:32:45 GMT</lastBuildDate>
        <atom:link href="https://medium.com/@randika/feed" rel="self" type="application/rss+xml"/>
        <webMaster><![CDATA[yourfriends@medium.com]]></webMaster>
        <atom:link href="http://medium.superfeedr.com" rel="hub"/>
        <item>
            <title><![CDATA[How to write Alexa skill data to DynamoDB with AWS Lambda]]></title>
            <link>https://medium.com/@randika/how-to-create-an-alexa-skill-with-aws-lambda-and-dynamodb-59d3402a3e9?source=rss-2677501c4d0e------2</link>
            <guid isPermaLink="false">https://medium.com/p/59d3402a3e9</guid>
            <category><![CDATA[serverless]]></category>
            <category><![CDATA[aws-lambda]]></category>
            <category><![CDATA[alexa]]></category>
            <dc:creator><![CDATA[Randika Rathugamage]]></dc:creator>
            <pubDate>Tue, 26 Jun 2018 15:07:50 GMT</pubDate>
            <atom:updated>2018-06-27T16:26:48.040Z</atom:updated>
            <content:encoded><![CDATA[<p>In this demo, We’ll go over how to write Alexa skill data to DynamoDB with AWS Lambda.</p><p>The skill, we’re going to build is an expense tracking assistant called “My expenses”. The user can ask to add an expense record and state the amount and the category of the expense. The record will be then stored in AWS DynamoDB and associated it with an userId.</p><p>The following video gives a quick demo of what the finished product will be:</p><iframe src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fwww.youtube.com%2Fembed%2Ft6tV3LqIT24%3Ffeature%3Doembed&amp;url=http%3A%2F%2Fwww.youtube.com%2Fwatch%3Fv%3Dt6tV3LqIT24&amp;image=https%3A%2F%2Fi.ytimg.com%2Fvi%2Ft6tV3LqIT24%2Fhqdefault.jpg&amp;key=a19fcc184b9711e1b4764040d3dc5c07&amp;type=text%2Fhtml&amp;schema=youtube" width="854" height="480" frameborder="0" scrolling="no"><a href="https://medium.com/media/40c45ccaeb42ef6145a5d2eb516722ae/href">https://medium.com/media/40c45ccaeb42ef6145a5d2eb516722ae/href</a></iframe><p>DynamoDB is a fully managed NoSQL database service that provides fast and predictable performance with seamless scalability. It requires no schema and can be used as a key-value or document-based store.</p><p>Skill will also require either an AWS Lambda ARN or a publicly available HTTP endpoint as a backend to process the logic behind the skill. We’ll be going with Lambda ARN, So we don’t need to run a server, and connect the skill via HTTP.</p><h3>Creating a skill on the Amazon Developer Portal</h3><ol><li>Go to Alexa developer console <a href="https://developer.amazon.com/alexa/">https://developer.amazon.com/alexa/</a> and add a new skill named “My expenses”.</li><li>In the next screen “Choose a model to add to your skill” and pick the “Custom” option.</li><li>Create the Interaction model. The quickest way to configure the interaction model is through the “JSON editor” in developer console. Copy and paste the code below in the editor and save the model. This will gives you:<br> — invocation name: my expenses<br> — Intent AddExpense<br> — Sample utterances. <br> — Slots - Amount, Category</li></ol><p><em>If you’re new to Alexa, please read more about </em><a href="https://developer.amazon.com/docs/custom-skills/create-intents-utterances-and-slots.html"><em>Intents, Utterances, and Slots.</em></a><em> So You’ll be able to understand the basics of Alexa.</em></p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/f452dae2af33eb40a281681984bb208f/href">https://medium.com/media/f452dae2af33eb40a281681984bb208f/href</a></iframe><h3>Create Lambda function</h3><p>We can write lambda function in any of these programing languages — (as of this writing ) Node.js, Python, Java (Java 8 compatible), and C# (.NET Core) and Go are supported. You can deploy the function either using AWS CLI or from AWS management console and <a href="https://developer.amazon.com/docs/custom-skills/host-a-custom-skill-as-an-aws-lambda-function.html">configure Alexa to invoke the lambda</a>.</p><p>You can also use a tool like “<a href="https://serverless.com">Serverless</a>” — write your code, configure events to trigger your functions, and then deploy &amp; run those functions to your cloud provider via the CLI provided by Serverless. <a href="https://randika.com/serverless-microservices-with-node-js-and-aws-lambda-build-deploy-34a8c3d80e41">Getting started with Serverless microservices with AWS Lambda</a>.</p><p>For the purpose of this demo, I’ll be creating a serverless project with nodejs:</p><pre>$ serverless create --template aws-nodejs</pre><pre>Serverless: Generating boilerplate...`</pre><p>Open handler.js and update the code</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/bda0c6f574f8b7ae62b17156919315e9/href">https://medium.com/media/bda0c6f574f8b7ae62b17156919315e9/href</a></iframe><p>serverless.yml</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/f441233d4255ff196ba5f95b88623a4d/href">https://medium.com/media/f441233d4255ff196ba5f95b88623a4d/href</a></iframe><p>Deploy the lambda function with serverless deploy command and find its ARN. Go back to your Alexa developer console -&gt; build -&gt; Endpoint and update the AWS Lambda ARN.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*BMdhMUyLP2wkXCyGBBitIg.png" /></figure><p>Also don’t forget to update the alexa.appId = “amzn1.ask.skill.XXXX” value in your lambda function. (line 10, handler.js)</p><p>This will also create your Dynamodb table with the required permissions. You can learn more about <a href="https://serverless.com/developers/guides/dynamodb/">serverless dyanamodb</a> templating here. Behind the scene serveless.yml will be transformed in to a single Cloudformation stack, you can see them from AWS console -&gt; Cloudformation.</p><p>AWS CLI credentials are stored in INI format in ~/.aws/credentials on a separate aws profile named serverless and serverless will pick the profile credentials during the deployment.</p><pre><strong>serverless.yml</strong><br>profile: ${self:custom.profiles.${self:provider.stage}}<br>...<br>custom:<br>  defaultStage: dev<br>  profiles:<br>    dev: serverless<br>    prod: serverless</pre><pre><strong>$cat ~/.aws/credentials</strong><br>[serverless]<br>aws_access_key_id = XXXX<br>aws_secret_access_key = XXXX</pre><h4>Testing on your Echo</h4><p>Now your code is ready and deployed, go try your skill out!</p><p>You can say “Alexa, open My Expenses” or just type in the words to fire your skill from Alexa developer console -&gt; Test.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/850/1*XqyE3lMiMajG_9tUXosJSg.png" /></figure><p>I hope you found this tutorial helpful. Please feel free to contact me, If you get stuck on anything. You can find the code at <a href="https://github.com/randika/demo-alexa-my-expenses">github</a>.</p><p>Happy coding with Alexa ❤</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=59d3402a3e9" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Getting started with Serverless microservices with AWS Lambda]]></title>
            <link>https://medium.com/@randika/serverless-microservices-with-node-js-and-aws-lambda-build-deploy-34a8c3d80e41?source=rss-2677501c4d0e------2</link>
            <guid isPermaLink="false">https://medium.com/p/34a8c3d80e41</guid>
            <category><![CDATA[serverless]]></category>
            <category><![CDATA[aws]]></category>
            <category><![CDATA[aws-lambda]]></category>
            <category><![CDATA[microservices]]></category>
            <dc:creator><![CDATA[Randika Rathugamage]]></dc:creator>
            <pubDate>Thu, 20 Apr 2017 16:30:37 GMT</pubDate>
            <atom:updated>2017-11-21T08:07:40.819Z</atom:updated>
            <content:encoded><![CDATA[<p>In this article, you’ll learn how to build a node.js serverless microservice — deploy it on AWS Lambda with DynamoDb and place it behind AWS API Gateway.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/610/1*VfuuRdNeVHEFnl8sdctpjg.png" /></figure><p>We’ll be using the <a href="https://serverless.com/">serverless framework</a> — <em>an open-source, application framework to easily build serverless architectures on AWS Lambda.</em></p><h4>Prerequisites</h4><ul><li>Node.js installed</li></ul><pre>$ node -v<br>v4.3.2</pre><ul><li>Serverless framework installed — see <a href="https://serverless.com/framework/docs/providers/aws/guide/installation/">here</a></li></ul><pre>$ serverless -v<br>1.10.2</pre><ul><li>Install <a href="http://docs.aws.amazon.com/cli/latest/userguide/installing.html">AWS CLI</a> &amp; create IAM Credentials — For the purpose of this demo, we’ll be using an IAM user policy with `AdministratorAccess` <em>(Don’t do that for your production apps)</em></li></ul><pre>$ cat ~/.aws/credentials<br>[serverless-demo]<br>aws_access_key_id=XXXXX<br>aws_secret_access_key=XXXXX</pre><p>Please note the AWS custom profile name is set to `[serverless-demo]` here. We’ll be using this profile in the next step.</p><h4>Create the application</h4><p>Let’s go ahead and generate the application template.</p><pre>$ mkdir serverless-demo<br>$ cd serverless-demo<br>$ serverless create — template aws-nodejs<br>Serverless: Generating boilerplate…<br> _______ __<br>| _ . — — -. — — . — . — . — — -. — — | . — — -. — — -. — — -.<br>| |___| -__| _| | | -__| _| | -__|__ — |__ — |<br>|____ |_____|__| \___/|_____|__| |__|_____|_____|_____|<br>| | | The Serverless Application Framework<br>| | serverless.com, v1.10.2<br> — — — -’</pre><pre>Serverless: Successfully generated boilerplate for template: “aws-nodejs”<br>Serverless: NOTE: Please update the “service” property in serverless.yml with your service name</pre><p>You’ll see the following files in your working directory:</p><p>#AppRoot/handler.js — By default template will provide a `hello` function handler.</p><pre>‘use strict’;</pre><pre>module.exports.hello = (event, context, callback) =&gt; {<br> const response = {<br> statusCode: 200,<br> body: JSON.stringify({<br> message: ‘Go Serverless v1.0! Your function executed successfully!’,<br> input: event,<br> }),<br> };</pre><pre>callback(null, response);</pre><pre>// Use this code if you don’t use the http event with the LAMBDA-PROXY integration<br> // callback(null, { message: ‘Go Serverless v1.0! Your function executed successfully!’, event });<br>};</pre><p>AWS Lambda can invoke this handler when the service executes your code. Handler signature has these three arguments.</p><ul><li><strong>event</strong> — AWS Lambda uses this parameter to pass in event data to the handler.</li><li><strong>context</strong> — AWS Lambda uses this parameter to provide your handler the runtime information of the Lambda function that is executing. Ex: AWS requestId, logs, timeout values etc.</li><li><strong>callback</strong> — You can use the optional callback to return information to the caller, otherwise return value is null.</li></ul><p>read more on function handler <a href="http://docs.aws.amazon.com/lambda/latest/dg/nodejs-prog-model-handler.html">here</a>.</p><p>#AppRoot/serverless.yml — Set the stage, profile, region parameters. The updated file should look like this.</p><pre>service: serverless-demo<br>provider:<br>  name: aws<br>  runtime: nodejs4.3<br>  stage: dev # Set the default stage used. Default is dev<br>  profile: serverless-demo # The AWS credentials profile to use with this service<br>  region: us-east-1<br>functions:<br>  hello:<br>    handler: handler.hello</pre><p>This is more than enough to test our setup. Let’s deploy our first function to Lambda.</p><pre>$ serverless deploy<br>Serverless: Packaging service…<br>Serverless: Uploading CloudFormation file to S3…<br>Serverless: Uploading function .zip files to S3…<br>Serverless: Uploading service .zip file to S3 (409 B)…<br>Serverless: Updating Stack…<br>Serverless: Checking Stack update progress…<br>………<br>Serverless: Stack update finished…<br>Service Information<br>service: serverless-demo<br>stage: dev<br>region: us-east-1<br>api keys:<br> None<br>endpoints:<br> None<br>functions:<br> hello: serverless-demo-dev-hello</pre><p>Once completed, lambda function can be viewed from the aws console.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*I9yO7ulKTQIYg-ezcgqTiQ.png" /></figure><p>While the function doesn’t do anything other than printing a message, you can still test it by clicking the “test” action.</p><h4>Creating the MicroService</h4><p>Let’s create an example microservice, which has a RESTful CRUD API to manage book information. The book data will be stored on a DynamoDB table.</p><p>CREATE a new book — First we’ll need to add new handler to our application.</p><p>#AppRoot/books/create.js</p><pre>‘use strict’;<br>const uuid = require(‘uuid’);<br>const AWS = require(‘aws-sdk’);</pre><pre>const dynamoDb = new AWS.DynamoDB.DocumentClient();</pre><pre>module.exports.create = (event, context, callback) =&gt; {<br> const timestamp = new Date().getTime();<br> const data = JSON.parse(event.body);</pre><pre>const params = {<br> TableName: process.env.DYNAMODB_TABLE,<br> Item: {<br> id: uuid.v4(),<br> title: data.title,<br> price: data.price,<br> author: data.author,<br> createdAt: timestamp,<br> updatedAt: timestamp,<br> },<br> };</pre><pre>// write the book to the database<br> dynamoDb.put(params, (error) =&gt; {<br> // handle potential errors<br> if (error) {<br> console.error(error);<br> callback(new Error(‘Couldn\’t create the book item.’));<br> return;<br> }</pre><pre>// create a response<br> const response = {<br> statusCode: 201,<br> body: JSON.stringify(params.Item),<br> };<br> callback(null, response);<br> });<br>};</pre><p>Let’s update the function definition in `serverless.yml` to point this new handler.</p><pre>functions:<br> hello:<br> handler: handler.hello<br> booksCreate: # A Function<br> handler: books/create.create<br> events: # The Events that trigger this Function<br> — http:<br> path: books<br> method: post<br> cors: true</pre><p>This setup specifies that the booksCreate function should be run when someone accesses the API gateway at books/ via a POST request. Further the HTTP endpoints defined here, have cross-site requests enabled for all source domains.</p><h4>Creating the DynamoDB Table</h4><p>One thing I really like with Serverless framework is, by simply adding the aws resource configuration to serverless.yml we can bring up other aws resources like dynamodb tables, s3 buckets etc. Serverless Framework translates all syntax in serverless.yml to a AWS CloudFormation template — automagically.</p><p>Add DynamoDB config to serverless.yml</p><pre>service: serverless-demo<br>provider:<br> name: aws<br> runtime: nodejs4.3<br> stage: dev # Set the default stage used. Default is dev<br> profile: serverless-demo # The AWS credentials profile to use with this service<br> region: us-east-1<br> environment:<br> DYNAMODB_TABLE: ${self:service}-${opt:stage, self:provider.stage}<br> iamRoleStatements:<br> — Effect: Allow<br> Action:<br> — dynamodb:Query<br> — dynamodb:Scan<br> — dynamodb:GetItem<br> — dynamodb:PutItem<br> — dynamodb:UpdateItem<br> — dynamodb:DeleteItem<br> Resource: “arn:aws:dynamodb:${opt:region, self:provider.region}:*:table/${self:provider.environment.DYNAMODB_TABLE}”<br>resources:<br> Resources:<br> AppointmentsDynamoDbTable:<br> Type: ‘AWS::DynamoDB::Table’<br> DeletionPolicy: Retain<br> Properties:<br> AttributeDefinitions:<br> -<br> AttributeName: id<br> AttributeType: S<br> KeySchema:<br> -<br> AttributeName: id<br> KeyType: HASH<br> ProvisionedThroughput:<br> ReadCapacityUnits: 1<br> WriteCapacityUnits: 1<br> TableName: ${self:provider.environment.DYNAMODB_TABLE}<br>functions:<br> hello:<br> handler: handler.hello</pre><p>You can learn more about AWS resources configurations <a href="https://serverless.com/framework/docs/providers/aws/guide/resources/">here</a>.</p><h4>Deploy to AWS</h4><p>During the deployment, it will setup a DynamoDb table, an API Gateway endpoint and your CREATE function will be added to Lambda functions list.</p><pre>$ serverless deploy <br>Serverless: Packaging service…<br>…………………………………..<br>Serverless: Stack update finished…<br>Service Information<br>service: serverless-demo<br>stage: dev<br>region: us-east-1<br>api keys:<br> None<br>endpoints:<br> POST — https://XXX.execute-api.us-east-1.amazonaws.com/dev/books<br>functions:<br> hello: serverless-demo-dev-hello<br> booksCreate: serverless-demo-dev-booksCreate</pre><p>That’s it. You now have your API Gateway endpoint to invoke the REST API call. Let’s add some book data.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/983/1*9uymjK3QkVcS9QJk2GM3fw.png" /></figure><p>Your DynamoDb table is named as `serverless-demo-dev`</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*Dc90E_-ziu-p8Y21ijoGnQ.jpeg" /></figure><h4>Monitoring</h4><p>AWS Lambda automatically monitors functions and these metrics include total requests, latency, and error rates is available through AWS CloudWatch.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*YuzVm3UEwyxjgCW_YdtPyw.png" /></figure><p>You can find the complete source code in <a href="https://github.com/randika/serverless-demo">GitHub</a>. <br>Happy coding ❤</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=34a8c3d80e41" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[High Availability with Route53 DNS Failover]]></title>
            <link>https://medium.com/@randika/high-availability-with-route53-dns-failover-c13cb30cbe94?source=rss-2677501c4d0e------2</link>
            <guid isPermaLink="false">https://medium.com/p/c13cb30cbe94</guid>
            <category><![CDATA[route-53]]></category>
            <category><![CDATA[dns]]></category>
            <category><![CDATA[aws]]></category>
            <dc:creator><![CDATA[Randika Rathugamage]]></dc:creator>
            <pubDate>Sat, 11 Mar 2017 02:45:10 GMT</pubDate>
            <atom:updated>2017-03-23T12:10:00.337Z</atom:updated>
            <content:encoded><![CDATA[<p>DNS failover feature in Route53 is very useful during an outage of your application, as it’s automatically routes traffic to alternate locations where your application is operating properly.</p><p>Failover configuration can be either active-passive or active-active, if not you can also consider to go for a even more complex setup like active-active-passive or other mixed configurations with route53.</p><p>In this post, I’ll explain how you could build an <strong>active-active</strong> dns failover for your wep application spans over <strong>multiple aws regions</strong>.</p><p>At the end your setup should look like below.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/912/1*o76vPCV2AF0jeVVunVwYDA.png" /></figure><p>As described in the diagram you will have 2 sets of app instances, each behind an elastic load balancer in two separate regions.</p><p>Active-Active failover is used when you want all of your app nodes in all regions to be available simultaneously, in this example both region 1 and region 2 are active. When one of the region becomes unavailable (This could happen due to application node crash, elb failures or even the region itself experiencing any problems), Route 53 can detect that it’s unhealthy and stop including it when responding to DNS queries.</p><p>I’ll be using the latency based failover for this setup. With latency-based routing, Amazon Route 53 can direct your users to the lowest-latency AWS endpoint available.</p><p>For demo purpose I’m going to deploy 2 demo web app in region <strong>us-east-1</strong> and <strong>ap-southeast-1</strong>, each behind elb.</p><p><strong>us-east-1</strong></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*IJE9ZG2wcofTTyjTQxovbg.png" /></figure><p><strong>ap-southeast-1</strong></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*76OfLYQYS_785GGbxNsHoQ.png" /></figure><p>I<em>deally the deployed application should be identical in both regions, but I think I said its a demo ;)</em></p><p>When setting up DNS Failover for an ELB Endpoint, you simply set <strong>Evaluate Target Health</strong> to <strong>true</strong>. DNS Failover for ELB endpoints is available at no additional charge — you aren&#39;t charged for any health checks.</p><p>In Route 53, create 2 records sets for each ELB endpoints as described here.</p><p><strong>For ELB in us-east-1 (Region 1)</strong></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/844/1*-y49KsFT71jHfaX0lGSIzg.png" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/804/1*TmQP7nmVStPghjyDNy9bDA.png" /></figure><p><strong>For ELB in ap-southeast-1 (Region 2)</strong></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/844/1*-y49KsFT71jHfaX0lGSIzg.png" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/802/1*wCJVJ4xg0PKu2WhVAkF24g.png" /></figure><p>Now when you access your application, you should get your resolved DNS based on the lowest latency. Since I’m living closer to ap-southeast-1, mine looks like this.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*KbBsL9QOmv6P8xjboqCXpQ.png" /></figure><p>Now it’s time to see, if the failover works for real.</p><p>Let’s go ahead and stop the instances in ap-southeast-1. The ELB in ap-southeast-1 region now marks it instances as “Out of Service” and Route53 will begin to route traffic to the other healthy region — which is us-east-1.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*BJ_gM8HtzgVcNbpjsfizAg.png" /></figure><p>This is a basic example of how you can use the Route53 DNS failover to detects the failures and route the traffic away from failed endpoint. Route53 evaluate the health of the load balancer and the health of the EC2 instances running behind in it.</p><p>If you want to try more complex scenario, check out the <a href="http://docs.aws.amazon.com/Route53/latest/DeveloperGuide/dns-failover-complex-configs.html">docs</a></p><p>— RR</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=c13cb30cbe94" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[AWS SNS — Send SMS in Sri Lanka]]></title>
            <link>https://medium.com/@randika/aws-sns-send-sms-in-sri-lanka-300c358bcad1?source=rss-2677501c4d0e------2</link>
            <guid isPermaLink="false">https://medium.com/p/300c358bcad1</guid>
            <category><![CDATA[sri-lanka]]></category>
            <category><![CDATA[aws]]></category>
            <category><![CDATA[sms]]></category>
            <dc:creator><![CDATA[Randika Rathugamage]]></dc:creator>
            <pubDate>Sun, 17 Jul 2016 03:56:27 GMT</pubDate>
            <atom:updated>2016-07-17T06:18:42.138Z</atom:updated>
            <content:encoded><![CDATA[<p>With the recent announcement of its worldwide support to send SMS, now we can deliver both transactional and promotional text messages to carriers in Sri Lanka — a much awaited feature in SNS. (earlier it was a US-based phone numbers only feature in SNS)</p><p>Along with this expansion, SNS has also enabled the default “Opt-in” for recipients. Now the developers can deliver messages right away to recipient phone number without a prior opt-in. This will help in several occasions such as when sending OTP, MFA codes or any other direct publishing requirements in your application. As recipients, you can “Opt-out” your self by sending a SMS with “STOP” text.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/590/1*3kkRBBs3IjjXI9znH-885Q.png" /></figure><p>AWS no longer use 30304 as the short code for SMS, instead it has a pool of short codes/long codes. However the SMS send from an AWS account will use the same code — mine was set to “NXSMS”. Ideally you can set your own Sticky sender ID, but unfortunately this doesn’t support in Sri Lanka yet.</p><p>Something really doesn’t work well is the pricing introduced for Sri Lankan carriers — Who to blame local carriers or AWS ? For Promotional text messages there is a lower rate, but still it’s way too expensive for a SMS.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*jy2djfcLpvmRMLAz4f_iBg.png" /></figure><p>But despite the cost, SNS/SMS comes with some rich set of features which doesn’t available right now from any local SMS API provider.</p><p>To send SMS you can either use AWS console or AWS API with delivery status, logging, usage reports, opt-out management etc — more on this <a href="https://aws.amazon.com/blogs/aws/new-worldwide-delivery-of-amazon-sns-messages-via-sms/">here</a>.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=300c358bcad1" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Using CDN for Assets Hosting]]></title>
            <link>https://medium.com/@randika/using-cdn-for-assets-hosting-1adeeb5f64ba?source=rss-2677501c4d0e------2</link>
            <guid isPermaLink="false">https://medium.com/p/1adeeb5f64ba</guid>
            <category><![CDATA[cdn]]></category>
            <dc:creator><![CDATA[Randika Rathugamage]]></dc:creator>
            <pubDate>Sat, 28 Nov 2015 16:26:52 GMT</pubDate>
            <atom:updated>2015-11-29T05:17:44.897Z</atom:updated>
            <content:encoded><![CDATA[<p>In general a web application consists of 2 types of assets — Static &amp; Dynamic. Static assets doesn’t change very often — logos, banner images, javascripts, stylesheets and other rich media contents such as audio, video can be considered as static assets. On the other hand dynamic assets can be the contents which uploaded by its users or other systems on-the-fly.</p><p>In general most web applications uses the local file system or Network Attached Storage (NAS) as the asset storage. Here is an example of a website using local file storage to host the assets.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*wRlEtSytdMWgykCSFl1tIg.png" /></figure><p>In the example we have a web page located at <a href="http://domain.com/index.html">http://domain.com/index.html</a> with 2 images, a stylesheet and a javascript.</p><p>When a request is made to access the index.html, the web browser receives the response and parses the HTML, a DOM tree is built out of the HTML. However new requests are made to the web server for each new resource that is found in the HTML source (typically for all images, style sheets, and JavaScript files) — So as per this example there will be 5 requests to the web server.</p><p>List of HTTP requests from users browser to server</p><ol><li><a href="http://domain.com/index.html">http://domain.com/index.html</a></li><li><a href="http://domain.com/assets/logo.jpg">http://domain.com/assets/logo.jpg</a></li><li><a href="http://domain.com/assets/banner.jpg">http://domain.com/assets/banner.jpg</a></li><li><a href="http://domain.com/assets/stylesheet.css">http://domain.com/assets/stylesheet.css</a></li><li><a href="http://domain.com/assets/javascript.js">http://domain.com/assets/javascript.js</a></li></ol><p>The above approach works and there is nothing wrong about it, but this is not optimal.</p><p>Here is why — Consider a situation domain.com is a high traffic website. Higher the traffic the more is going to cost as you will need to scale up the servers to meet the demand. What if we move the assets to an external CDN? as per above example out of those 5 HTTP requests only 1 request will reach the nginx server — and all the other assets will be served from external CDN, saving the bandwidth, computing resources like CPU, RAM on the primary web server(s).</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*gm9Fmu60aFf1RV5HMOfNRQ.png" /></figure><p>Another example is — If your apps are deployed on a load balanced environment with multiple web server instances, you will need to keep each instance up to date with static contents and things will be even messy with dynamic contents as you need to either copy the assets to all the nodes or use a shared storage. But with a CDN in place you will need to copy them into one place — your CDN.</p><p>That’s some theory inedeed — In my next post on CDN I’ll try and compare these two approaches and see if this really works — in terms of improved performances as well as cost savings.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=1adeeb5f64ba" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Load Balancing AWS RDS MySQL read traffic using Route53 Weighted Routing]]></title>
            <link>https://medium.com/@randika/load-balancing-aws-rds-mysql-read-traffic-using-route53-weighted-routing-56eb3383f684?source=rss-2677501c4d0e------2</link>
            <guid isPermaLink="false">https://medium.com/p/56eb3383f684</guid>
            <category><![CDATA[aws]]></category>
            <category><![CDATA[cloud-computing]]></category>
            <dc:creator><![CDATA[Randika Rathugamage]]></dc:creator>
            <pubDate>Sat, 31 Oct 2015 17:37:54 GMT</pubDate>
            <atom:updated>2017-12-23T17:02:49.512Z</atom:updated>
            <cc:license>https://creativecommons.org/publicdomain/mark/1.0/</cc:license>
            <content:encoded><![CDATA[<p><strong><em>[Update] <br></em></strong><em>As of Sep 2016, AWS Aurora has the load balancing built-in — By using the </em>cluster endpoint, you can <a href="https://aws.amazon.com/blogs/aws/new-reader-endpoint-for-amazon-aurora-load-balancing-higher-availability/">load-balance connections across the replicas</a> in the DB cluster. <em>As of Nov 2017, </em><a href="https://aws.amazon.com/about-aws/whats-new/2017/11/amazon-aurora-now-supports-auto-scaling-for-aurora-replicas/?sc_channel=sm&amp;sc_campaign=launch_&amp;sc_publisher=LINKEDIN&amp;sc_country=Global&amp;sc_geo=GLOBAL&amp;sc_outcome=awareness&amp;trk=_LINKEDIN&amp;sc_content=Aurora_b15b16ea_Auto_Scaling_Replicas&amp;sc_category=Amazon_Aurora&amp;linkId=44867025"><em>Auto-scaling</em></a><em> is available for Aurora read-replicas. <br>You may need to consider these options instead the solutions described in this post.</em></p><p>If you do have any read heavy applications hopefully you must have experienced some sudden CPU spikes on your RDS MySQL read replicas.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/882/1*c_ZjJ3pJySu8mw8KVSdJcw.png" /></figure><p>If you’re running on a single read replica, chances are your read replica may not respond when the CPU hits 100%. The solution is to add more read replicas to your stack and distribute the read traffic evenly by enabling load-balancing. As of this writing MySQL RDS allows maximum of 5 read replicas per single master rds.</p><p>In general you can load-balance your MySQL read replicas from these logical layers.</p><ul><li>Application layer — Create multiple connection pools and distribute the read traffic between one or more read replicas.</li><li>External proxy — Configure HAProxy[1] or MySQLProxy[2]</li></ul><p>[1] <a href="http://www.haproxy.org/">http://www.haproxy.org</a><br>[2] <a href="https://dev.mysql.com/downloads/mysql-proxy/">https://dev.mysql.com/downloads/mysql-proxy/</a></p><p>Both these options requires some code level and server level configuration work. And these are the most well known methods to setup load-balanced environments.</p><p>There is however a quick and easy way — that is using the <strong>Route53 Weighted Routing</strong>. Let’s see how — the diagram below shows how the setup would look like once completed.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/960/1*Ai5fWxqG8B4_maeLT8Rqcw.jpeg" /></figure><p>As per the diagram we have 2 application instances (EC2) and both these apps configured to connect with read replicas using a CNAME — <strong>read.db.yourdomain.com</strong>. We also have our master RDS with its 2 read replicas R1, R2 under same VPC.</p><p>For this we will be using a Private hosted zone for VPC on Route53, so the routing queries will not be public.</p><blockquote>A private hosted zone determines how traffic is routed within an Amazon VPC. Your resources are not accessible outside the VPC. You can use any domain name.</blockquote><p>Go to your Route53 on aws console and setup a new private hosted zone — example: <strong>db.yourdomain.com.</strong></p><p>On your newly created hosted zone, create these CNAME records sets as described below.</p><pre>Name: read.db.yourdomain.com<br>Type: CNAME<br>Value: <strong>my-rds-read1</strong>.us-east-1.rds.amazonaws.com<br>TTL: 0<br>Routing policy: Weighted<br>Weight: 0<br>SetId: <strong>read1</strong></pre><pre>Name: read.db.yourdomain.com<br>Type: CNAME<br>Value: <strong>my-rds-read2</strong>.us-east-1.rds.amazonaws.com<br>TTL: 0<br>Routing policy: Weighted<br>Weight: 0<br>SetId: <strong>read2</strong></pre><p>That’s it — Route53 will now load-balance the DNS queries received to read.db.yourdomain.com between the 2 read replicas. You can also add more read replicas (up to 5) without changing your database connection endpoint on your apps.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=56eb3383f684" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[AWS-Ruby SDK and Elastic Transcoder Example]]></title>
            <link>https://medium.com/@randika/aws-ruby-sdk-and-elastic-transcoder-example-c6c34fb5bc32?source=rss-2677501c4d0e------2</link>
            <guid isPermaLink="false">https://medium.com/p/c6c34fb5bc32</guid>
            <category><![CDATA[ruby-on-rails]]></category>
            <category><![CDATA[aws]]></category>
            <dc:creator><![CDATA[Randika Rathugamage]]></dc:creator>
            <pubDate>Fri, 30 Oct 2015 04:11:17 GMT</pubDate>
            <atom:updated>2015-10-31T03:12:44.226Z</atom:updated>
            <content:encoded><![CDATA[<p>AWS Elastic Transcoder is a very handy service if you looking for a cost effective, scalable solution to Transcode your audio or video files. AWS Elastic Transcoder takes input from a S3 bucket, transcodes it, and writes the resulting file to another S3 bucket — well you could also use the same bucket if you prefer.</p><p>Here is a very quick code extracted from one of a project I’m currenly working on. Here the uploaded .m4a audio files will be transcoded to HLS (HTTP Live Streaming) — m4a files will be first uploaded to a S3 bucket let’s call it “s3.audio.input”. Files will be saved on the root of the input s3 bucket <strong>s3.audio.input/{UUID}.m4a</strong> and transcoded HLS audio will be saved on <strong>s3.audio.output/hlsv4/{UUID}/index.m3u8</strong></p><pre>#### transcoder.rb #### <br>class Transcoder &lt; Message<br><br>  STATUS_SUBMITTED =  &quot;Submitted&quot;<br>  STATUS_PROGRESSING =  &quot;Progressing&quot;<br>  STATUS_COMPLETE =  &quot;Complete&quot;<br>  STATUS_CANCELED =  &quot;Canceled&quot;<br>  STATUS_ERROR =  &quot;Error&quot;<br><br>  def initialize(message)<br>    @message = message<br>  end<br><br>  def create<br>    uuid = UUID.new<br>    transcode_job_uuid = uuid.generate<br><br>    transcoder = Aws::ElasticTranscoder::Client.new(<br>      :access_key_id =&gt; &quot;YOUR_AWS_ACCESS_KEY_ID&quot;,<br>      :secret_access_key =&gt; &quot;YOUR_AWS_SECRET_ACCESS_KEY&quot;,<br>      :region =&gt; &quot;us-east-1&quot;)<br><br>    #HLSV4<br><br>    options = {<br>      pipeline_id: &quot;1432361831290-XXXXX&quot;,<br>      input: {<br>        key: &quot;ACB685E9-8C3C-4E5D-A49A-8F3BB5298DDC-201509021233.m4a&quot;<br>        },<br>      outputs: [<br>        {<br>          key: &quot;hls_64k&quot;,<br>          preset_id: &#39;1351620000001-200071&#39;,<br>          segment_duration: &quot;10&quot;<br>        }<br>      ],<br>      playlists: [<br>        {<br>          name: &quot;index&quot;,<br>          format: &quot;HLSv4&quot;,<br>          output_keys: [&quot;hls_64k&quot;]<br>        }<br>      ],<br>      output_key_prefix: &quot;hlsv4/#{@message.id}-#{transcode_job_uuid}/&quot;<br>    }<br>    job = transcoder.create_job(options)<br><br>    @message.update_attributes(<br>      transcode_job_uuid: transcode_job_uuid,<br>      transcode_job_id: job.data[:job][:id],<br>      transcode_job_status: job.data[:job][:status],<br>      state: Message::STATE_PUBLISHED)<br><br>  end<br><br>end</pre><p>As you have already noticed, I’m using an UUID to keep track of the data submiited to S3, Trancoder pipeline with active record — (MySQL database).</p><p>The example above writes the resulting job data to active record object immediately after submit the job to transcoder service. job.data[:job][:id] is the uniqe identification (Usually looks like 1441177406727-xxxxx) returned from AWS which you can use for further querying the transcoder API and get the details of the submited job.</p><pre>@message.update_attributes(<br>      transcode_job_uuid: transcode_job_uuid,<br>      transcode_job_id: job.data[:job][:id],<br>      transcode_job_status: job.data[:job][:status],<br>      state: Message::STATE_PUBLISHED)</pre><p>You can also configure Elastic transcoder to work with SNS. AWS transcoder service will trigger SNS notifications to a predefined topic based on these events.</p><ul><li>On Progressing Event</li><li>On Warning Event</li><li>On Completion Event</li><li>On Error Event</li></ul><p>For example once the transcode job is finished SNS will notify the status of the job to an endpoint you have configured on your SNS topic.</p><p>Hope this helps — Happy coding :)</p><p>— RR</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=c6c34fb5bc32" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Installing nvm, nodejs and npm on Ubuntu]]></title>
            <link>https://medium.com/@randika/installing-nvm-nodejs-and-npm-on-ubuntu-f6deef0cd22a?source=rss-2677501c4d0e------2</link>
            <guid isPermaLink="false">https://medium.com/p/f6deef0cd22a</guid>
            <category><![CDATA[how-to]]></category>
            <dc:creator><![CDATA[Randika Rathugamage]]></dc:creator>
            <pubDate>Fri, 30 Oct 2015 04:07:08 GMT</pubDate>
            <atom:updated>2016-08-20T03:18:11.804Z</atom:updated>
            <content:encoded><![CDATA[<p>Those who familiar with Ruby must know how useful was your <strong>rbenv</strong> and <strong>rvm</strong>. When it comes to nodejs you have nvm —( node version manager) for the same job. Installing nvm, nodejs and npm on a ubuntu box is just few commands. Let’s get started.</p><p><strong>Install nvm — </strong>Let’s clone the nvm repository</p><pre>$ git clone <a href="https://github.com/creationix/nvm.git">https://github.com/creationix/nvm.git</a> ~/.nvm</pre><p><strong>Update your profile config file</strong> — Depends on what you use <strong><em>.bashrc</em></strong> ,<strong><em> .zshrc</em></strong> or <strong><em>.profile</em></strong> you need to add this line. Mine is a .zshrc</p><pre>$ echo &quot;source ~/.nvm/nvm.sh&quot; &gt;&gt; .zshrc</pre><p><strong>Find the list of nodejs versions out there</strong></p><pre>$ nvm ls-remote</pre><p>Your output would looks like</p><pre>v0.1.14<br>v0.1.15<br>v0.1.16<br>v0.1.17<br>…..<br>v4.1.1<br>v4.1.2<br>v4.2.0<br>v4.2.1<br>v5.0.0</pre><p>Install the required version of your choice — I’m going to go for the latest stable version here</p><pre>$ nvm install v5.0.0</pre><p>This will install both nodejs v5.0.0 and npm. Let’s verify</p><pre>➜ ~ node -v &amp;&amp; npm -v <br>v5.0.0<br>3.3.6</pre><p>Additionally you can set the default nodejs version using</p><pre>nvm alias default 5.0.0</pre><p>And we’re ready — Happy coding :)</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=f6deef0cd22a" width="1" height="1" alt="">]]></content:encoded>
        </item>
    </channel>
</rss>