

End of support notice: On October 7th, 2026, AWS will discontinue support for AWS IoT Greengrass Version 1. After October 7th, 2026, you will no longer be able to access the AWS IoT Greengrass V1 resources. For more information, please visit [Migrate from AWS IoT Greengrass Version 1](https://docs.aws.amazon.com/greengrass/v2/developerguide/migrate-from-v1.html).

# Module 3 (part 2): Lambda functions on AWS IoT Greengrass
<a name="module3-II"></a>

This module explores the differences between on-demand and long-lived Lambda functions running on the AWS IoT Greengrass core.

Before you begin, run the [Greengrass Device Setup](quick-start.md) script or make sure you have completed [Module 1](module1.md), [Module 2](module2.md), and [Module 3 (Part 1)](module3-I.md).

This module should take about 30 minutes to complete.

**Topics**
+ [Create and package the Lambda function](package.md)
+ [Configure long-lived Lambda functions for AWS IoT Greengrass](long-lived.md)
+ [Test long-lived Lambda functions](long-testing.md)
+ [Test on-demand Lambda functions](on-demand.md)

# Create and package the Lambda function
<a name="package"></a>

In this step, you:
+ Create a Lambda function deployment package that contains the function code and dependencies.
+ Use the Lambda console to create a Lambda function and upload the deployment package.
+ Publish a version of the Lambda function and create an alias that points to the version.

 

1. On your computer, go to the AWS IoT Greengrass Core SDK for Python that you downloaded and extracted in [Create and package a Lambda function](create-lambda.md) in Module 3-1.

   The Lambda function in this module uses:
   + The `greengrassHelloWorldCounter.py` file in `examples\HelloWorldCounter`. This is your Lambda function code.
   + The `greengrasssdk` folder. This is the SDK.

1. Create a Lambda function deployment package:

   1. Copy the `greengrasssdk` folder into the `HelloWorldCounter` folder that contains `greengrassHelloWorldCounter.py`.

   1. Save `greengrassHelloWorldCounter.py` and the `greengrasssdk` folder to a `zip` file named `hello_world_counter_python_lambda.zip`. The `py` file and `greengrasssdk` folder must be in the root of the directory.  
![\[Screenshot showing zipped contents of hello_word_counter_python_lambda.zip.\]](http://docs.aws.amazon.com/greengrass/v1/developerguide/images/gg-get-started-046.png)

      On UNIX-like systems (including the Mac terminal) that have `zip` installed, you can use the following command to package the file and folder:

      ```
      zip -r hello_world_counter_python_lambda.zip greengrasssdk greengrassHelloWorldCounter.py
      ```

   Now you're ready to create your Lambda function and upload the deployment package.

1. Open the Lambda console and choose **Create function**.

1. Choose **Author from scratch**.

1. Name your function **Greengrass\$1HelloWorld\$1Counter**, and set the remaining fields as follows:
   + For **Runtime**, choose **Python 3.7**.
   + For **Permissions**, keep the default setting. This creates an execution role that grants basic Lambda permissions. This role isn't used by AWS IoT Greengrass. Or, you can reuse the role that you created in Module 3-1.

   Choose **Create function**.  
![\[The "Basic information" section with the "Function name" field set to "Greengrass_HelloWorld_Counter" and the "Runtime" field set to "Python 3.7".\]](http://docs.aws.amazon.com/greengrass/v1/developerguide/images/gg-get-started-023-3.png)

1. Upload your Lambda function deployment package.

   1. <a name="lambda-console-upload"></a>On the **Code** tab, under **Code source**, choose **Upload from**. From the dropdown, choose **.zip file**.  
![\[The Upload from dropdown with .zip file highlighted.\]](http://docs.aws.amazon.com/greengrass/v1/developerguide/images/lra-console/upload-deployment-package.png)

   1. Choose **Upload**, and then choose your `hello_world_counter_python_lambda.zip` deployment package. Then, choose **Save**. 

   1. <a name="lambda-console-runtime-settings-para"></a>On the **Code** tab for the function, under **Runtime settings**, choose **Edit**, and then enter the following values.
      + For **Runtime**, choose **Python 3.7**.
      + For **Handler**, enter **greengrassHelloWorldCounter.function\$1handler**

   1. <a name="lambda-console-save-config"></a>Choose **Save**.
**Note**  
The **Test** button on the AWS Lambda console doesn't work with this function. The AWS IoT Greengrass Core SDK doesn't contain modules that are required to run your Greengrass Lambda functions independently in the AWS Lambda console. These modules (for example, `greengrass_common`) are supplied to the functions after they are deployed to your Greengrass core.

1. Publish the first version of the function.

   1. From the **Actions** menu at the top of the page, choose **Publish new version**. For **Version description**, enter **First version**.

   1. Choose **Publish**.

1. Create an alias for the function version.

   1. From the **Actions** menu at the top of the page, choose **Create alias**.  
![\[Screenshot of the Actions menu set to Create alias.\]](http://docs.aws.amazon.com/greengrass/v1/developerguide/images/gg-get-started-028.png)

   1. For **Name**, enter **GG\$1HW\$1Counter**.

   1. For **Version**, choose **1**.

   1. Choose **Save**.  
![\[Create alias screenshot with the Name field set to GG_HW_Counter and the Version field set to 1.\]](http://docs.aws.amazon.com/greengrass/v1/developerguide/images/gg-get-started-048.png)

   Aliases create a single entity for your Lambda function that Greengrass devices can subscribe to. This way, you don't have to update subscriptions with new Lambda function version numbers every time the function is modified.

# Configure long-lived Lambda functions for AWS IoT Greengrass
<a name="long-lived"></a>

You are now ready to configure your Lambda function for AWS IoT Greengrass.

1. <a name="console-gg-groups"></a>In the AWS IoT console navigation pane, under **Manage**, expand **Greengrass devices**, and then choose **Groups (V1)**.

1. Under **Greengrass groups**, choose the group that you created in [Module 2](module2.md).

1. On the group configuration page, choose the **Lambda functions** tab, and then under **My Lambda functions**, choose **Add**.

1. For **Lambda function**, choose **Greengrass\$1HelloWorld\$1Counter**.

1. For **Lambda function version**, choose the alias to the version that you published.

1. For **Timeout (seconds)**, enter **25**. This Lambda function sleeps for 20 seconds before each invocation.

1. For **Pinned**, choose **True**.

1. Keep the default values for all other fields, and choose **Add Lambda function**.

# Test long-lived Lambda functions
<a name="long-testing"></a>

A *[long-lived](lambda-functions.md#lambda-lifecycle)* Lambda function starts automatically when the AWS IoT Greengrass core starts and runs in a single container (or sandbox). Any variables and preprocessing logic defined outside of the function handler are retained for every invocation of the function handler. Multiple invocations of the function handler are queued until earlier invocations have been executed.

 The `greengrassHelloWorldCounter.py` code used in this module defines a `my_counter` variable outside of the function handler.

**Note**  
You can view the code in the AWS Lambda console or in the [AWS IoT Greengrass Core SDK for Python](https://github.com/aws/aws-greengrass-core-sdk-python/blob/master/examples/HelloWorldCounter/greengrassHelloWorldCounter.py) on GitHub.

In this step, you create subscriptions that allow the Lambda function and AWS IoT to exchange MQTT messages. Then you deploy the group and test the function.

1. On the group configuration page, choose **Subscriptions**, and then choose **Add**.

1. Under **Source type**, choose **Lambda function**, and then choose **Greengrass\$1HelloWorld\$1Counter**.

1. Under **Target type**, choose **Service**, choose **IoT Cloud**.

1. For **Topic filter**, enter **hello/world/counter**.

1. Choose **Create subscription**.

   This single subscription goes in one direction only: from the `Greengrass_HelloWorld_Counter` Lambda function to AWS IoT. To invoke (or trigger) this Lambda function from the cloud, you must create a subscription in the opposite direction.

1. Follow steps 1 - 5 to add another subscription that uses the following values. This subscription allows the Lambda function to receive messages from AWS IoT. You use this subscription when you send a message from the AWS IoT console that invokes the function.
   + For the source, choose **Service**, and then choose **IoT Cloud**.
   + For the target, choose **Lambda function**, and then choose **Greengrass\$1HelloWorld\$1Counter**.
   + For the topic filter, enter **hello/world/counter/trigger**.

   The `/trigger` extension is used in this topic filter because you created two subscriptions and don't want them to interfere with each other.

1. Make sure that the Greengrass daemon is running, as described in [Deploy cloud configurations to a core device](configs-core.md).

1. <a name="console-actions-deploy"></a>On the group configuration page, choose **Deploy**.

1. <a name="console-test-after-deploy"></a>After your deployment is complete, return to the AWS IoT console home page and choose **Test**.

1. Configure the following fields:
   + For **Subscription topic**, enter **hello/world/counter**.
   + For **Quality of Service**, choose **0**.
   + For **MQTT payload display**, choose **Display payloads as strings**.

1. Choose **Subscribe**.

   Unlike [Part 1](module3-I.md) of this module, you shouldn't see any messages after you subscribe to `hello/world/counter`. This is because the `greengrassHelloWorldCounter.py` code that publishes to the `hello/world/counter` topic is inside the function handler, which runs only when the function is invoked.

   In this module, you configured the `Greengrass_HelloWorld_Counter` Lambda function to be invoked when it receives an MQTT message on the `hello/world/counter/trigger` topic.

   The **Greengrass\$1HelloWorld\$1Counter** to **IoT Cloud** subscription allows the function to send messages to AWS IoT on the `hello/world/counter` topic. The **IoT Cloud** to **Greengrass\$1HelloWorld\$1Counter** subscription allows AWS IoT to send messages to the function on the `hello/world/counter/trigger` topic.

1. To test the long-lived lifecycle, invoke the Lambda function by publishing a message to the `hello/world/counter/trigger` topic. You can use the default message.  
![\[Default Hello from AWS IoT console message sent to hello/world/counter/trigger with the Publish to topic button highlighted.\]](http://docs.aws.amazon.com/greengrass/v1/developerguide/images/gg-get-started-057.png)
**Note**  
 The `Greengrass_HelloWorld_Counter` function ignores the content of received messages. It just runs the code in `function_handler`, which sends a message to the `hello/world/counter` topic. You can review this code from the [AWS IoT Greengrass Core SDK for Python](https://github.com/aws/aws-greengrass-core-sdk-python/blob/master/examples/HelloWorldCounter/greengrassHelloWorldCounter.py) on GitHub.

Every time a message is published to the `hello/world/counter/trigger` topic, the `my_counter` variable is incremented. This invocation count is shown in the messages sent from the Lambda function. Because the function handler includes a 20-second sleep cycle (`time.sleep(20)`), repeatedly triggering the handler queues up responses from the AWS IoT Greengrass core.

![\[Screenshot showing the incrementing of Invocation Count from 1, 2, and 3.\]](http://docs.aws.amazon.com/greengrass/v1/developerguide/images/gg-get-started-058.png)


# Test on-demand Lambda functions
<a name="on-demand"></a>

An *[on-demand](lambda-functions.md#lambda-lifecycle)* Lambda function is similar in functionality to a cloud-based AWS Lambda function. Multiple invocations of an on-demand Lambda function can run in parallel. An invocation of the Lambda function creates a separate container to process invocations or reuses an existing container, if resources permit. Any variables or preprocessing that are defined outside of the function handler are not retained when containers are created.

1. On the group configuration page, choose the **Lambda functions** tab.

1. Under **My Lambda functions**, choose the **Greengrass\$1HelloWorld\$1Counter** Lambda function.

1. On the **Greengrass\$1HelloWorld\$1Counter** details page, choose **Edit**.

1. For **Pinned**, choose **False**, and then choose **Save**.

1. <a name="console-actions-deploy"></a>On the group configuration page, choose **Deploy**.

1. <a name="console-test-after-deploy"></a>After your deployment is complete, return to the AWS IoT console home page and choose **Test**.

1. Configure the following fields:
   + For **Subscription topic**, enter **hello/world/counter**.
   + For **Quality of Service**, choose **0**.
   + For **MQTT payload display**, choose **Display payloads as strings**.  
![\[Screenshot of Subscriptions test page.\]](http://docs.aws.amazon.com/greengrass/v1/developerguide/images/gg-get-started-056.png)

1. Choose **Subscribe**.
**Note**  
You should not see any messages after you subscribe.

1. To test the on-demand lifecycle, invoke the function by publishing a message to the `hello/world/counter/trigger` topic. You can use the default message.

   1. Choose **Publish** three times quickly, within five seconds of each press of the button.  
![\[Screenshot showing the Publish to topic button, which must be clicked rapidly three times.\]](http://docs.aws.amazon.com/greengrass/v1/developerguide/images/gg-get-started-063.png)

      Each publish invokes the function handler and creates a container for each invocation. The invocation count is not incremented for the three times you triggered the function because each on-demand Lambda function has its own container/sandbox.  
![\[Screenshot showing Invocation Count fixed at 1.\]](http://docs.aws.amazon.com/greengrass/v1/developerguide/images/gg-get-started-064.png)

   1. After approximately 30 seconds, choose **Publish to topic**. The invocation count should be incremented to 2. This shows that a container created from an earlier invocation is being reused, and that preprocessing variables outside of the function handler were stored.  
![\[Screenshot showing Invocation Count now at 2.\]](http://docs.aws.amazon.com/greengrass/v1/developerguide/images/gg-get-started-065.png)

You should now understand the two types of Lambda functions that can run on the AWS IoT Greengrass core. The next module, [Module 4](module4.md), shows you how local IoT devices can interact in an AWS IoT Greengrass group.