

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

# Getting started with AWS IoT Greengrass
<a name="gg-gs"></a>

This Getting Started tutorial includes several modules designed to show you AWS IoT Greengrass basics and help you get started using AWS IoT Greengrass. This tutorial covers fundamental concepts, such as:
+ Configuring AWS IoT Greengrass cores and groups.
+ The deployment process for running AWS Lambda functions at the edge.
+ Connecting AWS IoT devices, called client devices, to the AWS IoT Greengrass core.
+ Creating subscriptions to allow MQTT communication between local Lambda functions, client devices, and AWS IoT.

## Choose how to get started with AWS IoT Greengrass
<a name="gg-getting-started"></a>

You can choose how to use this tutorial to set up your core device:
+ Run [Greengrass device setup](quick-start.md) on your core device, which takes you from installing AWS IoT Greengrass dependencies to testing a Hello World Lambda function in minutes. This script reproduces the steps in Module 1 through Module 3-1.

   

   - or -

   
+ Walk through the steps in Module 1 through Module 3-1 to examine Greengrass requirements and processes more closely. These steps set up your core device, create and configure a Greengrass group that contains a Hello World Lambda function, and deploy your Greengrass group. Typically, this takes an hour or two to complete.

![\[Getting Started modules\]](http://docs.aws.amazon.com/greengrass/v1/developerguide/images/getting-started-modules.png)


**Quick Start**  
[Greengrass device setup](quick-start.md) configures your core device and Greengrass resources. The script:  
+ Installs AWS IoT Greengrass dependencies.
+ Downloads the root CA certificate and core device certificate and keys.
+ Downloads, installs, and configures the AWS IoT Greengrass Core software on your device.
+ Starts the Greengrass daemon process on the core device.
+ Creates or updates the [Greengrass service role](service-role.md), if needed.
+ Creates a Greengrass group and Greengrass core.
+ (Optional) Creates a Hello World Lambda function, subscription, and local logging configuration.
+ (Optional) Deploys the Greengrass group.

**Modules 1 and 2**  
[Module 1](module1.md) and [Module 2](module2.md) describe how to set up your environment. (Or, use [Greengrass device setup](quick-start.md) to run these modules for you.)  
+ Configure your core device for Greengrass.
+ Run the dependency checker script.
+ Create a Greengrass group and Greengrass core.
+ Download and install the latest AWS IoT Greengrass Core software from a tar.gz file.
+ Start the Greengrass daemon process on the core.
AWS IoT Greengrass also provides other options for installing the AWS IoT Greengrass Core software, including `apt` installations on supported Debian platforms. For more information, see [Install the AWS IoT Greengrass Core software](install-ggc.md).

**Modules 3-1 and 3-2**  
[Module 3-1](module3-I.md) and [Module 3-2](module3-II.md) describe how to use local Lambda functions. (Or, use [Greengrass device setup](quick-start.md) to run Module 3-1 for you.)  
+ Create Hello World Lambda functions in AWS Lambda.
+ Add Lambda functions to your Greengrass group.
+ Create subscriptions that allow MQTT communication between the Lambda functions and AWS IoT.
+ Configure local logging for Greengrass system components and Lambda functions.
+ Deploy a Greengrass group that contains your Lambda functions and subscriptions.
+ Send messages from local Lambda functions to AWS IoT.
+ Invoke local Lambda functions from AWS IoT.
+ Test on-demand and long-lived functions.

**Modules 4 and 5**  
[Module 4](module4.md) shows how client devices connect to the core and communicate with each other.  
[Module 5](module5.md) shows how client devices can use shadows to control state.  
+ Register and provision AWS IoT devices (represented by command-line terminals).
+ Install the AWS IoT Device SDK for Python. This is used by client devices to discover the Greengrass core.
+ Add the client devices to your Greengrass group.
+ Create subscriptions that allow MQTT communication.
+ Deploy a Greengrass group that contains your client devices.
+ Test device-to-device communication.
+ Test shadow state updates.

**Module 6**  
[Module 6](module6.md) shows you how Lambda functions can access the AWS Cloud.  
+ Create a Greengrass group role that allows access to Amazon DynamoDB resources.
+ Add a Lambda function to your Greengrass group. This function uses the AWS SDK for Python to interact with DynamoDB.
+ Create subscriptions that allow MQTT communication.
+ Test the interaction with DynamoDB.

**Module 7**  
[Module 7](console-mod7.md) shows you how to configure a simulated hardware security module (HSM) for use with a Greengrass core.  
This advanced module is provided only for experimentation and initial testing. It is not for production use of any kind.
+ Install and configure a software-based HSM and private key.
+ Configure the Greengrass core to use hardware security.
+ Test the hardware security configuration.

## Requirements
<a name="gg-requirements"></a>

To complete this tutorial, you need the following:
+ A Mac, Windows PC, or UNIX-like system.
+ An AWS account. If you don't have one, see [Create an AWS account](#create-aws-account). 
+ The use of an AWS [Region](https://en.wikipedia.org/wiki/Amazon_Web_Services#Availability_and_topology) that supports AWS IoT Greengrass. For the list of supported regions for AWS IoT Greengrass, see [AWS endpoints and quotas](https://docs.aws.amazon.com/general/latest/gr/greengrass.html) in the *AWS General Reference*.
**Note**  
Make a note of your AWS Region and make sure that it is consistently used throughout this tutorial. If you switch your AWS Region during the tutorial, you might experience problems completing the steps.
+ A Raspberry Pi 4 Model B, or Raspberry Pi 3 Model B/B\$1, with a 8 GB microSD card, or an Amazon EC2 instance. Because AWS IoT Greengrass should ideally be used with physical hardware, we recommend that you use a Raspberry Pi.
**Note**  
Run the following command to get the model of your Raspberry Pi:  

  ```
  cat /proc/cpuinfo
  ```
Near the bottom of the listing, make a note of the value of the `Revision` attribute and then consult the [Which Pi have I got?](https://elinux.org/RPi_HardwareHistory#Which_Pi_have_I_got.3F) table. For example, if the value of `Revision` is `a02082`, the table shows the Pi is a 3 Model B.   
Run the following command to determine the architecture of your Raspberry Pi:  

  ```
  uname -m
  ```
For this tutorial, the result should be greater than or equal to `armv71`.
+ Basic familiarity with Python.

Although this tutorial is intended to run AWS IoT Greengrass on a Raspberry Pi, AWS IoT Greengrass also supports other platforms. For more information, see [Supported platforms and requirements](what-is-gg.md#gg-platforms).

## Create an AWS account
<a name="create-aws-account"></a>

If you don't have an AWS account, follow these steps to create and activate an AWS account:

### Sign up for an AWS account
<a name="sign-up-for-aws"></a>

If you do not have an AWS account, complete the following steps to create one.

**To sign up for an AWS account**

1. Open [https://portal.aws.amazon.com/billing/signup](https://portal.aws.amazon.com/billing/signup).

1. Follow the online instructions.

   Part of the sign-up procedure involves receiving a phone call or text message and entering a verification code on the phone keypad.

   When you sign up for an AWS account, an *AWS account root user* is created. The root user has access to all AWS services and resources in the account. As a security best practice, assign administrative access to a user, and use only the root user to perform [tasks that require root user access](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_root-user.html#root-user-tasks).

AWS sends you a confirmation email after the sign-up process is complete. At any time, you can view your current account activity and manage your account by going to [https://aws.amazon.com/](https://aws.amazon.com/) and choosing **My Account**.

### Create a user with administrative access
<a name="create-an-admin"></a>

After you sign up for an AWS account, secure your AWS account root user, enable AWS IAM Identity Center, and create an administrative user so that you don't use the root user for everyday tasks.

**Secure your AWS account root user**

1.  Sign in to the [AWS Management Console](https://console.aws.amazon.com/) as the account owner by choosing **Root user** and entering your AWS account email address. On the next page, enter your password.

   For help signing in by using root user, see [Signing in as the root user](https://docs.aws.amazon.com/signin/latest/userguide/console-sign-in-tutorials.html#introduction-to-root-user-sign-in-tutorial) in the *AWS Sign-In User Guide*.

1. Turn on multi-factor authentication (MFA) for your root user.

   For instructions, see [Enable a virtual MFA device for your AWS account root user (console)](https://docs.aws.amazon.com/IAM/latest/UserGuide/enable-virt-mfa-for-root.html) in the *IAM User Guide*.

**Create a user with administrative access**

1. Enable IAM Identity Center.

   For instructions, see [Enabling AWS IAM Identity Center](https://docs.aws.amazon.com//singlesignon/latest/userguide/get-set-up-for-idc.html) in the *AWS IAM Identity Center User Guide*.

1. In IAM Identity Center, grant administrative access to a user.

   For a tutorial about using the IAM Identity Center directory as your identity source, see [ Configure user access with the default IAM Identity Center directory](https://docs.aws.amazon.com//singlesignon/latest/userguide/quick-start-default-idc.html) in the *AWS IAM Identity Center User Guide*.

**Sign in as the user with administrative access**
+ To sign in with your IAM Identity Center user, use the sign-in URL that was sent to your email address when you created the IAM Identity Center user.

  For help signing in using an IAM Identity Center user, see [Signing in to the AWS access portal](https://docs.aws.amazon.com/signin/latest/userguide/iam-id-center-sign-in-tutorial.html) in the *AWS Sign-In User Guide*.

**Assign access to additional users**

1. In IAM Identity Center, create a permission set that follows the best practice of applying least-privilege permissions.

   For instructions, see [ Create a permission set](https://docs.aws.amazon.com//singlesignon/latest/userguide/get-started-create-a-permission-set.html) in the *AWS IAM Identity Center User Guide*.

1. Assign users to a group, and then assign single sign-on access to the group.

   For instructions, see [ Add groups](https://docs.aws.amazon.com//singlesignon/latest/userguide/addgroups.html) in the *AWS IAM Identity Center User Guide*.

**Important**  
For this tutorial, we assume that your IAM user account has administrator access permissions.

# Quick start: Greengrass device setup
<a name="quick-start"></a>

Greengrass device setup is a script that sets up your core device in minutes, so that you can start using AWS IoT Greengrass. Use this script to:

1. Configure your device and installs the AWS IoT Greengrass Core software.

1. Configure your cloud-based resources.

1. Optionally deploy a Greengrass group with a Hello World Lambda function that sends MQTT messages to AWS IoT from the AWS IoT Greengrass core. This sets up the Greengrass environment shown in the following diagram.  
![\[Hello World Lambda function sending an MQTT message to AWS IoT from the AWS IoT Greengrass core.\]](http://docs.aws.amazon.com/greengrass/v1/developerguide/images/quick-start-gg-architecture.png)

## Requirements
<a name="gg-device-setup-requirements"></a>

Greengrass device setup has the following requirements:
+ Your core device must use a [supported platform](what-is-gg.md#gg-platforms). The device must have an appropriate package manager installed: `apt`, `yum`, or `opkg`.

   
+ The Linux user who runs the script must have permissions to run as `sudo`.

   
+ You must provide your AWS account credentials. For more information, see [Provide AWS account credentials](#gg-device-setup-credentials).
**Note**  
Greengrass device setup installs the [latest version](what-is-gg.md#ggc-versions) of the AWS IoT Greengrass Core software on the device. By installing the AWS IoT Greengrass Core software, you agree to the [Greengrass Core Software License Agreement](https://greengrass-release-license.s3.us-west-2.amazonaws.com/greengrass-license-v1.pdf).

## Run Greengrass device setup
<a name="run-gg-device-setup"></a>

You can run Greengrass device setup in just a few steps. After you provide your AWS account credentials, the script provisions your Greengrass core device and deploys a Greengrass group in minutes. Run the following commands in a terminal window on the target device.

**Note**  
These steps show you how to run the script in interactive mode, which prompts you to enter or accept each input value. For information about how to run the script silently, see [Run Greengrass device setup in silent mode](#gg-device-setup-silent-mode).

 

1. [Provide your credentials](#gg-device-setup-credentials). In this procedure, we assume you provide temporary security credentials as environment variables.

   ```
   export AWS_ACCESS_KEY_ID=AKIAIOSFODNN7EXAMPLE
   export AWS_SECRET_ACCESS_KEY=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
   export AWS_SESSION_TOKEN=AQoDYXdzEJr1K...o5OytwEXAMPLE=
   ```
**Note**  
If you're running Greengrass device setup on a Raspbian or OpenWrt platform, make a copy of these commands. You must provide them again after you reboot the device.

1. Download and start the script. You can use `wget` or `curl` to download the script.  
  
`wget`:  

   ```
   wget -q -O ./gg-device-setup-latest.sh https://d1onfpft10uf5o.cloudfront.net/greengrass-device-setup/downloads/gg-device-setup-latest.sh && chmod +x ./gg-device-setup-latest.sh && sudo -E ./gg-device-setup-latest.sh bootstrap-greengrass-interactive
   ```  
  
`curl`:  

   ```
   curl https://d1onfpft10uf5o.cloudfront.net/greengrass-device-setup/downloads/gg-device-setup-latest.sh > gg-device-setup-latest.sh && chmod +x ./gg-device-setup-latest.sh && sudo -E ./gg-device-setup-latest.sh bootstrap-greengrass-interactive 
   ```

1. Proceed through the command prompts for [input values](#gg-device-setup-input). You can press the **Enter** key to use the default value or type a custom value and then press **Enter**.

   The script writes status messages to the terminal that are similar to the following.  
![\[Output messages in the terminal.\]](http://docs.aws.amazon.com/greengrass/v1/developerguide/images/quick-start-in-progress.png)

1. If your core device is running Raspbian or OpenWrt, reboot the device when prompted, provide your credentials, and then restart the script.

   1. <a name="quick-start-reboot"></a>When prompted to reboot the device, run one of the following commands.  
  
For Raspbian platforms:  

      ```
      sudo reboot
      ```  
  
For OpenWrt platforms:  

      ```
      reboot
      ```

   1. <a name="quick-start-reboot-creds"></a>After the device reboots, open the terminal and provide your credentials as environment variables.

      ```
      export AWS_ACCESS_KEY_ID=AKIAIOSFODNN7EXAMPLE
      export AWS_SECRET_ACCESS_KEY=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
      export AWS_SESSION_TOKEN=AQoDYXdzEJr1K...o5OytwEXAMPLE=
      ```

   1. Restart the script.

      ```
      sudo -E ./gg-device-setup-latest.sh bootstrap-greengrass-interactive
      ```

   1. <a name="quick-start-reuse-input-values"></a>When prompted whether to use your input values from the previous session or start a new installation, enter `yes` to reuse your input values.
**Note**  
On platforms that require a reboot, your input values from the previous session, excluding credentials, are temporarily stored in the `GreengrassDeviceSetup.config.info` file.

   When the setup is complete, the terminal displays a success status message that's similar to the following.  
![\[Success message in the terminal output.\]](http://docs.aws.amazon.com/greengrass/v1/developerguide/images/quick-start-completed.png)

1. Review the new Greengrass group that the script configures using the input values you provide. 

   1. Sign in to the [AWS Management Console](https://console.aws.amazon.com/) on your computer and open the AWS IoT console. 
**Note**  
Make sure that the AWS Region selected in the console is the same one that you used to configure your Greengrass environment. By default, the Region is US West (Oregon).

   1. In the navigation pane, expand **Greengrass devices**, then choose **Groups (V1)** to locate the newly created group. 

1. <a name="quick-start-next-steps"></a>If you included the Hello World Lambda function, Greengrass device setup deploys the Greengrass group to your core device. To test the Lambda function, or for information about how to remove the Lambda function from the group, continue to [Verify the Lambda function is running on the core device](lambda-check.md) in Module 3-1 of the Getting Started tutorial.
**Note**  
Make sure that the AWS Region selected in the console is the same one that you used to configure your Greengrass environment. By default, the Region is US West (Oregon).

   If you didn't include the Hello World Lambda function, you can [create your own Lambda function](create-lambda.md) or try other Greengrass features. For example, you can add the [Docker application deployment](docker-app-connector.md) connector to your group and use it to deploy Docker containers to your core device.

    

## Troubleshooting issues
<a name="gg-device-setup-troubleshooting"></a>

 You can use the following information to troubleshoot issues with the AWS IoT Greengrass device setup. 

### Error: Python (python3.7) not found. Attempting to install it...
<a name="ec2-python-install-location"></a>

**Solution:** You might see this error when working with an Amazon EC2 instance. This error occurs when Python is not installed in the `/usr/bin/python3.7` folder. To resolve this error, move Python in the correct directory after installing it:

```
sudo ln -s /usr/local/bin/python3.7 /usr/bin/python3.7
```

### Additional troubleshooting
<a name="gg-device-other"></a>

To troubleshoot additional issues with the AWS IoT Greengrass device setup, you can look for debug information in the log files:
+ For issues with the Greengrass device setup configuration, check the `/tmp/greengrass-device-setup-bootstrap-epoch-timestamp.log` file.
+ For issues with the Greengrass group or core environment setup, check the `GreengrassDeviceSetup-date-time.log` file in the same directory as `gg-device-setup-latest.sh` or in the location you specified.

For more troubleshooting help, see [Troubleshooting AWS IoT Greengrass](gg-troubleshooting.md) or check the [AWS IoT Greengrass tag on AWS re:Post](https://repost.aws/tags/TA4ckIed1sR4enZBey29rKTg/aws-io-t-greengrass).

## Greengrass device setup configuration options
<a name="gg-device-setup-options"></a>

You configure Greengrass device setup to access your AWS resources and set up your Greengrass environment.

### Provide AWS account credentials
<a name="gg-device-setup-credentials"></a>

Greengrass device setup uses your AWS account credentials to access your AWS resources. It supports long-term credentials for an IAM user or temporary security credentials from an IAM role.

First, get your credentials.
+ To use long-term credentials, provide the access key ID and secret access key for your IAM user. For information about creating access keys for long-term credentials, see [Managing access keys for IAM users](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_access-keys.html) in the *IAM User Guide*.

   
+ To use temporary security credentials (recommended), provide the access key ID, secret access key, and session token from an assumed IAM role. For information about extracting temporary security credentials from the AWS STS `assume-role` command, see [Using temporary security credentials with the AWS CLI](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_use-resources.html#using-temp-creds-sdk-cli) in the *IAM User Guide*.

**Note**  
For the purposes of this tutorial, we assume that the IAM user or IAM role has administrator access permissions.

Then, provide your credentials to Greengrass device setup in one of two ways:
+ **As environment variables.** Set the `AWS_ACCESS_KEY_ID`, `AWS_SECRET_ACCESS_KEY`, and `AWS_SESSION_TOKEN` (if required) environment variables before you start the script, as shown in step 1 of [Run Greengrass device setup](#run-gg-device-setup).

   
+ **As input values.** Enter your access key ID, secret access key, and session token (if required) values directly in the terminal after you start the script.

Greengrass device setup doesn't save or store your credentials.

 

### Provide input values
<a name="gg-device-setup-input"></a>

In interactive mode, Greengrass device setup prompts you for input values. You can press the **Enter** key to use the default value or type a custom value and then press **Enter**. In silent mode, you provide input values after you start the script.

#### Input values
<a name="gg-device-setup-input-values"></a>

**AWS access key ID**  
The access key ID from the long-term or temporary security credentials. Specify this option as an input value only if you don't provide your credentials as environment variables. For more information, see [Provide AWS account credentials](#gg-device-setup-credentials).  
Option name for silent mode: `--aws-access-key-id`

**AWS secret access key**  
The secret access key from the long-term or temporary security credentials. Specify this option as an input value only if you don't provide your credentials as environment variables. For more information, see [Provide AWS account credentials](#gg-device-setup-credentials).  
Option name for silent mode: `--aws-secret-access-key`

**AWS session token**  
The session token from the temporary security credentials. Specify this option as an input value only if you don't provide your credentials as environment variables. For more information, see [Provide AWS account credentials](#gg-device-setup-credentials).  
Option name for silent mode: `--aws-session-token`

**AWS Region**  
The AWS Region where you want to create the Greengrass group. For the list of supported AWS Regions, see [AWS IoT Greengrass](https://docs.aws.amazon.com/general/latest/gr/greengrass.html) in the *Amazon Web Services General Reference*.  
Default value: `us-west-2`  
Option name for silent mode: `--region`

**Group name**  
The name for the Greengrass group.  
Default value: `GreengrassDeviceSetup_Group_guid`  
Option name for silent mode: `--group-name`

**Core name**  
The name for the Greengrass core. The core is an AWS IoT device (thing) that runs the AWS IoT Greengrass Core software. The core is added to the AWS IoT registry and the Greengrass group. If you provide a name, it must be unique in the AWS account and AWS Region.  
Default value: `GreengrassDeviceSetup_Core_guid`  
Option name for silent mode: `--core-name`

**AWS IoT Greengrass Core software installation path**  
The location in the device file system where you want to install the AWS IoT Greengrass Core software.  
Default value: `/`  
Option name for silent mode: `--ggc-root-path`

**Hello World Lambda function**  <a name="option-hello-world-lambda-function"></a>
Indicates whether to include a Hello World Lambda function in the Greengrass group. The function publishes an MQTT message to the `hello/world` topic every five seconds.  
The script creates and publishes this user-defined Lambda function in AWS Lambda and adds it to your Greengrass group. The script also creates a subscription in the group that allows the function to send MQTT messages to AWS IoT.  
This is a Python 3.7 Lambda function. If Python 3.7 isn't installed on the device and the script is unable to install it, the script prints an error message in the terminal. To include the Lambda function in the group, you must install Python 3.7 manually and restart the script. To create the Greengrass group without the Lambda function, restart the script and enter `no` when prompted to include the function.
Default value: `no`  
Option name for silent mode: `--hello-world-lambda` - This option doesn't take a value. Include it in your command if you want to create the function.

**Deployment timeout**  
The number of seconds before Greengrass device setup stops checking the status of the [Greengrass group deployment](deployments.md). This is used only when the group includes the Hello World Lambda function. Otherwise, the group is not deployed.  
The deployment time depends on your network speed. For slow network speeds, you can increase this value.  
Default value: `180`  
Option name for silent mode: `--deployment-timeout`

**Log path**  
The location of the log file that contains information about Greengrass group and core setup operations. Use this log to troubleshoot deployment and other issues with the Greengrass group and core setup.  
Default value: `./`  
Option name for silent mode: `--log-path`

**Verbosity**  
Indicates whether to print detailed log information in the terminal while the script runs. You can use this information to troubleshoot device setup.  
Default value: `no`  
Option name for silent mode: `--verbose` - This option doesn't take a value. Include it in your command if you want to print detailed log information.

 

### Run Greengrass device setup in silent mode
<a name="gg-device-setup-silent-mode"></a>

You can run Greengrass device setup in silent mode so that the script doesn't prompt you for any values. To run in silent mode, specify `bootstrap-greengrass` mode and your [input values](#gg-device-setup-input-values) after you start the script. You can omit input values if you want to use their defaults.

The procedure depends on whether you provide your AWS account credentials as environment variables before you start the script, or as input values after you start the script.

#### Provide credentials as environment variables
<a name="gg-device-setup-silent-mode-env-vars"></a>

1. [Provide your credentials](#gg-device-setup-credentials) as environment variables. The following example exports temporary credentials, which include the session token.

   ```
   export AWS_ACCESS_KEY_ID=AKIAIOSFODNN7EXAMPLE
   export AWS_SECRET_ACCESS_KEY=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
   export AWS_SESSION_TOKEN=AQoDYXdzEJr1K...o5OytwEXAMPLE=
   ```
**Note**  
If you're running Greengrass device setup on a Raspbian or OpenWrt platform, make a copy of these commands. You must provide them again after you reboot the device.

1. Download and start the script. Provide input values as needed. For example:
   + To use all default values:

     ```
     wget -q -O ./gg-device-setup-latest.sh https://d1onfpft10uf5o.cloudfront.net/greengrass-device-setup/downloads/gg-device-setup-latest.sh && chmod +x ./gg-device-setup-latest.sh && sudo -E ./gg-device-setup-latest.sh bootstrap-greengrass
     ```
   + To specify custom values:

     ```
     wget -q -O ./gg-device-setup-latest.sh https://d1onfpft10uf5o.cloudfront.net/greengrass-device-setup/downloads/gg-device-setup-latest.sh && chmod +x ./gg-device-setup-latest.sh && sudo -E ./gg-device-setup-latest.sh bootstrap-greengrass
     --region us-east-1
     --group-name Custom_Group_Name
     --core-name Custom_Core_Name
     --ggc-root-path /custom/ggc/root/path
     --deployment-timeout 300
     --log-path /customized/log/path
     --hello-world-lambda
     --verbose
     ```
**Note**  
To use `curl` to download the script, replace `wget -q -O` with `curl` in the command.

1. If your core device is running Raspbian or OpenWrt, reboot the device when prompted, provide your credentials, and then restart the script.

   1. <a name="quick-start-reboot"></a>When prompted to reboot the device, run one of the following commands.  
  
For Raspbian platforms:  

      ```
      sudo reboot
      ```  
  
For OpenWrt platforms:  

      ```
      reboot
      ```

   1. <a name="quick-start-reboot-creds"></a>After the device reboots, open the terminal and provide your credentials as environment variables.

      ```
      export AWS_ACCESS_KEY_ID=AKIAIOSFODNN7EXAMPLE
      export AWS_SECRET_ACCESS_KEY=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
      export AWS_SESSION_TOKEN=AQoDYXdzEJr1K...o5OytwEXAMPLE=
      ```

   1. Restart the script.

      ```
      sudo -E ./gg-device-setup-latest.sh bootstrap-greengrass
      ```

   1. <a name="quick-start-reuse-input-values"></a>When prompted whether to use your input values from the previous session or start a new installation, enter `yes` to reuse your input values.
**Note**  
On platforms that require a reboot, your input values from the previous session, excluding credentials, are temporarily stored in the `GreengrassDeviceSetup.config.info` file.

   When the setup is complete, the terminal displays a success status message that's similar to the following.  
![\[Success message in the terminal output.\]](http://docs.aws.amazon.com/greengrass/v1/developerguide/images/quick-start-completed.png)

1. <a name="quick-start-next-steps"></a>If you included the Hello World Lambda function, Greengrass device setup deploys the Greengrass group to your core device. To test the Lambda function, or for information about how to remove the Lambda function from the group, continue to [Verify the Lambda function is running on the core device](lambda-check.md) in Module 3-1 of the Getting Started tutorial.
**Note**  
Make sure that the AWS Region selected in the console is the same one that you used to configure your Greengrass environment. By default, the Region is US West (Oregon).

   If you didn't include the Hello World Lambda function, you can [create your own Lambda function](create-lambda.md) or try other Greengrass features. For example, you can add the [Docker application deployment](docker-app-connector.md) connector to your group and use it to deploy Docker containers to your core device.

    

#### Provide credentials as input values
<a name="gg-device-setup-silent-mode-input-values"></a>

1. Download and start the script. [Provide your credentials](#gg-device-setup-credentials) and any other input values that you want to specify. The following examples show how to provide temporary credentials, which include the session token.
   + To use all default values:

     ```
     wget -q -O ./gg-device-setup-latest.sh https://d1onfpft10uf5o.cloudfront.net/greengrass-device-setup/downloads/gg-device-setup-latest.sh && chmod +x ./gg-device-setup-latest.sh && sudo -E ./gg-device-setup-latest.sh bootstrap-greengrass
     --aws-access-key-id AKIAIOSFODNN7EXAMPLE
     --aws-secret-access-key wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
     --aws-session-token AQoDYXdzEJr1K...o5OytwEXAMPLE=
     ```
   + To specify custom values:

     ```
     wget -q -O ./gg-device-setup-latest.sh https://d1onfpft10uf5o.cloudfront.net/greengrass-device-setup/downloads/gg-device-setup-latest.sh && chmod +x ./gg-device-setup-latest.sh && sudo -E ./gg-device-setup-latest.sh bootstrap-greengrass
     --aws-access-key-id AKIAIOSFODNN7EXAMPLE
     --aws-secret-access-key wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
     --aws-session-token AQoDYXdzEJr1K...o5OytwEXAMPLE=
     --region us-east-1
     --group-name Custom_Group_Name
     --core-name Custom_Core_Name
     --ggc-root-path /custom/ggc/root/path
     --deployment-timeout 300
     --log-path /customized/log/path
     --hello-world-lambda
     --verbose
     ```
**Note**  
If you're running Greengrass device setup on a Raspbian or OpenWrt platform, make a copy of your credentials. You must provide them again after you reboot the device.  
To use `curl` to download the script, replace `wget -q -O` with `curl` in the command.

1. If your core device is running Raspbian or OpenWrt, reboot the device when prompted, provide your credentials, and then restart the script.

   1. <a name="quick-start-reboot"></a>When prompted to reboot the device, run one of the following commands.  
  
For Raspbian platforms:  

      ```
      sudo reboot
      ```  
  
For OpenWrt platforms:  

      ```
      reboot
      ```

   1. Restart the script. You must include your credentials in the command, but not the other input values. For example:

      ```
      sudo -E ./gg-device-setup-latest.sh bootstrap-greengrass
      --aws-access-key-id AKIAIOSFODNN7EXAMPLE
      --aws-secret-access-key wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
      --aws-session-token AQoDYXdzEJr1K...o5OytwEXAMPLE=
      ```

   1. <a name="quick-start-reuse-input-values"></a>When prompted whether to use your input values from the previous session or start a new installation, enter `yes` to reuse your input values.
**Note**  
On platforms that require a reboot, your input values from the previous session, excluding credentials, are temporarily stored in the `GreengrassDeviceSetup.config.info` file.

   When the setup is complete, the terminal displays a success status message that's similar to the following.  
![\[Success message in the terminal output.\]](http://docs.aws.amazon.com/greengrass/v1/developerguide/images/quick-start-completed.png)

1. <a name="quick-start-next-steps"></a>If you included the Hello World Lambda function, Greengrass device setup deploys the Greengrass group to your core device. To test the Lambda function, or for information about how to remove the Lambda function from the group, continue to [Verify the Lambda function is running on the core device](lambda-check.md) in Module 3-1 of the Getting Started tutorial.
**Note**  
Make sure that the AWS Region selected in the console is the same one that you used to configure your Greengrass environment. By default, the Region is US West (Oregon).

   If you didn't include the Hello World Lambda function, you can [create your own Lambda function](create-lambda.md) or try other Greengrass features. For example, you can add the [Docker application deployment](docker-app-connector.md) connector to your group and use it to deploy Docker containers to your core device.

    

# Module 1: Environment setup for Greengrass
<a name="module1"></a>

This module shows you how to get an out-of-the-box Raspberry Pi, Amazon EC2 instance, or other device ready to be used by AWS IoT Greengrass as your AWS IoT Greengrass core device.

**Tip**  
Or, to use a script that sets up your core device for you, see [Quick start: Greengrass device setup](quick-start.md).

This module should take less than 30 minutes to complete.

Before you begin, read the [requirements](gg-gs.md#gg-requirements) for this tutorial. Then, follow the setup instructions in one of the following topics. Choose only the topic that applies to your core device type.

**Topics**
+ [Setting up a Raspberry Pi](setup-filter.rpi.md)
+ [Setting up an Amazon EC2 instance](setup-filter.ec2.md)
+ [Setting up other devices](setup-filter.other.md)

**Note**  
To learn how to use AWS IoT Greengrass running in a prebuilt Docker container, see [Running AWS IoT Greengrass in a Docker container](run-gg-in-docker-container.md).

# Setting up a Raspberry Pi
<a name="setup-filter.rpi"></a>

Follow the steps in this topic to set up a Raspberry Pi to use as an AWS IoT Greengrass core.

**Tip**  
<a name="ggc-install-options"></a>AWS IoT Greengrass also provides other options for installing the AWS IoT Greengrass Core software. For example, you can use [Greengrass device setup](quick-start.md) to configure your environment and install the latest version of the AWS IoT Greengrass Core software. Or, on supported Debian platforms, you can use the [APT package manager](install-ggc.md#ggc-package-manager) to install or upgrade the AWS IoT Greengrass Core software. For more information, see [Install the AWS IoT Greengrass Core software](install-ggc.md).

If you are setting up a Raspberry Pi for the first time, you must follow all of these steps. Otherwise, you can skip to [step 9](#add-ggc-user-ggc-group). However, we recommend that you re-image your Raspberry Pi with the operating system as recommended in step 2.

 

1. Download and install an SD card formatter such as [SD Memory Card Formatter](https://www.sdcard.org/downloads/formatter/). Insert the SD card into your computer. Start the program and choose the drive where you have inserted your SD card. You can perform a quick format of the SD card.

1. Download the [Raspbian Buster](https://downloads.raspberrypi.org/raspbian/images/raspbian-2020-02-14/) operating system as a `zip` file.

1. Using an SD card-writing tool (such as [Etcher](https://etcher.io/)), follow the tool's instructions to flash the downloaded `zip` file onto the SD card. Because the operating system image is large, this step might take some time. Eject your SD card from your computer, and insert the microSD card into your Raspberry Pi.

1. For the first boot, we recommend that you connect the Raspberry Pi to a monitor (through HDMI), a keyboard, and a mouse. Next, connect your Pi to a micro USB power source and the Raspbian operating system should start up. 

1. You might want to configure the Pi's keyboard layout before you continue. To do so, choose the Raspberry icon in the upper-right, choose **Preferences** and then choose **Mouse and Keyboard Settings**. Next, on the **Keyboard** tab, choose **Keyboard Layout**, and then choose an appropriate keyboard variant.

1. Next, [connect your Raspberry Pi to the internet through a Wi-Fi network](https://www.raspberrypi.org/documentation/configuration/wireless/desktop.md) or an Ethernet cable.
**Note**  
Connect your Raspberry Pi to the *same* network that your computer is connected to, and be sure that both your computer and Raspberry Pi have internet access before you continue. If you're in a work environment or behind a firewall, you might need to connect your Pi and your computer to the guest network to get both devices on the same network. However, this approach might disconnect your computer from local network resources, such as your intranet. One solution is to connect the Pi to the guest Wi-Fi network and to connect your computer to the guest Wi-Fi network *and* your local network through an Ethernet cable. In this configuration, your computer should be able to connect to the Raspberry Pi through the guest Wi-Fi network and your local network resources through the Ethernet cable.

1. You must set up [SSH](https://en.wikipedia.org/wiki/Secure_Shell) on your Pi to remotely connect to it. On your Raspberry Pi, open a [terminal window](https://www.raspberrypi.org/documentation/usage/terminal/) and run the following command:

   ```
   sudo raspi-config
   ```

   You should see the following:  
![\[Raspberry Pi Software Configuration Tool (raspi-config) screenshot.\]](http://docs.aws.amazon.com/greengrass/v1/developerguide/images/gg-get-started-001.png)

   Scroll down and choose **Interfacing Options** and then choose **P2 SSH**. When prompted, choose **Yes**. (Use the Tab key followed by Enter). SSH should now be enabled. Choose **OK**. Use the Tab key to choose **Finish** and then press Enter. If the Raspberry Pi doesn't reboot automatically, run the following command:

   ```
   sudo reboot
   ```

1. On your Raspberry Pi, run the following command in the terminal:

   ```
   hostname -I
   ```

   This returns the IP address of your Raspberry Pi.
**Note**  
For the following, if you receive an ECDSA key fingerprint message (`Are you sure you want to continue connecting (yes/no)?`), enter `yes`. The default password for the Raspberry Pi is **raspberry**.

   If you are using macOS, open a terminal window and enter the following:

   ```
   ssh pi@IP-address
   ```

   *IP-address* is the IP address of your Raspberry Pi that you obtained by using the `hostname -I` command.

   If you are using Windows, you need to install and configure [PuTTY](https://www.chiark.greenend.org.uk/~sgtatham/putty/latest.html). Expand **Connection**, choose **Data**, and make sure that **Prompt** is selected:   
![\[PuTTY window with Prompt selected.\]](http://docs.aws.amazon.com/greengrass/v1/developerguide/images/gg-get-started-001.4.png)

   Next, choose **Session**, enter the IP address of the Raspberry Pi, and then choose **Open** using default settings.   
![\[PuTTY window with IP address in the "Host Name (or IP address)" field.\]](http://docs.aws.amazon.com/greengrass/v1/developerguide/images/gg-get-started-001.5.png)

   If a PuTTY security alert is displayed, choose **Yes**.

   The default Raspberry Pi login and password are **pi** and **raspberry**, respectively.  
![\[Initial PuTTY terminal window.\]](http://docs.aws.amazon.com/greengrass/v1/developerguide/images/gg-get-started-001.6.png)
**Note**  
If your computer is connected to a remote network using VPN, you might have difficulty connecting from the computer to the Raspberry Pi using SSH.

1. <a name="add-ggc-user-ggc-group"></a>You are now ready to set up the Raspberry Pi for AWS IoT Greengrass. First, run the following commands from a local Raspberry Pi terminal window or an SSH terminal window:
**Tip**  
<a name="ggc-install-options"></a>AWS IoT Greengrass also provides other options for installing the AWS IoT Greengrass Core software. For example, you can use [Greengrass device setup](quick-start.md) to configure your environment and install the latest version of the AWS IoT Greengrass Core software. Or, on supported Debian platforms, you can use the [APT package manager](install-ggc.md#ggc-package-manager) to install or upgrade the AWS IoT Greengrass Core software. For more information, see [Install the AWS IoT Greengrass Core software](install-ggc.md).

   ```
   sudo adduser --system ggc_user
   sudo addgroup --system ggc_group
   ```

1. To improve security on the Pi device, enable hardlink and softlink (symlink) protection on the operating system at startup.

   1. Navigate to the `98-rpi.conf` file.

      ```
      cd /etc/sysctl.d
      ls
      ```
**Note**  
If you don't see the `98-rpi.conf` file, follow the instructions in the `README.sysctl` file.

   1. Use a text editor (such as Leafpad, GNU nano, or vi) to add the following two lines to the end of the file. You might need to use the `sudo` command to edit as root (for example, `sudo nano 98-rpi.conf`).

      ```
      fs.protected_hardlinks = 1
      fs.protected_symlinks = 1
      ```

   1. Reboot the Pi.

      ```
      sudo reboot
      ```

      After about a minute, connect to the Pi using SSH and then run the following command to confirm the change:

      ```
      sudo sysctl -a 2> /dev/null | grep fs.protected
      ```

      You should see `fs.protected_hardlinks = 1` and `fs.protected_symlinks = 1`.

1. <a name="stretch-step"></a> Edit your command line boot file to enable and mount memory cgroups. This allows AWS IoT Greengrass to set the memory limit for Lambda functions. Cgroups are also required to run AWS IoT Greengrass in the default [containerization](lambda-group-config.md#lambda-containerization-considerations) mode.

   1.  Navigate to your `boot` directory. 

      ```
      cd /boot/
      ```

   1.  Use a text editor to open `cmdline.txt`. Append the following to the end of the existing line, not as a new line. You might need to use the `sudo` command to edit as root (for example, `sudo nano cmdline.txt`).

      ```
      cgroup_enable=memory cgroup_memory=1
      ```

   1. Now reboot the Pi.

      ```
      sudo reboot
      ```

   Your Raspberry Pi should now be ready for AWS IoT Greengrass.

1. <a name="install-java-8-runtime"></a>Optional. Install the Java 8 runtime, which is required by [stream manager](stream-manager.md). This tutorial doesn't use stream manager, but it does use the **Default Group creation** workflow that enables stream manager by default. Use the following commands to install the Java 8 runtime on the core device, or disable stream manager before you deploy your group. Instructions for disabling stream manager are provided in Module 3.

   ```
   sudo apt install openjdk-8-jdk
   ```

1. To make sure that you have all required dependencies, download and run the Greengrass dependency checker from the [AWS IoT Greengrass Samples](https://github.com/aws-samples/aws-greengrass-samples) repository on GitHub. These commands unzip and run the dependency checker script in the `Downloads` directory.
**Note**  
 The dependency checker might fail if you are running version 5.4.51 of the Raspbian kernel. This version does not mount memory cgroups correctly. This might cause Lambda functions running in container mode to fail.  
For more information on updating your kernel, see the [ Cgroups not loaded after kernel upgrade](https://www.raspberrypi.org/forums/viewtopic.php?t=280656) in the Raspberry Pi forums. 

   ```
   cd /home/pi/Downloads
   mkdir greengrass-dependency-checker-GGCv1.11.x
   cd greengrass-dependency-checker-GGCv1.11.x
   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
   ```

   Where `more` appears, press the Spacebar key to display another screen of text. 
**Important**  
<a name="lambda-runtime-prereqs"></a>This tutorial requires the Python 3.7 runtime to run local Lambda functions. When stream manager is enabled, it also requires the Java 8 runtime. If the `check_ggc_dependencies` script produces warnings about these missing runtime prerequisites, make sure to install them before you continue. You can ignore warnings about other missing optional runtime prerequisites.

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

Your Raspberry Pi configuration is complete. Continue to [Module 2: Installing the AWS IoT Greengrass Core software](module2.md).

# Setting up an Amazon EC2 instance
<a name="setup-filter.ec2"></a>

Follow the steps in this topic to set up an Amazon EC2 instance to use as your AWS IoT Greengrass core.

**Tip**  
Or, to use a script that sets up your environment and installs the AWS IoT Greengrass Core software for you, see [Quick start: Greengrass device setup](quick-start.md).

 Although you can complete this tutorial using an Amazon EC2 instance, AWS IoT Greengrass should ideally be used with physical hardware. We recommend that you [set up a Raspberry Pi](setup-filter.rpi.md) instead of using an Amazon EC2 instance when possible. If you're using a Raspberry Pi, you do not need to follow the steps in this topic. 

 

1. Sign in to the [AWS Management Console](https://console.aws.amazon.com/) and launch an Amazon EC2 instance using an Amazon Linux AMI. For information about Amazon EC2 instances, see the [Amazon EC2 Getting Started Guide](https://docs.aws.amazon.com/AWSEC2/latest/GettingStartedGuide/).

1. After your Amazon EC2 instance is running, enable port 8883 to allow incoming MQTT communications so that other devices can connect with the AWS IoT Greengrass core.

   1. In the navigation pane of the Amazon EC2 console, choose **Security Groups**.  
![\[Navigation pane with Security Groups highlighted.\]](http://docs.aws.amazon.com/greengrass/v1/developerguide/images/gg-get-started-002.6.1.png)

   1. Select the security group for the instance that you just launched, and then choose the **Inbound rules** tab.

   1. Choose **Edit inbound rules**.

      To enable port 8883, you add a custom TCP rule to the security group. For more information, see [ Adding rules to a security group](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/using-network-security.html#adding-security-group-rule) in the *Amazon EC2 User Guide*.

   1. On the **Edit inbound rules** page, choose **Add rule**, enter the following settings, and then choose **Save**.
      + For **Type**, choose **Custom TCP Rule**.
      + For **Port range**, enter **8883**.
      + For **Source**, choose **Anywhere**.
      + For **Description**, enter **MQTT Communications**.

       

1. Connect to your Amazon EC2 instance.

   1. In the navigation pane, choose **Instances**, choose your instance, and then choose **Connect**.

   1. Follow the instructions on the **Connect To Your Instance** page to connect to your instance [ by using SSH](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/AccessingInstancesLinux.html) and your private key file.

   You can use [PuTTY](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/putty.html) for Windows or Terminal for macOS. For more information, see [ Connect to your Linux instance](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/AccessingInstances.html) in the *Amazon EC2 User Guide*.

   You are now ready to set up your Amazon EC2 instance for AWS IoT Greengrass.

1. After you are connected to your Amazon EC2 instance, create the `ggc_user` and `ggc_group` accounts:

   ```
   sudo adduser --system ggc_user
   sudo groupadd --system ggc_group
   ```
**Note**  
If the `adduser` command isn't available on your system, use the following command.  

   ```
   sudo useradd --system ggc_user
   ```

1. To improve security, make sure that hardlink and softlink (symlink) protections are enabled on the operating system of the Amazon EC2 instance at startup.
**Note**  
 The steps for enabling hardlink and softlink protection vary by operating system. Consult the documentation for your distribution. 

   1.  Run the following command to check if hardlink and softlink protections are enabled: 

      ```
      sudo sysctl -a | grep fs.protected
      ```

       If hardlinks and softlinks are set to `1`, your protections are enabled correctly. Proceed to step 6. 
**Note**  
Softlinks are represented by `fs.protected_symlinks`.

   1. If hardlinks and softlinks are not set to `1`, enable these protections. Navigate to your system configuration file. 

      ```
      cd /etc/sysctl.d
      ls
      ```

   1. Using your favorite text editor (Leafpad, GNU nano, or vi), add the following two lines to the end of the system configuration file. On Amazon Linux 1, this is the `00-defaults.conf` file. On Amazon Linux 2, this is the `99-amazon.conf` file. You might need to change permissions (using the `chmod` command) to write to the file, or use the `sudo` command to edit as root (for example, `sudo nano 00-defaults.conf`).

      ```
      fs.protected_hardlinks = 1
      fs.protected_symlinks = 1
      ```

   1. Reboot the Amazon EC2 instance.

      ```
      sudo reboot
      ```

      After a few minutes, connect to your instance using SSH and then run the following command to confirm the change.

      ```
      sudo sysctl -a | grep fs.protected
      ```

      You should see that hardlinks and softlinks are set to 1.

1. Extract and run the following script to mount [Linux control groups](https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/6/html/resource_management_guide/ch01) (cgroups). This allows AWS IoT Greengrass to set the memory limit for Lambda functions. Cgroups are also required to run AWS IoT Greengrass in the default [containerization](lambda-group-config.md#lambda-containerization-considerations) mode.

   ```
   curl https://raw.githubusercontent.com/tianon/cgroupfs-mount/951c38ee8d802330454bdede20d85ec1c0f8d312/cgroupfs-mount > cgroupfs-mount.sh
   chmod +x cgroupfs-mount.sh 
   sudo bash ./cgroupfs-mount.sh
   ```

   Your Amazon EC2 instance should now be ready for AWS IoT Greengrass.

1. <a name="install-java-8-runtime"></a>Optional. Install the Java 8 runtime, which is required by [stream manager](stream-manager.md). This tutorial doesn't use stream manager, but it does use the **Default Group creation** workflow that enables stream manager by default. Use the following commands to install the Java 8 runtime on the core device, or disable stream manager before you deploy your group. Instructions for disabling stream manager are provided in Module 3.
   + For Debian-based distributions:

     ```
     sudo apt install openjdk-8-jdk
     ```
   + For Red Hat-based distributions:

     ```
     sudo yum install java-1.8.0-openjdk
     ```

1. To make sure that you have all required dependencies, download and run the Greengrass dependency checker from the [AWS IoT Greengrass Samples](https://github.com/aws-samples/aws-greengrass-samples) repository on GitHub. These commands download, unzip, and run the dependency checker script in your Amazon EC2 instance.

   ```
   mkdir greengrass-dependency-checker-GGCv1.11.x
   cd greengrass-dependency-checker-GGCv1.11.x
   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 ./check_ggc_dependencies | more
   ```
**Important**  
<a name="lambda-runtime-prereqs"></a>This tutorial requires the Python 3.7 runtime to run local Lambda functions. When stream manager is enabled, it also requires the Java 8 runtime. If the `check_ggc_dependencies` script produces warnings about these missing runtime prerequisites, make sure to install them before you continue. You can ignore warnings about other missing optional runtime prerequisites.

Your Amazon EC2 instance configuration is complete. Continue to [Module 2: Installing the AWS IoT Greengrass Core software](module2.md).

# Setting up other devices
<a name="setup-filter.other"></a>

Follow the steps in this topic to set up a device (other than a Raspberry Pi) to use as your AWS IoT Greengrass core.

**Tip**  
Or, to use a script that sets up your environment and installs the AWS IoT Greengrass Core software for you, see [Quick start: Greengrass device setup](quick-start.md).

If you're new to AWS IoT Greengrass, we recommend that you use a Raspberry Pi or an Amazon EC2 instance as your core device, and follow the [setup steps](module1.md) appropriate for your device.

If you plan to build a custom Linux-based system using the Yocto Project, you can use the AWS IoT Greengrass Bitbake Recipe from the `meta-aws` project. This recipe also helps you develop a software platform that supports AWS edge software for embedded applications. The Bitbake build installs, configures, and automatically runs the AWS IoT Greengrass Core software on your device.

Yocto Project  
An open source collaboration project that helps you build custom Linux-based systems for embedded applications regardless hardware architecture. For more information, see the [Yocto Project](https://www.yoctoproject.org/).

`meta-aws`  
An AWS managed project that provides Yocto recipes. You can use the recipes to develop AWS edge sofware in Linux-based systems built with [OpenEmbedded](https://www.openembedded.org/wiki/Main_Page) and Yocto Project. For more information about this community supported capability, see the [https://github.com/aws/meta-aws](https://github.com/aws/meta-aws)project on GitHub.

`meta-aws-demos`  
An AWS managed project that contains demonstrations for the `meta-aws` project. For more examples about the integration process, see the [https://github.com/aws-samples/meta-aws-demos](https://github.com/aws-samples/meta-aws-demos) project on GitHub.

To use a different device or [supported platform](what-is-gg.md#gg-platforms), follow the steps in this topic.

1. <a name="setup-jetson"></a>If your core device is an NVIDIA Jetson device, you must first flash the firmware with the JetPack 4.3 installer. If you're configuring a different device, skip to step 2.
**Note**  
The JetPack installer version that you use is based on your target CUDA Toolkit version. The following instructions use JetPack 4.3 and CUDA Toolkit 10.0. For information about using the versions appropriate for your device, see [How to Install Jetpack](https://docs.nvidia.com/jetson/jetpack/install-jetpack/index.html) in the NVIDIA documentation.

   1. On a physical desktop that is running Ubuntu 16.04 or later, flash the firmware with the JetPack 4.3 installer, as described in [Download and Install JetPack](https://docs.nvidia.com/jetson/archives/jetpack-archived/jetpack-33/index.html#jetpack/3.3/install.htm%3FTocPath%3D_____3) (4.3) in the NVIDIA documentation.

      Follow the instructions in the installer to install all the packages and dependencies on the Jetson board, which must be connected to the desktop with a Micro-B cable.

   1. Reboot your board in normal mode, and connect a display to the board.
**Note**  
When you use SSH to connect to the Jetson board, use the default user name (**nvidia**) and the default password (**nvidia**).

1. Run the following commands to create user `ggc_user` and group `ggc_group`. The commands you run differ, depending on the distribution installed on your core device.
   + If your core device is running OpenWrt, run the following commands:

     ```
     opkg install shadow-useradd
     opkg install shadow-groupadd
     useradd --system ggc_user
     groupadd --system ggc_group
     ```
   + Otherwise, run the following commands:

     ```
     sudo adduser --system ggc_user
     sudo addgroup --system ggc_group
     ```
**Note**  
If the `addgroup` command isn't available on your system, use the following command.  

     ```
     sudo groupadd --system ggc_group
     ```

1. <a name="install-java-8-runtime"></a>Optional. Install the Java 8 runtime, which is required by [stream manager](stream-manager.md). This tutorial doesn't use stream manager, but it does use the **Default Group creation** workflow that enables stream manager by default. Use the following commands to install the Java 8 runtime on the core device, or disable stream manager before you deploy your group. Instructions for disabling stream manager are provided in Module 3.
   + For Debian-based or Ubuntu-based distributions:

     ```
     sudo apt install openjdk-8-jdk
     ```
   + For Red Hat-based distributions:

     ```
     sudo yum install java-1.8.0-openjdk
     ```

1. To make sure that you have all required dependencies, download and run the Greengrass dependency checker from the [AWS IoT Greengrass Samples](https://github.com/aws-samples/aws-greengrass-samples) repository on GitHub. These commands unzip and run the dependency checker script.

   ```
   mkdir greengrass-dependency-checker-GGCv1.11.x
   cd greengrass-dependency-checker-GGCv1.11.x
   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 ./check_ggc_dependencies | more
   ```
**Note**  
The `check_ggc_dependencies` script runs on AWS IoT Greengrass supported platforms and requires specific Linux system commands. For more information, see the dependency checker's [Readme](https://github.com/aws-samples/aws-greengrass-samples/blob/master/greengrass-dependency-checker-GGCv1.11.x/README.md).

1. Install all required dependencies on your device, as indicated by the dependency checker output. For missing kernel-level dependencies, you might have to recompile your kernel. For mounting Linux control groups (`cgroups`), you can run the [cgroupfs-mount](https://raw.githubusercontent.com/tianon/cgroupfs-mount/master/cgroupfs-mount) script. This allows AWS IoT Greengrass to set the memory limit for Lambda functions. Cgroups are also required to run AWS IoT Greengrass in the default [containerization](lambda-group-config.md#lambda-containerization-considerations) mode.

   If no errors appear in the output, AWS IoT Greengrass should be able to run successfully on your device.
**Important**  
<a name="lambda-runtime-prereqs"></a>This tutorial requires the Python 3.7 runtime to run local Lambda functions. When stream manager is enabled, it also requires the Java 8 runtime. If the `check_ggc_dependencies` script produces warnings about these missing runtime prerequisites, make sure to install them before you continue. You can ignore warnings about other missing optional runtime prerequisites.

   For the list of AWS IoT Greengrass requirements and dependencies, see [Supported platforms and requirements](what-is-gg.md#gg-platforms).

# Module 2: Installing the AWS IoT Greengrass Core software
<a name="module2"></a>

This module shows you how to install the AWS IoT Greengrass Core software on your chosen device. In this module, you first create a Greengrass group and core. Then, you download, configure, and start the software on your core device. For more information about AWS IoT Greengrass Core software functionality, see [Configure the AWS IoT Greengrass core](gg-core.md).

Before you begin, make sure that you have completed the setup steps in [Module 1](module1.md) for your chosen device.

**Tip**  
<a name="ggc-install-options"></a>AWS IoT Greengrass also provides other options for installing the AWS IoT Greengrass Core software. For example, you can use [Greengrass device setup](quick-start.md) to configure your environment and install the latest version of the AWS IoT Greengrass Core software. Or, on supported Debian platforms, you can use the [APT package manager](install-ggc.md#ggc-package-manager) to install or upgrade the AWS IoT Greengrass Core software. For more information, see [Install the AWS IoT Greengrass Core software](install-ggc.md).

This module should take less than 30 minutes to complete.

**Topics**
+ [Provision an AWS IoT thing to use as a Greengrass core](provision-core.md)
+ [Create an AWS IoT Greengrass group for the core](create-group.md)
+ [Install and run AWS IoT Greengrass on the core device](start-greengrass.md)

# Provision an AWS IoT thing to use as a Greengrass core
<a name="provision-core"></a>

Greengrass *cores* are devices that run the AWS IoT Greengrass Core software to manage local IoT processes. To set up a Greengrass core, you create an AWS IoT *thing*, which represents a device or logical entity that connects to AWS IoT. When you register a device as an AWS IoT thing, that device can use a digital certificate and keys that allow it to access AWS IoT. You use an [AWS IoT policy](https://docs.aws.amazon.com/iot/latest/developerguide/iot-policies.html) to allow the device to communicate with the AWS IoT and AWS IoT Greengrass services.

In this section, you register your device as an AWS IoT thing to use it as a Greengrass core.

**To create an AWS IoT thing**

1. Navigate to the [AWS IoT console](https://console.aws.amazon.com/iot).

1. Under **Manage**, expand **All devices**, and then choose **Things**.

1. On the **Things** page, choose **Create things**.

1. <a name="gg-group-create-single-thing"></a>On the **Create things** page, choose **Create single thing**, and then choose **Next**.

1. On the **Specify thing properties** page, do the following:

   1. For **Thing name**, enter a name that represents your device, such as **MyGreengrassV1Core**.

   1. Choose **Next**.

1. <a name="gg-group-create-device-configure-certificate"></a>On the **Configure device certificate** page, choose **Next**.

1. On the **Attach policies to certificate** page, do one of the following:
   + Select an existing policy that grants permissions that cores require, and then choose **Create thing**.

     A modal opens where you can download the certificates and keys that the device uses to connect to the AWS Cloud.
   + Create an attach a new policy that grants core device permissions. Do the following:

     1. Choose **Create policy**.

        The **Create policy** page opens in a new tab.

     1. On the **Create policy** page, do the following:

        1. For **Policy name**, enter a name that describes the policy, such as **GreengrassV1CorePolicy**.

        1. On the **Policy statements** tab, under **Policy document**, choose **JSON**.

        1. Enter the following policy document. This policy allows the core to communicate with the AWS IoT Core service, interact with device shadows, and communicate with the AWS IoT Greengrass service. For information about how to restrict this policy's access based on your use case, see [Minimal AWS IoT policy for the AWS IoT Greengrass core device](device-auth.md#gg-config-sec-min-iot-policy).

------
#### [ JSON ]

****  

           ```
           {
             "Version":"2012-10-17",		 	 	 
             "Statement": [
               {
                 "Effect": "Allow",
                 "Action": [
                   "iot:Publish",
                   "iot:Subscribe",
                   "iot:Connect",
                   "iot:Receive"
                 ],
                 "Resource": [
                   "*"
                 ]
               },
               {
                 "Effect": "Allow",
                 "Action": [
                   "iot:GetThingShadow",
                   "iot:UpdateThingShadow",
                   "iot:DeleteThingShadow"
                 ],
                 "Resource": [
                   "*"
                 ]
               },
               {
                 "Effect": "Allow",
                 "Action": [
                   "greengrass:*"
                 ],
                 "Resource": [
                   "*"
                 ]
               }
             ]
           }
           ```

------

        1. Choose **Create** to create the policy.

     1. Return to the browser tab with the **Attach policies to certificate** page open. Do the following:

        1. In the **Policies** list, select the policy that you created, such as **GreengrassV1CorePolicy**.

           If you don't see the policy, choose the refresh button.

        1. Choose **Create thing**.

           A modal opens where you can download the certificates and keys that the core uses to connect to AWS IoT.

1. Return to the browser tab with the **Attach policies to certificate** page open. Do the following:

   1. In the **Policies** list, select the policy that you created, such as **GreengrassV1CorePolicy**.

      If you don't see the policy, choose the refresh button.

   1. Choose **Create thing**.

      A modal opens where you can download the certificates and keys that the core uses to connect to AWS IoT.

1. <a name="gg-group-create-device-download-certs"></a>In the **Download certificates and keys** modal, download the device's certificates.
**Important**  
Before you choose **Done**, download the security resources.

   Do the following:

   1. For **Device certificate**, choose **Download** to download the device certificate.

   1. For **Public key file**, choose **Download** to download the public key for the certificate.

   1. For **Private key file**, choose **Download** to download the private key file for the certificate.

   1. Review [Server Authentication](https://docs.aws.amazon.com/iot/latest/developerguide/server-authentication.html) in the *AWS IoT Developer Guide* and choose the appropriate root CA certificate. We recommend that you use Amazon Trust Services (ATS) endpoints and ATS root CA certificates. Under **Root CA certificates**, choose **Download** for a root CA certificate.

   1. Choose **Done**.

   Make a note of the certificate ID that's common in the file names for the device certificate and keys. You need it later.

# Create an AWS IoT Greengrass group for the core
<a name="create-group"></a>

AWS IoT Greengrass *groups* contain settings and other information about its components, such as client devices, Lambda functions, and connectors. A group defines the configuration for a core, including how its components can interact with each other.

In this section, you create a group for your core.

**Tip**  
For an example that uses the AWS IoT Greengrass API to create and deploy a group, see the [gg\$1group\$1setup](https://github.com/awslabs/aws-greengrass-group-setup) repository on GitHub.

**To create a group for the core**

1. Navigate to the [AWS IoT console](https://console.aws.amazon.com/iot).

1. Under **Manage**, expand **Greengrass devices**, and choose **Groups (V1)**.
**Note**  
If you don't see the **Greengrass devices** menu, change to an AWS Region that supports AWS IoT Greengrass V1. For the list of supported Regions, see [AWS IoT Greengrass V1 endpoints and quotas](https://docs.aws.amazon.com/general/latest/gr/greengrass.html) in the *AWS General Reference*. You must [create the AWS IoT thing for your core](provision-core.md) in a Region where AWS IoT Greengrass V1 is available.

1. On the **Greengrass groups** page, choose **Create group**.

1. On the **Create Greengrass group** page, do the following:

   1. For **Greengrass group name**, enter a name that describes the group, such as **MyGreengrassGroup**.

   1. For **Greengrass core**, choose the AWS IoT thing that you created earlier, such as **MyGreengrassV1Core**.

      The console automatically selects the thing's device certificate for you.

   1. Choose **Create group**.

# Install and run AWS IoT Greengrass on the core device
<a name="start-greengrass"></a>

**Note**  
This tutorial provides instructions for you to run the AWS IoT Greengrass Core software on a Raspberry Pi, but you can use any supported device.

In this section, you configure, install, and run the AWS IoT Greengrass Core software on your core device.

**To install and run AWS IoT Greengrass**

1. From the [AWS IoT Greengrass Core software](what-is-gg.md#gg-core-download-tab) section in this guide, download the AWS IoT Greengrass Core software installation package. Choose the package that best fits the CPU architecture, distribution, and OS of your core device.
   + For Raspberry Pi, download the package for the Armv7l architecture and Linux operating system.
   + For an Amazon EC2 instance, download the package for the x86\$164 architecture and Linux operating system.
   + For NVIDIA Jetson TX2, download the package for the Armv8 (AArch64) architecture and Linux operating system.
   + For Intel Atom, download the package for the x86\$164 architecture and Linux operating system.

1. In previous steps, you downloaded five files to your computer:
   + `greengrass-OS-architecture-1.11.6.tar.gz` – This compressed file contains the AWS IoT Greengrass Core software that runs on the core device.
   + `certificateId-certificate.pem.crt` – The device certificate file.
   + `certificateId-public.pem.key` – The device certificate's public key file.
   + `certificateId-private.pem.key` – The device certificate's private key file.
   + `AmazonRootCA1.pem` – The Amazon root certificate authority (CA) file.

   In this step, you transfer these files from your computer to your core device. Do the following:

   1. If you don't know the IP address of your Greengrass core device, open a terminal on the core device and run the following command.
**Note**  
This command might not return the correct IP address for some devices. Consult the documentation for your device to retrieve your device IP address.

      ```
      hostname -I
      ```

   1. <a name="transfer-files-to-device"></a>Transfer these files from your computer to your core device. The file transfer steps vary depending on the operating system of your computer. Choose your operating system for steps that show how to transfer files to your Raspberry Pi device.
**Note**  
For a Raspberry Pi, the default user name is **pi** and the default password is **raspberry**.  
For an NVIDIA Jetson TX2, the default user name is **nvidia** and the default password is **nvidia**.

------
#### [ Windows ]

      To transfer the compressed files from your computer to a Raspberry Pi core device, use a tool such as [WinSCP](https://winscp.net/eng/download.php) or the [PuTTY](https://www.chiark.greenend.org.uk/~sgtatham/putty/latest.html) **pscp** command. To use the **pscp** command, open a Command Prompt window on your computer and run the following:

      ```
      cd path-to-downloaded-files
      pscp -pw Pi-password greengrass-OS-architecture-1.11.6.tar.gz pi@IP-address:/home/pi
      pscp -pw Pi-password certificateId-certificate.pem.crt pi@IP-address:/home/pi
      pscp -pw Pi-password certificateId-public.pem.key pi@IP-address:/home/pi
      pscp -pw Pi-password certificateId-private.pem.key pi@IP-address:/home/pi
      pscp -pw Pi-password AmazonRootCA1.pem pi@IP-address:/home/pi
      ```

**Note**  
<a name="use-correct-package-version"></a>The version number in this command must match the version of your AWS IoT Greengrass Core software package.

------
#### [ macOS ]

      To transfer the compressed files from your Mac to a Raspberry Pi core device, open a Terminal window on your computer and run the following commands. The *path-to-downloaded-files* is typically `~/Downloads`.

**Note**  
You might be prompted for two passwords. If so, the first password is for the Mac's `sudo` command and the second is the password for the Raspberry Pi.

      ```
      cd path-to-downloaded-files
      scp greengrass-OS-architecture-1.11.6.tar.gz pi@IP-address:/home/pi
      scp certificateId-certificate.pem.crt pi@IP-address:/home/pi
      scp certificateId-public.pem.key pi@IP-address:/home/pi
      scp certificateId-private.pem.key pi@IP-address:/home/pi
      scp AmazonRootCA1.pem pi@IP-address:/home/pi
      ```

**Note**  
<a name="use-correct-package-version"></a>The version number in this command must match the version of your AWS IoT Greengrass Core software package.

------
#### [ UNIX-like system ]

      To transfer the compressed files from your computer to a Raspberry Pi core device, open a terminal window on your computer and run the following commands:

      ```
      cd path-to-downloaded-files
      scp greengrass-OS-architecture-1.11.6.tar.gz pi@IP-address:/home/pi
      scp certificateId-certificate.pem.crt pi@IP-address:/home/pi
      scp certificateId-public.pem.key pi@IP-address:/home/pi
      scp certificateId-private.pem.key pi@IP-address:/home/pi
      scp AmazonRootCA1.pem pi@IP-address:/home/pi
      ```

**Note**  
<a name="use-correct-package-version"></a>The version number in this command must match the version of your AWS IoT Greengrass Core software package.

------
#### [ Raspberry Pi web browser ]

      If you used the Raspberry Pi's web browser to download the compressed files, the files should be in the Pi's `~/Downloads` folder, such as `/home/pi/Downloads`. Otherwise, the compressed files should be in the Pi's `~` folder, such as `/home/pi`.

------

1. On the Greengrass core device, open a terminal, and navigate to the folder that contains the AWS IoT Greengrass Core software and certificates. Replace *path-to-transferred-files* with the path where you transferred the files on the core device. For example, on a Raspberry Pi, run `cd /home/pi`.

   ```
   cd path-to-transferred-files
   ```

1. Unpack the AWS IoT Greengrass Core software on the core device. Run the following command to unpack the software archive that you transferred to the core device. This command uses the `-C /` argument to create the `/greengrass` folder in the root folder of the core device.

   ```
   sudo tar -xzvf greengrass-OS-architecture-1.11.6.tar.gz -C /
   ```
**Note**  
<a name="use-correct-package-version"></a>The version number in this command must match the version of your AWS IoT Greengrass Core software package.

1. Move the certificates and keys to the AWS IoT Greengrass Core software folder. Run the following commands to create a folder for certificates and move the certificates and keys to it. Replace *path-to-transferred-files* with the path where you transferred the files on the core device, and replace *certificateId* with the certificate ID in the file names. For example, on a Raspberry Pi, replace *path-to-transferred-files* with **/home/pi**

   ```
   sudo mv path-to-transferred-files/certificateId-certificate.pem.crt /greengrass/certs
   sudo mv path-to-transferred-files/certificateId-public.pem.key /greengrass/certs
   sudo mv path-to-transferred-files/certificateId-private.pem.key /greengrass/certs
   sudo mv path-to-transferred-files/AmazonRootCA1.pem /greengrass/certs
   ```

1. The AWS IoT Greengrass Core software uses a configuration file that specifies parameters for the software. This configuration file specifies the file paths for certificate files and the AWS Cloud endpoints to use. In this step, you create the AWS IoT Greengrass Core software configuration file for your core. Do the following:

   1. Get the Amazon Resource Name (ARN) for your core's AWS IoT thing. Do the following:

      1. In the [AWS IoT console](https://console.aws.amazon.com/iot), under **Manage**, under **Greengrass devices**, choose **Groups (V1)**.

      1. On the **Greengrass groups** page, choose the group that you created earlier.

      1. Under **Overview**, choose **Greengrass core**.

      1. On the core details page, copy the **AWS IoT thing ARN**, and save it to use in the AWS IoT Greengrass Core configuration file.

   1. Get the AWS IoT device data endpoint for your AWS account in the current Region. Devices use this endpoint to connect to AWS as AWS IoT things. Do the following:

      1. In the [AWS IoT console](https://console.aws.amazon.com/iot), choose **Settings**.

      1. Under **Device data endpoint**, copy the **Endpoint**, and save it to use in the AWS IoT Greengrass Core configuration file.

   1. Create the AWS IoT Greengrass Core software configuration file. For example, you can run the following command to use GNU nano to create the file.

      ```
      sudo nano /greengrass/config/config.json
      ```

      Replace the contents of the file with the following JSON document.

      ```
      {
        "coreThing" : {
          "caPath": "AmazonRootCA1.pem",
          "certPath": "certificateId-certificate.pem.crt",
          "keyPath": "certificateId-private.pem.key",
          "thingArn": "arn:aws:iot:region:account-id:thing/MyGreengrassV1Core",
          "iotHost": "device-data-prefix-ats.iot.region.amazonaws.com",
          "ggHost": "greengrass-ats.iot.region.amazonaws.com",
          "keepAlive": 600
        },
        "runtime": {
          "cgroup": {
            "useSystemd": "yes"
          }
        },
        "managedRespawn": false,
        "crypto": {
          "caPath": "file:///greengrass/certs/AmazonRootCA1.pem",
          "principals": {
            "SecretsManager": {
              "privateKeyPath": "file:///greengrass/certs/certificateId-private.pem.key"
            },
            "IoTCertificate": {
              "privateKeyPath": "file:///greengrass/certs/certificateId-private.pem.key",
              "certificatePath": "file:///greengrass/certs/certificateId-certificate.pem.crt"
            }
          }
        }
      }
      ```

      Then, do the following:
      + If you downloaded a different Amazon root CA certificate than Amazon Root CA 1, replace each instance of *AmazonRootCA1.pem* with the name of the Amazon root CA file.
      + Replace each instance of *certificateId* with the certificate ID in the name of the certificate and key files.
      + Replace *arn:aws:iot:*region*:*account-id*:thing/MyGreengrassV1Core* with the ARN of your core's thing that you saved earlier.
      + Replace *MyGreengrassV1core* with the name of your core's thing.
      + Replace *device-data-prefix-ats.iot.region.amazonaws.com* with the AWS IoT device data endpoint that you saved earlier.
      + Replace *region* with your AWS Region.

      For more information about the configuration options that you can specify in this configuration file, see [AWS IoT Greengrass core configuration file](gg-core.md#config-json).

1. Make sure that your core device is connected to the internet. Then, start AWS IoT Greengrass on your core device.

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

   You should see a `Greengrass successfully started` message. Make a note of the PID.
**Note**  
To set up your core device to start AWS IoT Greengrass on system boot, see [Configure the init system to start the Greengrass daemon](gg-core.md#start-on-boot).

   You can run the following command to confirm that the AWS IoT Greengrass Core software (Greengrass daemon) is functioning. Replace *PID-number* with your PID:

   ```
   ps aux | grep PID-number
   ```

   You should see an entry for the PID with a path to the running Greengrass daemon (for example, `/greengrass/ggc/packages/1.11.6/bin/daemon`). If you run into issues starting AWS IoT Greengrass, see [Troubleshooting AWS IoT Greengrass](gg-troubleshooting.md).

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

This module shows you how to create and deploy a Lambda function that sends MQTT messages from your AWS IoT Greengrass core device. The module describes Lambda function configurations, subscriptions used to allow MQTT messaging, and deployments to a core device.

[Module 3 (Part 2)](module3-II.md) covers the differences between on-demand and long-lived Lambda functions running on the AWS IoT Greengrass core.

Before you begin, make sure that you have completed [Module 1](module1.md) and [Module 2](module2.md) and have a running AWS IoT Greengrass core device.

**Tip**  
Or, to use a script that sets up your core device for you, see [Quick start: Greengrass device setup](quick-start.md). The script can also create and deploy the Lambda function used in this module.

This module should take about 30 minutes to complete.

**Topics**
+ [Create and package a Lambda function](create-lambda.md)
+ [Configure the Lambda function for AWS IoT Greengrass](config-lambda.md)
+ [Deploy cloud configurations to a Greengrass core device](configs-core.md)
+ [Verify the Lambda function is running on the core device](lambda-check.md)

# Create and package a Lambda function
<a name="create-lambda"></a>

The example Python Lambda function in this module uses the [AWS IoT Greengrass Core SDK](lambda-functions.md#lambda-sdks-core) for Python to publish MQTT messages.

In this step, you:
+ Download the AWS IoT Greengrass Core SDK for Python to your computer (not the AWS IoT Greengrass core device).
+ Create a Lambda function deployment package that contains the function code and dependencies.
+ Use the Lambda console to create a Lambda function and upload the deployment package.
+ Publish a version of the Lambda function and create an alias that points to the version.

To complete this module, Python 3.7 must be installed on your core device.

 <a name="create-lambda-procedure"></a>

1. <a name="download-ggc-sdk"></a> From the [AWS IoT Greengrass Core SDK](what-is-gg.md#gg-core-sdk-download) downloads page, download the AWS IoT Greengrass Core SDK for Python to your computer.

1. Unzip the downloaded package to get the Lambda function code and the SDK.

   The Lambda function in this module uses:
   + The `greengrassHelloWorld.py` file in `examples\HelloWorld`. This is your Lambda function code. Every five seconds, the function publishes one of two possible messages to the `hello/world` topic.
   + The `greengrasssdk` folder. This is the SDK.

1. Copy the `greengrasssdk` folder into the `HelloWorld` folder that contains `greengrassHelloWorld.py`.

1. To create the Lambda function deployment package, save `greengrassHelloWorld.py` and the `greengrasssdk` folder to a compressed `zip` file named `hello_world_python_lambda.zip`. The `py` file and `greengrasssdk` folder must be in the root of the directory.  
![\[Screenshot showing zipped contents of hello_word_python_lambda.zip.\]](http://docs.aws.amazon.com/greengrass/v1/developerguide/images/gg-get-started-017.png)

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

   ```
   zip -r hello_world_python_lambda.zip greengrasssdk greengrassHelloWorld.py
   ```
**Note**  
Depending on your distribution, you might need to install `zip` first (for example, by running `sudo apt-get install zip`). The installation command for your distribution might be different.

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

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

1. Choose **Author from scratch**.

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

   Choose **Create function**.

1. Upload your Lambda function deployment package:

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

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

   1. <a name="lambda-console-runtime-settings-para"></a>On the **Code** tab for the function, under **Runtime settings**, choose **Edit**, and then enter the following values.
      + For **Runtime**, choose **Python 3.7**.
      + For **Handler**, enter **greengrassHelloWorld.function\$1handler**  
![\[The "Runtime settings" section with the "Runtime" field set to "Python 3.7" and the "Handler" field set to "greengrassHelloWorld.function_handler".\]](http://docs.aws.amazon.com/greengrass/v1/developerguide/images/gg-get-started-023-2.png)

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

1. <a name="publish-function-version"></a>Publish the Lambda function:

   1. From the **Actions** menu at the top of the page, choose **Publish new version**.  
![\[Screenshot of the Actions menu with Publish new version highlighted.\]](http://docs.aws.amazon.com/greengrass/v1/developerguide/images/gg-get-started-026.png)

   1. For **Version description**, enter **First version**, and then choose **Publish**.  
![\[Screenshot with the Version description field set to First version and the Publish button highlighted.\]](http://docs.aws.amazon.com/greengrass/v1/developerguide/images/gg-get-started-027.png)

1. <a name="create-version-alias"></a>Create an [alias](https://docs.aws.amazon.com/lambda/latest/dg/configuration-aliases.html) for the Lambda function [version](https://docs.aws.amazon.com/lambda/latest/dg/versioning-aliases.html):
**Note**  
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.

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

   1. Name the alias **GG\$1HelloWorld**, set the version to **1** (which corresponds to the version that you just published), and then choose **Save**.
**Note**  
AWS IoT Greengrass doesn't support Lambda aliases for **\$1LATEST** versions.

         
![\[Screenshot of Create a new alias with the Name field set to GG_HelloWorld, and the Version field set to 1.\]](http://docs.aws.amazon.com/greengrass/v1/developerguide/images/gg-get-started-029.png)

# Configure the Lambda function for AWS IoT Greengrass
<a name="config-lambda"></a>

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

In this step, you:
+ Use the AWS IoT console to add the Lambda function to your Greengrass group.
+ Configure group-specific settings for the Lambda function.
+ Add a subscription to the group that allows the Lambda function to publish MQTT messages to AWS IoT.
+ Configure local log settings for the 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. Under **Greengrass groups**, choose the group that you created in [Module 2](module2.md).

1. On the group configuration page, choose the **Lambda functions** tab, and then scroll down to the **My Lambda functions** section and choose **Add Lambda function**.

1. Select the name of the Lambda function you created in the previous step (**Greengrass\$1HelloWorld**, not the alias name).

1. For the version, choose **Alias: GG\$1HelloWorld**.

1. In the **Lambda function configuration** section, make the following changes:
   + Set the **System user and group** to **Use group default**.
   + Set the **Lambda function containerization** to **Use group default**.
   + Set **Timeout** to 25 seconds. This Lambda function sleeps for 5 seconds before each invocation.
   + For **Pinned**, choose **True**.

    
**Note**  
<a name="long-lived-lambda"></a>A *long-lived* (or *pinned*) Lambda function starts automatically after AWS IoT Greengrass starts and keeps running in its own container. This is in contrast to an *on-demand* Lambda function, which starts when invoked and stops when there are no tasks left to run. For more information, see [Lifecycle configuration for Greengrass Lambda functions](lambda-functions.md#lambda-lifecycle).

1. Choose **Add Lambda function** to save your changes. For information about Lambda function properties, see [Controlling execution of Greengrass Lambda functions by using group-specific configuration](lambda-group-config.md).

   Next, create a subscription that allows the Lambda function to send [MQTT](http://mqtt.org/) messages to AWS IoT Core.

   A Greengrass Lambda function can exchange MQTT messages with:
   + [Devices](what-is-gg.md#greengrass-devices) in the Greengrass group.
   + [Connectors](connectors.md) in the group.
   + Other Lambda functions in the group.
   + AWS IoT Core.
   + The local shadow service. For more information, see [Module 5: Interacting with device shadows](module5.md).

   The group uses subscriptions to control how these entities can communicate with each other. Subscriptions provide predictable interactions and a layer of security.

   A subscription consists of a source, target, and topic. The source is the originator of the message. The target is the destination of the message. The topic allows you to filter the data that is sent from the source to the target. The source or target can be a Greengrass device, Lambda function, connector, device shadow, or AWS IoT Core.
**Note**  
A subscription is directed in the sense that messages flow in a specific direction: from the source to the target. To allow two-way communication, you must set up two subscriptions.
**Note**  
 Currently, the subscription topic filter does not allow more than a single `+` character in a topic. The topic filter only allows a single `#` character at the end of a topic. 

   The `Greengrass_HelloWorld` Lambda function sends messages only to the `hello/world` topic in AWS IoT Core, so you only need to create one subscription from the Lambda function to AWS IoT Core. You create this in the next step.

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

   For an example that shows you how to create a subscription using the AWS CLI, see [create-subscription-definition](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/greengrass/create-subscription-definition.html) in the *AWS CLI Command Reference*.

1. In the **Source type**, choose **Lambda function** and, for the **Source**, choose **Greengrass\$1HelloWorld**.

1. For the **Target type**, choose **Service** and, for the **Target** select **IoT Cloud**.

1. For **Topic filter**, enter **hello/world**, and then choose **Create subscription**.

1. Configure the group's logging settings. For this tutorial, you configure AWS IoT Greengrass system components and user-defined Lambda functions to write logs to the file system of the core device.

   1. On the group configuration page, choose the **Logs** tab.

   1. In the **Local logs configuration** section, choose **Edit**.

   1. On the **Edit local logs configuration** dialog box, keep the default values for both log levels and storage sizes, and then choose **Save**.

   You can use logs to troubleshoot any issues you might encounter when running this tutorial. When troubleshooting issues, you can temporarily change the logging level to **Debug**. For more information, see [Accessing file system logs](greengrass-logs-overview.md#gg-logs-local).

1. <a name="disable-stream-manager-no-java"></a>If the Java 8 runtime isn't installed on your core device, you must install it or disable stream manager.
**Note**  
This tutorial doesn't use stream manager, but it does use the **Default Group creation** workflow that enables stream manager by default. If stream manager is enabled but Java 8 isn't installed, the group deployment fails. For more information, see the [stream manager requirements](stream-manager.md#stream-manager-requirements).

   To disable stream manager:

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

   1. Under the **System Lambda functions** section, select **Stream manager** and choose **Edit**.

   1. Choose **Disable**, and then choose **Save**.

# Deploy cloud configurations to a Greengrass core device
<a name="configs-core"></a>

1. Make sure that your Greengrass core device is connected to the internet. For example, try successfully navigating to a webpage.

1. Make sure that the Greengrass daemon is running on your core device. In your core device terminal, run the following commands to check whether the daemon is running and start it, if needed.

   1. To check whether the daemon is running:

      ```
      ps aux | grep -E 'greengrass.*daemon'
      ```

      If the output contains a `root` entry for `/greengrass/ggc/packages/1.11.6/bin/daemon`, then the daemon is running.

   1. To start the daemon:

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

   Now you're ready to deploy the Lambda function and subscription configurations to your Greengrass core device.

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

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

1. On the group configuration page, choose **Deploy**.

1. On the **Lambda functions** tab, in the **System Lambda functions** section, choose **IP detector**.

1. Choose **Edit** and select **Automatically detect and override MQTT broker endpoints**. This enables devices to automatically acquire connectivity information for the core, such as IP address, DNS, and port number. Automatic detection is recommended, but AWS IoT Greengrass also supports manually specified endpoints. You're only prompted for the discovery method the first time that the group is deployed.

The first deployment might take a few minutes. When the deployment is complete, you should see **Successfully completed** in the **Status** column on the **Deployments** page:

**Note**  
The deployment status is also displayed below the group's name on the page header.

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

# Verify the Lambda function is running on the core device
<a name="lambda-check"></a>

1. From the navigation pane of the [AWS IoT console](https://console.aws.amazon.com/iot/), under **Test**, choose **MQTT test client**.

1. Choose the **Subscribe to topic** tab.

1. Enter **hello/world** into the **Topic filter** and expand the **Additional configuration**.

1. Enter the information listed in each of the following fields:
   + For **Quality of Service**, choose **0**.
   + For **MQTT payload display**, choose **Display payloads as strings**.

    

1. Choose **Subscribe**.

Assuming the Lambda function is running on your device, it publishes messages similar to the following to the `hello/world` topic:

![\[Screenshot of message sent to the hello/world topic with message highlighted.\]](http://docs.aws.amazon.com/greengrass/v1/developerguide/images/gg-get-started-045.png)


Although the Lambda function continues to send MQTT messages to the `hello/world` topic, don't stop the AWS IoT Greengrass daemon. The remaining modules are written with the assumption that it's running.

You can delete the function and subscription from the group:
+ On the groups configuration page, under the **Lambda functions** tab, select the Lambda function you want to remove and choose **Remove**.
+ On the groups configuration page, under the **Subscriptions** tab, choose the subscription, and then choose **Delete**.

The function and subscription are removed from the core during the next group deployment.

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

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

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

This module should take about 30 minutes to complete.

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

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

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

 

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

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

1. Create a Lambda function deployment package:

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

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

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

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

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

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

1. Choose **Author from scratch**.

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

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

1. Upload your Lambda function deployment package.

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

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

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

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

1. Publish the first version of the function.

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

   1. Choose **Publish**.

1. Create an alias for the function version.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

1. Choose **Create subscription**.

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

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

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

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

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

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

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

1. Choose **Subscribe**.

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

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

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

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

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

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


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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

# Module 4: Interacting with client devices in an AWS IoT Greengrass group
<a name="module4"></a>

This module shows you how local IoT devices, called *client devices* or *devices*, can connect to and communicate with an AWS IoT Greengrass core device. Client devices that connect to an AWS IoT Greengrass core are part of an AWS IoT Greengrass group and can participate in the AWS IoT Greengrass programming paradigm. In this module, one client device sends a Hello World message to another client device in the Greengrass group.

![\[AWS IoT connected to an AWS IoT Greengrass core, which is connected to client device #1 and client device #2.\]](http://docs.aws.amazon.com/greengrass/v1/developerguide/images/gg-get-started-065.5.png)


Before you begin, run the [Greengrass device setup](quick-start.md) script or complete [Module 1](module1.md) and [Module 2](module2.md). This module creates two simulated client devices. You do not need other components or devices.

This module should take less than 30 minutes to complete.

**Topics**
+ [Create client devices in an AWS IoT Greengrass group](device-group.md)
+ [Configure subscriptions](config-subs.md)
+ [Install the AWS IoT Device SDK for Python](IoT-SDK.md)
+ [Test communications](test-comms.md)

# Create client devices in an AWS IoT Greengrass group
<a name="device-group"></a>

In this step, you add two client devices to your Greengrass group. This process includes registering the devices as AWS IoT things and configuring certificates and keys to allow them to connect to AWS IoT Greengrass.

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

1. <a name="group-choose-target-group"></a>Choose the target group.

1. <a name="gg-group-add-device"></a>On the group configuration page, choose **Client devices**, and then choose **Associate**.

1. <a name="gg-group-create-device"></a>In the **Associate a client device with this group** modal, choose **Create new AWS IoT thing**.

   The **Create things** page opens in a new tab.

1. <a name="gg-group-create-single-thing"></a>On the **Create things** page, choose **Create single thing**, and then choose **Next**.

1. On the **Specify thing properties** page, register this client device as **HelloWorld\$1Publisher**, and then choose **Next**.

1. <a name="gg-group-create-device-configure-certificate"></a>On the **Configure device certificate** page, choose **Next**.

1. <a name="gg-group-create-device-attach-policy"></a>On the **Attach policies to certificate** page, do one of the following:
   + Select an existing policy that grants permissions that client devices require, and then choose **Create thing**.

     A modal opens where you can download the certificates and keys that the device uses to connect to the AWS Cloud and the core.
   + Create and attach a new policy that grants client device permissions. Do the following:

     1. Choose **Create policy**.

        The **Create policy** page opens in a new tab.

     1. On the **Create policy** page, do the following:

        1. For **Policy name**, enter a name that describes the policy, such as **GreengrassV1ClientDevicePolicy**.

        1. On the **Policy statements** tab, under **Policy document**, choose **JSON**.

        1. Enter the following policy document. This policy allows the client device to discover Greengrass cores and communicate on all MQTT topics. For information about how to restrict this policy's access, see [Device authentication and authorization for AWS IoT Greengrass](device-auth.md).

------
#### [ JSON ]

****  

           ```
           {
             "Version":"2012-10-17",		 	 	 
             "Statement": [
               {
                 "Effect": "Allow",
                 "Action": [
                   "iot:Publish",
                   "iot:Subscribe",
                   "iot:Connect",
                   "iot:Receive"
                 ],
                 "Resource": [
                   "*"
                 ]
               },
               {
                 "Effect": "Allow",
                 "Action": [
                   "greengrass:*"
                 ],
                 "Resource": [
                   "*"
                 ]
               }
             ]
           }
           ```

------

        1. Choose **Create** to create the policy.

     1. Return to the browser tab with the **Attach policies to certificate** page open. Do the following:

        1. In the **Policies** list, select the policy that you created, such as **GreengrassV1ClientDevicePolicy**.

           If you don't see the policy, choose the refresh button.

        1. Choose **Create thing**.

           A modal opens where you can download the certificates and keys that the device uses to connect to the AWS Cloud and the core.

1. <a name="gg-group-create-device-download-certs"></a>In the **Download certificates and keys** modal, download the device's certificates.
**Important**  
Before you choose **Done**, download the security resources.

   Do the following:

   1. For **Device certificate**, choose **Download** to download the device certificate.

   1. For **Public key file**, choose **Download** to download the public key for the certificate.

   1. For **Private key file**, choose **Download** to download the private key file for the certificate.

   1. Review [Server Authentication](https://docs.aws.amazon.com/iot/latest/developerguide/server-authentication.html) in the *AWS IoT Developer Guide* and choose the appropriate root CA certificate. We recommend that you use Amazon Trust Services (ATS) endpoints and ATS root CA certificates. Under **Root CA certificates**, choose **Download** for a root CA certificate.

   1. Choose **Done**.

   Make a note of the certificate ID that's common in the file names for the device certificate and keys. You need it later.

1. Return to the browser tab with the **Associate a client device with this group** modal open. Do the following:

   1. For **AWS IoT thing name**, choose the **HelloWorld\$1Publisher** thing that you created.

      If you don't see the thing, choose the refresh button.

   1. Choose **Associate**.

1. Repeat steps 3 - 10 to add a second client device to the group.

   Name this client device **HelloWorld\$1Subscriber**. Download the certificates and keys for this client device to your computer. Again, make a note of the certificate's ID that's common in the file names for the HelloWorld\$1Subscriber device.

   You should now have two client devices in your Greengrass group:
   + HelloWorld\$1Publisher
   + HelloWorld\$1Subscriber

1. Create a folder on your computer for these client devices' security credentials. Copy the certificates and keys into this folder.

# Configure subscriptions
<a name="config-subs"></a>

In this step, you enable the HelloWorld\$1Publisher client device to send MQTT messages to the HelloWorld\$1Subscriber client device.

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

1. On the **Create a subscription** page, do the following to configure the subscription:

   1. For **Source type**, choose **Client device**, and then choose **HelloWorld\$1Publisher**.

   1. Under **Target type**, choose **Client device**, and then choose **HelloWorld\$1Subscriber**.

   1. For **Topic filter**, enter **hello/world/pubsub**.
**Note**  
You can delete subscriptions from the previous modules. On the group's **Subscriptions** page, select the subscriptions to delete, and then choose **Delete**.

   1. Choose **Create subscription**.

1. <a name="enable-automatic-detection"></a>Make sure that automatic detection is enabled so the Greengrass core can publish a list of its IP addresses. Client devices use this information to discover the core. Do the following:

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

   1. Under **System Lambda functions**, choose **IP detector**, and then choose **Edit**.

   1. In the **Edit IP detector settings**, choose **Automatically detect and override MQTT broker endpoints**, and then choose **Save**.

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

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

The deployment status is displayed below the group name on the page header. To see deployment details, choose the **Deployments** tab.

# Install the AWS IoT Device SDK for Python
<a name="IoT-SDK"></a>

Client devices can use the AWS IoT Device SDK for Python to communicate with AWS IoT and AWS IoT Greengrass core devices (using the Python programming language). For more information, including requirements, see the AWS IoT Device SDK for Python [ Readme](https://github.com/aws/aws-iot-device-sdk-python) on GitHub.

In this step, you install the SDK and get the `basicDiscovery.py` sample function used by the simulated client devices on your computer.

1. To install the SDK on your computer, with all required components, choose your operating system:

------
#### [ Windows ]

   1. Open an [elevated command prompt](https://technet.microsoft.com/en-us/library/cc947813(v=ws.10).aspx) and run the following command:

      ```
      python --version
      ```

      If no version information is returned or if the version number is less than 2.7 for Python 2 or less than 3.3 for Python 3, follow the instructions in [Downloading Python](https://wiki.python.org/moin/BeginnersGuide/Download) to install Python 2.7\$1 or Python 3.3\$1. For more information, see [Using Python on Windows](https://docs.python.org/3.6/using/windows.html).

   1. Download the [AWS IoT Device SDK for Python](https://github.com/aws/aws-iot-device-sdk-python) as a `zip` file and extract it to an appropriate location on your computer.

      Make a note of the file path to the extracted `aws-iot-device-sdk-python-master` folder that contains the `setup.py` file. In the next step, this file path is indicated by *path-to-SDK-folder*.

   1. From the elevated command prompt, run the following:

      ```
      cd path-to-SDK-folder
      python setup.py install
      ```

------
#### [ macOS ]

   1. Open a Terminal window and run the following command:

      ```
      python --version
      ```

      If no version information is returned or if the version number is less than 2.7 for Python 2 or less than 3.3 for Python 3, follow the instructions in [Downloading Python](https://wiki.python.org/moin/BeginnersGuide/Download) to install Python 2.7\$1 or Python 3.3\$1. For more information, see [Using Python on a Macintosh](https://docs.python.org/3/using/mac.html).

   1. In the Terminal window, run the following commands to determine the OpenSSL version:

      ```
      python
      >>>import ssl
      >>>print ssl.OPENSSL_VERSION
      ```

      Make a note of the OpenSSL version value. 
**Note**  
If you're running Python 3, use **print(ssl.OPENSSL\$1VERSION)**.

      To close the Python shell, run the following command:

      ```
      >>>exit()
      ```

      If the OpenSSL version is 1.0.1 or later, skip to [step c](#step-c-install-python-sdk). Otherwise, follow these steps:

      1. From the Terminal window, run the following command to determine if the computer is using Simple Python Version Management:

        ```
        which pyenv
        ```

      If a file path is returned, then choose the **Using `pyenv`** tab. If nothing is returned, choose the **Not using `pyenv`** tab.

------
#### [ Using pyenv ]

      1. See [Python Releases for Mac OS X](https://www.python.org/downloads/mac-osx/) (or similar) to determine the latest stable Python version. In the following example, this value is indicated by *latest-Python-version*.

      1. From the Terminal window, run the following commands:

         ```
         pyenv install latest-Python-version
         pyenv global latest-Python-version
         ```

         For example, if the latest version for Python 2 is 2.7.14, then these commands are:

         ```
         pyenv install 2.7.14
         pyenv global 2.7.14
         ```

      1. Close and then reopen the Terminal window and then run the following commands:

         ```
         python
         >>>import ssl
         >>>print ssl.OPENSSL_VERSION
         ```

         The OpenSSL version should be at least 1.0.1. If the version is less than 1.0.1, then the update failed. Check the Python version value used in the **pyenv install** and **pyenv global** commands and try again.

      1. Run the following command to exit the Python shell:

         ```
          exit()
         ```

------
#### [ Not using pyenv ]

      1. From a Terminal window, run the following command to determine if [brew](https://brew.sh/) is installed:

         ```
         which brew
         ```

         If a file path is not returned, install `brew` as follows:

         ```
         /usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
         ```
**Note**  
Follow the installation prompts. The download for the Xcode command line tools can take some time.

      1. Run the following commands:

         ```
         brew update
         brew install openssl
         brew install python@2
         ```

         The AWS IoT Device SDK for Python requires OpenSSL version 1.0.1 (or later) compiled with the Python executable. The **brew install python** command installs a `python2` executable that meets this requirement. The `python2` executable is installed in the `/usr/local/bin` directory, which should be part of the `PATH` environment variable. To confirm, run the following command:

         ```
         python2 --version
         ```

         If `python2` version information is provided, skip to the next step. Otherwise, permanently add the `/usr/local/bin` path to your `PATH` environment variable by appending the following line to your shell profile:

         ```
         export PATH="/usr/local/bin:$PATH"
         ```

         For example, if you're using `.bash_profile` or do not yet have a shell profile, run the following command from a Terminal window:

         ```
         echo 'export PATH="/usr/local/bin:$PATH"' >> ~/.bash_profile
         ```

         Next, [source](https://en.wikipedia.org/wiki/Source_(command)) your shell profile and confirm that `python2 --version` provides version information. For example, if you're using `.bash_profile`, run the following commands:

         ```
         source ~/.bash_profile
         python2 --version
         ```

         `python2` version information should be returned.

      1. Append the following line to your shell profile:

         ```
         alias python="python2"
         ```

         For example, if you're using `.bash_profile` or do not yet have a shell profile, run the following command:

         ```
         echo 'alias python="python2"' >> ~/.bash_profile
         ```

      1. Next, [source](https://en.wikipedia.org/wiki/Source_(command)) your shell profile. For example, if you're using `.bash_profile`, run the following command:

         ```
         source ~/.bash_profile
         ```

         Invoking the **python** command runs the Python executable that contains the required OpenSSL version (`python2`) .

      1. Run the following commands:

         ```
         python
          import ssl
          print ssl.OPENSSL_VERSION
         ```

         The OpenSSL version should be 1.0.1 or later.

      1. To exit the Python shell, run the following command:

         ```
          exit()
         ```

------

   1. <a name="step-c-install-python-sdk"></a>Run the following commands to install the AWS IoT Device SDK for Python:

      ```
      cd ~
      git clone https://github.com/aws/aws-iot-device-sdk-python.git
      cd aws-iot-device-sdk-python
      sudo python setup.py install
      ```

------
#### [ UNIX-like system ]

   1. From a terminal window, run the following command:

      ```
      python --version
      ```

      If no version information is returned or if the version number is less than 2.7 for Python 2 or less than 3.3 for Python 3, follow the instructions in [Downloading Python](https://wiki.python.org/moin/BeginnersGuide/Download) to install Python 2.7\$1 or Python 3.3\$1. For more information, see [Using Python on Unix platforms](https://docs.python.org/3.6/using/unix.html).

   1. In the terminal, run the following commands to determine the OpenSSL version:

      ```
      python
      >>>import ssl
      >>>print ssl.OPENSSL_VERSION
      ```

      Make a note of the OpenSSL version value. 
**Note**  
If you're running Python 3, use **print(ssl.OPENSSL\$1VERSION)**.

      To close the Python shell, run the following command:

      ```
       exit()
      ```

      If the OpenSSL version is 1.0.1 or later, skip to the next step. Otherwise, run the command(s) to update OpenSSL for your distribution (for example, `sudo yum update openssl`, `sudo apt-get update`, and so on).

      Confirm that the OpenSSL version is 1.0.1 or later by running the following commands:

      ```
      python
      >>>import ssl
      >>>print ssl.OPENSSL_VERSION
      >>>exit()
      ```

   1. Run the following commands to install the AWS IoT Device SDK for Python:

      ```
      cd ~
      git clone https://github.com/aws/aws-iot-device-sdk-python.git
      cd aws-iot-device-sdk-python
      sudo python setup.py install
      ```

------

1. After the AWS IoT Device SDK for Python is installed, navigate to the `samples` folder and open the `greengrass` folder.

   For this tutorial, you copy the `basicDiscovery.py` sample function, which uses the certificates and keys that you downloaded in [Create client devices in an AWS IoT Greengrass group](device-group.md).

1. Copy `basicDiscovery.py` to the folder that contains the HelloWorld\$1Publisher and HelloWorld\$1Subscriber device certificates and keys.

# Test communications
<a name="test-comms"></a>

1. <a name="ping-device"></a>Make sure that your computer and the AWS IoT Greengrass core device are connected to the internet using the same network.

   1. On the AWS IoT Greengrass core device, run the following command to find its IP address.

      ```
      hostname -I
      ```

   1. On your computer, run the following command using the IP address of the core. You can use Ctrl \$1 C to stop the **ping** command.

      ```
      ping IP-address
      ```

      Output similar to the following indicates successful communication between the computer and the AWS IoT Greengrass core device (0% packet loss):  
![\[Successful ping command output.\]](http://docs.aws.amazon.com/greengrass/v1/developerguide/images/gg-get-started-075.5.png)
**Note**  
If you're unable to ping an EC2 instance that's running AWS IoT Greengrass, make sure that the inbound security group rules for the instance allow ICMP traffic for [Echo request](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/security-group-rules-reference.html#sg-rules-ping) messages. For more information, see [ Adding rules to a security group](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/using-network-security.html#adding-security-group-rule) in the *Amazon EC2 User Guide*.  
On Windows host computers, in the Windows Firewall with Advanced Security app, you might also need to enable an inbound rule that allows inbound echo requests (for example, **File and Printer Sharing (Echo Request - ICMPv4-In)**), or create one.

1. Get your AWS IoT endpoint.

   1. <a name="iot-settings"></a>From the [AWS IoT console](https://console.aws.amazon.com/iot/) navigation pane, choose **Settings**.

   1. <a name="iot-settings-endpoint"></a>Under **Device data endpoint**, make a note of the value of **Endpoint**. You use this value to replace the *AWS\$1IOT\$1ENDPOINT* placeholder in the commands in the following steps.
**Note**  
Make sure that your [endpoints correspond to your certificate type](gg-core.md#certificate-endpoints).

1. On your computer (not the AWS IoT Greengrass core device), open two [command-line](https://en.wikipedia.org/wiki/Command-line_interface) (terminal or command prompt) windows. One window represents the HelloWorld\$1Publisher client device and the other represents the HelloWorld\$1Subscriber client device.

   Upon execution, `basicDiscovery.py` attempts to collect information on the location of the AWS IoT Greengrass core at its endpoints. This information is stored after the client device has discovered and successfully connected to the core. This allows future messaging and operations to be executed locally (without the need for an internet connection).
**Note**  
Client IDs used for MQTT connections must match the thing name of the client device. The `basicDiscovery.py` script sets the client ID for MQTT connections to the thing name that you specify when you run the script.   
Run the following command from the folder that contains the `basicDiscovery.py` file for detailed script usage information:  

   ```
   python basicDiscovery.py --help
   ```

1. From the HelloWorld\$1Publisher client device window, run the following commands.
   + Replace *path-to-certs-folder* with the path to the folder that contains the certificates, keys, and `basicDiscovery.py`.
   + Replace *AWS\$1IOT\$1ENDPOINT* with your endpoint.
   + Replace the two *publisherCertId* instances with the certificate ID in the file name for your HelloWorld\$1Publisher client device.

   ```
   cd path-to-certs-folder
   python basicDiscovery.py --endpoint AWS_IOT_ENDPOINT --rootCA AmazonRootCA1.pem --cert publisherCertId-certificate.pem.crt --key publisherCertId-private.pem.key --thingName HelloWorld_Publisher --topic 'hello/world/pubsub' --mode publish --message 'Hello, World! Sent from HelloWorld_Publisher'
   ```

   You should see output similar to the following, which includes entries such as `Published topic 'hello/world/pubsub': {"message": "Hello, World! Sent from HelloWorld_Publisher", "sequence": 1}`.
**Note**  
If the script returns an `error: unrecognized arguments` message, change the single quotation marks to double quotation marks for the `--topic` and `--message` parameters and run the command again.  
To troubleshoot a connection issue, you can try using [manual IP detection](#corp-network-manual-detection).  
![\[Screenshot of the publisher output.\]](http://docs.aws.amazon.com/greengrass/v1/developerguide/images/gg-get-started-076.png)

1. From the HelloWorld\$1Subscriber client device window, run the following commands.
   + Replace *path-to-certs-folder* with the path to the folder that contains the certificates, keys, and `basicDiscovery.py`.
   + Replace *AWS\$1IOT\$1ENDPOINT* with your endpoint.
   + Replace the two *subscriberCertId* instances with the certificate ID in the file name for your HelloWorld\$1Subscriber client device.

   ```
   cd path-to-certs-folder
   python basicDiscovery.py --endpoint AWS_IOT_ENDPOINT --rootCA AmazonRootCA1.pem --cert subscriberCertId-certificate.pem.crt --key subscriberCertId-private.pem.key --thingName HelloWorld_Subscriber --topic 'hello/world/pubsub' --mode subscribe
   ```

   You should see the following output, which includes entries such as `Received message on topic hello/world/pubsub: {"message": "Hello, World! Sent from HelloWorld_Publisher", "sequence": 1}`.  
![\[Screenshot of the subscriber output.\]](http://docs.aws.amazon.com/greengrass/v1/developerguide/images/gg-get-started-077.png)

Close the HelloWorld\$1Publisher window to stop messages from accruing in the HelloWorld\$1Subscriber window.

Testing on a corporate network might interfere with connecting to the core. As a workaround, you can manually enter the endpoint. This ensures that the `basicDiscovery.py` script connects to the correct IP address of the AWS IoT Greengrass core device.

**To manually enter the endpoint**

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

1. Under **Greengrass groups**, choose your group.

1. Configure the core to manually manage MQTT broker endpoints. Do the following:

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

   1. Under **System Lambda functions**, choose **IP detector**, and then choose **Edit**.

   1. In the **Edit IP detector settings**, choose **Manually manage MQTT broker endpoints**, and then choose **Save**.

1. Enter the MQTT broker endpoint for the core. Do the following:

   1. Under **Overview**, choose the **Greengrass core**.

   1. Under **MQTT broker endpoints**, choose **Manage endpoints**.

   1. Choose **Add endpoint** and make sure that you have only one endpoint value. This value must be the IP address endpoint for port 8883 of your AWS IoT Greengrass core device (for example, `192.168.1.4`).

   1. Choose **Update**.

# Module 5: Interacting with device shadows
<a name="module5"></a>

This advanced module shows you how client devices can interact with [AWS IoT device shadows](https://docs.aws.amazon.com/iot/latest/developerguide/iot-device-shadows.html) in an AWS IoT Greengrass group. A *shadow* is a JSON document that is used to store current or desired state information for a thing. In this module, you discover how one client device (`GG_Switch`) can modify the state of another client device (`GG_TrafficLight`) and how these states can be synced to the AWS IoT Greengrass cloud:

![\[AWS IoT Greengrass core is connected to a traffic light device shadow and a light switch device.\]](http://docs.aws.amazon.com/greengrass/v1/developerguide/images/gg-get-started-077.5.png)


Before you begin, run the [Greengrass device setup](quick-start.md) script, or make sure that you have completed [Module 1](module1.md) and [Module 2](module2.md). You should also understand how to connect client devices to an AWS IoT Greengrass core ([Module 4](module4.md)). You do not need other components or devices.

This module should take about 30 minutes to complete.

**Topics**
+ [Configure devices and subscriptions](config-dev-subs.md)
+ [Download required files](file-download.md)
+ [Test communications (device syncs disabled)](comms-disabled.md)
+ [Test communications (device syncs enabled)](comms-enabled.md)

# Configure devices and subscriptions
<a name="config-dev-subs"></a>

Shadows can be synced to AWS IoT when the AWS IoT Greengrass core is connected to the internet. In this module, you first use local shadows without syncing to the cloud. Then, you enable cloud syncing.

Each client device has its own shadow. For more information, see [Device shadow service for AWS IoT](https://docs.aws.amazon.com/iot/latest/developerguide/iot-device-shadows.html) in the *AWS IoT Developer Guide*.

1. On the group configuration page, choose the **Client devices** tab.

1. From the **Client devices** tab, add two new client devices in your AWS IoT Greengrass group. For detailed steps of this process, see [Create client devices in an AWS IoT Greengrass group](device-group.md).
   + Name the client devices **GG\$1Switch** and **GG\$1TrafficLight**.
   + Generate and download the security resources for both client devices.
   + Make a note of the certificate ID in the file names of the security resources for the client devices. You use these values later.

1. Create a folder on your computer for these client devices' security credentials. Copy the certificates and keys into this folder.

1. Make sure that the client devices are set to use local shadows and not sync with the AWS Cloud. If not, select the client device, choose **Sync shadow**, and then choose **Disable shadow sync with cloud**.

1. <a name="module5-subscriptions"></a>Add the subscriptions in the following table to your group. For example, to create the first subscription:

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

   1. For **Source type**, choose **Client device**, and then choose **GG\$1Switch**.

   1. For **Target type**, choose **Service**, and then choose **Local Shadow Service**.

   1. For **Topic filter**, enter **\$1aws/things/GG\$1TrafficLight/shadow/update**

   1. Choose **Create subscription**.

   The topics must be entered exactly as shown in the table. Although it's possible to use wildcards to consolidate some of the subscriptions, we don't recommend this practice. For more information, see [Shadow MQTT topics](https://docs.aws.amazon.com/iot/latest/developerguide/device-shadow-mqtt.html) in the *AWS IoT Developer Guide*.    
[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/greengrass/v1/developerguide/config-dev-subs.html)

   The new subscriptions are displayed on the **Subscriptions** tab.
**Note**  
For information about the `$` character, see [Reserved topics](https://docs.aws.amazon.com/iot/latest/developerguide/topics.html#reserved-topics).

1. <a name="enable-automatic-detection"></a>Make sure that automatic detection is enabled so the Greengrass core can publish a list of its IP addresses. Client devices use this information to discover the core. Do the following:

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

   1. Under **System Lambda functions**, choose **IP detector**, and then choose **Edit**.

   1. In the **Edit IP detector settings**, choose **Automatically detect and override MQTT broker endpoints**, and then choose **Save**.

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

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

# Download required files
<a name="file-download"></a>

1. If you haven't already done so, install the AWS IoT Device SDK for Python. For instructions, see step 1 in [Install the AWS IoT Device SDK for Python](IoT-SDK.md).

   This SDK is used by client devices to communicate with AWS IoT and with AWS IoT Greengrass core devices.

1. From the [ TrafficLight](https://github.com/aws/aws-greengrass-core-sdk-python/tree/master/examples/TrafficLight) examples folder on GitHub, download the `lightController.py` and `trafficLight.py` files to your computer. Save them in the folder that contains the GG\$1Switch and GG\$1TrafficLight client device certificates and keys.

   The `lightController.py` script corresponds to the GG\$1Switch client device, and the `trafficLight.py` script corresponds to the GG\$1TrafficLight client device.   
![\[Screenshot of files including the two Python scripts and the device certificates and keys.\]](http://docs.aws.amazon.com/greengrass/v1/developerguide/images/gg-get-started-082.png)
**Note**  
The example Python files are stored in the AWS IoT Greengrass Core SDK for Python repository for convenience, but they don't use the AWS IoT Greengrass Core SDK.

# Test communications (device syncs disabled)
<a name="comms-disabled"></a>

1. <a name="ping-device"></a>Make sure that your computer and the AWS IoT Greengrass core device are connected to the internet using the same network.

   1. On the AWS IoT Greengrass core device, run the following command to find its IP address.

      ```
      hostname -I
      ```

   1. On your computer, run the following command using the IP address of the core. You can use Ctrl \$1 C to stop the **ping** command.

      ```
      ping IP-address
      ```

      Output similar to the following indicates successful communication between the computer and the AWS IoT Greengrass core device (0% packet loss):  
![\[Successful ping command output.\]](http://docs.aws.amazon.com/greengrass/v1/developerguide/images/gg-get-started-075.5.png)
**Note**  
If you're unable to ping an EC2 instance that's running AWS IoT Greengrass, make sure that the inbound security group rules for the instance allow ICMP traffic for [Echo request](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/security-group-rules-reference.html#sg-rules-ping) messages. For more information, see [ Adding rules to a security group](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/using-network-security.html#adding-security-group-rule) in the *Amazon EC2 User Guide*.  
On Windows host computers, in the Windows Firewall with Advanced Security app, you might also need to enable an inbound rule that allows inbound echo requests (for example, **File and Printer Sharing (Echo Request - ICMPv4-In)**), or create one.

1. Get your AWS IoT endpoint.

   1. <a name="iot-settings"></a>From the [AWS IoT console](https://console.aws.amazon.com/iot/) navigation pane, choose **Settings**.

   1. <a name="iot-settings-endpoint"></a>Under **Device data endpoint**, make a note of the value of **Endpoint**. You use this value to replace the *AWS\$1IOT\$1ENDPOINT* placeholder in the commands in the following steps.
**Note**  
Make sure that your [endpoints correspond to your certificate type](gg-core.md#certificate-endpoints).

1. <a name="repeated-step"></a>On your computer (not the AWS IoT Greengrass core device), open two [command-line](https://en.wikipedia.org/wiki/Command-line_interface) (terminal or command prompt) windows. One window represents the GG\$1Switch client device and the other represents the GG\$1TrafficLight client device.

   1. <a name="run-switch-device"></a>From the GG\$1Switch client device window, run the following commands.
      + Replace *path-to-certs-folder* with the path to the folder that contains the certificates, keys, and Python files.
      + Replace *AWS\$1IOT\$1ENDPOINT* with your endpoint.
      + Replace the two *switchCertId* instances with the certificate ID in the file name for your GG\$1Switch client device.

      ```
      cd path-to-certs-folder
      python lightController.py --endpoint AWS_IOT_ENDPOINT --rootCA AmazonRootCA1.pem --cert switchCertId-certificate.pem.crt --key switchCertId-private.pem.key --thingName GG_TrafficLight --clientId GG_Switch
      ```

   1. <a name="run-trafficlight-device"></a>From the GG\$1TrafficLight client device window, run the following commands.
      + Replace *path-to-certs-folder* with the path to the folder that contains the certificates, keys, and Python files.
      + Replace *AWS\$1IOT\$1ENDPOINT* with your endpoint.
      + Replace the two *lightCertId* instances with the certificate ID in the file name for your GG\$1TrafficLight client device.

      ```
      cd path-to-certs-folder
      python trafficLight.py --endpoint AWS_IOT_ENDPOINT --rootCA AmazonRootCA1.pem --cert lightCertId-certificate.pem.crt --key lightCertId-private.pem.key --thingName GG_TrafficLight --clientId GG_TrafficLight
      ```

      Every 20 seconds, the switch updates the shadow state to G, Y, and R, and the light displays its new state, as shown next.

      GG\$1Switch output:  
![\[Screenshot of the output associated with GG_Switch.\]](http://docs.aws.amazon.com/greengrass/v1/developerguide/images/gg-get-started-083.png)

      GG\$1TrafficLight output:  
![\[Screenshot of the output associated with GG_TrafficLight.\]](http://docs.aws.amazon.com/greengrass/v1/developerguide/images/gg-get-started-084.png)

   When executed for the first time, each client device script runs the AWS IoT Greengrass discovery service to connect to the AWS IoT Greengrass core (through the internet). After a client device has discovered and successfully connected to the AWS IoT Greengrass core, future operations can be executed locally.
**Note**  
<a name="check-connection-info"></a> The `lightController.py` and `trafficLight.py` scripts store connection information in the `groupCA` folder, which is created in the same folder as the scripts. If you receive connection errors, make sure that the IP address in the `ggc-host` file matches the IP address endpoint for your core.

1. In the AWS IoT console, choose your AWS IoT Greengrass group, choose the **Client devices** tab, and then choose **GG\$1TrafficLight** to open the client device's AWS IoT thing details page.

1. Choose the **Device Shadows** tab. After the GG\$1Switch changes states, there should not be any updates to this shadow. That's because the GG\$1TrafficLight is set to **Disable shadow sync with cloud**.

1. Press Ctrl \$1 C in the GG\$1Switch (`lightController.py`) client device window. You should see that the GG\$1TrafficLight (`trafficLight.py`) window stops receiving state change messages.

   Keep these windows open so you can run the commands in the next section.

# Test communications (device syncs enabled)
<a name="comms-enabled"></a>

For this test, you configure the GG\$1TrafficLight device shadow to sync to AWS IoT. You run the same commands as in the previous test, but this time the shadow state in the cloud is updated when GG\$1Switch sends an update request.

1. In the AWS IoT console, choose your AWS IoT Greengrass group, and then choose the **Client devices** tab.

1. Select the GG\$1TrafficLight device, choose **Sync shadow**, and then choose **Enable shadow sync with cloud**.

   You should receive a notification that the device shadow sync status was updated.

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

1. In your two command-line windows, run the commands from the previous test for the [GG\$1Switch](comms-disabled.md#run-switch-device) and [GG\$1TrafficLight](comms-disabled.md#run-trafficlight-device) client devices.

1. Now, check the shadow state in the AWS IoT console. Choose your AWS IoT Greengrass group, choose the **Client devices** tab, choose **GG\$1TrafficLight**, choose the **Device Shadows** tab, and then choose **Classic Shadow**.

   Because you enabled sync of the GG\$1TrafficLight shadow to AWS IoT, the shadow state in the cloud should be updated whenever GG\$1Switch sends an update. This functionality can be used to expose the state of a client device to AWS IoT.
**Note**  
If necessary, you can troubleshoot issues by viewing the AWS IoT Greengrass core logs, particularly `runtime.log`:  

   ```
   cd /greengrass/ggc/var/log
   sudo cat system/runtime.log | more
   ```
 You can also view `GGShadowSyncManager.log` and `GGShadowService.log`. For more information, see [Troubleshooting AWS IoT Greengrass](gg-troubleshooting.md). 

Keep the client devices and subscriptions set up. You use them in the next module. You also run the same commands.

# Module 6: Accessing other AWS services
<a name="module6"></a>

This advanced module shows you how AWS IoT Greengrass cores can interact with other AWS services in the cloud. It builds on the traffic light example from [Module 5](module5.md) and adds a Lambda function that processes shadow states and uploads a summary to an Amazon DynamoDB table.

![\[AWS IoT connected to an AWS IoT Greengrass core, which is connected to a light switch device and a traffic light device shadow. The traffic light device shadow is connected to a Lambda function, which is connected to a DynamoDB table.\]](http://docs.aws.amazon.com/greengrass/v1/developerguide/images/gg-get-started-089.5.png)


Before you begin, run the [Greengrass device setup](quick-start.md) script, or make sure that you have completed [Module 1](module1.md) and [Module 2](module2.md). You should also complete [Module 5](module5.md). You do not need other components or devices.

This module should take about 30 minutes to complete.

**Note**  
This module creates and updates a table in DynamoDB. Although most of the operations are small and fall within the Amazon Web Services Free Tier, performing some of the steps in this module might result in charges to your account. For information about pricing, see [DynamoDB pricing documentation](https://aws.amazon.com/dynamodb/pricing/).

**Topics**
+ [Configure the group role](config-iam-roles.md)
+ [Create and configure the Lambda function](create-config-lambda.md)
+ [Configure subscriptions](config_subs.md)
+ [Test communications](comms-test.md)

# Configure the group role
<a name="config-iam-roles"></a>

The group role is an [IAM role](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles.html) that you create and attach to your Greengrass group. This role contains the permissions that deployed Lambda functions (and other AWS IoT Greengrass features) use to access AWS services. For more information, see [Greengrass group role](group-role.md).

You use the following high-level steps to create a group role in the IAM console.

1. Create a policy that allows or denies actions on one or more resources.

1. Create a role that uses the Greengrass service as a trusted entity.

1. Attach your policy to the role.

Then, in the AWS IoT console, you add the role to the Greengrass group.

**Note**  
A Greengrass group has one group role. If you want to add permissions, you can edit attached policies or attach more policies.

 

For this tutorial, you create a permissions policy that allows describe, create, and update actions on an Amazon DynamoDB table. Then, you attach the policy to a new role and associate the role with your Greengrass group.

First, create a customer-managed policy that grants permissions required by the Lambda function in this module.

1. In the IAM console, in the navigation pane, choose **Policies**, and then choose **Create policy**.

1. On the **JSON** tab, replace the placeholder content with the following policy. The Lambda function in this module uses these permissions to create and update a DynamoDB table named `CarStats`.

------
#### [ JSON ]

****  

   ```
   {
       "Version":"2012-10-17",		 	 	 
       "Statement": [
           {
               "Sid": "PermissionsForModule6",
               "Effect": "Allow",
               "Action": [
                   "dynamodb:DescribeTable",
                   "dynamodb:CreateTable",
                   "dynamodb:PutItem"
               ],
               "Resource": "arn:aws:dynamodb:*:*:table/CarStats"
           }
       ]
   }
   ```

------

1. Choose **Next: Tags**, and then choose **Next: Review**. Tags aren't used in this tutorial.

1. For **Name**, enter **greengrass\$1CarStats\$1Table**, and then choose **Create policy**.

    

   Next, create a role that uses the new policy.

1. In the navigation pane, choose **Roles**, and then choose **Create role**.

1. Under **Trusted entity type**, choose **AWS service**.

1. Under **Use case**, **Use cases for other AWS services** choose **Greengrass**, select **Greengrass**, and then choose **Next**.

1. Under **Permissions policies**, select the new **greengrass\$1CarStats\$1Table** policy, and then choose **Next**.

1. For **Role name**, enter **Greengrass\$1Group\$1Role**.

1. For **Description**, enter **Greengrass group role for connectors and user-defined Lambda functions**.

1. Choose **Create role**.

   Now, add the role to your 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. Under **Greengrass groups**, choose your group.

1. Choose **Settings**, and then choose **Associate role**.

1. Choose **Greengrass\$1Group\$1Role** from your list of roles, and then choose **Associate role**.

# Create and configure the Lambda function
<a name="create-config-lambda"></a>

In this step, you create a Lambda function that tracks the number of cars that pass the traffic light. Every time that the `GG_TrafficLight` shadow state changes to `G`, the Lambda function simulates the passing of a random number of cars (from 1 to 20). On every third `G` light change, the Lambda function sends basic statistics, such as min and max, to a DynamoDB table.

1. On your computer, create a folder named `car_aggregator`.

1. From the [TrafficLight ](https://github.com/aws/aws-greengrass-core-sdk-python/tree/master/examples/TrafficLight) examples folder on GitHub, download the `carAggregator.py` file to the `car_aggregator` folder. This is your Lambda function code.
**Note**  
This example Python file is stored in the AWS IoT Greengrass Core SDK repository for convenience, but it doesn't use the AWS IoT Greengrass Core SDK.

1. If you aren't working in the US East (N. Virgina) Region, open `carAggregator.py` and change `region_name` in the following line to the AWS Region that's currently selected in the AWS IoT console. For the list of supported AWS Regions, see [AWS IoT Greengrass](https://docs.aws.amazon.com/general/latest/gr/greengrass.html) in the *Amazon Web Services General Reference*.

   ```
   dynamodb = boto3.resource('dynamodb', region_name='us-east-1')
   ```

1. Run the following command in a [command-line](https://en.wikipedia.org/wiki/Command-line_interface) window to install the [AWS SDK for Python (Boto3)](https://github.com/boto/boto3/blob/develop/README.rst) package and its dependencies in the `car_aggregator` folder. Greengrass Lambda functions use the AWS SDK to access other AWS services. (For Windows, use an [elevated command prompt](https://technet.microsoft.com/en-us/library/cc947813(v=ws.10).aspx).)

   ```
   pip install boto3 -t path-to-car_aggregator-folder
   ```

   This results in a directory listing similar to the following:  
![\[Screenshot of directory listing showing carAggregator.py.\]](http://docs.aws.amazon.com/greengrass/v1/developerguide/images/gg-get-started-095.png)

1. Compress the contents of the `car_aggregator` folder into a `.zip` file named `car_aggregator.zip`. (Compress the folder's contents, not the folder.) This is your Lambda function deployment package.

1. In the Lambda console, create a function named **GG\$1Car\$1Aggregator**, and set the remaining fields as follows:
   + For **Runtime**, choose **Python 3.7**.
   + For **Permissions**, keep the default setting. This creates an execution role that grants basic Lambda permissions. This role isn't used by AWS IoT Greengrass.

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

1. Upload your Lambda function deployment package:

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

   1. Choose upload, and then choose your `car_aggregator.zip` deployment package. Then, choose **Save**.

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

   1. Choose **Save**.

1. Publish the Lambda function, and then create an alias named **GG\$1CarAggregator**. For step-by-step instructions, see the steps to [publish the Lambda function](create-lambda.md#publish-function-version) and [create an alias](create-lambda.md#create-version-alias) in Module 3 (Part 1).

1. In the AWS IoT console, add the Lambda function that you just created to your AWS IoT Greengrass group:

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

   1. For **Lambda function**, choose **GG\$1Car\$1Aggregator**.

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

   1. For **Memory limit**, enter **64 MB**.

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

   1. Choose **Add Lambda function**.
**Note**  
You can remove other Lambda functions from earlier modules.

# Configure subscriptions
<a name="config_subs"></a>

In this step, you create a subscription that enables the GG\$1TrafficLight shadow to send updated state information to the GG\$1Car\$1Aggregator Lambda function. This subscription is added to the subscriptions that you created in [Module 5](module5.md), which are all required for this module.

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

1. On the **Create a subscription** page, do the following:

   1. For **Source type**, choose **Service**, and then choose **Local Shadow Service**.

   1. For **Target type**, choose **Lambda function**, and then choose **GG\$1Car\$1Aggregator**.

   1. For **Topic filter**, enter **\$1aws/things/GG\$1TrafficLight/shadow/update/documents**

   1. Choose **Create subscription**.

   This module requires the new subscription and the [subscriptions](config-dev-subs.md#module5-subscriptions) that you created in Module 5.

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

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

# Test communications
<a name="comms-test"></a>

1. On your computer, open two [command-line](https://en.wikipedia.org/wiki/Command-line_interface) windows. Just as in [Module 5](module5.md), one window is for the GG\$1Switch client device and the other is for the GG\$1TrafficLight client device. You use them to run the same commands that you ran in Module 5.

   Run the following commands for the GG\$1Switch client device:

   ```
   cd path-to-certs-folder
   python lightController.py --endpoint AWS_IOT_ENDPOINT --rootCA AmazonRootCA1.pem --cert switchCertId-certificate.pem.crt --key switchCertId-private.pem.key --thingName GG_TrafficLight --clientId GG_Switch
   ```

   Run the following commands for the GG\$1TrafficLight client device:

   ```
   cd path-to-certs-folder
   python trafficLight.py --endpoint AWS_IOT_ENDPOINT --rootCA AmazonRootCA1.pem --cert lightCertId-certificate.pem.crt --key lightCertId-private.pem.key --thingName GG_TrafficLight --clientId GG_TrafficLight
   ```

   Every 20 seconds, the switch updates the shadow state to G, Y, and R, and the light displays its new state.

1. The function handler of the Lambda function is triggered on every third green light (every three minutes), and a new DynamoDB record is created. After `lightController.py` and `trafficLight.py` have run for three minutes, go to the AWS Management Console, and open the DynamoDB console.

1. Choose **US East (N. Virginia)** in the AWS Region menu. This is the Region where the `GG_Car_Aggregator` function creates the table.

1. In the navigation pane, choose **Tables**, and then choose the **CarStats** table. 

1. Choose **View items** to view the entries in the table.

   You should see entries with basic statistics on cars passed (one entry for every three minutes). You might need to choose the refresh button to view updates to the table.

1. If the test is not successful, you can look for troubleshooting information in the Greengrass logs.

   1. <a name="root-access-logs"></a>Switch to the root user and navigate to the `log` directory. Access to AWS IoT Greengrass logs requires root permissions.

      ```
      sudo su
      cd /greengrass/ggc/var/log
      ```

   1. Check `runtime.log` for errors.

      ```
      cat system/runtime.log | grep 'ERROR'
      ```

   1. Check the log generated by the Lambda function.

      ```
      cat user/region/account-id/GG_Car_Aggregator.log
      ```

      <a name="check-connection-info"></a> The `lightController.py` and `trafficLight.py` scripts store connection information in the `groupCA` folder, which is created in the same folder as the scripts. If you receive connection errors, make sure that the IP address in the `ggc-host` file matches the IP address endpoint for your core.

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

This is the end of the basic tutorial. You should now understand the AWS IoT Greengrass programming model and its fundamental concepts, including AWS IoT Greengrass cores, groups, subscriptions, client devices, and the deployment process for Lambda functions running at the edge.

You can delete the DynamoDB table and the Greengrass Lambda functions and subscriptions. To stop communications between the AWS IoT Greengrass core device and the AWS IoT cloud, open a terminal on the core device and run one of the following commands:
+ To shut down the AWS IoT Greengrass core device:

  ```
  sudo halt
  ```
+ To stop the AWS IoT Greengrass daemon:

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

# Module 7: Simulating hardware security integration
<a name="console-mod7"></a>

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

This advanced module shows you how to configure a simulated hardware security module (HSM) for use with a Greengrass core. The configuration uses SoftHSM, which is a pure software implementation that uses the [PKCS\$111](#console-mod7-see-also) application programming interface (API). The purpose of this module is to allow you to set up an environment where you can learn and do initial testing against a software-only implementation of the PKCS\$111 API. It is provided only for learning and initial testing, not for production use of any kind.

You can use this configuration to experiment with using a PKCS\$111-compatible service to store your private keys. For more information about the software-only implementation, see [SoftHSM](https://www.opendnssec.org/softhsm/). For more information about integrating hardware security on an AWS IoT Greengrass core, including general requirements, see [Hardware security integration](hardware-security.md).

**Important**  
This module is intended for experimentation purposes only. We strongly discourage the use of SoftHSM in a production environment because it might provide a false sense of additional security. The resulting configuration doesn't provide any actual security benefits. The keys stored in SoftHSM are not stored more securely than any other means of secrets storage in the Greengrass environment.  
The purpose of this module is to allow you to learn about the PKCS\$111 specification and do initial testing of your software if you plan to use a real hardware-based HSM in the future.  
You must test your future hardware implementation separately and completely before any production usage because there might be differences between the PKCS\$111 implementation provided in SoftHSM and a hardware-based implementation.

If you need assistance with the onboarding of a [supported hardware security module](hardware-security.md#hardware-security-reqs), contact your AWS Enterprise Support representative.

Before you begin, run the [Greengrass Device Setup](quick-start.md) script, or make sure that you completed [Module 1](module1.md) and [Module 2](module2.md) of the Getting Started tutorial. In this module, we assume that your core is already provisioned and communicating with AWS. This module should take about 30 minutes to complete.

## Install the SoftHSM software
<a name="softhsm-install"></a>

In this step, you install SoftHSM and the pkcs11 tools, which are used to manage your SoftHSM instance.
+ In a terminal on your AWS IoT Greengrass core device, run the following command:

  ```
  sudo apt-get install softhsm2 libsofthsm2-dev pkcs11-dump
  ```

  For more information about these packages, see [Install softhsm2](https://www.howtoinstall.co/en/ubuntu/xenial/softhsm2), [Install libsofthsm2-dev](https://www.howtoinstall.co/en/ubuntu/xenial/libsofthsm2-dev), and [Install pkcs11-dump](https://www.howtoinstall.co/en/ubuntu/xenial/pkcs11-dump).
**Note**  
If you encounter issues when using this command on your system, see [SoftHSM version 2](https://github.com/opendnssec/SoftHSMv2) on GitHub. This site provides more installation information, including how to build from source.

## Configure SoftHSM
<a name="softhsm-config"></a>

In this step, you [configure SoftHSM](https://github.com/opendnssec/SoftHSMv2#configure-1).

1. Switch to the root user.

   ```
   sudo su
   ```

1. Use the manual page to find the system-wide `softhsm2.conf` location. A common location is `/etc/softhsm/softhsm2.conf`, but the location might be different on some systems.

   ```
   man softhsm2.conf
   ```

1. Create the directory for the softhsm2 configuration file in the system-wide location. In this example, we assume the location is `/etc/softhsm/softhsm2.conf`.

   ```
   mkdir -p /etc/softhsm
   ```

1. Create the token directory in the `/greengrass` directory.
**Note**  
If this step is skipped, softhsm2-util reports `ERROR: Could not initialize the library`.

   ```
   mkdir -p /greengrass/softhsm2/tokens
   ```

1. Configure the token directory.

   ```
   echo "directories.tokendir = /greengrass/softhsm2/tokens" > /etc/softhsm/softhsm2.conf
   ```

1. Configure a file-based backend.

   ```
   echo "objectstore.backend = file" >> /etc/softhsm/softhsm2.conf
   ```

**Note**  
These configuration settings are intended for experimentation purposes only. To see all configuration options, read the manual page for the configuration file.  

```
man softhsm2.conf
```

## Import the private key into SoftHSM
<a name="softhsm-import-key"></a>

In this step, you initialize the SoftHSM token, convert the private key format, and then import the private key.

1. Initialize the SoftHSM token.

   ```
   softhsm2-util --init-token --slot 0 --label greengrass --so-pin 12345 --pin 1234
   ```
**Note**  
If prompted, enter an SO pin of `12345` and a user pin of `1234`. AWS IoT Greengrass doesn't use the SO (supervisor) pin, so you can use any value.  
If you receive the error `CKR_SLOT_ID_INVALID: Slot 0 does not exist`, try the following command instead:  

   ```
   softhsm2-util --init-token --free --label greengrass --so-pin 12345 --pin 1234
   ```

1. Convert the private key to a format that can be used by the SoftHSM import tool. For this tutorial, you convert the private key that you obtained from the **Default Group creation** option in [Module 2](module2.md) of the Getting Started tutorial.

   ```
   openssl pkcs8 -topk8 -inform PEM -outform PEM -nocrypt -in hash.private.key -out hash.private.pem
   ```

1. Import the private key into SoftHSM. Run only one of the following commands, depending on your version of softhsm2-util.  
**Raspbian softhsm2-util v2.2.0** syntax  

   ```
   softhsm2-util --import hash.private.pem --token greengrass --label iotkey --id 0000 --pin 12340
   ```  
**Ubuntu softhsm2-util v2.0.0** syntax  

   ```
   softhsm2-util --import hash.private.pem --slot 0 --label iotkey --id 0000 --pin 1234
   ```

   This command identifies the slot as `0` and defines the key label as `iotkey`. You use these values in the next section.

After the private key is imported, you can optionally remove it from the `/greengrass/certs` directory. Make sure to keep the root CA and device certificates in the directory.

## Configure the Greengrass core to use SoftHSM
<a name="softhsm-config-core"></a>

In this step, you modify the Greengrass core configuration file to use SoftHSM.

1. Find the path to the SoftHSM provider library (`libsofthsm2.so`) on your system:

   1. Get the list of installed packages for the library.

      ```
      sudo dpkg -L libsofthsm2
      ```

      The `libsofthsm2.so` file is located in the `softhsm` directory.

   1. Copy the full path to the file (for example, `/usr/lib/x86_64-linux-gnu/softhsm/libsofthsm2.so`). You use this value later.

1. Stop the Greengrass daemon.

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

1. Open the Greengrass configuration file. This is the [`config.json`](gg-core.md#config-json) file in the `/greengrass/config` directory.
**Note**  
The examples in this procedure are written with the assumption that the `config.json` file uses the format that's generated from the **Default Group creation** option in [Module 2](module2.md) of the Getting Started tutorial.

1. In the `crypto.principals` object, insert the following MQTT server certificate object. Add a comma where needed to create a valid JSON file.

   ```
     "MQTTServerCertificate": {
       "privateKeyPath": "path-to-private-key"
     }
   ```

1. In the `crypto` object, insert the following `PKCS11` object. Add a comma where needed to create a valid JSON file.

   ```
     "PKCS11": {
       "P11Provider": "/path-to-pkcs11-provider-so",
       "slotLabel": "crypto-token-name",
       "slotUserPin": "crypto-token-user-pin"
     }
   ```

   Your file should look similar to the following:

   ```
   {
     "coreThing" : {
       "caPath" : "root.ca.pem",
       "certPath" : "hash.cert.pem",
       "keyPath" : "hash.private.key",
       "thingArn" : "arn:partition:iot:region:account-id:thing/core-thing-name",
       "iotHost" : "host-prefix.iot.region.amazonaws.com",
       "ggHost" : "greengrass.iot.region.amazonaws.com",
       "keepAlive" : 600
     },
     "runtime" : {
       "cgroup" : {
         "useSystemd" : "yes"
       }
     },
     "managedRespawn" : false,
     "crypto": {
       "PKCS11": {
         "P11Provider": "/path-to-pkcs11-provider-so",
         "slotLabel": "crypto-token-name",
         "slotUserPin": "crypto-token-user-pin"
       },
       "principals" : {
         "MQTTServerCertificate": {
           "privateKeyPath": "path-to-private-key"
         },
         "IoTCertificate" : {
           "privateKeyPath" : "file:///greengrass/certs/hash.private.key",
           "certificatePath" : "file:///greengrass/certs/hash.cert.pem"
         },
         "SecretsManager" : {
           "privateKeyPath" : "file:///greengrass/certs/hash.private.key"
         }
       },    
       "caPath" : "file:///greengrass/certs/root.ca.pem"
     }
   }
   ```
**Note**  
To use over-the-air (OTA) updates with hardware security, the `PKCS11` object must also contain the `OpenSSLEngine` property. For more information, see [Configure support for over-the-air updates](hardware-security.md#hardware-security-ota-updates).

1. Edit the `crypto` object:

   1. Configure the `PKCS11` object.
      + For `P11Provider`, enter the full path to `libsofthsm2.so`.
      + For `slotLabel`, enter `greengrass`.
      + For `slotUserPin`, enter `1234`.

   1. Configure the private key paths in the `principals` object. Do not edit the `certificatePath` property.
      + For the `privateKeyPath` properties, enter the following RFC 7512 PKCS\$111 path (which specifies the key's label). Do this for the `IoTCertificate`, `SecretsManager`, and `MQTTServerCertificate` principals.

        ```
        pkcs11:object=iotkey;type=private
        ```

   1. Check the `crypto` object. It should look similar to the following:

      ```
        "crypto": {
          "PKCS11": {
            "P11Provider": "/usr/lib/x86_64-linux-gnu/softhsm/libsofthsm2.so",
            "slotLabel": "greengrass",
            "slotUserPin": "1234"
          },
          "principals": {
            "MQTTServerCertificate": {
              "privateKeyPath": "pkcs11:object=iotkey;type=private"
            },
            "SecretsManager": {
              "privateKeyPath": "pkcs11:object=iotkey;type=private"
            },
            "IoTCertificate": {
              "certificatePath": "file://certs/core.crt",
              "privateKeyPath": "pkcs11:object=iotkey;type=private"
            }
          },
          "caPath": "file://certs/root.ca.pem"
        }
      ```

1. Remove the `caPath`, `certPath`, and `keyPath` values from the `coreThing` object. It should look similar to the following:

   ```
   "coreThing" : {
     "thingArn" : "arn:partition:iot:region:account-id:thing/core-thing-name",
     "iotHost" : "host-prefix-ats.iot.region.amazonaws.com",
     "ggHost" : "greengrass-ats.iot.region.amazonaws.com",
     "keepAlive" : 600
   }
   ```

**Note**  
For this tutorial, you specify the same private key for all principals. For more information about choosing the private key for the local MQTT server, see [Performance](hardware-security.md#hsm-performance). For more information about the local secrets manager, see [Deploy secrets to the AWS IoT Greengrass core](secrets.md).

## Test the configuration
<a name="softhsm-test"></a>
+ Start the Greengrass daemon.

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

  If the daemon starts successfully, then your core is configured correctly.

  You are now ready to learn about the PKCS\$111 specification and do initial testing with the PKCS\$111 API that's provided by the SoftHSM implementation.
**Important**  
Again, it's extremely important to be aware that this module is intended for learning and testing only. It doesn't actually increase the security posture of your Greengrass environment.  
Instead, the purpose of the module is to enable you to start learning and testing in preparation for using a true hardware-based HSM in the future. At that time, you must separately and completely test your software against the hardware-based HSM prior to any production usage, because there might be differences between the PKCS\$111 implementation provided in SoftHSM and a hardware-based implementation.

## See also
<a name="console-mod7-see-also"></a>
+ *PKCS \$111 Cryptographic Token Interface Usage Guide Version 2.40*. Edited by John Leiseboer and Robert Griffin. 16 November 2014. OASIS Committee Note 02. [ http://docs.oasis-open.org/pkcs11/pkcs11-ug/v2.40/cn02/pkcs11-ug-v2.40-cn02.html](http://docs.oasis-open.org/pkcs11/pkcs11-ug/v2.40/cn02/pkcs11-ug-v2.40-cn02.html). Latest version: [ http://docs.oasis-open.org/pkcs11/pkcs11-ug/v2.40/pkcs11-ug-v2.40.html](http://docs.oasis-open.org/pkcs11/pkcs11-ug/v2.40/pkcs11-ug-v2.40.html).
+ [RFC 7512](https://tools.ietf.org/html/rfc7512)