Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (9.79 MB, 388 trang )
To simplify the creation of a new Lambda function, blueprints are provided to show the
integration with other AWS services and other services such as Amazon Alexa, Twilio, and
Algorithmia (figure 2.1). Select the “Blank Function” to start from scratch.
Figure 2.1. With AWS Lambda you can create a new function using one of the provided blueprints, but for your first function you’ll
start from scratch.
You can then choose a trigger for the new function (figure 2.2). A trigger is a source of events
that will execute the function, providing the event an input. You have multiple options for the
trigger; a few of them will be used by the examples you’ll build while reading this book.
Figure 2.2. You can choose a trigger during the creation of a new function. Triggers invoke a Lambda function when certain events
happen.
For example, you can choose the Amazon API Gateway to have a Web API calling a function, or
AWS IoT, to build a serverless back end for an Internet of Things (IoT) platform connecting
devices with AWS. You’ll directly invoke this function and don’t need a trigger for now. Select
“Next.”
You can now create a new AWS Lambda function (figure 2.3). For the name of the function, type
“greetingsOnDemand”.
Figure 2.3. Configuring a new AWS Lambda function, starting with a name and a description, the runtime to use, and the code to
execute
Note
AWS Lambda has no official rule on how to write function names. Sometimes function names
are written in all lowercase, with dashes to separate words. In this book, I’ll follow
the lowerCamelCase convention, joining all words together, starting with a lowercase letter and
using uppercase for the first letter of every word after the first one.
The description text can be “Returns greetings when you ask for them.” Giving a meaningful
description can help when building an application with multiple functions or to facilitate reuse
of a function (or only its code) for different purposes.
https://avxhm.se/blogs/hill0
Tip
Descriptions can also be read through AWS APIs, and having conventions in the content of the
description—for example, describing the expected input/output—can help in implementing
automated “discovery” for your functions.
Using the AWS Lambda web console, you can provide the code for your function in three
different ways:
•
•
•
Edit code inline, straight from the web browser
Upload a zip file from your local environment
Upload a zip file from Amazon S3
You can include custom libraries or modules that your code depends on in the zip file. In part
3 you’ll see that uploading functions via Amazon S3 can be an interesting feature for
implementing automatic deployments and continuous integration with AWS Lambda.
As the runtime for your function, you can choose Node.js 4.3 or Python 2.7. Examples of both
are provided in this chapter; choose the language you prefer for your back end deployment.
Using the Java Runtime
I’m not providing Java 8 examples throughout the book for the sake of simplicity, because Java code
cannot be written inline in the web console and needs to be compiled, packaged, and uploaded. For
that, my suggestion is to use the AWS Toolkit for Eclipse, found at https://aws.amazon.com/eclipse.
2.2. WRITING THE FUNCTION
Leave the option to “Edit code inline” selected and write the following code in the online editor
below it, depending on the runtime you chose. Use the following listing for Node.js or listing
2.2 for Python.
Listing 2.1. Function greetingsOnDemand (Node.js)
Listing 2.2. Function greetingsOnDemand (Python)
The overall organization of the code and the execution flow are similar for both runtimes:
•
•
•
The code starts with an initialization phase before the function. AWS Lambda can reuse
the same “container” for multiple invocations of a function and the initialization isn’t
executed every time the function is invoked, but only the first time a function is invoked
in a container. In the initialization, you should put code that can be executed only once;
for example, to open a connection to a database, initialize a cache, or load configuration
data required by the function.
AWS Lambda executes functions in a headless environment without any display. For this
reason, all runtimes implement an easy way to write centralized logs to Amazon
CloudWatch Logs. Amazon CloudWatch is a monitoring and logging service that can be
used to manage metrics, alarms, and logs for your application and the AWS services used
by your application. For Node.js, anything written by console.log() goes to CloudWatch
Logs. For Python, it’s anything that you print.
After the initialization, a function takes as input an event and a context. Both are in the
native format for the runtime; for example, a JavaScript object in Node.js or a dictionary
•
•
•
•
•
in Python. That function will be the one that’s executed for every invocation, and you’ll
configure it in the next steps.
The logic of the function is simple: if a “name” key is present in the input event, then that
name is used to prepare a “greeting”; otherwise, a default “Hello World!” is provided.
The resulting greeting is then logged and returned by the function.
In Node.js, you end your function using the callback in a way familiar to the standard
Node.js programming model. In this case, callback(null, data) is used to terminate
successfully and return the greeting. If the first parameter of the callback is not null, you
terminate the function with an error; for example, callback(error).
In Python the return of the function terminates successfully, and you can raise an
exception on failure.
The input context has interesting information on the configuration of the function and
how the execution is handled by AWS Lambda. For example, you can check how much
time is left before you reach the configured timeout (more details on this in the next
section).
2.3. SPECIFYING OTHER SETTINGS
After you paste the code in the web console, you need to specify which function inside your code
should be called by AWS Lambda. You can do that via the Handler field below the code. Because
you can upload more than one file in a zip file, the following syntax is used by the handler:
For example, the default value for Node.js is index.handler, the handler (exported) function in
the index.js file. In Python, the default value is lambda_function .lambda_handler, for
the lambda_handler function in the lambda_function.py file. When you paste your code in the
web console, index (for Node.js) and lambda _function (for Python) are the default file names
and the Handler field is already configured to use the default names of the functions you used in
the previous code. When using Node.js, remember to export the function used by the Handler.
If you want to use a different function name in the code, you should update the name in the
handler (figure 2.4). You can have multiple functions in the code you provide and multiple files
if you upload a zip archive, but only the function specified by the Handler is called by AWS
Lambda. The other functions can be used internally in the code.
Figure 2.4. After giving the code, you have to choose which function in the code should be called by AWS Lambda, the AWS IAM role
that the function will assume to get permissions, how much memory to allocate, and a timeout in seconds. You can optionally specify
an Amazon VPC to access resources (for example, a database) inside the VPC.
AWS Lambda allows tight control of the security of your environment: everything that’s
executed by AWS Lambda needs to have the permissions to do what it’s supposed to do. This is
managed using AWS Identity and Access Management (IAM) roles and policies, which you’ll
explore in depth in chapter 4. When a function is executed it assumes the role given in the
configuration. A “role” can have one or more policies attached. A “policy” describes what you
can do in terms of actions, resources, and conditions. Assuming a role allows the function to do
what’s described in the policies attached to the role.
For this basic example, the function is interacting only with Amazon CloudWatch Logs (for
logging)—that’s the default behavior and you can use a “basic execution role.” You can create a
new basic execution role using the Role menu:
1. Choose create a new role.
2. You can use “myBasicExecutionRole” for the role name.
3. Don’t select a policy template, leaving the corresponding field empty.
Next time, if you need the same role, you can select the option to use an existing role and select
it from the “existing role” menu. It doesn’t make sense to have multiple roles with the same
configuration, so reuse a role if you can.
Tip
You don’t need to select a policy template now because your first function isn’t accessing any
external resources that would need additional permissions. In the more advanced examples in
the book you’ll create roles that will enable you to read or write permissions on specific
resources. Those roles will not be reused because they’re tightly customized for the functions
using them.
Now you have to configure two important aspects for a Lambda function:
•
•
How much memory to use. This setting also affects the quantity of CPU power and
the cost of executing the function, so you should use the least amount of memory (and
CPU) you need—in this case, for this simple function, 128 MB is more than enough. If you
need a shorter execution time, you can increase memory to have more CPU power.
The timeout after which the function is automatically terminated. This
setting is used to avoid mistakes that could start long-running functions, which in turn
could introduce a non-planned cost for your application. Three seconds is fine for our
simple function. You should use a value here that you’re sure is never reached by a
normal execution of your function.
You can monitor the usage of memory and the execution time from the logs, as you’ll see in the
next section on testing a function.
In the final setting, you can specify an Amazon Virtual Private Cloud (VPC), a logically isolated
section of the AWS Cloud where you can launch resources in a virtual network that you define,
to access those resources from the function you create. For example, a NoSQL database hosted
on one or more Amazon EC2 virtual servers or a relational database managed by Amazon RDS
can be directly addressed by a Lambda function, via private networking, if the correct VPC is
configured here. You can leave the default “No VPC” for now, because we aren’t using any
resource in a VPC in this example.
You can select Next to review all of the configurations, and then select “Create function.”
Congrats, you created your first function!
2.4. TESTING THE FUNCTION
Now that your function has been created, you can test it directly from the web console. Click the
Test button in the upper left of the console. You should now prepare a test event (figure 2.5) that
will be used for all test invocations in the console. When invoking a Lambda function, events are
expressed using a JSON syntax that’s translated to native objects or types when the event is
received by the actual runtime—for example, a JavaScript object for Node.js or a dictionary in
Python.
Figure 2.5. Configuring a test event, using a JSON syntax, to quickly test a function from the web console
The drop-down menu has a few sample events that could be received when subscribing to
standard resources such as Amazon S3 or Amazon DynamoDB, but this function uses a custom
format for the event, so you can’t use a standard sample event. Instead, you should edit the
proposed event to give the “name” the function needs:
{
"name": "John"
}
Feel free to replace “John” with your name.
If you click “Save and test” at the bottom of the window, the function is invoked with the test
event you provided. The result of the execution is shown at the bottom of the page (figure 2.6;
you need to scroll down to see this) in terms of returned value and logs with a summary of the
execution characteristics: actual duration, the billed duration (rounded up to 100 ms), and how
much memory (out of the 128 MB you gave) was used. All the information is also displayed in
the raw log output.
Figure 2.6. Result of a test execution from the web console, with a summary of the execution and the log output
If everything went fine, you should see “Hello John!” (or your name if you changed the sample
event) in the execution result. You executed your first function!
Warning
If instead you get an error, please check to be certain that you pasted all the code; the final lines
(callback() in Node.js and the return statement in Python) are very important.
Try executing the function multiple times. You may notice that the first execution is sometimes
slower than those that follow, but it shouldn’t be an issue in production when multiple
invocations are expected.
Tip
If your function is rarely executed, AWS can release the execution environment and your next
execution may be slower. If you always need a short execution time—for example, to fulfill a
Service Level Agreement (SLA) for your customers—you can use a scheduled execution (for
example, every five minutes) with “harmless” parameters that don’t change data stored by your
function to keep the environment ready.
To test the default behavior when no name is provided, you should change the test event. From
the Actions menu, select “Configure test event” and remove the “name” key from the JSON
payload, so that event is empty:
{}
Save and test the empty event, and review the outcome at the bottom of the page: when no
“name” is passed in the event, the function logic (check listings 2.1 and 2.2) replaces the name
with “World” and you should now have a proper “Hello World!” in the execution results.
Congratulations, you executed the mandatory “Hello World” example that any programming
book should provide!
2.5. EXECUTING THE FUNCTION THROUGH THE LAMBDA API
You’ve tested the function in the web console, but is the function available to be used on demand
outside of this web interface? As a matter of fact, any Lambda function can be executed via the
AWS Lambda Invoke API call. To do that, you can use the AWS command-line interface.
Installing and configuring the AWS CLI
To install and configure the AWS CLI, you can follow the instructions for Windows, Mac, and Linux
on the AWS website at http://aws.amazon.com/cli/.
I suggest that you follow the “Getting Started” link to the documentation and create an AWS IAM
user for the CLI. Attach the following (managed) policies to the user so you can follow all the
examples in the book:
•
•
•
AWSLambdaFullAccess
AmazonAPIGatewayAdministrator
AmazonCognitoPowerUser
When you configure the CLI with the aws configure command, specify the AWS region you’re using
now as the default. Otherwise, you’ll have to add –-region
end of all AWS CLI commands hereafter.
I also suggest that you enable automatic command completion for the CLI, as described in the
documentation.
To test whether the installation and configuration of the AWS CLI worked, you can get a list of the
AWS Lambda functions you created (together with configuration info such as memory size, timeout,
execution role, and so on) with aws lambda list-functions.
By default, the output of the CLI is in JSON format, but you can change that during the initial
configuration or by supplying the -–output option.
To invoke the function you created, use the following syntax from the command line (note that
the JSON event is enclosed between single quotation marks):
aws lambda invoke --function-name
Warning
If you’re using a Windows CLI to execute the AWS Lambda invoke commands, you need to
replace single quotes with double quotes and escape them by repeating them twice; for
example, --payload '
The output of the function is written to a local file. For example, to greet “John,” run the
following command from the command line:
aws lambda invoke --function-name greetingsOnDemand --payload
'{"name":"John"}' output.txt
Warning
If you didn’t specify the same region you used for AWS Lambda during the configuration of the
AWS CLI, you’ll get an error from the previous command unless you add --region
you want to use> at the end.
Run the following command from the command line to test the default behavior when no name
is provided and receive a “Hello World!”:
aws lambda invoke --function-name greetingsOnDemand-py --payload '{}'
output.txt
You can see the results of the function by looking at the content of the output.txt file after each
invocation. The file is created in the same directory where the command is executed. You can
specify a different location in the command line if you prefer to use a different directory (for
example, /tmp/output.txt or C:/Temp/output.txt).