

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).

# Run Lambda functions on the AWS IoT Greengrass core
<a name="lambda-functions"></a>

AWS IoT Greengrass provides a containerized Lambda runtime environment for user-defined code that you author in AWS Lambda. Lambda functions that are deployed to an AWS IoT Greengrass core run in the core's local Lambda runtime. Local Lambda functions can be triggered by local events, messages from the cloud, and other sources, which brings local compute functionality to client devices. For example, you can use Greengrass Lambda functions to filter device data before transmitting the data to the cloud.

To deploy a Lambda function to a core, you add the function to a Greengrass group (by referencing the existing Lambda function), configure group-specific settings for the function, and then deploy the group. If the function accesses AWS services, you also must add any required permissions to the [Greengrass group role](group-role.md).

You can configure parameters that determine how the Lambda functions run, including permissions, isolation, memory limits, and more. For more information, see [Controlling execution of Greengrass Lambda functions by using group-specific configuration](lambda-group-config.md).

**Note**  
These settings also make it possible to run AWS IoT Greengrass in a Docker container. For more information, see [Running AWS IoT Greengrass in a Docker container](run-gg-in-docker-container.md).

The following table lists supported [AWS Lambda runtimes](https://docs.aws.amazon.com/lambda/latest/dg/lambda-runtimes.html) and the versions of AWS IoT Greengrass Core software that they can run on.


****  

| Language or platform | GGC version | 
| --- | --- | 
| Python 3.8 | 1.11 | 
| Python 3.7 | 1.9 or later | 
| Python 2.7 \$1 | 1.0 or later | 
| Java 8 | 1.1 or later | 
| Node.js 12.x \$1 | 1.10 or later | 
| Node.js 8.10 \$1 | 1.9 or later | 
| Node.js 6.10 \$1 | 1.1 or later | 
| C, C\$1\$1 | 1.6 or later | 

\$1 You can run Lambda functions that use these runtimes on supported versions of AWS IoT Greengrass, but you can't create them in AWS Lambda. If the runtime on your device is different from the AWS Lambda runtime specified for that function, you are able to choose your own runtime by using `FunctionRuntimeOverride` in `FunctionDefintionVersion`. For more information, see [CreateFunctionDefinition](https://docs.aws.amazon.com/greengrass/v1/apireference/createfunctiondefinition-post.html). For more information about supported runtimes, see [Runtime support policy](https://docs.aws.amazon.com/lambda/latest/dg/runtime-support-policy.html) in the *AWS Lambda Developer Guide*.

## SDKs for Greengrass Lambda functions
<a name="lambda-sdks"></a>

AWS provides three SDKs that can be used by Greengrass Lambda functions running on an AWS IoT Greengrass core. These SDKs are contained in different packages, so functions can use them simultaneously. To use an SDK in a Greengrass Lambda function, include it in the Lambda function deployment package that you upload to AWS Lambda.

**AWS IoT Greengrass Core SDK**  <a name="lambda-sdks-core"></a>
Enables local Lambda functions to interact with the core to:  <a name="gg-core-sdk-functionality"></a>
+ Exchange MQTT messages with AWS IoT Core.
+ Exchange MQTT messages with connectors, client devices, and other Lambda functions in the Greengrass group.
+ Interact with the local shadow service.
+ Invoke other local Lambda functions.
+ Access [secret resources](secrets.md).
+ Interact with [stream manager](stream-manager.md).
AWS IoT Greengrass provides the AWS IoT Greengrass Core SDK in the following languages and platforms on GitHub.  <a name="gg-core-sdk-download-list"></a>
+ [AWS IoT Greengrass Core SDK for Java](https://github.com/aws/aws-greengrass-core-sdk-java/)
+ [AWS IoT Greengrass Core SDK for Node.js](https://github.com/aws/aws-greengrass-core-sdk-js/)
+ [AWS IoT Greengrass Core SDK for Python](https://github.com/aws/aws-greengrass-core-sdk-python/)
+ [AWS IoT Greengrass Core SDK for C](https://github.com/aws/aws-greengrass-core-sdk-c/)
To include the AWS IoT Greengrass Core SDK dependency in the Lambda function deployment package:  

1. Download the language or platform of the AWS IoT Greengrass Core SDK package that matches the runtime of your Lambda function.

1. Unzip the downloaded package to get the SDK. The SDK is the `greengrasssdk` folder.

1. Include `greengrasssdk` in the Lambda function deployment package that contains your function code. This is the package you upload to AWS Lambda when you create the Lambda function.
   
 **StreamManagerClient**  
Only the following AWS IoT Greengrass Core SDKs can be used for [stream manager](stream-manager.md) operations:  <a name="streammanagerclient-sdk-versions"></a>
+ Java SDK (v1.4.0 or later)
+ Python SDK (v1.5.0 or later)
+ Node.js SDK (v1.6.0 or later)
To use the AWS IoT Greengrass Core SDK for Python to interact with stream manager, you must install Python 3.7 or later. You must also install dependencies to include in your Python Lambda function deployment packages:  <a name="python-sdk-dependencies-stream-manager"></a>

1. Navigate to the SDK directory that contains the `requirements.txt` file. This file lists the dependencies.

1. Install the SDK dependencies. For example, run the following `pip` command to install them in the current directory:

   ```
   pip install --target . -r requirements.txt
   ```
   
 **Install the AWS IoT Greengrass Core SDK for Python on the core device**  
If you're running Python Lambda functions, you can also use [https://pypi.org/project/pip/](https://pypi.org/project/pip/) to install the AWS IoT Greengrass Core SDK for Python on the core device. Then you can deploy your functions without including the SDK in the Lambda function deployment package. For more information, see [greengrasssdk](https://pypi.org/project/greengrasssdk/).  
This support is intended for cores with size constraints. We recommend that you include the SDK in your Lambda function deployment packages when possible.  
 

**AWS IoT Greengrass Machine Learning SDK**  <a name="lambda-sdks-ml"></a>
Enables local Lambda functions to consume machine learning (ML) models that are deployed to the Greengrass core as ML resources. Lambda functions can use the SDK to invoke and interact with a local inference service that's deployed to the core as a connector. Lambda functions and ML connectors can also use the SDK to send data to the ML Feedback connector for uploading and publishing. For more information, including code examples that use the SDK, see [ML Image Classification connector](image-classification-connector.md), [ML Object Detection connector](obj-detection-connector.md), and [ML Feedback connector](ml-feedback-connector.md).  
The following table lists supported languages or platforms for SDK versions and the versions of AWS IoT Greengrass Core software they can run on.    
****    
[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/greengrass/v1/developerguide/lambda-functions.html)
For download information, see [AWS IoT Greengrass ML SDK software](what-is-gg.md#gg-ml-sdk-download).

**AWS SDKs**  <a name="lambda-sdks-aws"></a>
Enables local Lambda functions to make direct calls to AWS services, such as Amazon S3, DynamoDB, AWS IoT, and AWS IoT Greengrass. To use an AWS SDK in a Greengrass Lambda function, you must include it in your deployment package. When you use the AWS SDK in the same package as the AWS IoT Greengrass Core SDK, make sure that your Lambda functions use the correct namespaces. Greengrass Lambda functions can't communicate with cloud services when the core is offline.  
Download the AWS SDKs from the [ Getting Started Resource Center](https://aws.amazon.com/getting-started/tools-sdks/).

For more information about creating a deployment package, see [Create and package a Lambda function](create-lambda.md) in the Getting Started tutorial or [Creating a deployment package](https://docs.aws.amazon.com/lambda/latest/dg/deployment-package-v2.html) in the *AWS Lambda Developer Guide*.

### Migrating cloud-based Lambda functions
<a name="lambda-migrate-sdks"></a>

The AWS IoT Greengrass Core SDK follows the AWS SDK programming model, which makes it easy to port Lambda functions that are developed for the cloud to Lambda functions that run on an AWS IoT Greengrass core.

For example, the following Python Lambda function uses the AWS SDK for Python (Boto3) to publish a message to the topic `some/topic` in the cloud:

```
import boto3

iot_client = boto3.client("iot-data")
response = iot_client.publish(
    topic="some/topic", qos=0, payload="Some payload".encode()
)
```

To port the function for an AWS IoT Greengrass core, in the `import` statement and `client` initialization, change the `boto3` module name to `greengrasssdk`, as shown in the following example:

```
import greengrasssdk

iot_client = greengrasssdk.client("iot-data")
iot_client.publish(topic="some/topic", qos=0, payload="Some payload".encode())
```

**Note**  
The AWS IoT Greengrass Core SDK supports sending MQTT messages with QoS = 0 only. For more information, see [Message quality of service](gg-core.md#message-quality-of-service).

The similarity between programming models also makes it possible for you to develop your Lambda functions in the cloud and then migrate them to AWS IoT Greengrass with minimal effort. [Lambda executables](#lambda-executables) don't run in the cloud, so you can't use the AWS SDK to develop them in the cloud before deployment.

## Reference Lambda functions by alias or version
<a name="lambda-versions-aliases"></a>

Greengrass groups can reference a Lambda function by alias (recommended) or by version. Using an alias makes it easier to manage code updates because you don't have to change your subscription table or group definition when the function code is updated. Instead, you just point the alias to the new function version. Aliases resolve to version numbers during group deployment. When you use aliases, the resolved version is updated to the version that the alias is pointing to at the time of deployment.

AWS IoT Greengrass doesn't support Lambda aliases for **\$1LATEST** versions. **\$1LATEST** versions aren't bound to immutable, published function versions and can be changed at any time, which is counter to the AWS IoT Greengrass principle of version immutability.

A common practice for keeping your Greengrass Lambda functions updated with code changes is to use an alias named **PRODUCTION** in your Greengrass group and subscriptions. As you promote new versions of your Lambda function into production, point the alias to the latest stable version and then redeploy the group. You can also use this method to roll back to a previous version.

# Controlling execution of Greengrass Lambda functions by using group-specific configuration
<a name="lambda-group-config"></a>

AWS IoT Greengrass provides cloud-based management of Greengrass Lambda functions. Although a Lambda function's code and dependencies are managed using AWS Lambda, you can configure how the Lambda function behaves when it runs in a Greengrass group.

## Group-specific configuration settings
<a name="lambda-group-config-properties"></a>

AWS IoT Greengrass provides the following group-specific configuration settings for Greengrass Lambda functions.

**System user and group**  <a name="lambda-access-identity"></a>
The access identity used to run a Lambda function. By default, Lambda functions run as the group's [default access identity](#lambda-access-identity-groupsettings). Typically, this is the standard AWS IoT Greengrass system accounts (ggc\$1user and ggc\$1group). You can change the setting and choose the user ID and group ID that have the permissions required to run the Lambda function. You can override both UID and GID or just one if you leave the other field blank. This setting gives you more granular control over access to device resources. We recommend that you configure your Greengrass hardware with appropriate resource limits, file permissions, and disk quotas for the users and groups whose permissions are used to run Lambda functions.  
This feature is available for AWS IoT Greengrass Core v1.7 and later.  
We recommend that you avoid running Lambda functions as root unless absolutely necessary. Running as root increases the following risks:  
+ The risk of unintended changes, such as accidentally deleting a critical file.
+ The risk to your data and device from malicious individuals.
+ The risk of container escapes when Docker containers run with `--net=host` and `UID=EUID=0`.
If you do need to run as root, you must update the AWS IoT Greengrass configuration to enable it. For more information, see [Running a Lambda function as root](#lambda-running-as-root).  
**System user ID (number)**  
The user ID for the user that has the permissions required to run the Lambda function. This setting is only available if you choose to run as **Another user ID/group ID**. You can use the **getent passwd** command on your AWS IoT Greengrass core device to look up the user ID you want to use to run the Lambda function.  
If you use the same UID to run processes and the Lambda function on a Greengrass core device, your Greengrass group role can grant the processes temporary credentials. The processes can use the temporary credentials across Greengrass core deployments.  
**System group ID (number)**  
The group ID for the group that has the permissions required to run the Lambda function. This setting is only available if you choose to run as **Another user ID/group ID**. You can use the **getent group** command on your AWS IoT Greengrass core device to look up the group ID you want to use to run the Lambda function.

**Lambda function containerization**  <a name="lambda-function-containerization"></a>
Choose whether the Lambda function runs with the default containerization for the group, or specify the containerization that should always be used for this Lambda function.  
A Lambda function's containerization mode determines its level of isolation.  
+ Containerized Lambda functions run in **Greengrass container** mode. The Lambda function runs in an isolated runtime environment (or namespace) inside the AWS IoT Greengrass container.
+ Non-containerized Lambda functions run in **No container** mode. The Lambda functions runs as a regular Linux process without any isolation.
This feature is available for AWS IoT Greengrass Core v1.7 and later.  
We recommend that you run Lambda functions in a Greengrass container unless your use case requires them to run without containerization. When your Lambda functions run in a Greengrass container, you can use attached local and device resources and gain the benefits of isolation and increased security. Before you change the containerization, see [Considerations when choosing Lambda function containerization](#lambda-containerization-considerations).  
To run without enabling your device kernel namespace and cgroup, all your Lambda functions must run without containerization. You can accomplish this easily by setting the default containerization for the group. For information, see [Setting default containerization for Lambda functions in a group](#lambda-containerization-groupsettings).

**Memory limit**  
The memory allocation for the function. The default is 16 MB.  
The memory limit setting becomes unavailable when you change the Lambda function to run without containerization. Lambda functions that run without containerization have no memory limit. The memory limit setting is discarded when you change the Lambda function or group default containerization setting to run without containerization.

**Timeout**  
The amount of time before the function or request is terminated. The default is 3 seconds.

**Pinned**  
A Lambda function lifecycle can be *on-demand* or *long-lived*. The default is on-demand.  
An on-demand Lambda function starts in a new or reused container when invoked. Requests to the function might be processed by any available container. A long-lived—or *pinned*—Lambda function starts automatically after AWS IoT Greengrass starts and keeps running in its own container (or sandbox). All requests to the function are processed by the same container. For more information, see [Lifecycle configuration for Greengrass Lambda functions](lambda-functions.md#lambda-lifecycle).

**Read access to /sys directory**  
Whether the function can access the host's /sys folder. Use this when the function must read device information from /sys. The default is false.  
This setting is not available when you run a Lambda function without containerization. The value of this setting is discarded when you change the Lambda function to run without containerization.

**Encoding type**  
The expected encoding type of the input payload for the function, either JSON or binary. The default is JSON.  
Support for the binary encoding type is available starting in AWS IoT Greengrass Core Software v1.5.0 and AWS IoT Greengrass Core SDK v1.1.0. Accepting binary input data can be useful for functions that interact with device data, because the restricted hardware capabilities of devices often make it difficult or impossible for them to construct a JSON data type.  
[Lambda executables](lambda-functions.md#lambda-executables) support the binary encoding type only, not JSON.

**Process arguments**  
The command-line arguments are passed to the Lambda function when it runs.

**Environment variables**  
Key-value pairs that can dynamically pass settings to function code and libraries. Local environment variables work the same way as [AWS Lambda function environment variables](https://docs.aws.amazon.com/lambda/latest/dg/env_variables.html), but are available in the core environment.

**Resource access policies**  
A list of up to 10 [local resources](access-local-resources.md), [secret resources](secrets.md), and [machine learning resources](ml-inference.md) that the Lambda function is allowed to access, and the corresponding `read-only` or `read-write` permission. In the console, these *affiliated* resources are listed on the group configuration page in the **Resources** tab.  
The [containerization mode](#lambda-function-containerization) affects how Lambda functions can access local device and volume resources and machine learning resources.  
+ Non-containerized Lambda functions must access local device and volume resources directly through the file system on the core device.
+ To allow non-containerized Lambda functions to access machine learning resources in the Greengrass group, you must set the resource owner and access permissions properties on the machine learning resource. For more information, see [Access machine learning resources from Lambda functions](access-ml-resources.md).

For information about using the AWS IoT Greengrass API to set group-specific configuration settings for user-defined Lambda functions, see [CreateFunctionDefinition](https://docs.aws.amazon.com/greengrass/v1/apireference/createfunctiondefinition-post.html) in the *AWS IoT Greengrass Version 1 API Reference* or [create-function-definition](https://docs.aws.amazon.com/cli/latest/reference/greengrass/create-function-definition.html) in the *AWS CLI Command Reference*. To deploy Lambda functions to a Greengrass core, create a function definition version that contains your functions, create a group version that references the function definition version and other group components, and then [deploy the group](deployments.md).

## Running a Lambda function as root
<a name="lambda-running-as-root"></a>

This feature is available for AWS IoT Greengrass Core v1.7 and later.

Before you can run one or more Lambda functions as root, you must first update the AWS IoT Greengrass configuration to enable support. Support for running Lambda functions as root is off by default. The deployment fails if you try to deploy a Lambda function and run it as root (UID and GID of 0) and you haven't updated the AWS IoT Greengrass configuration. An error like the following appears in the runtime log (*greengrass\$1root*/ggc/var/log/system/runtime.log):

```
lambda(s)
[list of function arns] are configured to run as root while Greengrass is not configured to run lambdas with root permissions
```

**Important**  
We recommend that you avoid running Lambda functions as root unless absolutely necessary. Running as root increases the following risks:  
The risk of unintended changes, such as accidentally deleting a critical file.
The risk to your data and device from malicious individuals.
The risk of container escapes when Docker containers run with `--net=host` and `UID=EUID=0`.

**To allow Lambda functions to run as root**

1. On your AWS IoT Greengrass device, navigate to the *greengrass-root*/config folder.
**Note**  
By default, *greengrass-root* is the /greengrass directory.

1. Edit the config.json file to add `"allowFunctionsToRunAsRoot" : "yes"` to the `runtime` field. For example:

   ```
   {
     "coreThing" : {
       ...
     },
     "runtime" : {
       ...
       "allowFunctionsToRunAsRoot" : "yes"
     },
     ...
   }
   ```

1. Use the following commands to restart AWS IoT Greengrass:

   ```
   cd /greengrass/ggc/core
   sudo ./greengrassd restart
   ```

   Now you can set the user ID and group ID (UID/GID) of Lambda functions to 0 to run that Lambda function as root.

You can change the value of `"allowFunctionsToRunAsRoot"` to `"no"` and restart AWS IoT Greengrass if you want to disallow Lambda functions to run as root.

## Considerations when choosing Lambda function containerization
<a name="lambda-containerization-considerations"></a>

This feature is available for AWS IoT Greengrass Core v1.7 and later.

By default, Lambda functions run inside an AWS IoT Greengrass container. That container provides isolation between your functions and the host, which offers more 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 restricting access to resources.

Here are some example use cases for running without containerization:
+ You want to run AWS IoT Greengrass on a device that does not support container mode (for example, because you are using a special Linux distribution or have a kernel version that is too old).
+ 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, such as pluggable devices.
+ You have a legacy application that was written as a process and you have encountered issues when running it as a containerized Lambda function.


**Containerization differences**  

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

**Note**  
The default containerization setting for the Greengrass group doesn't apply to [connectors](connectors.md).

Changing the containerization for a Lambda function can cause problems when you deploy it. If you had assigned local resources to your Lambda function that are no longer available with your new containerization settings, deployment fails.
+ When you change a Lambda function from running in a Greengrass container to running without containerization, memory limits for the function are discarded. You must access the file system directly instead of using attached local resources. You must remove any attached resources before you deploy.
+ 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. You can configure those settings for each Lambda function before you deploy.<a name="change-containerization-lambda"></a>

**To change containerization settings for a Lambda function**

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. <a name="lambda-choose-group"></a>Choose the group that contains the Lambda function whose settings you want to change.

1. <a name="lambda-choose-lambdas"></a>Choose the **Lambda functions** tab.

1. <a name="lambda-edit-lambda"></a>On the Lambda function that you want to change, choose the ellipsis (**…**) and then choose **Edit configuration**.

1. Change the containerization settings. If you configure the Lambda function to run in a Greengrass container, you must also set **Memory limit** and **Read access to /sys directory**.

1. <a name="lambda-save-changes"></a>Choose **Save** and then **Confirm** to save the changes to your Lambda function.

The changes take effect when the group is deployed.

You can also use the [CreateFunctionDefinition](https://docs.aws.amazon.com/greengrass/v1/apireference/createfunctiondefinition-post.html) and [CreateFunctionDefinitionVersion](https://docs.aws.amazon.com/greengrass/v1/apireference/createfunctiondefinitionversion-post.html) in the *AWS IoT Greengrass API Reference*. If you are changing the containerization setting, be sure to update the other parameters too. For example, if you are changing from running a Lambda function in a Greengrass container to running without containerization, be sure to clear the `MemorySize` parameter.

### Determine the isolation modes supported by your Greengrass device
<a name="dependency-checker-tests-isolation"></a>

You can use the AWS IoT Greengrass dependency checker to determine which isolation modes (Greengrass container/no container) are supported by your Greengrass device.

**To run the AWS IoT Greengrass dependency checker**

1. Download and run the AWS IoT Greengrass dependency checker from the [GitHub repository](https://github.com/aws-samples/aws-greengrass-samples).

   ```
   wget https://github.com/aws-samples/aws-greengrass-samples/raw/master/greengrass-dependency-checker-GGCv1.11.x.zip
   unzip greengrass-dependency-checker-GGCv1.11.x.zip
   cd greengrass-dependency-checker-GGCv1.11.x
   sudo modprobe configs
   sudo ./check_ggc_dependencies | more
   ```

1. Where `more` appears, press the Spacebar key to display another page of text.

For information about the **modprobe** command, run **man modprobe** in the terminal. 

## Setting the default access identity for Lambda functions in a group
<a name="lambda-access-identity-groupsettings"></a>

This feature is available for AWS IoT Greengrass Core v1.8 and later.

For more control over access to device resources, you can configure the default access identity used to run Lambda functions in the group. This setting determines the default permissions given to your Lambda functions when they run on the core device. To override the setting for individual functions in the group, you can use the function's **Run as** property. For more information, see [Run as](#lambda-access-identity).

This group-level setting is also used for running the underlying AWS IoT Greengrass Core software. This consists of system Lambda functions that manage operations, such as message routing, local shadow sync, and automatic IP address detection.

The default access identity can be configured to run as the standard AWS IoT Greengrass system accounts (ggc\$1user and ggc\$1group) or use the permissions of another user or group. We recommend that you configure your Greengrass hardware with appropriate resource limits, file permissions, and disk quotas for any users and groups whose permissions are used to run user-defined or system Lambda functions.

**To modify the default access identity for your AWS IoT Greengrass group**

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. <a name="group-choose-group"></a>Choose the group whose settings you want to change.

1. Choose the **Lambda functions** tab and, under the **Default Lambda function runtime environment** section, choose **Edit**.

1. In the **Edit default Lambda function runtime environment** page, under **Default system user and group**, choose **Another user ID/group ID**.

   When you choose this option, the **System user ID (number)** and **System group ID (number)** fields are displayed.

1. Enter a user ID, group ID, or both. If you leave a field blank, the respective Greengrass system account (ggc\$1user or ggc\$1group) is used.
   + For **System user ID (number)**, enter the user ID for the user who has the permissions you want to use by default to run Lambda functions in the group. You can use the **getent passwd** command on your AWS IoT Greengrass device to look up the user ID.
   + For **System group ID (number)**, enter the group ID for the group that has the permissions you want to use by default to run Lambda functions in the group. You can use the **getent group** command on your AWS IoT Greengrass device to look up the group ID.
**Important**  
Running as the root user increases risks to your data and device. Do not run as root (UID/GID=0) unless your business case requires it. For more information, see [Running a Lambda function as root](#lambda-running-as-root).

The changes take effect when the group is deployed.

## Setting default containerization for Lambda functions in a group
<a name="lambda-containerization-groupsettings"></a>

This feature is available for AWS IoT Greengrass Core v1.7 and later.

The containerization setting for a Greengrass group determines the default containerization for the Lambda functions in the group.
+ In **Greengrass container** mode, Lambda functions run in an isolated runtime environment inside the AWS IoT Greengrass container by default.
+ In **No container** mode, Lambda functions run as regular Linux processes by default.

You can modify group settings to specify the default containerization for Lambda functions in the group. You can override this setting for one or more Lambda functions in the group if you want the Lambda functions to run with containerization different from the group default. Before you change containerization settings, see [Considerations when choosing Lambda function containerization](#lambda-containerization-considerations).

**Important**  
If you want to change the default containerization for the group, but have one or more functions that use a different containerization, change the settings for the Lambda functions before you change the group setting. If you change the group containerization setting first, the values for the **Memory limit** and **Read access to /sys directory** settings are discarded.

**To modify containerization settings for your AWS IoT Greengrass group**

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. <a name="group-choose-group"></a>Choose the group whose settings you want to change.

1. Choose the **Lambda functions** tab.

1. Under **Default Lambda function runtime environment**, choose **Edit**.

1. In the **Edit default Lambda function runtime environment**, page, under **Default Lambda function containerization**, change the containerization setting.

1. Choose **Save**.

The changes take effect when the group is deployed.

## Communication flows for Greengrass Lambda functions
<a name="lambda-communication"></a>

Greengrass Lambda functions support several methods of communicating with other members of the AWS IoT Greengrass group, local services, and cloud services (including AWS services).

### Communication using MQTT messages
<a name="lambda-messages"></a>

Lambda functions can send and receive MQTT messages using a publish-subscribe pattern that's controlled by subscriptions.

This communication flow allows Lambda functions to exchange messages with the following entities:
+ Client devices in the group.
+ Connectors in the group.
+ Other Lambda functions in the group.
+ AWS IoT.
+ Local Device Shadow service.

A subscription defines a message source, a message target, and a topic (or subject) that's used to route messages from the source to the target. Messages that are published to a Lambda function are passed to the function's registered handler. Subscriptions enable more security and provide predictable interactions. For more information, see [Managed subscriptions in the MQTT messaging workflow](gg-sec.md#gg-msg-workflow).

**Note**  
When the core is offline, Greengrass Lambda functions can exchange messages with client devices, connectors, other functions, and local shadows, but messages to AWS IoT are queued. For more information, see [MQTT message queue for cloud targets](gg-core.md#mqtt-message-queue).

### Other communication flows
<a name="lambda-other-communication"></a>
+ To interact with local device and volume resources and machine learning models on a core device, Greengrass Lambda functions use platform-specific operating system interfaces. For example, you can use the `open` method in the [os](https://docs.python.org/2/library/os.html) module in Python functions. To allow a function to access a resource, the function must be *affiliated* with the resource and granted `read-only` or `read-write` permission. For more information, including AWS IoT Greengrass core version availability, see [Access local resources with Lambda functions and connectors](access-local-resources.md) and [Accessing machine learning resources from Lambda function code](access-ml-resources.md#access-resource-function-code).
**Note**  
If you run your Lambda function without containerization, you cannot use attached local device and volume resources and must access those resources directly.
+ Lambda functions can use the `Lambda` client in the AWS IoT Greengrass Core SDK to invoke other Lambda functions in the Greengrass group.
+ Lambda functions can use the AWS SDK to communicate with AWS services. For more information, see [AWS SDK](#aws-sdk).
+ Lambda functions can use third-party interfaces to communicate with external cloud services, similar to cloud-based Lambda functions.

**Note**  
Greengrass Lambda functions can't communicate with AWS or other cloud services when the core is offline.

## Retrieve the input MQTT topic (or subject)
<a name="lambda-get-mqtt-topic"></a>

AWS IoT Greengrass uses subscriptions to control the exchange of MQTT messages between client devices, Lambda functions, and connectors in a group, and with AWS IoT or the local shadow service. Subscriptions define a message source, message target, and an MQTT topic used to route messages. When the target is a Lambda function, the function's handler is invoked when the source publishes a message. For more information, see [Communication using MQTT messages](#lambda-messages).

The following example shows how a Lambda function can get the input topic from the `context` that's passed to the handler. It does this by accessing the `subject` key from the context hierarchy (`context.client_context.custom['subject']`). The example also parses the input JSON message and then publishes the parsed topic and message.

**Note**  
In the AWS IoT Greengrass API, the topic of a [subscription](https://docs.aws.amazon.com/greengrass/v1/apireference/definitions-subscription.html) is represented by the `subject` property.

```
import greengrasssdk
import logging

client = greengrasssdk.client('iot-data')

OUTPUT_TOPIC = 'test/topic_results'

def get_input_topic(context):
    try:
        topic = context.client_context.custom['subject']
    except Exception as e:
        logging.error('Topic could not be parsed. ' + repr(e))
    return topic
    
def get_input_message(event):
    try:
        message = event['test-key']
    except Exception as e:
        logging.error('Message could not be parsed. ' + repr(e))
    return message

def function_handler(event, context):
    try:
        input_topic = get_input_topic(context)
        input_message = get_input_message(event)
        response = 'Invoked on topic "%s" with message "%s"' % (input_topic, input_message)
        logging.info(response)
    except Exception as e:
        logging.error(e)

    client.publish(topic=OUTPUT_TOPIC, payload=response)

    return
```

To test the function, add it to your group using the default configuration settings. Then, add the following subscriptions and deploy the group. For instructions, see [Module 3 (part 1): Lambda functions on AWS IoT Greengrass](module3-I.md).


****  

| Source | Target | Topic filter | 
| --- | --- | --- | 
| IoT Cloud | This function | test/input\$1message | 
| This function | IoT Cloud | test/topic\$1results | 

After the deployment is completed, invoke the function.

1. In the AWS IoT console, open the **MQTT test client** page.

1. Subscribe to the `test/topic_results` topic by selecting the **Subscribe to a topic** tab.

1. Publish a message to the `test/input_message` topic by selecting the **Publish to a topic** tab. For this example, you must include the `test-key` property in the JSON messsage.

   ```
   {
     "test-key": "Some string value"
   }
   ```

   If successful, the function publishes the input topic and message string to the `test/topic_results` topic.

## Lifecycle configuration for Greengrass Lambda functions
<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 variables and preprocessing logic that are outside of the function handler are retained.

AWS IoT Greengrass supports the on-demand (default) or long-lived lifecycles:
+ **On-demand** functions start when they are invoked and stop when there are no tasks left to execute. An invocation of the function creates a separate container (or sandbox) to process invocations, unless an existing container is available for reuse. Data that's sent to the function might be pulled by any of the containers.

  Multiple invocations of an on-demand function can run in parallel.

  Variables and preprocessing logic that are defined outside of the function handler are not retained when new containers are created.
+ **Long-lived** (or *pinned*) functions start automatically when the AWS IoT Greengrass core starts and run in a single container. All data that's sent to the function is pulled by the same container.

  Multiple invocations are queued until earlier invocations are executed.

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

  Long-lived Lambda functions are useful when you need to start doing work without any initial input. For example, a long-lived function can load and start processing an ML model to be ready when the function starts receiving device data.
**Note**  
Remember that long-lived functions have timeouts that are associated with invocations of their handler. If you want to execute indefinitely running code, you must start it outside the handler. Make sure that there's no blocking code outside the handler that might prevent the function from completing its initialization.  
 These functions run unless the core stops (for example, during a group deployment or a device reboot) or the function enters an error state (such as a handler timeout, uncaught exception, or when it exceeds its memory limits).

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.

## Lambda executables
<a name="lambda-executables"></a>

This feature is available for AWS IoT Greengrass Core v1.6 and later.

A Lambda executable is a type of Greengrass Lambda function that you can use to run binary code in the core environment. It lets you execute device-specific functionality natively and benefit from the smaller footprint of compiled code. Lambda executables can be invoked by events, invoke other functions, and access local resources.

Lambda executables support the binary encoding type only (not JSON), but otherwise you can manage them in your Greengrass group and deploy them like other Greengrass Lambda functions. However, the process of creating Lambda executables is different from creating Python, Java, and Node.js Lambda functions:
+ You can't use the AWS Lambda console to create (or manage) a Lambda executable. You can create a Lambda executable only by using the AWS Lambda API.
+ You upload the function code to AWS Lambda as a compiled executable that includes the [AWS IoT Greengrass Core SDK for C](https://github.com/aws/aws-greengrass-core-sdk-c).
+ You specify the executable name as the function handler.

Lambda executables must implement certain calls and programming patterns in their function code. For example, the `main` method must:
+ Call `gg_global_init` to initialize Greengrass internal global variables. This function must be called before creating any threads, and before calling any other AWS IoT Greengrass Core SDK functions.
+ Call `gg_runtime_start` to register the function handler with the Greengrass Lambda runtime. This function must be called during initialization. Calling this function causes the current thread to be used by the runtime. The optional `GG_RT_OPT_ASYNC` parameter tells this function to not block, but instead to create a new thread for the runtime. This function uses a `SIGTERM` handler.

The following snippet is the `main` method from the [simple\$1handler.c](https://github.com/aws/aws-greengrass-core-sdk-c/blob/master/aws-greengrass-core-sdk-c-example/simple_handler.c) code example on GitHub.

```
int main() {
    gg_error err = GGE_SUCCESS;

    err = gg_global_init(0);
    if(err) {
        gg_log(GG_LOG_ERROR, "gg_global_init failed %d", err);
        goto cleanup;
    }

    gg_runtime_start(handler, 0);

cleanup:
    return -1;
}
```

For more information about requirements, constraints, and other implementation details, see [AWS IoT Greengrass Core SDK for C](https://github.com/aws/aws-greengrass-core-sdk-c).

### Create a Lambda executable
<a name="create-lambda-executable"></a>

After you compile your code along with the SDK, use the AWS Lambda API to create a Lambda function and upload your compiled executable.

**Note**  
Your function must be compiled with a C89 compatible compiler.

The following example uses the [create-function](https://docs.aws.amazon.com/cli/latest/reference/lambda/create-function.html) CLI command to create a Lambda executable. The command specifies:
+ The name of the executable for the handler. This must be the exact name of your compiled executable.
+ The path to the `.zip` file that contains the compiled executable.
+ `arn:aws:greengrass:::runtime/function/executable` for the runtime. This is the runtime for all Lambda executables.

**Note**  
For `role`, you can specify the ARN of any Lambda execution role. AWS IoT Greengrass doesn't use this role, but the parameter is required to create the function. For more information about Lambda execution roles, see [AWS Lambda permissions model](https://docs.aws.amazon.com/lambda/latest/dg/intro-permission-model.html) in the *AWS Lambda Developer Guide*.

```
aws lambda create-function \
--region aws-region \
--function-name function-name \
--handler executable-name \
--role role-arn \
--zip-file fileb://file-name.zip \
--runtime arn:aws:greengrass:::runtime/function/executable
```

Next, use the AWS Lambda API to publish a version and create an alias.
+ Use [publish-version](https://docs.aws.amazon.com/cli/latest/reference/lambda/publish-version.html) to publish a function version.

  ```
  aws lambda publish-version \
  --function-name function-name \
  --region aws-region
  ```
+ Use [create-alias](https://docs.aws.amazon.com/cli/latest/reference/lambda/create-alias.html) to create an alias the points to the version you just published. We recommend that you reference Lambda functions by alias when you add them to a Greengrass group.

  ```
  aws lambda create-alias \
  --function-name function-name \
  --name alias-name \
  --function-version version-number \
  --region aws-region
  ```

**Note**  
The AWS Lambda console doesn't display Lambda executables. To update the function code, you must use the AWS Lambda API.

Then, add the Lambda executable to a Greengrass group, configure it to accept binary input data in its group-specific settings, and deploy the group. You can do this in the AWS IoT Greengrass console or by using the AWS IoT Greengrass API.

# Running AWS IoT Greengrass in a Docker container
<a name="run-gg-in-docker-container"></a>

AWS IoT Greengrass can be configured to run in a [Docker](https://www.docker.com/) container.

You can download a Dockerfile [through Amazon CloudFront](what-is-gg.md#gg-docker-download) that has the AWS IoT Greengrass Core software and dependencies installed. To modify the Docker image to run on different platform architectures or reduce the size of the Docker image, see the `README` file in the Docker package download.

To help you get started experimenting with AWS IoT Greengrass, AWS also provides prebuilt Docker images that have the AWS IoT Greengrass Core software and dependencies installed. You can download an image from [Docker Hub](https://hub.docker.com/r/amazon/aws-iot-greengrass) or [Amazon Elastic Container Registry](https://docs.aws.amazon.com/AmazonECR/latest/userguide/what-is-ecr.html) (Amazon ECR). These prebuilt images use Amazon Linux 2 (x86\$164) and Alpine Linux (x86\$164, Armv7l, or AArch64) base images.

**Important**  
<a name="docker-images-end-of-maintenance"></a>On June 30, 2022, AWS IoT Greengrass ended maintenance for AWS IoT Greengrass Core software v1.x Docker images that are published to Amazon Elastic Container Registry (Amazon ECR) and Docker Hub. You can continue to download these Docker images from Amazon ECR and Docker Hub until June 30, 2023, which is 1 year after maintenance ended. However, the AWS IoT Greengrass Core software v1.x Docker images no longer receive security patches or bug fixes after maintenance ended on June 30, 2022. If you run a production workload that depends on these Docker images, we recommend that you build your own Docker images using the Dockerfiles that AWS IoT Greengrass provides. For more information, see [AWS IoT Greengrass Docker software](what-is-gg.md#gg-docker-download).

This topic describes how to download the AWS IoT Greengrass Docker image from Amazon ECR and run it on a Windows, macOS, or Linux (x86\$164) platform. The topic contains the following steps:

1. [Get the AWS IoT Greengrass container image from Amazon ECR](#docker-pull-image)

1. [Create and configure the Greengrass group and core](#docker-config-gg)

1. [Run AWS IoT Greengrass locally](#docker-run-gg)

1. [Configure "No container" containerization for the group](#docker-no-container)

1. [Deploy Lambda functions to the Docker container](#docker-add-lambdas)

1. [(Optional) Deploy client devices that interact with Greengrass in the Docker container](#docker-add-devices)

The following features aren't supported when you run AWS IoT Greengrass in a Docker container:<a name="docker-image-unsupported-features"></a>
+ [Connectors](connectors.md) that run in **Greengrass container** mode. To run a connector in a Docker container, the connector must run in **No container** mode. To find connectors that support **No container** mode, see [AWS-provided Greengrass connectors](connectors-list.md). Some of these connectors have an isolation mode parameter that you must set to **No container**.
+ [Local device and volume resources](access-local-resources.md). Your user-defined Lambda functions that run in the Docker container must access devices and volumes on the core directly.

These features aren't supported when the Lambda runtime environment for the Greengrass group is set to [No container](lambda-group-config.md#no-container-mode), which is required to run AWS IoT Greengrass in a Docker container.

## Prerequisites
<a name="docker-image-prerequisites"></a>

Before you start this tutorial, you must do the following.<a name="docker-image-prereq-list"></a>
+ You must install the following software and versions on your host computer based on the AWS Command Line Interface (AWS CLI) version that you choose.

------
#### [ AWS CLI version 2 ]
  + [Docker](https://docs.docker.com/install/) version 18.09 or later. Earlier versions might also work, but we recommend 18.09 or later.
  + AWS CLI version 2.0.0 or later.
    + To install the AWS CLI version 2, see [Installing the AWS CLI version 2](https://docs.aws.amazon.com/cli/latest/userguide/install-cliv2.html).
    + To configure the AWS CLI, see [Configuring the AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-configure.html).
**Note**  
To upgrade to a later AWS CLI version 2 on a Windows computer, you must repeat the [MSI installation](https://docs.aws.amazon.com/cli/latest/userguide/install-cliv2-windows.html) process.

------
#### [ AWS CLI version 1 ]
  + [Docker](https://docs.docker.com/install/) version 18.09 or later. Earlier versions might also work, but we recommend 18.09 or later.
  + [Python](https://www.python.org/downloads/) version 3.6 or later.
  + [pip](https://pip.pypa.io/en/stable/installing) version 18.1 or later.
  + AWS CLI version 1.17.10 or later
    + To install the AWS CLI version 1, see [Installing the AWS CLI version 1](https://docs.aws.amazon.com/cli/latest/userguide/install-cliv1.html).
    + To configure the AWS CLI, see [Configuring the AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-configure.html).
    + To upgrade to the latest version of the AWS CLI version 1, run the following command.

      ```
      pip install awscli --upgrade --user
      ```
**Note**  
If you use the [MSI installation](https://docs.aws.amazon.com/cli/latest/userguide/install-windows.html#msi-on-windows) of the AWS CLI version 1 on Windows, be aware of the following:  
If the AWS CLI version 1 installation fails to install botocore, try using the [Python and pip installation](https://docs.aws.amazon.com/cli/latest/userguide/awscli-install-windows.html#awscli-install-windows-pip).
To upgrade to a later AWS CLI version 1, you must repeat the MSI installation process.

------
+ To access Amazon Elastic Container Registry (Amazon ECR) resources, you must grant the following permission. 
  + Amazon ECR requires users to grant the `ecr:GetAuthorizationToken` permission through an AWS Identity and Access Management (IAM) policy before they can authenticate to a registry and push or pull images from an Amazon ECR repository. For more information, see [Amazon ECR Repository Policy Examples](https://docs.aws.amazon.com/AmazonECR/latest/userguide/repository-policy-examples.html) and [Accessing One Amazon ECR Repository](https://docs.aws.amazon.com/AmazonECR/latest/userguide/security_iam_id-based-policy-examples.html#security_iam_id-based-policy-examples-access-one-bucket) in the *Amazon Elastic Container Registry User Guide*.

## Step 1: Get the AWS IoT Greengrass container image from Amazon ECR
<a name="docker-pull-image"></a>

AWS provides Docker images that have the AWS IoT Greengrass Core software installed.

**Warning**  <a name="docker-images-python-2.7-removal"></a>
Starting with v1.11.6 of the AWS IoT Greengrass Core software, the Greengrass Docker images no longer include Python 2.7, because Python 2.7 reached end-of-life in 2020 and no longer receives security updates. If you choose to update to these Docker images, we recommend that you validate that your applications work with the new Docker images before you deploy the updates to production devices. If you require Python 2.7 for your application that uses a Greengrass Docker image, you can modify the Greengrass Dockerfile to include Python 2.7 for your application.

For steps that show how to pull the `latest` image from Amazon ECR, choose your operating system:

### Pull the container image (Linux)
<a name="docker-pull-image-linux"></a>

Run the following commands in your computer terminal.

1. <a name="docker-get-login"></a>Log in to the AWS IoT Greengrass registry in Amazon ECR.

   ```
   aws ecr get-login-password --region  us-west-2 | docker login --username AWS --password-stdin https://216483018798.dkr.ecr.us-west-2.amazonaws.com
   ```

   If successful, the output prints `Login Succeeded`.

1. <a name="docker-docker-pull"></a>Retrieve the AWS IoT Greengrass container image.

   ```
   docker pull 216483018798.dkr.ecr.us-west-2.amazonaws.com/aws-iot-greengrass:latest
   ```
**Note**  
The `latest` image contains the latest stable version of the AWS IoT Greengrass Core software installed on an Amazon Linux 2 base image. You can also pull other images from the repository. To find all available images, check the **Tags** page on [Docker Hub](https://hub.docker.com/r/amazon/aws-iot-greengrass) or use the **aws ecr list-images** command. For example:  

   ```
   aws ecr list-images --region us-west-2 --registry-id 216483018798 --repository-name aws-iot-greengrass
   ```

1. Enable symlink and hardlink protection. If you're experimenting with running AWS IoT Greengrass in a container, you can enable the settings for the current boot only.
**Note**  
You might need to use **sudo** to run these commands.
   + To enable the settings for the current boot only:

     ```
     echo 1 > /proc/sys/fs/protected_hardlinks
     echo 1 > /proc/sys/fs/protected_symlinks
     ```
   + To enable the settings to persist across restarts:

     ```
     echo '# AWS IoT Greengrass' >> /etc/sysctl.conf 
     echo 'fs.protected_hardlinks = 1' >> /etc/sysctl.conf 
     echo 'fs.protected_symlinks = 1' >> /etc/sysctl.conf
     
     sysctl -p
     ```

1. <a name="docker-linux-enable-ipv4"></a>Enable IPv4 network forwarding, which is required for AWS IoT Greengrass cloud deployment and MQTT communications to work on Linux. In the `/etc/sysctl.conf` file, set `net.ipv4.ip_forward` to 1, and then reload `sysctls`.

   ```
   sudo nano /etc/sysctl.conf
   # set this net.ipv4.ip_forward = 1
   sudo sysctl -p
   ```
**Note**  
You can use the editor of your choice instead of nano.

### Pull the container image (macOS)
<a name="docker-pull-image-mac"></a>

Run the following commands in your computer terminal.

1. <a name="docker-get-login"></a>Log in to the AWS IoT Greengrass registry in Amazon ECR.

   ```
   aws ecr get-login-password --region  us-west-2 | docker login --username AWS --password-stdin https://216483018798.dkr.ecr.us-west-2.amazonaws.com
   ```

   If successful, the output prints `Login Succeeded`.

1. <a name="docker-docker-pull"></a>Retrieve the AWS IoT Greengrass container image.

   ```
   docker pull 216483018798.dkr.ecr.us-west-2.amazonaws.com/aws-iot-greengrass:latest
   ```
**Note**  
The `latest` image contains the latest stable version of the AWS IoT Greengrass Core software installed on an Amazon Linux 2 base image. You can also pull other images from the repository. To find all available images, check the **Tags** page on [Docker Hub](https://hub.docker.com/r/amazon/aws-iot-greengrass) or use the **aws ecr list-images** command. For example:  

   ```
   aws ecr list-images --region us-west-2 --registry-id 216483018798 --repository-name aws-iot-greengrass
   ```

### Pull the container image (Windows)
<a name="docker-pull-image-windows"></a>

Run the following commands in a command prompt. Before you can use Docker commands on Windows, Docker Desktop must be running.

1. <a name="docker-get-login"></a>Log in to the AWS IoT Greengrass registry in Amazon ECR.

   ```
   aws ecr get-login-password --region  us-west-2 | docker login --username AWS --password-stdin https://216483018798.dkr.ecr.us-west-2.amazonaws.com
   ```

   If successful, the output prints `Login Succeeded`.

1. <a name="docker-docker-pull"></a>Retrieve the AWS IoT Greengrass container image.

   ```
   docker pull 216483018798.dkr.ecr.us-west-2.amazonaws.com/aws-iot-greengrass:latest
   ```
**Note**  
The `latest` image contains the latest stable version of the AWS IoT Greengrass Core software installed on an Amazon Linux 2 base image. You can also pull other images from the repository. To find all available images, check the **Tags** page on [Docker Hub](https://hub.docker.com/r/amazon/aws-iot-greengrass) or use the **aws ecr list-images** command. For example:  

   ```
   aws ecr list-images --region us-west-2 --registry-id 216483018798 --repository-name aws-iot-greengrass
   ```

## Step 2: Create and configure the Greengrass group and core
<a name="docker-config-gg"></a>

The Docker image has the AWS IoT Greengrass Core software installed, but you must create a Greengrass group and core. This includes downloading certificates and the core configuration file.
+ Follow the steps in [Module 2: Installing the AWS IoT Greengrass Core software](module2.md). Skip the steps where you download and run the AWS IoT Greengrass Core software. The software and its runtime dependencies are already set up in the Docker image.

## Step 3: Run AWS IoT Greengrass locally
<a name="docker-run-gg"></a>

After your group is configured, you're ready to configure and start the core. For steps that show how to do this, choose your operating system:

### Run Greengrass locally (Linux)
<a name="docker-run-gg-linux"></a>

Run the following commands in your computer terminal.

1. <a name="docker-create-certs-folder"></a>Create a folder for the device's security resources, and move the certificate and keys into that folder. Run the following commands. Replace *path-to-security-files* with the path to the security resources, and replace *certificateId* with the certificate ID in the file names.

   ```
   mkdir /tmp/certs
   mv path-to-security-files/certificateId-certificate.pem.crt /tmp/certs
   mv path-to-security-files/certificateId-public.pem.key /tmp/certs
   mv path-to-security-files/certificateId-private.pem.key /tmp/certs
   mv path-to-security-files/AmazonRootCA1.pem /tmp/certs
   ```

1. <a name="docker-create-config-folder"></a>Create a folder for the device's configuration, and move the AWS IoT Greengrass Core configuration file to that folder. Run the following commands. Replace *path-to-config-file* with the path to the configuration file.

   ```
   mkdir /tmp/config
   mv path-to-config-file/config.json /tmp/config
   ```

1. <a name="docker-docker-run"></a>Start AWS IoT Greengrass and bind-mount the certificates and configuration file in the Docker container.

   Replace `/tmp` with the path where you decompressed your certificates and configuration file.

   ```
   docker run --rm --init -it --name aws-iot-greengrass \
   --entrypoint /greengrass-entrypoint.sh \
   -v /tmp/certs:/greengrass/certs \
   -v /tmp/config:/greengrass/config \
   -p 8883:8883 \
   216483018798.dkr.ecr.us-west-2.amazonaws.com/aws-iot-greengrass:latest
   ```

   The output should look like this example:

   ```
   Setting up greengrass daemon
   Validating hardlink/softlink protection
   Waiting for up to 30s for Daemon to start
   
   Greengrass successfully started with PID: 10
   ```

### Run Greengrass locally (macOS)
<a name="docker-run-gg-mac"></a>

Run the following commands in your computer terminal.

1. <a name="docker-create-certs-folder"></a>Create a folder for the device's security resources, and move the certificate and keys into that folder. Run the following commands. Replace *path-to-security-files* with the path to the security resources, and replace *certificateId* with the certificate ID in the file names.

   ```
   mkdir /tmp/certs
   mv path-to-security-files/certificateId-certificate.pem.crt /tmp/certs
   mv path-to-security-files/certificateId-public.pem.key /tmp/certs
   mv path-to-security-files/certificateId-private.pem.key /tmp/certs
   mv path-to-security-files/AmazonRootCA1.pem /tmp/certs
   ```

1. <a name="docker-create-config-folder"></a>Create a folder for the device's configuration, and move the AWS IoT Greengrass Core configuration file to that folder. Run the following commands. Replace *path-to-config-file* with the path to the configuration file.

   ```
   mkdir /tmp/config
   mv path-to-config-file/config.json /tmp/config
   ```

1. <a name="docker-docker-run"></a>Start AWS IoT Greengrass and bind-mount the certificates and configuration file in the Docker container.

   Replace `/tmp` with the path where you decompressed your certificates and configuration file.

   ```
   docker run --rm --init -it --name aws-iot-greengrass \
   --entrypoint /greengrass-entrypoint.sh \
   -v /tmp/certs:/greengrass/certs \
   -v /tmp/config:/greengrass/config \
   -p 8883:8883 \
   216483018798.dkr.ecr.us-west-2.amazonaws.com/aws-iot-greengrass:latest
   ```

   The output should look like this example:

   ```
   Setting up greengrass daemon
   Validating hardlink/softlink protection
   Waiting for up to 30s for Daemon to start
   
   Greengrass successfully started with PID: 10
   ```

### Run Greengrass locally (Windows)
<a name="docker-run-gg-windows"></a>

1. Create a folder for the device's security resources, and move the certificate and keys into that folder. Run the following commands in a command prompt. Replace *path-to-security-files* with the path to the security resources, and replace *certificateId* with the certificate ID in the file names.

   ```
   mkdir C:\Users\%USERNAME%\Downloads\certs
   move path-to-security-files\certificateId-certificate.pem.crt C:\Users\%USERNAME%\Downloads\certs
   move path-to-security-files\certificateId-public.pem.key C:\Users\%USERNAME%\Downloads\certs
   move path-to-security-files\certificateId-private.pem.key C:\Users\%USERNAME%\Downloads\certs
   move path-to-security-files\AmazonRootCA1.pem C:\Users\%USERNAME%\Downloads\certs
   ```

1. Create a folder for the device's configuration, and move the AWS IoT Greengrass Core configuration file to that folder. Run the following commands in a command prompt. Replace *path-to-config-file* with the path to the configuration file.

   ```
   mkdir C:\Users\%USERNAME%\Downloads\config
   move path-to-config-file\config.json C:\Users\%USERNAME%\Downloads\config
   ```

1. Start AWS IoT Greengrass and bind-mount the certificates and configuration file in the Docker container. Run the following commands in your command prompt.

   ```
   docker run --rm --init -it --name aws-iot-greengrass --entrypoint /greengrass-entrypoint.sh -v c:/Users/%USERNAME%/Downloads/certs:/greengrass/certs -v c:/Users/%USERNAME%/Downloads/config:/greengrass/config -p 8883:8883 216483018798.dkr.ecr.us-west-2.amazonaws.com/aws-iot-greengrass:latest
   ```

   When Docker prompts you to share your `C:\` drive with the Docker daemon, allow it to bind-mount the `C:\` directory inside the Docker container. For more information, see [Shared drives](https://docs.docker.com/docker-for-windows/#shared-drives) in the Docker documentation. 

   The output should look like this example:

   ```
   Setting up greengrass daemon
   Validating hardlink/softlink protection
   Waiting for up to 30s for Daemon to start
   
   Greengrass successfully started with PID: 10
   ```

**Note**  
If the container doesn't open the shell and exits immediately, you can debug the issue by bind-mounting the Greengrass runtime logs when you start the image. For more information, see [To persist Greengrass runtime logs outside of the Docker container](#debugging-docker-persist-logs).

## Step 4: Configure "No container" containerization for the Greengrass group
<a name="docker-no-container"></a>

When you run AWS IoT Greengrass in a Docker container, all Lambda functions must run without containerization. In this step, you set the default containerization for the group to **No container**. You must do this before you deploy the group for the first time.

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. <a name="group-choose-group"></a>Choose the group whose settings you want to change.

1. Choose the **Lambda functions** tab.

1. Under **Default Lambda function runtime environment**, choose **Edit**.

1. In the **Edit default Lambda function runtime environment**, under **Default Lambda function containerization**, change the containerization settings.

1. Choose **Save**.

The changes take effect when the group is deployed.

For more information, see [Setting default containerization for Lambda functions in a group](lambda-group-config.md#lambda-containerization-groupsettings).

**Note**  
By default, Lambda functions use the group containerization setting. If you override the **No container** setting for any Lambda functions when AWS IoT Greengrass is running in a Docker container, the deployment fails.

## Step 5: Deploy Lambda functions to the AWS IoT Greengrass Docker container
<a name="docker-add-lambdas"></a>

You can deploy long-lived Lambda functions to the Greengrass Docker container.
+ Follow the steps in [Module 3 (part 1): Lambda functions on AWS IoT Greengrass](module3-I.md) to deploy a long-lived Hello World Lambda function to the container.

## Step 6: (Optional) Deploy client devices that interact with Greengrass running in the Docker container
<a name="docker-add-devices"></a>

You can also deploy client devices that interact with AWS IoT Greengrass when it's running in a Docker container.
+ Follow the steps in [Module 4: Interacting with client devices in an AWS IoT Greengrass group](module4.md) to deploy client devices that connect to the core and send MQTT messages.

## Stopping the AWS IoT Greengrass Docker container
<a name="docker-stop"></a>

To stop the AWS IoT Greengrass Docker container, press Ctrl\$1C in your terminal or command prompt. This action sends `SIGTERM` to the Greengrass daemon process to tear down the Greengrass daemon process and all Lambda processes that were started by the daemon process. The Docker container is initialized with `/dev/init` process as PID 1, which helps in removing any leftover zombie processes. For more information, see the [Docker run reference](https://docs.docker.com/engine/reference/commandline/run/#options).

## Troubleshooting AWS IoT Greengrass in a Docker container
<a name="troubleshooting-docker-gg"></a>

Use the following information to help troubleshoot issues with running AWS IoT Greengrass in a Docker container.

### Error: Cannot perform an interactive login from a non TTY device.
<a name="docker-troubleshootin-ecr-get-login-password"></a>

**Solution:** This error can occur when you run the `aws ecr get-login-password` command. Make sure that you installed the latest AWS CLI version 2 or version 1. We recommend that you use the AWS CLI version 2. For more information, see [Installing the AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-install.html) in the *AWS Command Line Interface User Guide*.

### Error: Unknown options: -no-include-email.
<a name="docker-troubleshooting-cli-version"></a>

**Solution:** This error can occur when you run the `aws ecr get-login` command. Make sure that you have the latest AWS CLI version installed (for example, run: `pip install awscli --upgrade --user`). If you're using Windows and you installed the CLI using the MSI installer, you must repeat the installation process. For more information, see [Installing the AWS Command Line Interface on Microsoft Windows](https://docs.aws.amazon.com/cli/latest/userguide/awscli-install-windows.html) in the *AWS Command Line Interface User Guide*.

### Warning: IPv4 is disabled. Networking will not work.
<a name="docker-troubleshooting-ipv4-disabled"></a>

**Solution:** You might receive this warning or a similar message when running AWS IoT Greengrass on a Linux computer. Enable IPv4 network forwarding as described in this [step](#docker-linux-enable-ipv4). AWS IoT Greengrass cloud deployment and MQTT communications don't work when IPv4 forwarding isn't enabled. For more information, see [Configure namespaced kernel parameters (sysctls) at runtime](https://docs.docker.com/engine/reference/commandline/run/#configure-namespaced-kernel-parameters-sysctls-at-runtime) in the Docker documentation.

### Error: A firewall is blocking file Sharing between windows and the containers.
<a name="docker-troubleshooting-firewall"></a>

**Solution:** You might receive this error or a `Firewall Detected` message when running Docker on a Windows computer. This can also occur if you are signed in on a virtual private network (VPN) and your network settings are preventing the shared drive from being mounted. In that situation, turn off VPN and re-run the Docker container.

### Error: An error occurred (AccessDeniedException) when calling the GetAuthorizationToken operation: User: arn:aws:iam::<account-id>:user/<user-name> is not authorized to perform: ecr:GetAuthorizationToken on resource: \$1
<a name="docker-troubleshooting-ecr-perms"></a>

You might receive this error when running the `aws ecr get-login-password` command if you don't have sufficient permissions to access an Amazon ECR repository. For more information, see [Amazon ECR Repository Policy Examples](https://docs.aws.amazon.com/AmazonECR/latest/userguide/repository-policy-examples.html) and [Accessing One Amazon ECR Repository](https://docs.aws.amazon.com/AmazonECR/latest/userguide/security_iam_id-based-policy-examples.html) in the *Amazon ECR User Guide*.

For general AWS IoT Greengrass troubleshooting help, see [Troubleshooting AWS IoT Greengrass](gg-troubleshooting.md).

### Debugging AWS IoT Greengrass in a Docker container
<a name="debugging-docker-gg"></a>

To debug issues with a Docker container, you can persist the Greengrass runtime logs or attach an interactive shell to the Docker container.

#### To persist Greengrass runtime logs outside of the Docker container
<a name="debugging-docker-persist-logs"></a>

You can run the AWS IoT Greengrass Docker container after bind-mounting the `/greengrass/ggc/var/log` directory. The logs persist even after the container exits or is removed.

**On Linux or macOS**  
[Stop any Greengrass Docker containers](#docker-stop) running on the host, and then run the following command in a terminal. This bind-mounts the Greengrass `log` directory and starts the Docker image.   
Replace `/tmp` with the path where you decompressed your certificates and configuration file.  

```
docker run --rm --init -it --name aws-iot-greengrass \
      --entrypoint /greengrass-entrypoint.sh \
      -v /tmp/certs:/greengrass/certs \
      -v /tmp/config:/greengrass/config \
      -v /tmp/log:/greengrass/ggc/var/log \
      -p 8883:8883 \
      216483018798.dkr.ecr.us-west-2.amazonaws.com/aws-iot-greengrass:latest
```
You can then check your logs at `/tmp/log` on your host to see what happened while Greengrass was running inside the Docker container.

**On Windows**  
[Stop any Greengrass Docker containers](#docker-stop) running on the host, and then run the following command in a command prompt. This bind-mounts the Greengrass `log` directory and starts the Docker image.  

```
cd C:\Users\%USERNAME%\Downloads
mkdir log
docker run --rm --init -it --name aws-iot-greengrass --entrypoint /greengrass-entrypoint.sh -v c:/Users/%USERNAME%/Downloads/certs:/greengrass/certs -v c:/Users/%USERNAME%/Downloads/config:/greengrass/config -v c:/Users/%USERNAME%/Downloads/log:/greengrass/ggc/var/log -p 8883:8883 216483018798.dkr.ecr.us-west-2.amazonaws.com/aws-iot-greengrass:latest
```
You can then check your logs at `C:/Users/%USERNAME%/Downloads/log` on your host to see what happened while Greengrass was running inside the Docker container.

#### To attach an interactive shell to the Docker container
<a name="debugging-docker-attach-shell"></a>

You can attach an interactive shell to a running AWS IoT Greengrass Docker container. This can help you investigate the state of the Greengrass Docker container.

**On Linux or macOS**  
While the Greengrass Docker container is running, run the following command in a separate terminal.  

```
docker exec -it $(docker ps -a -q -f "name=aws-iot-greengrass") /bin/bash
```

**On Windows**  
While the Greengrass Docker container is running, run the following commands in a separate command prompt.  

```
docker ps -a -q -f "name=aws-iot-greengrass"
```
Replace *gg-container-id* with the `container_id` result from the previous command.  

```
docker exec -it gg-container-id /bin/bash
```