lambda command¶
lambda
is finks AWS Lambda deployment tool.
Usage¶
To see available commands, call this:
Usage:
lambda clean
lambda bundle [--keep] [-v]
lambda deploy [--keep] [-v]
lambda list
lambda metrics <lambda>
lambda info
lambda wire [-v]
lambda unwire [-v]
lambda delete [-v] -f <lambda> [--delete-logs]
lambda rollback [-v] <lambda> [<version>]
lambda ping [-v] <lambda> [<version>]
lambda invoke [-v] <lambda> [<version>] [--invocation-type=<type>] --payload=<payload> [--outfile=<file>]
lambda logs <lambda> [--start=<start>] [--end=<end>] [--tail]
lambda version
Options:
-h --help show this
-v --verbose show debug messages
--keep keep (reuse) installed packages
--payload=payload '{"foo": "bar"}' or file://input.txt
--invocation-type=type Event, RequestResponse or DryRun
--outfile=file write the response to file
--delete-logs delete the log group and contained logs
--start=start log start UTC '2017-06-28 14:23' or '1h', '3d', '5w', ...
--end=end log end UTC '2017-06-28 14:25' or '2h', '4d', '6w', ...
--tail continuously output logs (can't use '--end'), stop 'Ctrl-C'
clean¶
removes local bundle files.
bundle¶
zips all the files belonging to your lambda according to your config and requirements.txt and puts it in your current working directory as bundle.zip
. Useful for debugging as you can still provide different environments.
deploy¶
Deploy an AWS Lambda function to AWS. If the lambda function is non-existent it will create a new one.
For an existing lambda function lambda checks whether the hashcode of the bundle has changed and updates the lambda function accordingly. This feature was added to lambda so we are able to compare the hashcodes locally and save time for bundle uploads to AWS.
This only works if subsequent deployments are executed from the same virtualenv (and same machine). The current implementation of the fink-bundler starts every deployment with a fresh virtualenv. If you want the hashcode comparison you need to provide the --keep
option. With the ‘–keep’ option the virtualenv is preserved. Otherwise the hashcodes of the lambda code bundles will be different and the code will be deployed.
If you can not reuse (‘–keep’) the virtualenv for example in case you deploy from different machines you need to use git
to check for code changes and skip deployments accordingly.
In any case configuration will be updated and an alias called “ACTIVE” will be set to this version.
list¶
lists all existing lambda functions including additional information like config and active version:
dp-dev-store-redshift-create-cdn-tables
Memory: 128
Timeout: 180
Role: arn:aws:iam::644239850139:role/lambda/dp-dev-store-redshift-cdn-LambdaCdnRedshiftTableCr-G7ME657RXFDB
Current Version: $LATEST
Last Modified: 2016-04-26T18:03:44.705+0000
CodeSha256: KY0Xk+g/Gt69V0siRhgaG7zWbg234dmb2hoz0NHIa3A=
metrics¶
displays metric for a given lambda:
dp-dev-ingest-lambda-cdnnorm
Duration 488872443
Errors 642
Invocations 5202
Throttles 13
wire¶
“wires” the AWS Lambda function to an event source.
unwire¶
delets the event configuration for the lambda function
delete¶
deletes a lambda function
If you use the --delete-logs
the cloudwatch log group associated to the AWS Lambda function is deleted including log entries, too. This helps to save cost for items used in testing.
rollback¶
sets the active version to ACTIVE -1 or to a given version
invoke¶
In this section, you invoke your Lambda function manually using the lambda invoke
command.
$ lambda invoke my_hello_world \
--invocation-type RequestResponse \
--payload '{"key1":"value1", "key2":"value2", "key3":"value3"}'
If you want you can save the payload to a file (for example, input.txt) and provide the file name as a parameter:
$ lambda invoke my_hello_world \
--invocation-type RequestResponse \
--payload file://input.txt
The preceding invoke command specifies RequestResponse as the invocation type, which returns a response immediately in response to the function execution. Alternatively, you can specify Event as the invocation type to invoke the function asynchronously.
logs¶
The lambda logs
command provides you with convenient access to log events emitted by your AWS Lambda function.
The command offers ‘–start’ and ‘–end’ options where you can filter the log events to your specification. You can use human readable dates like ‘2017-07-24 14:00:00’ or you can specify dates in the past relative to now
using ‘1m’, ‘2h’, ‘3d’, ‘5w’, etc.
$ lambda logs ops-dev-captain-crunch-slack-notifier --start=1d
MoinMoin fin0007m!
2017-07-07
07:00:32 START RequestId: f75cd7de-62e1-11e7-937d-ef5726c6f5c8 Version: $LATEST
07:00:36 END RequestId: f75cd7de-62e1-11e7-937d-ef5726c6f5c8
07:00:36 REPORT RequestId: f75cd7de-62e1-11e7-937d-ef5726c6f5c8 Duration: 4221.50 ms Billed Duration: 4300 ms Memory Size: 128 MB Max Memory Used: 43 MB
Bye fin0007m. Talk to you soon!
The ‘–start’ option has a default of ‘1d’. This means if you run lambda logs <your-function-name>
you get the log output of your function for the last 24 hours.
$ lambda logs ops-dev-captain-crunch-slack-notifier
MoinMoin fin0007m!
2017-07-07
07:00:32 START RequestId: f75cd7de-62e1-11e7-937d-ef5726c6f5c8 Version: $LATEST
07:00:36 END RequestId: f75cd7de-62e1-11e7-937d-ef5726c6f5c8
07:00:36 REPORT RequestId: f75cd7de-62e1-11e7-937d-ef5726c6f5c8 Duration: 4221.50 ms Billed Duration: 4300 ms Memory Size: 128 MB Max Memory Used: 43 MB
Bye fin0007m. Talk to you soon!
You can use lambda logs
to tail the log output of your lambda function. The default start date in tail mode is 5 minutes before. You can specify any past start date in tail mode but you can not specify an ‘–end’ option in tail mode. To exit the lambda logs
tail mode use Ctrl-C
.
$ lambda logs ops-dev-captain-crunch-slack-notifier --start=1d --tail
MoinMoin fin0007m!
Use 'Ctrl-C' to exit tail mode
2017-07-07
07:00:32 START RequestId: f75cd7de-62e1-11e7-937d-ef5726c6f5c8 Version: $LATEST
07:00:36 END RequestId: f75cd7de-62e1-11e7-937d-ef5726c6f5c8
07:00:36 REPORT RequestId: f75cd7de-62e1-11e7-937d-ef5726c6f5c8 Duration: 4221.50 ms Billed Duration: 4300 ms Memory Size: 128 MB Max Memory Used: 43 MB
^CReceived SIGINT signal - exiting command 'lambda logs'
version¶
will print the version of fink you are using
Folder Layout¶
Sample config file¶
sample fink_dev.json file:
{
"lambda": {
"lambda": {
"name": "dp-dev-store-redshift-load",
"description": "Lambda function which loads normalized files into redshift",
"role": "arn:aws:iam::644239850139:role/lambda/dp-dev-store-redshift-cdn-lo-LambdaCdnRedshiftLoad-DD2S84CZFGT4",
"handlerFunction": "handler.lambda_handler",
"handlerFile": "handler.py",
"timeout": "180",
"memorySize": "128",
"events": [
{
"event_source": {
"arn": "arn:aws:s3:::my-bucket",
"events": ["s3:ObjectCreated:*"]
}
},
{
"event_source": {
"name": "send_reminder_to_slack",
"schedule": "rate(1 minute)"
}
}
],
"vpc": {
"subnetIds": [
"subnet-87685dde",
"subnet-9f39ccfb",
"subnet-166d7061"
],
"securityGroups": [
"sg-ae6850ca"
]
}
},
"bundling": {
"zip": "bundle.zip",
"preBundle": [
"../bin/first_script.sh",
"../bin/second_script.sh"
],
"folders": [
{
"source": "../redshiftcdnloader",
"target": "./redshiftcdnloader"
},
{
"source": "psycopg2-linux",
"target": "psycopg2"
}
]
},
"deployment": {
"region": "eu-west-1",
"artifactBucket": "7finity-$PROJECT-deployment"
}
}
}
lambda configuration as part of the fink_<env>.json file¶
log retention¶
Possible values for the log retention in days are: 1, 3, 5, 7, 14, 30, 60, 90, 120, 150, 180, 365, 400, 545, 731, 1827, and 3653.
{
"lambda": {
...
"logs": {
"retentionInDays": 90
}
}
S3 upload¶
lambda can upload your lambda functions to S3 instead of inline through the API.
To enable this feature add this to the “lambda” section of your fink_<env>.json
config file:
"deployment": {
"region": "eu-west-1",
"artifactBucket": "7finity-$PROJECT-deployment"
}
You can get the name of the bucket from Ops and it should be part of the stack outputs of the base stack in your account (s3DeploymentBucket).
runtime support¶
fink supports the nodejs4.3
, nodejs6.10
, python2.7
, python3.6
runtimes.
Add the runtime config to the lambda
section of your fink configuration.
"runtime": "nodejs4.3"
At this point the following features are implemented:
- install dependencies before bundling (dependencies are defined in package.json)
- bundling (bundle the lambda function code and dependencies)
- deployment (the nodejs4.3 lambda function is setup with the nodejs4.3 runtime)
- configuration (bundles
settings_<env>.conf
file for your environments) - nodejs support is tested by our automated fink testsuite
- if no runtime is defined fink uses the default runtime
python2.7
Note: for this to work you need to have npm installed on the machine you want to run the lambda bundling!
AWS Lambda environment variables¶
Ramuda supports AWS Lambda environment variables. You can specify them within the lambda
section.
...
"environment": {
"MYVALUE": "FOO"
}
More information you can find in AWS docs.
Adding a settings.json file¶
Ramuda supports a settings section. If used a settings.json
file is added to the zip bundle. You can specify the settings within the lambda
section.
...
"settings": {
"MYVALUE": "FOO"
}
You can use lookups like for the rest of the configuration. Note that the values are looked up BEFORE the AWS Lambda function is deployed. If values change during the AWS Lambda function lifecycle it does not recognise the changes. For values that must be updated you should lookup the values in your code using for example credstash.
...
"settings": {
"accountId": "lookup:stack:infra-dev:AWSAccountId"
}
Adding event configuration¶
fink can be used to easily schedule functions to occur on regular intervals. Just list your expressions to schedule them using cron or rate syntax in your fink_<env>.json config file like this:
...
"events": [{
"event_source": {
"name": "send_reminder_to_slack",
"schedule": "rate(1 minute)"
}
}]
The schedule expression defines when to execute your lambda function in cron or rate format.
Similarly, you can have your functions execute in response to events that happen in the AWS ecosystem, such as S3 uploads, Kinesis streams, and SNS messages, etc..
In your fink_<env>.json config file, define your event sources. The following sample config will execute your AWS Lambda function in response to new objects in your my-bucket S3 bucket. Note that your function must accept event and context parameters.
...
"events": [{
"event_source": {
"arn": "arn:aws:s3:::my-bucket",
"events": ["s3:ObjectCreated:*"],
"suffix": ".jpg"
}
}],
Similarly, for a Simple Notification Service (SNS) event:
...
"events": [{
"event_source": {
"arn": "arn:aws:sns:::your-event-topic-arn",
"events": ["sns:Publish"]
}
}]
Kinesis is slightly different as it is not event-based but pulling from a stream:
...
"events": [{
"event_source": {
"arn": arn:aws:kinesis:eu-west-1:1234554:stream/your_stream"
"starting_position": "TRIM_HORIZON",
"batch_size": 50,
"enabled": true
}
}]
Lambda@Edge needs a CloudFront event trigger.
...
"events": [{
"event_source": {
"arn": "arn:aws:cloudfront::420189626185:distribution/E1V934UN4EJGJA",
"cache_behavior": "*",
"cloudfront_event": "origin-request"
}
}]
Deploying AWS Lambda@Edge¶
AWS Lambda@Edge is relatively new so we have to deal with some (hopefully temporary) limitations (like it is only available in Virginia):
- AWS Lambda@Edge functions must be deployed to ‘us-east-1’ region
- can not use artifact bucket for upload
- max memory use 128 MB
- max timeout 3 seconds for ‘origin request’ and ‘origin response’ events; for ‘viewer request’ and ‘viewer response’ events timeout is 1 second
- lambda@edge does not implement ALIAS or $LATEST so we use the version-nbr of the last published version of the lambda function for wiring
- unwire removes the lambda trigger for the configured CloudFront distribution (regardless if the lambda function is the same as the configured one or not)
- ‘lambda wire’ and ‘lambda unwire’ finish after initiation of the replication to CloudFront. This means CloudFront distribution is in ‘Pending’ state when fink.lambda exits.
- you cannot delete lambda functions that have been replicated to CloudFront edge locations
Setting the ENV variable¶
You you need to set an environment variable “ENV” which indicates the account/staging area you want to work with. This parameter tells the tools which config file to use. For example if you want to set the environment variable ENV to ‘DEV’ you can do that as follows:
export ENV=DEV
Environment specific configuration for your lambda functions¶
Please put the environment specific configuration for your lambda function into a fink_<env>.json
file. For most teams a useful convention would be to maintain at least ‘dev’, ‘qa’, and ‘prod’ envs.
Defining dependencies for your NodeJs lambda function¶
A sample package.json
file to that defines a dependency to the 1337
npm module:
{
"name": "my-sample-lambda",
"version": "0.0.1",
"description": "A very simple lambda function",
"main": "index.js",
"dependencies": {
"1337": "^1.0.0"
}
}
Sample NodeJs lambda function¶
From using lambda extensively we find it a good practise to implement the ping
feature. With the ping ramdua
automatically checks if your code is running fine on AWS.
Please consider to implement a ping
in your own lambda functions:
var l33t = require('1337')
exports.handler = function(event, context, callback) {
console.log( "event", event );
if (typeof(event.lambda_action) !== "undefined" && event.lambda_action == "ping") {
console.log("respond to ping event");
callback(null, "alive");
} else {
console.log(l33t('finklabs rocks!')); // 910m3x r0ck5!
callback(); // success
}
};