AWS Lambda For The Impatient Part 3
Written by Nikos Vaggalis   
Monday, 20 February 2017
Article Index
AWS Lambda For The Impatient Part 3
Paws::STS

We completed Part 2 of our tutorial on AWS Lambda by calling our Lambda function through an authenticated HTTP endpoint, aided by Postman and leveraging IAM security. In this third and final part, we do the same, only this time programmatically, with the aid of Perl and the Paws module.

Introducing Paws

Paws is a namespace rather than a module, that encompasses a plethora of sub-modules, which aim to, and actually succeed, in achieving the unprecedented:

to provide a unified programming interface to all accessible through APIs Amazon hosted services, be it Amazon Simple Queue Service, Amazon Simple Notification Service, EC2, DynamoDB

or as in this case, AWS Lambda.

We're going to consider Paws in action from two perspectives, assuming a user and assuming a role.

Assuming a User

Starting with the former, we're going to give our 'nikosvAuth' user, created in the previous installments, the required permissions for directly invoking the function.

So let's revisit the user's profile from within the IAM panel:


 We want to add a new inline policy that grants execute permission to 'nikosvAuth' on function 'helloWorldNodeJsAuth':

5

 

On the server side we have to make a slight modification to our lambda code to accomodate Paw's requirements in a 'Payload' instead of a 'body'. That is, our function's code will have to change from: 

use strict';
exports.handler = (event, context, callback) => {  console.log('Received event:',
                 JSON.stringify(event, null, 2));
 var inputObj = JSON.parse(event["body"]);
 callback(null, {
    "statusCode": 200,
    "headers": { },
 // Echo back the first key value
    "body": JSON.stringify(
                    {"received":inputObj.key1})
 })
}

to:

'use strict';

exports.handler = (event, context, callback) => {
    console.log('Received event:', JSON.stringify(event, null, 2));

   var inputObj=JSON.parse(event["Payload"]);

   callback(null, {
    "statusCode": 200,
    "headers": { },
    // Echo back the first key value
      "Payload": JSON.stringify(    
               {"received":inputObj.key1})

    })
}

On the client side, since we've already setup the AWS CLI as well as configured our user's environment, Paws will just have read the required settings from the environmental variables set by the CLI.This way we can just focus on the actual calling of our function:

use Paws;
use Data::Dumper;
use JSON::MaybeXS;
use strict;

my $lambda = Paws->service('Lambda',
                     region => 'eu-west-1' );


my $data_structure={key1=>value1};

my $json_text = encode_json($data_structure);

my $response=$lambda->Invoke(
      FunctionName => 'helloWorldNodeJsAuth',
      Payload=>$json_text,

      InvocationType => 'RequestResponse');

print Dumper $response;

print $response->Payload;

6

 

We first initialize the object that is going to make the request:
my $lambda = Paws->service('Lambda',
                      region => 'eu-west-1' );


Then we initialize a hash data structure which holds the payload to send:
my $data_structure={key1=>value1};

which we further encode as JSON :
my $json_text = encode_json($data_structure);

then make the call:
my $response=$lambda->Invoke(
   FunctionName => 'helloWorldNodeJsAuth',
   Payload=>$json_text,

   InvocationType => 'RequestResponse');

and finally take a peek at the internals of the response:

print Dumper $response;

and the value returned:

print $response->Payload;

 

Assuming a Role

We've already discussed the merits of a Role versus direct calling through a User instance, therefore in order to make the example more credible we're going to first revoke 'nikosvAuth' rights and watch how the role based invocation handles it.


Reusing the code from above, this time we end up with the glorious error message:

'...user is not authorized to perform lambda:InvokeFunction on resource...'

and the accompanying long-winded stack trace, which proves the point that our user no longer posesses any execute permissions:


Nevertheless, since he has the required permissions to assume a Role (lambda_basic_execution_helloWorldNodeJS_auth) that in turn has the required permissions to execute the lambda, he still can make the call, albeit indirectly.

To assume a role the AWS way, first a call to the STS,  AWS Security Token Service, has to be made for acquiring a set of temporary security credentials (consisting of an access key ID, a secret access key, and a security token) which you use to access AWS resources that you might not normally have access to.

 

 

aws logo. v400518270

 



Last Updated ( Tuesday, 21 February 2017 )