

# Run AWS Lambda functions
<a name="run-lambda-functions"></a>

**Note**  
AWS IoT Greengrass doesn't currently support this feature on Windows core devices. 

You can import AWS Lambda functions as components that run on AWS IoT Greengrass core devices. You might want to do this in the following cases:
+ You have application code in Lambda functions that you want to deploy to core devices.
+ You have AWS IoT Greengrass V1 applications that you want to run on AWS IoT Greengrass V2 core devices. For more information, see [Step 2: Create and deploy AWS IoT Greengrass V2 components to migrate AWS IoT Greengrass V1 applications](set-up-v2-test-device.md#run-v1-applications).

Lambda functions include dependencies on the following components. You don't need to define these components as dependencies when you import the function. When you deploy the Lambda function component, the deployment includes these Lambda component dependencies.
+ The [Lambda launcher component](lambda-launcher-component.md) (`aws.greengrass.LambdaLauncher`) handles processes and environment configuration.
+ The [Lambda manager component](lambda-manager-component.md) (`aws.greengrass.LambdaManager`) handles interprocess communication and scaling.
+ The [Lambda runtimes component](lambda-runtimes-component.md) (`aws.greengrass.LambdaRuntimes`) provides artifacts for each supported Lambda runtime.

**Topics**
+ [

## Requirements
](#run-lambda-functions-requirements)
+ [

## Configure Lambda function lifecycle
](#lambda-lifecycle)
+ [

## Configure Lambda function containerization
](#lambda-containerization)
+ [

# Import a Lambda function as a component (console)
](import-lambda-function-console.md)
+ [

# Import a Lambda function as a component (AWS CLI)
](import-lambda-function-cli.md)

## Requirements
<a name="run-lambda-functions-requirements"></a>

Your core devices and Lambda functions must meet the following requirements for you to run the functions on the AWS IoT Greengrass Core software:
+ <a name="core-device-lambda-function-requirements"></a>Your core device must meet the requirements to run Lambda functions. If you want the core device to run containerized Lambda functions, the device must meet the requirements to do so. For more information, see [Lambda function requirements](setting-up.md#greengrass-v2-lambda-requirements).
+ You must install the programming languages that the Lambda function uses on your core devices.
**Tip**  
You can create a component that installs the programming language, and then specify that component as a dependency of your Lambda function component. Greengrass supports all Lambda supported versions of Python, Node.js, and Java runtimes. Greengrass doesn't apply any additional restrictions on deprecated Lambda runtime versions. You can run Lambda functions that use these deprecated runtimes on AWS IoT Greengrass, but you can't create them in AWS Lambda. For more information about AWS IoT Greengrass support for Lambda runtimes, see [Run AWS Lambda functions](#run-lambda-functions).

## Configure Lambda function lifecycle
<a name="lambda-lifecycle"></a>

The Greengrass Lambda function lifecycle determines when a function starts and how it creates and uses containers. The lifecycle also determines how the AWS IoT Greengrass Core software retains variables and preprocessing logic that are outside of the function handler.

AWS IoT Greengrass supports on-demand (default) and long-lived lifecycles:
+ **On-demand** functions start when they are invoked and stop when there are no tasks left to run. Each invocation of the function creates a separate container, also called a sandbox, to process invocations, unless an existing container is available for reuse. Any of the containers might process data that you send to the function.

  Multiple invocations of an on-demand function can run simultaneously.

  Variables and preprocessing logic that you define outside of the function handler are not retained when new containers are created.
+ **Long-lived** (or *pinned*) functions start when the AWS IoT Greengrass Core software starts and run in a single container. The same container processes all data that you send to the function.

  Multiple invocations are queued until the AWS IoT Greengrass Core software runs earlier invocations.

  Variables and preprocessing logic that you define outside of the function handler are retained for every invocation of the handler.

  Use long-lived Lambda functions when you need to start doing work without any initial input. For example, a long-lived function can load and start processing a machine learning model to be ready when the function receives device data.
**Note**  
Long-lived functions have timeouts that are associated with each invocation of their handler. If you want to invoke code that runs indefinitely, you must start it outside of the handler. Make sure that there's no blocking code outside of the handler that might prevent the function from initializing.  
These functions run unless the AWS IoT Greengrass Core software stops, such as during a deployment or reboot. These functions won't run if the function encounters an uncaught exception, exceeds its memory limits, or enters an error state, such as a handler timeout.

For more information about container reuse, see [Understanding Container Reuse in AWS Lambda](https://aws.amazon.com/blogs/compute/container-reuse-in-lambda/) in the *AWS Compute Blog*.

## Configure Lambda function containerization
<a name="lambda-containerization"></a>

By default, Lambda functions run inside of an AWS IoT Greengrass container. Greengrass containers provide isolation between your functions and the host. This isolation increases security for both the host and the functions in the container.

We recommend that you run Lambda functions in a Greengrass container, unless your use case requires them to run without containerization. By running your Lambda functions in a Greengrass container, you have more control over how you restrict access to resources.

You might run a Lambda function without containerization in the following cases:
+ You want to run AWS IoT Greengrass on a device that doesn't support container mode. An example would be if you wanted to use a special Linux distribution, or have an earlier kernel version that is out of date.
+ You want to run your Lambda function in another container environment with its own OverlayFS, but encounter OverlayFS conflicts when you run in a Greengrass container.
+ You need access to local resources with paths that can't be determined at deployment time, or whose paths can change after deployment. An example of this resource would be a pluggable device.
+ You have an earlier application that was written as a process, and you encounter issues when you run it in a Greengrass container.


**Containerization differences**  

| Containerization | Notes | 
| --- | --- | 
|  Greengrass container  |  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/greengrass/v2/developerguide/run-lambda-functions.html)  | 
|  No container  |  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/greengrass/v2/developerguide/run-lambda-functions.html)  | 

If you change the containerization for a Lambda function when you deploy it, the function might not work as expected. If the Lambda function uses local resources that are no longer available with the new containerization setting, deployment fails.
+ When you change a Lambda function from running in a Greengrass container to running without containerization, the function's memory limits are discarded. You must access the file system directly instead of using attached local resources. You must remove any attached resources before you deploy the Lambda function.
+ When you change a Lambda function from running without containerization to running in a container, your Lambda function loses direct access to the file system. You must define a memory limit for each function or accept the default 16 MB memory limit. You can configure these settings for each Lambda function when you deploy it.

To change containerization settings for a Lambda function component, set the value of the `containerMode` configuration parameter to one of the following options when you deploy the component.<a name="lambda-function-component-container-mode-parameter"></a>
+ `NoContainer` – The component doesn't run in an isolated runtime environment.
+ `GreengrassContainer` – The component runs in an isolated runtime environment inside the AWS IoT Greengrass container.

For more information about how to deploy and configure components, see [Deploy AWS IoT Greengrass components to devices](manage-deployments.md) and [Update component configurations](update-component-configurations.md).

# Import a Lambda function as a component (console)
<a name="import-lambda-function-console"></a>

When you use the [AWS IoT Greengrass console](https://console.aws.amazon.com/greengrass) to create a Lambda function component, you import an existing AWS Lambda function and then configure it to create a component that runs on your Greengrass device.

Before you begin, review the [requirements](https://docs.aws.amazon.com/greengrass/v2/developerguide/run-lambda-functions.html#run-lambda-functions-requirements) to run Lambda functions on Greengrass devices.

**Topics**
+ [

## Step 1: Choose a Lambda function to import
](#import-lambda-console-choose-function)
+ [

## Step 2: Configure Lambda function parameters
](#import-lambda-console-configure-function-parameters)
+ [

## Step 3: (Optional) Specify supported platforms for the Lambda function
](#import-lambda-console-configure-platforms)
+ [

## Step 4: (Optional) Specify component dependencies for the Lambda function
](#import-lambda-console-configure-dependencies)
+ [

## Step 5: (Optional) Run the Lambda function in a container
](#import-lambda-console-run-isolated)
+ [

## Step 6: Create the Lambda function component
](#import-lambda-console-create-deploy)

## Step 1: Choose a Lambda function to import
<a name="import-lambda-console-choose-function"></a>

1. In the [AWS IoT Greengrass console](https://console.aws.amazon.com/greengrass) navigation menu, choose **Components**.

1. On the **Components** page, choose **Create component**.

1. On the **Create component** page, under **Component information**, choose **Import Lambda function**.

1. In **Lambda function**, search for and choose the Lambda function that you want to import. 

   AWS IoT Greengrass creates the component with the name of the Lambda function.

1. In **Lambda function version**, choose the version to import. You can't choose Lambda aliases like `$LATEST`.

   AWS IoT Greengrass creates the component with the version of the Lambda function as a valid semantic version. For example, if your function version is `3`, the component version becomes `3.0.0`.

## Step 2: Configure Lambda function parameters
<a name="import-lambda-console-configure-function-parameters"></a>

On the **Create component** page, under **Lambda function configuration**, configure the following parameters to use to run the Lambda function.

1. (Optional) Add the list of event sources to which the Lambda function subscribes for work messages. You can specify event sources to subscribe this function to local publish/subscribe messages and AWS IoT Core MQTT messages. The Lambda function is called when it receives a message from an event source.
**Note**  
To subscribe this function to messages from other Lambda functions or components, deploy the [legacy subscription router component](legacy-subscription-router-component.md) when you deploy this Lambda function component. When you deploy the legacy subscription router component, specify the subscriptions that the Lambda function uses.

   Under **Event sources**, do the following to add an event source:

   1. For each event source that you add, specify the following options: 
      + **Topic** – The topic to subscribe for messages.
      + **Type** – The type of event source. Choose from the following options:
        + **Local publish/subscribe** – Subscribe to local publish/subscribe messages.

          If you use [Greengrass nucleus](greengrass-nucleus-component.md) v2.6.0 or later and [Lambda manager](lambda-manager-component.md) v2.2.5 or later, you can use MQTT topic wildcards (`+` and `#`) in the **Topic** when you specify this type.
        + **AWS IoT Core MQTT** – Subscribe to AWS IoT Core MQTT messages.

          You can use MQTT topic wildcards (`+` and `#`) in the **Topic** when you specify this type.

   1. To add another event source, choose **Add event source** and repeat the previous step. To remove an event source, choose **Remove** next to the event source that you want to remove.

1. For **Timeout (seconds)**, enter the maximum amount of time in seconds that a non-pinned Lambda function can run before it times out. The default is 3 seconds.

1. For **Pinned**, choose whether the Lambda function component is pinned. The default is **True**.<a name="lambda-function-lifecycle-type"></a>
   + A pinned (or long-lived) Lambda function starts when AWS IoT Greengrass starts and keeps running in its own container.
   + A non-pinned (or on-demand) Lambda function starts only when it receives a work item and exits after it remains idle for a specified maximum idle time. If the function has multiple work items, the AWS IoT Greengrass Core software creates multiple instances of the function.

1. (Optional) Under **Additional parameters**, set the following Lambda function parameters.
   + **Status timeout (seconds)** – The interval in seconds at which the Lambda function component sends status updates to the Lambda manager component. This parameter applies only to pinned functions. The default is 60 seconds.
   + **Maximum queue size** – The maximum size of the message queue for the Lambda function component. The AWS IoT Greengrass Core software stores messages in a FIFO (first-in, first-out) queue until it can run the Lambda function to consume each message. The default is 1,000 messages.
   + **Maximum number of instances** – The maximum number of instances that a non-pinned Lambda function can run at the same time. The default is 100 instances.
   + **Maximum idle time (seconds)** – The maximum amount of time in seconds that a non-pinned Lambda function can idle before the AWS IoT Greengrass Core software stops its process. The default is 60 seconds.
   + **Encoding type** – The type of payload that the Lambda function supports. Choose from the following options:
     + **JSON**
     + **Binary**

     The default is JSON.

1. (Optional) Specify the list of command line arguments to pass to the Lambda function when it runs. 

   1. Under **Additional parameters, Process arguments**, choose **Add argument**.

   1. For each argument that you add, enter the argument that you want to pass to the function.

   1. To remove an argument, choose **Remove** next to the argument that you want to remove.

1. (Optional) Specify the environment variables that are available to the Lambda function when it runs. Environment variables enable you to store and update configuration settings without the need to change function code.

   1. Under **Additional parameters, Environment variables**, choose **Add environment variable**.

   1. For each environment variable that you add, specify the following options:
      + **Key** – The variable name.
      + **Value** – The default value for this variable.

   1. To remove an environment variable, choose **Remove** next to the environment variable that you want to remove.

## Step 3: (Optional) Specify supported platforms for the Lambda function
<a name="import-lambda-console-configure-platforms"></a>

All core devices have attributes for operating system and architecture. When you deploy the Lambda function component, the AWS IoT Greengrass Core software compares the platform values that you specify with the platform attributes on the core device to determine whether the Lambda function is supported on that device. 

**Note**  
You can also specify custom platform attributes when you deploy the Greengrass nucleus component to a core device. For more information, see the [platform overrides parameter](greengrass-nucleus-component.md#greengrass-nucleus-component-configuration-platform-overrides) of the [Greengrass nucleus component](greengrass-nucleus-component.md). 

Under **Lambda function configuration, Additional parameters, Platforms**, do the following to specify the platforms that this Lambda function supports.

1. For each platform, specify the following options: 
   + **Operating system** – The name of the operating system for the platform. Currently, the only supported value is `linux`.
   + **Architecture** – The processor architecture for the platform. Supported values are:
     + `amd64`
     + `arm`
     + `aarch64`
     + `x86`

1. To add another platform, choose **Add platform** and repeat the previous step. To remove a supported platform, choose **Remove** next to the platform that you want to remove.

## Step 4: (Optional) Specify component dependencies for the Lambda function
<a name="import-lambda-console-configure-dependencies"></a>

Component dependencies identify additional AWS-provided components or custom components that your function uses. When you deploy the Lambda function component, the deployment includes these dependencies for your function to run.

**Important**  <a name="import-v1-lambda-note"></a>
To import a Lambda function that you created to run on AWS IoT Greengrass V1, you must define individual component dependencies for the features that your function uses, such as secrets, local shadows, and stream manager. Define these components as [hard dependencies](component-recipe-reference.md) so that your Lambda function component restarts if the dependency changes state. For more information, see [Import V1 Lambda functions](set-up-v2-test-device.md#run-v1-lambda-functions).

Under **Lambda function configuration, Additional parameters, Component dependencies**, complete the following steps to specify the component dependencies for your Lambda function.

1.  Choose **Add dependency**.

1. For each component dependency that you add, specify the following options: 
   + **Component name** – The component name. For example, enter **aws.greengrass.StreamManager** to include the [stream manager component](stream-manager-component.md).
   + **Version requirement** – The npm-style semantic version constraint that identifies the compatible versions of this component dependency. You can specify a single version or a range of versions. For example, enter **^1.0.0** to specify that this Lambda function depends on any version in the first major version of the stream manager component. For more information about semantic version constraints, see the [npm semver calculator](https://semver.npmjs.com/). 
   + **Type** – The type of dependency. Choose from the following options:
     + **Hard** – The Lambda function component restarts if the dependency changes state. This is the default selection.
     + **Soft** – The Lambda function component doesn't restart if the dependency changes state.

1. To remove a component dependency, choose **Remove** next to the component dependency

## Step 5: (Optional) Run the Lambda function in a container
<a name="import-lambda-console-run-isolated"></a>

By default, Lambda functions run in an isolated runtime environment inside the AWS IoT Greengrass Core software. You can also choose to run the Lambda function as a process without any isolation (that is, in **No container** mode). 

Under **Linux process configuration**, for **Isolation mode**, choose from the following options to select the containerization for your Lambda function:
+ **Greengrass container** – The Lambda function runs in a container. This is the default selection.
+ **No container** – The Lambda function runs as a process without any isolation.

If you run the Lambda function in a container, complete the following steps to configure the process configuration for the Lambda function. 

1. Configure the amount of memory and the system resources, such as volumes and devices, to make available to the container.

   Under **Container parameters**, do the following.

   1. For **Memory size**, enter the memory size that you want to allocate to the container. You can specify the memory size in **MB** or **kB**.

   1. For **Read-only sys folder**, choose whether or not the container can read information from the device's `/sys` folder. The default is **False**.

1. (Optional) Configure the local volumes that the containerized Lambda function can access. When you define a volume, the AWS IoT Greengrass Core software mounts the source files to the destination inside the container. 

   1. Under **Volumes**, choose **Add volume**. 

   1. For each volume that you add, specify the following options:
      + **Physical volume** – The path to the source folder on the core device.
      + **Logical volume** – The path to the destination folder in the container.
      + **Permission** – (Optional) The permission to access the source folder from the container. Choose from the following options:
        + **Read-only** – The Lambda function has read-only access to the source folder. This is the default selection.
        + **Read-write** – The Lambda function has read/write access to the source folder.
      + **Add group owner** – (Optional) Whether or not to add the system group that runs the Lambda function component as an owner of the source folder. The default is **False**.

   1. To remove a volume, choose **Remove** next to the volume that you want to remove.

1. (Optional) Configure the local system devices that the containerized Lambda function can access.

   1. Under **Devices**, choose **Add device**. 

   1. For each device that you add, specify the following options:
      + **Mount path** – The path to the system device on the core device.
      + **Permission** – (Optional) The permission to access the system device from the container. Choose from the following options:
        + **Read-only** – The Lambda function has read-only access to the system device. This is the default selection.
        + **Read-write** – The Lambda function has read/write access to the source folder.
      + **Add group owner** – (Optional) Whether or not to add the system group that runs the Lambda function component as an owner of the system device. The default is **False**.

## Step 6: Create the Lambda function component
<a name="import-lambda-console-create-deploy"></a>

After you configure settings for your Lambda function component, choose **Create** to finish creating the new component. 

To run the Lambda function on your core device, you can then deploy the new component to your core devices. For more information, see [Deploy AWS IoT Greengrass components to devices](manage-deployments.md).

# Import a Lambda function as a component (AWS CLI)
<a name="import-lambda-function-cli"></a>

Use the [CreateComponentVersion](https://docs.aws.amazon.com/greengrass/v2/APIReference/API_CreateComponentVersion.html) operation to create components from Lambda functions. When you call this operation, specify `lambdaFunction` to import a Lambda function. 

**Topics**
+ [

## Step 1: Define the Lambda function configuration
](#create-lambda-function-configuration-cli)
+ [

## Step 2: Create the Lambda function component
](#create-lambda-component-cli)

## Step 1: Define the Lambda function configuration
<a name="create-lambda-function-configuration-cli"></a>

1. Create a file called `lambda-function-component.json`, and then copy the following JSON object into the file. Replace the `lambdaArn` with the ARN of the Lambda function to import.

   ```
   {
     "lambdaFunction": {
       "lambdaArn": "arn:aws:lambda:region:account-id:function:HelloWorld:1"
     }
   }
   ```
**Important**  
You must specify an ARN that includes the version of the function to import. You can't use version aliases like `$LATEST`.

1. (Optional) Specify the name (`componentName`) of the component. If you omit this parameter, AWS IoT Greengrass creates the component with the name of the Lambda function.

   ```
   {
     "lambdaFunction": {
       "lambdaArn": "arn:aws:lambda:region:account-id:function:HelloWorld:1",
       "componentName": "com.example.HelloWorldLambda"
     }
   }
   ```

1. (Optional) Specify the version (`componentVersion`) for the component. If you omit this parameter, AWS IoT Greengrass creates the component with the version of the Lambda function as a valid semantic version. For example, if your function version is `3`, the component version becomes `3.0.0`.
**Note**  
<a name="component-version-uniqueness-para"></a>Each component version that you upload must be unique. Make sure that you upload the correct component version, because you can't edit it after you upload it.  
<a name="semver-para"></a>AWS IoT Greengrass uses semantic versions for components. Semantic versions follow a *major*.*minor*.*patch* number system. For example, version `1.0.0` represents the first major release for a component. For more information, see the [semantic version specification](https://semver.org/).

   ```
   {
     "lambdaFunction": {
       "lambdaArn": "arn:aws:lambda:region:account-id:function:HelloWorld:1",
       "componentName": "com.example.HelloWorldLambda",
       "componentVersion": "1.0.0"
     }
   }
   ```

1. (Optional) Specify the platforms that this Lambda function supports. Each platform contains a map of attributes that identify a platform. All core devices have attributes for operating system (`os`) and architecture (`architecture`). The AWS IoT Greengrass Core software may add other platform attributes. You can also specify custom platform attributes when you deploy the [Greengrass nucleus component](greengrass-nucleus-component.md) to a core device. Do the following:

   1. Add a list of platforms (`componentPlatforms`) to the Lambda function in `lambda-function-component.json`.

      ```
      {
        "lambdaFunction": {
          "lambdaArn": "arn:aws:lambda:region:account-id:function:HelloWorld:1",
          "componentName": "com.example.HelloWorldLambda",
          "componentVersion": "1.0.0",
          "componentPlatforms": [
          
          ]
        }
      }
      ```

   1. Add each supported platform to the list. Each platform has a friendly `name` to identify it and a map of attributes. The following example specifies that this function supports x86 devices that run Linux.

      ```
      {
        "name": "Linux x86",
        "attributes": {
          "os": "linux",
          "architecture": "x86"
        }
      }
      ```

      Your `lambda-function-component.json` might contain a document similar to the following example.

      ```
      {
        "lambdaFunction": {
          "lambdaArn": "arn:aws:lambda:region:account-id:function:HelloWorld:1",
          "componentName": "com.example.HelloWorldLambda",
          "componentVersion": "1.0.0",
          "componentPlatforms": [
            {
              "name": "Linux x86",
              "attributes": {
                "os": "linux",
                "architecture": "x86"
              }
            }
          ]
        }
      }
      ```

1. (Optional) Specify the component dependencies for your Lambda function. When you deploy the Lambda function component, the deployment includes these dependencies for your function to run.
**Important**  <a name="import-v1-lambda-note"></a>
To import a Lambda function that you created to run on AWS IoT Greengrass V1, you must define individual component dependencies for the features that your function uses, such as secrets, local shadows, and stream manager. Define these components as [hard dependencies](component-recipe-reference.md) so that your Lambda function component restarts if the dependency changes state. For more information, see [Import V1 Lambda functions](set-up-v2-test-device.md#run-v1-lambda-functions).

   Do the following:

   1. Add a map of component dependencies (`componentDependencies`) to the Lambda function in `lambda-function-component.json`.

      ```
      {
        "lambdaFunction": {
          "lambdaArn": "arn:aws:lambda:region:account-id:function:HelloWorld:1",
          "componentName": "com.example.HelloWorldLambda",
          "componentVersion": "1.0.0",
          "componentPlatforms": [
            {
              "name": "Linux x86",
              "attributes": {
                "os": "linux",
                "architecture": "x86"
              }
            }
          ],
          "componentDependencies": {
            
          }
        }
      }
      ```

   1. Add each component dependency to the map. Specify the component name as the key and specify an object with the following parameters:
      + `versionRequirement` – The npm-style semantic version constraint that identifies the compatible versions of the component dependency. You can specify a single version or a range of versions. For more information about semantic version constraints, see the [npm semver calculator](https://semver.npmjs.com/).
      + `dependencyType` – (Optional) The type of the dependency. Choose from the following:
        + `SOFT` – The Lambda function component doesn't restart if the dependency changes state.
        + `HARD` – The Lambda function component restarts if the dependency changes state.

        The default is `HARD`.

      The following example specifies that this Lambda function depends on any version in the first major version of the [stream manager component](stream-manager-component.md). The Lambda function component restarts when stream manager restarts or updates.

      ```
      {
        "aws.greengrass.StreamManager": {
          "versionRequirement": "^1.0.0",
          "dependencyType": "HARD"
        }
      }
      ```

      Your `lambda-function-component.json` might contain a document similar to the following example.

      ```
      {
        "lambdaFunction": {
          "lambdaArn": "arn:aws:lambda:region:account-id:function:HelloWorld:1",
          "componentName": "com.example.HelloWorldLambda",
          "componentVersion": "1.0.0",
          "componentPlatforms": [
            {
              "name": "Linux x86",
              "attributes": {
                "os": "linux",
                "architecture": "x86"
              }
            }
          ],
          "componentDependencies": {
            "aws.greengrass.StreamManager": {
              "versionRequirement": "^1.0.0",
              "dependencyType": "HARD"
            }
          }
        }
      }
      ```

1. (Optional) Configure the Lambda function parameters to use to run the function. You can configure options such environment variables, message event sources, timeouts, and container settings. Do the following:

   1. Add the Lambda parameters object (`componentLambdaParameters`) to the Lambda function in `lambda-function-component.json`.

      ```
      {
        "lambdaFunction": {
          "lambdaArn": "arn:aws:lambda:region:account-id:function:HelloWorld:1",
          "componentName": "com.example.HelloWorldLambda",
          "componentVersion": "1.0.0",
          "componentPlatforms": [
            {
              "name": "Linux x86",
              "attributes": {
                "os": "linux",
                "architecture": "x86"
              }
            }
          ],
          "componentDependencies": {
            "aws.greengrass.StreamManager": {
              "versionRequirement": "^1.0.0",
              "dependencyType": "HARD"
            }
          },
          "componentLambdaParameters": {
          
          }
        }
      }
      ```

   1. (Optional) Specify the event sources to which the Lambda function subscribes for work messages. You can specify event sources to subscribe this function to local publish/subscribe messages and AWS IoT Core MQTT messages. The Lambda function is called when it receives a message from an event source.
**Note**  
To subscribe this function to messages from other Lambda functions or components, deploy the [legacy subscription router component](legacy-subscription-router-component.md) when you deploy this Lambda function component. When you deploy the legacy subscription router component, specify the subscriptions that the Lambda function uses.

      Do the following:

      1. Add the list of event sources (`eventSources`) to the Lambda function parameters.

         ```
         {
           "lambdaFunction": {
             "lambdaArn": "arn:aws:lambda:region:account-id:function:HelloWorld:1",
             "componentName": "com.example.HelloWorldLambda",
             "componentVersion": "1.0.0",
             "componentPlatforms": [
               {
                 "name": "Linux x86",
                 "attributes": {
                   "os": "linux",
                   "architecture": "x86"
                 }
               }
             ],
             "componentDependencies": {
               "aws.greengrass.StreamManager": {
                 "versionRequirement": "^1.0.0",
                 "dependencyType": "HARD"
               }
             },
             "componentLambdaParameters": {
               "eventSources": [
               
               ]
             }
           }
         }
         ```

      1. Add each event source to the list. Each event source has the following parameters:
         + `topic` – The topic to subscribe for messages.
         + `type` – The type of event source. Choose from the following options:
           + `PUB_SUB` – Subscribe to local publish/subscribe messages.

             If you use [Greengrass nucleus](greengrass-nucleus-component.md) v2.6.0 or later and [Lambda manager](lambda-manager-component.md) v2.2.5 or later, you can use MQTT topic wildcards (`+` and `#`) in the `topic` when you specify this type.
           + `IOT_CORE` – Subscribe to AWS IoT Core MQTT messages.

             You can use MQTT topic wildcards (`+` and `#`) in the `topic` when you specify this type.

           The following example subscribes to AWS IoT Core MQTT on topics that match the `hello/world/+` topic filter.

           ```
           {
             "topic": "hello/world/+",
             "type": "IOT_CORE"
           }
           ```

           Your `lambda-function-component.json` might look similar to the following example.

           ```
           {
             "lambdaFunction": {
               "lambdaArn": "arn:aws:lambda:region:account-id:function:HelloWorld:1",
               "componentName": "com.example.HelloWorldLambda",
               "componentVersion": "1.0.0",
               "componentPlatforms": [
                 {
                   "name": "Linux x86",
                   "attributes": {
                     "os": "linux",
                     "architecture": "x86"
                   }
                 }
               ],
               "componentDependencies": {
                 "aws.greengrass.StreamManager": {
                   "versionRequirement": "^1.0.0",
                   "dependencyType": "HARD"
                 }
               },
               "componentLambdaParameters": {
                 "eventSources": [
                   {
                     "topic": "hello/world/+",
                     "type": "IOT_CORE"
                   }
                 ]
               }
             }
           }
           ```

   1. (Optional) Specify any of the following parameters in the Lambda function parameters object:
      + `environmentVariables` – The map of environment variables that are available to the Lambda function when it runs.
      + `execArgs` – The list of arguments to pass to the Lambda function when it runs.
      + `inputPayloadEncodingType` – The type of payload that the Lambda function supports. Choose from the following options:
        +  `json` 
        +  `binary` 

        Default: `json`
      + `pinned` – Whether or not the Lambda function is pinned. The default is `true`.<a name="lambda-function-lifecycle-type"></a>
        + A pinned (or long-lived) Lambda function starts when AWS IoT Greengrass starts and keeps running in its own container.
        + A non-pinned (or on-demand) Lambda function starts only when it receives a work item and exits after it remains idle for a specified maximum idle time. If the function has multiple work items, the AWS IoT Greengrass Core software creates multiple instances of the function.

        Use `maxIdleTimeInSeconds` to set the maximum idle time for your function.
      + `timeoutInSeconds` – The maximum amount of time in seconds that the Lambda function can run before it times out. The default is 3 seconds.
      + `statusTimeoutInSeconds` – The interval in seconds at which the Lambda function component sends status updates to the Lambda manager component. This parameter applies only to pinned functions. The default is 60 seconds.
      + `maxIdleTimeInSeconds` – The maximum amount of time in seconds that a non-pinned Lambda function can idle before the AWS IoT Greengrass Core software stops its process. The default is 60 seconds.
      + `maxInstancesCount` – The maximum number of instances that a non-pinned Lambda function can run at the same time. The default is 100 instances.
      + `maxQueueSize` – The maximum size of the message queue for the Lambda function component. The AWS IoT Greengrass Core software stores messages in a FIFO (first-in-first-out) queue until it can run the Lambda function to consume each message. The default is 1,000 messages.

      Your `lambda-function-component.json` might contain a document similar to the following example.

      ```
      {
        "lambdaFunction": {
          "lambdaArn": "arn:aws:lambda:region:account-id:function:HelloWorld:1",
          "componentName": "com.example.HelloWorldLambda",
          "componentVersion": "1.0.0",
          "componentPlatforms": [
            {
              "name": "Linux x86",
              "attributes": {
                "os": "linux",
                "architecture": "x86"
              }
            }
          ],
          "componentDependencies": {
            "aws.greengrass.StreamManager": {
              "versionRequirement": "^1.0.0",
              "dependencyType": "HARD"
            }
          },
          "componentLambdaParameters": {
            "eventSources": [
              {
                "topic": "hello/world/+",
                "type": "IOT_CORE"
              }
            ],
            "environmentVariables": {
              "LIMIT": "300"
            },
            "execArgs": [
              "-d"
            ],
            "inputPayloadEncodingType": "json",
            "pinned": true,
            "timeoutInSeconds": 120,
            "statusTimeoutInSeconds": 30,
            "maxIdleTimeInSeconds": 30,
            "maxInstancesCount": 50,
            "maxQueueSize": 500
          }
        }
      }
      ```

   1. (Optional) Configure the container settings for the Lambda function. By default, Lambda functions run in an isolated runtime environment inside the AWS IoT Greengrass Core software. You can also choose to run the Lambda function as a process without any isolation. If you run the Lambda function in a container, you configure the memory size of the container and what system resources are available to the Lambda function. Do the following:

      1. Add the Linux process parameters object (`linuxProcessParams`) to the Lambda parameters object in `lambda-function-component.json`.

         ```
         {
           "lambdaFunction": {
             "lambdaArn": "arn:aws:lambda:region:account-id:function:HelloWorld:1",
             "componentName": "com.example.HelloWorldLambda",
             "componentVersion": "1.0.0",
             "componentPlatforms": [
               {
                 "name": "Linux x86",
                 "attributes": {
                   "os": "linux",
                   "architecture": "x86"
                 }
               }
             ],
             "componentDependencies": {
               "aws.greengrass.StreamManager": {
                 "versionRequirement": "^1.0.0",
                 "dependencyType": "HARD"
               }
             },
             "componentLambdaParameters": {
               "eventSources": [
                 {
                   "topic": "hello/world/+",
                   "type": "IOT_CORE"
                 }
               ],
               "environmentVariables": {
                 "LIMIT": "300"
               },
               "execArgs": [
                 "-d"
               ],
               "inputPayloadEncodingType": "json",
               "pinned": true,
               "timeoutInSeconds": 120,
               "statusTimeoutInSeconds": 30,
               "maxIdleTimeInSeconds": 30,
               "maxInstancesCount": 50,
               "maxQueueSize": 500,
               "linuxProcessParams": {
               
               }
             }
           }
         }
         ```

      1. (Optional) Specify whether or not the Lambda function runs in a container. Add the `isolationMode` parameter to the process parameters object, and choose from the following options:
         + `GreengrassContainer` – The Lambda function runs in a container.
         + `NoContainer` – The Lambda function runs as a process without any isolation.

         The default is `GreengrassContainer`.

      1. (Optional) If you run the Lambda function in a container, you can configure the amount of memory and the system resources, such as volumes and devices, to make available to the container. Do the following:

         1. Add the container parameters object (`containerParams`) to the Linux process parameters object in `lambda-function-component.json`.

            ```
            {
              "lambdaFunction": {
                "lambdaArn": "arn:aws:lambda:region:account-id:function:HelloWorld:1",
                "componentName": "com.example.HelloWorldLambda",
                "componentVersion": "1.0.0",
                "componentPlatforms": [
                  {
                    "name": "Linux x86",
                    "attributes": {
                      "os": "linux",
                      "architecture": "x86"
                    }
                  }
                ],
                "componentDependencies": {
                  "aws.greengrass.StreamManager": {
                    "versionRequirement": "^1.0.0",
                    "dependencyType": "HARD"
                  }
                },
                "componentLambdaParameters": {
                  "eventSources": [
                    {
                      "topic": "hello/world/+",
                      "type": "IOT_CORE"
                    }
                  ],
                  "environmentVariables": {
                    "LIMIT": "300"
                  },
                  "execArgs": [
                    "-d"
                  ],
                  "inputPayloadEncodingType": "json",
                  "pinned": true,
                  "timeoutInSeconds": 120,
                  "statusTimeoutInSeconds": 30,
                  "maxIdleTimeInSeconds": 30,
                  "maxInstancesCount": 50,
                  "maxQueueSize": 500,
                  "linuxProcessParams": {
                    "containerParams": {
                    
                    }
                  }
                }
              }
            }
            ```

         1. (Optional) Add the `memorySizeInKB` parameter to specify the memory size of the container. The default is 16,384 KB (16 MB).

         1. (Optional) Add the `mountROSysfs` parameter to specify whether or not the container can read information from the device's `/sys` folder. The default is `false`.

         1. (Optional) Configure the local volumes that the containerized Lambda function can access. When you define a volume, the AWS IoT Greengrass Core software mounts the source files to the destination inside the container. Do the following:

            1. Add the list of volumes (`volumes`) to the container parameters.

               ```
               {
                 "lambdaFunction": {
                   "lambdaArn": "arn:aws:lambda:region:account-id:function:HelloWorld:1",
                   "componentName": "com.example.HelloWorldLambda",
                   "componentVersion": "1.0.0",
                   "componentPlatforms": [
                     {
                       "name": "Linux x86",
                       "attributes": {
                         "os": "linux",
                         "architecture": "x86"
                       }
                     }
                   ],
                   "componentDependencies": {
                     "aws.greengrass.StreamManager": {
                       "versionRequirement": "^1.0.0",
                       "dependencyType": "HARD"
                     }
                   },
                   "componentLambdaParameters": {
                     "eventSources": [
                       {
                         "topic": "hello/world/+",
                         "type": "IOT_CORE"
                       }
                     ],
                     "environmentVariables": {
                       "LIMIT": "300"
                     },
                     "execArgs": [
                       "-d"
                     ],
                     "inputPayloadEncodingType": "json",
                     "pinned": true,
                     "timeoutInSeconds": 120,
                     "statusTimeoutInSeconds": 30,
                     "maxIdleTimeInSeconds": 30,
                     "maxInstancesCount": 50,
                     "maxQueueSize": 500,
                     "linuxProcessParams": {
                       "containerParams": {
                         "memorySizeInKB": 32768,
                         "mountROSysfs": true,
                         "volumes": [
                         
                         ]
                       }
                     }
                   }
                 }
               }
               ```

            1. Add each volume to the list. Each volume has the following parameters:
               + `sourcePath` – The path to the source folder on the core device.
               + `destinationPath` – The path to the destination folder in the container.
               + `permission` – (Optional) The permission to access the source folder from the container. Choose from the following options:
                 + `ro` – The Lambda function has read-only access to the source folder.
                 + `rw` – The Lambda function has read-write access to the source folder.

                 The default is `ro`.
               + `addGroupOwner` – (Optional) Whether or not to add the system group that runs the Lambda function component as an owner of the source folder. The default is `false`.

               Your `lambda-function-component.json` might contain a document similar to the following example.

               ```
               {
                 "lambdaFunction": {
                   "lambdaArn": "arn:aws:lambda:region:account-id:function:HelloWorld:1",
                   "componentName": "com.example.HelloWorldLambda",
                   "componentVersion": "1.0.0",
                   "componentPlatforms": [
                     {
                       "name": "Linux x86",
                       "attributes": {
                         "os": "linux",
                         "architecture": "x86"
                       }
                     }
                   ],
                   "componentDependencies": {
                     "aws.greengrass.StreamManager": {
                       "versionRequirement": "^1.0.0",
                       "dependencyType": "HARD"
                     }
                   },
                   "componentLambdaParameters": {
                     "eventSources": [
                       {
                         "topic": "hello/world/+",
                         "type": "IOT_CORE"
                       }
                     ],
                     "environmentVariables": {
                       "LIMIT": "300"
                     },
                     "execArgs": [
                       "-d"
                     ],
                     "inputPayloadEncodingType": "json",
                     "pinned": true,
                     "timeoutInSeconds": 120,
                     "statusTimeoutInSeconds": 30,
                     "maxIdleTimeInSeconds": 30,
                     "maxInstancesCount": 50,
                     "maxQueueSize": 500,
                     "linuxProcessParams": {
                       "containerParams": {
                         "memorySizeInKB": 32768,
                         "mountROSysfs": true,
                         "volumes": [
                           {
                             "sourcePath": "/var/data/src",
                             "destinationPath": "/var/data/dest",
                             "permission": "rw",
                             "addGroupOwner": true
                           }
                         ]
                       }
                     }
                   }
                 }
               }
               ```

         1. (Optional) Configure the local system devices that the containerized Lambda function can access. Do the following:

            1. Add the list of system devices (`devices`) to the container parameters.

               ```
               {
                 "lambdaFunction": {
                   "lambdaArn": "arn:aws:lambda:region:account-id:function:HelloWorld:1",
                   "componentName": "com.example.HelloWorldLambda",
                   "componentVersion": "1.0.0",
                   "componentPlatforms": [
                     {
                       "name": "Linux x86",
                       "attributes": {
                         "os": "linux",
                         "architecture": "x86"
                       }
                     }
                   ],
                   "componentDependencies": {
                     "aws.greengrass.StreamManager": {
                       "versionRequirement": "^1.0.0",
                       "dependencyType": "HARD"
                     }
                   },
                   "componentLambdaParameters": {
                     "eventSources": [
                       {
                         "topic": "hello/world/+",
                         "type": "IOT_CORE"
                       }
                     ],
                     "environmentVariables": {
                       "LIMIT": "300"
                     },
                     "execArgs": [
                       "-d"
                     ],
                     "inputPayloadEncodingType": "json",
                     "pinned": true,
                     "timeoutInSeconds": 120,
                     "statusTimeoutInSeconds": 30,
                     "maxIdleTimeInSeconds": 30,
                     "maxInstancesCount": 50,
                     "maxQueueSize": 500,
                     "linuxProcessParams": {
                       "containerParams": {
                         "memorySizeInKB": 32768,
                         "mountROSysfs": true,
                         "volumes": [
                           {
                             "sourcePath": "/var/data/src",
                             "destinationPath": "/var/data/dest",
                             "permission": "rw",
                             "addGroupOwner": true
                           }
                         ],
                         "devices": [
                         
                         ]
                       }
                     }
                   }
                 }
               }
               ```

            1. Add each system device to the list. Each system device has the following parameters:
               + `path` – The path to the system device on the core device.
               + `permission` – (Optional) The permission to access the system device from the container. Choose from the following options:
                 + `ro` – The Lambda function has read-only access to the system device.
                 + `rw` – The Lambda function has read-write access to the system device.

                 The default is `ro`.
               + `addGroupOwner` – (Optional) Whether or not to add the system group that runs the Lambda function component as an owner of the system device. The default is `false`.

            Your `lambda-function-component.json` might contain a document similar to the following example.

            ```
            {
              "lambdaFunction": {
                "lambdaArn": "arn:aws:lambda:region:account-id:function:HelloWorld:1",
                "componentName": "com.example.HelloWorldLambda",
                "componentVersion": "1.0.0",
                "componentPlatforms": [
                  {
                    "name": "Linux x86",
                    "attributes": {
                      "os": "linux",
                      "architecture": "x86"
                    }
                  }
                ],
                "componentDependencies": {
                  "aws.greengrass.StreamManager": {
                    "versionRequirement": "^1.0.0",
                    "dependencyType": "HARD"
                  }
                },
                "componentLambdaParameters": {
                  "eventSources": [
                    {
                      "topic": "hello/world/+",
                      "type": "IOT_CORE"
                    }
                  ],
                  "environmentVariables": {
                    "LIMIT": "300"
                  },
                  "execArgs": [
                    "-d"
                  ],
                  "inputPayloadEncodingType": "json",
                  "pinned": true,
                  "timeoutInSeconds": 120,
                  "statusTimeoutInSeconds": 30,
                  "maxIdleTimeInSeconds": 30,
                  "maxInstancesCount": 50,
                  "maxQueueSize": 500,
                  "linuxProcessParams": {
                    "containerParams": {
                      "memorySizeInKB": 32768,
                      "mountROSysfs": true,
                      "volumes": [
                        {
                          "sourcePath": "/var/data/src",
                          "destinationPath": "/var/data/dest",
                          "permission": "rw",
                          "addGroupOwner": true
                        }
                      ],
                      "devices": [
                        {
                          "path": "/dev/sda3",
                          "permission": "rw",
                          "addGroupOwner": true
                        }
                      ]
                    }
                  }
                }
              }
            }
            ```

1. (Optional) Add tags (`tags`) for the component. For more information, see [Tag your AWS IoT Greengrass Version 2 resources](tag-resources.md).

## Step 2: Create the Lambda function component
<a name="create-lambda-component-cli"></a>

1. Run the following command to create the Lambda function component from `lambda-function-component.json`.

   ```
   aws greengrassv2 create-component-version --cli-input-json file://lambda-function-component.json
   ```

   The response looks similar to the following example if the request succeeds.

   ```
   {
     "arn": "arn:aws:greengrass:region:123456789012:components:com.example.HelloWorldLambda:versions:1.0.0",
     "componentName": "com.example.HelloWorldLambda",
     "componentVersion": "1.0.0",
     "creationTimestamp": "Mon Dec 15 20:56:34 UTC 2020",
     "status": {
       "componentState": "REQUESTED",
       "message": "NONE",
       "errors": {}
     }
   }
   ```

   Copy the `arn` from the output to check the state of the component in the next step.

1. When you create a component, its state is `REQUESTED`. Then, AWS IoT Greengrass validates that the component is deployable. You can run the following command to query the component status and verify that your component is deployable. Replace the `arn` with the ARN from the previous step.

   ```
   aws greengrassv2 describe-component \
     --arn "arn:aws:greengrass:region:account-id:components:com.example.HelloWorldLambda:versions:1.0.0"
   ```

   If the component validates, the response indicates that the component state is `DEPLOYABLE`.

   ```
   {
     "arn": "arn:aws:greengrass:region:account-id:components:com.example.HelloWorldLambda:versions:1.0.0",
     "componentName": "com.example.HelloWorldLambda",
     "componentVersion": "1.0.0",
     "creationTimestamp": "2020-12-15T20:56:34.376000-08:00",
     "publisher": "AWS Lambda",
     "status": {
       "componentState": "DEPLOYABLE",
       "message": "NONE",
       "errors": {}
     },
     "platforms": [
       {
         "name": "Linux x86",
         "attributes": {
           "architecture": "x86",
           "os": "linux"
         }
       }
     ]
   }
   ```

   After the component is `DEPLOYABLE`, you can deploy the Lambda function to your core devices. For more information, see [Deploy AWS IoT Greengrass components to devices](manage-deployments.md).