AWS Greengrass – Run AWS Lambda Functions on Connected Devices
I first told you about AWS IoT Greengrass in the post that I published during re:Invent (AWS Greengrass – Ubiquitous Real-World Computing). We launched a limited preview of IoT Greengrass at that time and invited you to sign up if you were interested.
As I noted at the time, many AWS customers want to collect and process data out in the field, where connectivity is often slow and sometimes either intermittent or unreliable. IoT Greengrass allows them to extend the AWS programming model to small, simple, field-based devices. It builds on AWS IoT Core and AWS Lambda, and supports access to the ever-increasing variety of services that are available in the AWS Cloud.
IoT Greengrass gives you access to compute, messaging, data caching, and syncing services that run in the field, and that do not depend on constant, high-bandwidth connectivity to an AWS Region. You can write Lambda functions in Python 2.7 and deploy them to your Greengrass devices from the cloud while using device shadows to maintain state. Your devices and peripherals can talk to each other using local messaging that does not pass through the cloud.
Now Generally Available
Today we are making IoT Greengrass generally available in the US East (N. Virginia) and US West (Oregon) Regions. During the preview, AWS customers were able to get hands-on experience with IoT Greengrass and to start building applications and businesses around it. I’ll share a few of these early successes later in this post.
The Greengrass Core code runs on each device. It allows you to deploy and run Lambda applications on the device, supports local MQTT messaging across a secure network, and also ensures that conversations between devices and the cloud are made across secure connections. The Greengrass Core also supports secure, over-the-air software updates, including Lambda functions. It includes a message broker, a Lambda runtime, a Thing Shadows implementation, and a deployment agent. Greengrass Core and (optionally) other devices make up a Greengrass Group. The group includes configuration data, the list of devices and the identity of the Greengrass Core, a list of Lambda functions, and a set of subscriptions that define where the messages should go. All of this information is copied to the Greengrass core devices during the deployment process.
Your Lambda functions can use APIs in three distinct SDKs:
AWS IoT Device SDK – This SDK (available for Node.js, Python, Java, and C++) helps you to connect your hardware devices to AWS IoT. The C++ SDK has a few extra features including access to the Greengrass Discovery Service and support for root CA downloads.
AWS Greengrass Core SDK – This SDK provides APIs that allow local invocation of other Lambda functions, publish messages, and work with thing shadows.
You can run the Greengrass Core on x86 and ARM devices that have version 4.4.11 (or newer) of the Linux kernel, with the OverlayFS and user namespace features enabled. While most deployments of Greengrass will be targeted at specialized, industrial-grade hardware, you can also run the Greengrass Core on a Raspberry Pi or an EC2 instance for development and test purposes.
For this post, I used a Raspberry Pi attached to a BrickPi, connected to my home network via WiFi:
The Raspberry Pi, the BrickPi, the case, and all of the other parts are available in the BrickPi 3 Starter Kit. You will need some Linux command-line expertise and a decent amount of manual dexterity to put all of this together, but if I did it then you surely can.
Greengrass in Action
I can access Greengrass from the Console, API, or CLI. I’ll use the Console. The intro page of the Greengrass Console lets me define groups, add Greengrass Cores, and add devices to my groups:
I click on Get Started and then on Use easy creation:
Then I name my group:
And name my first Greengrass Core:
I’m ready to go, so I click on Create Group and Core:
This runs for a few seconds and then offers up my security resources (two keys and a certificate) for downloading, along with the Greengrass Core:
I download the security resources and put them in a safe place, and select and download the desired version of the Greengrass Core software (ARMv7l for my Raspberry Pi), and click on Finish.
Now I power up my Pi, and copy the security resources and the software to it (I put them in an S3 bucket and pulled them down with
wget). Here’s my shell history at that point:
Important Update: As one of my sharp-eyed colleagues on the AWS Security team pointed out, this is not a good way to distribute the secrets to the devices. I could have used the AWS CLI to download them from a encrypted bucket, copied them via cut and paste, or used a USB key.
Following the directions in the user guide, I create a new user and group, run the
rpi-update script, and install several packages including
openssl. After a couple of reboots, I am ready to proceed!
Next, still following the directions, I untar the Greengrass Core software and move the security resources to their final destination (
/greengrass/configuration/certs), giving them generic names along the way. Here’s what the directory looks like:
The next step is to associate the core with an AWS IoT thing. I return to the Console, click through the group and the Greengrass Core, and find the Thing ARN:
I insert the names of the certificates and the Thing ARN into the
config.json file, and also fill in the missing sections of the
I start the Greengrass demon (this was my second attempt; I had a typo in one of my path names the first time around):
After all of this pleasant time at the command line (taking me back to my Unix v7 and BSD 4.2 days), it is time to go visual once again! I visit my AWS IoT dashboard and see that my Greengrass Core is making connections to IoT:
I go to the Lambda Console and create a Lambda function using the Python 2.7 runtime (the IAM role does not matter here):
I publish the function in the usual way and, hop over to the Greengrass Console, click on my group, and choose to add a Lambda function:
Then I choose the version to deploy:
I also configure the function to be long-lived instead of on-demand:
My code will publish messages to AWS IoT, so I create a subscription by specifying the source and destination:
I set up a topic filter (hello/world) on the subscription as well:
I confirm my settings and save my subscription and I am just about ready to deploy my code. I revisit my group, click on Deployments, and choose Deploy from the Actions menu:
I choose Automatic detection to move forward:
Since this is my first deployment, I need to create a service-level role that gives Greengrass permission to access other AWS services. I simply click on Grant permission:
I can see the status of each deployment:
The code is now running on my Pi! It publishes messages to topic hello/world; I can see them by going to the IoT Console, clicking on Test, and subscribing to the topic:
And here are the messages:
With all of the setup work taken care of, I can do iterative development by uploading, publishing, and deploying new versions of my code. I plan to use the BrickPi to control some LEGO Technic motors and to publish data collected from some sensors. Stay tuned for that post!
You can run the Greengrass Core on three devices free for one year as part of the AWS Free Tier. At the next level (3 to 10,000 devices) two options are available:
- Pay as You Go – $0.16 per month per device.
- Annual Commitment – $1.49 per year per device, a 17.5% savings.
If you want to run the Greengrass Core on more than 10,000 devices or make a longer commitment, please get in touch with us; details on all pricing models are on the Greengrass Pricing page.