

# Tutorial: Installing and configuring the AWS IoT Device Client
<a name="iot-dc-install-dc"></a>

This tutorial walks you through the installation and configuration of the AWS IoT Device Client and the creation of AWS IoT resources that you'll use in this and other demos.

**To start this tutorial:**
+ Have your local host computer and Raspberry Pi from [the previous tutorial](iot-dc-prepare-device.md) ready.

This tutorial can take up to 90 minutes to complete.

**When you're finished with this topic:**
+ Your IoT device will be ready to use in other AWS IoT Device Client demos.
+ You'll have provisioned your IoT device in AWS IoT Core.
+ You'll have downloaded and installed the AWS IoT Device Client on your device.
+ You'll have saved an image of your device's microSD card that can be used in subsequent tutorials.

**Required equipment:**
+ Your local development and testing environment from [the previous section](iot-dc-prepare-device-test.md)
+ The Raspberry Pi that you used in [the previous section](iot-dc-prepare-device-test.md)
+ The microSD memory card from the Raspberry Pi that you used in [the previous section](iot-dc-prepare-device-test.md)

**Topics**
+ [Download and save the AWS IoT Device Client](iot-dc-install-download.md)
+ [Provision your Raspberry Pi in AWS IoT](iot-dc-install-provision.md)
+ [Configure the AWS IoT Device Client to test connectivity](iot-dc-install-configure.md)

# Download and save the AWS IoT Device Client
<a name="iot-dc-install-download"></a>

The procedures in this section download the AWS IoT Device Client, compile it, and install it on your Raspberry Pi. After you test the installation, you can save the image of the Raspberry Pi's microSD card to use later when you want to try the tutorials again.

**Topics**
+ [Download and build the AWS IoT Device Client](#iot-dc-install-dc-download)
+ [Create the directories used by the tutorials](#iot-dc-install-dc-files)
+ [(Optional) Save the microSD card image](#iot-dc-install-dc-save)

## Download and build the AWS IoT Device Client
<a name="iot-dc-install-dc-download"></a>

This procedure installs the AWS IoT Device Client on your Raspberry Pi.

Perform these commands in the terminal window on your local host computer that is connected to your Raspberry Pi.

**To install the AWS IoT Device Client on your Raspberry Pi**

1. Enter these commands to download and build the AWS IoT Device Client on your Raspberry Pi.

   ```
   cd ~
   git clone https://github.com/awslabs/aws-iot-device-client aws-iot-device-client
   mkdir ~/aws-iot-device-client/build && cd ~/aws-iot-device-client/build
   cmake ../
   ```

1. Run this command to build the AWS IoT Device Client. This command can take up to 15 minutes to complete.

   ```
   cmake --build . --target aws-iot-device-client
   ```

   The warning messages displayed as the AWS IoT Device Client compiles can be ignored.

   These tutorials have been tested with the AWS IoT Device Client built on **gcc**, version (Raspbian 10.2.1-6\$1rpi1) 10.2.1 20210110 on the Oct 30th 2021 version of Raspberry Pi OS (bullseye) on **gcc**, version (Raspbian 8.3.0-6\$1rpi1) 8.3.0 on the May 7th 2021 version of the Raspberry Pi OS (buster).

1. After the AWS IoT Device Client finishes building, test it by running this command.

   ```
   ./aws-iot-device-client --help
   ```

If you see the command line help for the AWS IoT Device Client, the AWS IoT Device Client has been built successfully and is ready for you to use.

## Create the directories used by the tutorials
<a name="iot-dc-install-dc-files"></a>

This procedure creates the directories on the Raspberry Pi that will be used to store the files used by the tutorials in this learning path.

**To create the directories used by the tutorials in this learning path:**

1. Run these commands to create the required directories.

   ```
   mkdir ~/dc-configs
   mkdir ~/policies
   mkdir ~/messages
   mkdir ~/certs/testconn
   mkdir ~/certs/pubsub
   mkdir ~/certs/jobs
   ```

1. Run these commands to set the permissions on the new directories.

   ```
   chmod 745 ~
   chmod 700 ~/certs/testconn
   chmod 700 ~/certs/pubsub
   chmod 700 ~/certs/jobs
   ```

After you create these directories and set their permission, continue to [(Optional) Save the microSD card image](#iot-dc-install-dc-save).

## (Optional) Save the microSD card image
<a name="iot-dc-install-dc-save"></a>

At this point, your Raspberry Pi's microSD card has an updated OS, the basic application software, and the AWS IoT Device Client. 

If you want to come back to try these exercises and tutorials again, you can skip the preceding procedures by writing the microSD card image that you save with this procedure to a new microSD card and continue the tutorials from [Provision your Raspberry Pi in AWS IoT](iot-dc-install-provision.md).

**To save the microSD card image to a file:**

In the terminal window on your local host computer that's connected to your Raspberry Pi:

1. Confirm that your AWS account credentials have not been stored.

   1. Run the AWS configure app with this command:

      ```
      aws configure
      ```

   1. If your credentials have been stored (if they are displayed in the prompt), then enter the **XYXYXYXYX** string when prompted as shown here. Leave **Default region name** and **Default output format** blank.

      ```
      AWS Access Key ID [****************YXYX]: XYXYXYXYX
      AWS Secret Access Key [****************YXYX]: XYXYXYXYX
      Default region name: 
      Default output format:
      ```

1. Enter this command to shutdown the Raspberry Pi.

   ```
   sudo shutdown -h 0
   ```

1. After the Raspberry Pi shuts down completely, remove its power connector.

1. Remove the microSD card from your device.

1. On your local host computer: 

   1. Insert the microSD card.

   1. Using your SD card imaging tool, save the microSD card’s image to a file.

   1. After the microSD card’s image has been saved, eject the card from the local host computer.

You can continue with this microSD card in [Provision your Raspberry Pi in AWS IoT](iot-dc-install-provision.md).

# Provision your Raspberry Pi in AWS IoT
<a name="iot-dc-install-provision"></a>

The procedures in this section start with the saved microSD image that has the AWS CLI and AWS IoT Device Client installed and create the AWS IoT resources and device certificates that provision your Raspberry Pi in AWS IoT.

## Install the microSD card in your Raspberry Pi
<a name="iot-dc-install-dc-restore"></a>

This procedure installs the microSD card with the necessary software loaded and configured into the Raspberry Pi and configures your AWS account so that you can continue with the tutorials in this learning path.

Use a microSD card from [(Optional) Save the microSD card image](iot-dc-install-download.md#iot-dc-install-dc-save) that has the necessary software for the exercises and tutorials in this learning path.

**To install the microSD card in your Raspberry Pi**

1. With the power disconnected from the Raspberry Pi, insert the microSD card into the Raspberry Pi.

1. Apply power to the Raspberry Pi.

1. After about a minute, on the local host computer, restart the terminal window session and log in to the Raspberry Pi.

1. On your local host computer, in the terminal window, and with the **Access Key ID** and **Secret Access Key** credentials for your Raspberry Pi:

   1. Run the AWS configure app with this command:

      ```
      aws configure
      ```

   1. Enter your AWS account credentials and configuration information when prompted:

      ```
      AWS Access Key ID [****************YXYX]: your Access Key ID
      AWS Secret Access Key [****************YXYX]: your Secret Access Key
      Default region name [us-west-2]: your AWS Region code
      Default output format [json]: json
      ```

After you have restored your AWS account credentials, you're ready to continue to [Provision your device in AWS IoT Core](#iot-dc-install-dc-provision).

## Provision your device in AWS IoT Core
<a name="iot-dc-install-dc-provision"></a>

The procedures in this section create the AWS IoT resources that provision your Raspberry Pi in AWS IoT. As you create these resources, you'll be asked to record various pieces of information. This information is used by the AWS IoT Device Client configuration in the next procedure.

For your Raspberry Pi to work with AWS IoT, it must be provisioned. Provisioning is the process of creating and configuring the AWS IoT resources that are necessary to support your Raspberry Pi as an IoT device.

With your Raspberry Pi powered up and restarted, connect the terminal window on your local host computer to the Raspberry Pi and complete these procedures.

**Topics**
+ [Create and download device certificate files](#iot-dc-install-dc-provision-certs)
+ [Create AWS IoT resources](#iot-dc-install-dc-provision-resources)

### Create and download device certificate files
<a name="iot-dc-install-dc-provision-certs"></a>

This procedure creates the device certificate files for this demo.

**To create and download the device certificate files for your Raspberry Pi**

1. In the terminal window on your local host computer, enter these commands to create the device certificate files for your device.

   ```
   mkdir ~/certs/testconn
   aws iot create-keys-and-certificate \
   --set-as-active \
   --certificate-pem-outfile "~/certs/testconn/device.pem.crt" \
   --public-key-outfile "~/certs/testconn/public.pem.key" \
   --private-key-outfile "~/certs/testconn/private.pem.key"
   ```

   The command returns a response like the following. Record the `certificateArn` value for later use.

   ```
   {
       "certificateArn": "arn:aws:iot:us-west-2:57EXAMPLE833:cert/76e7e4edb3e52f52334be2f387a06145b2aa4c7fcd810f3aea2d92abc227d269",
       "certificateId": "76e7e4edb3e52f5233EXAMPLE7a06145b2aa4c7fcd810f3aea2d92abc227d269",
       "certificatePem": "-----BEGIN CERTIFICATE-----\nMIIDWTCCAkGgAwIBAgI_SHORTENED_FOR_EXAMPLE_Lgn4jfgtS\n-----END CERTIFICATE-----\n",
       "keyPair": {
           "PublicKey": "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BA_SHORTENED_FOR_EXAMPLE_ImwIDAQAB\n-----END PUBLIC KEY-----\n",
           "PrivateKey": "-----BEGIN RSA PRIVATE KEY-----\nMIIEowIBAAKCAQE_SHORTENED_FOR_EXAMPLE_T9RoDiukY\n-----END RSA PRIVATE KEY-----\n"
       }
   }
   ```

1. Enter the following commands to set the permissions on the certificate directory and its files.

   ```
   chmod 745 ~
   chmod 700 ~/certs/testconn
   chmod 644 ~/certs/testconn/*
   chmod 600 ~/certs/testconn/private.pem.key
   ```

1. Run this command to review the permissions on your certificate directories and files.

   ```
   ls -l ~/certs/testconn
   ```

   The output of the command should be the same as what you see here, except the file dates and times will be different.

   ```
   -rw-r--r-- 1 pi pi 1220 Oct 28 13:02 device.pem.crt
   -rw------- 1 pi pi 1675 Oct 28 13:02 private.pem.key
   -rw-r--r-- 1 pi pi  451 Oct 28 13:02 public.pem.key
   ```

At this point, you have the device certificate files installed on your Raspberry Pi and you can continue to [Create AWS IoT resources](#iot-dc-install-dc-provision-resources).

### Create AWS IoT resources
<a name="iot-dc-install-dc-provision-resources"></a>

This procedure provisions your device in AWS IoT by creating the resources that your device needs to access AWS IoT features and services.

**To provision your device in AWS IoT**

1. In the terminal window on your local host computer, enter the following command to get the address of the device data endpoint for your AWS account.

   ```
   aws iot describe-endpoint --endpoint-type IoT:Data-ATS
   ```

   The command from the previous steps returns a response like the following. Record the `endpointAddress` value for later use.

   ```
   {
       "endpointAddress": "a3qjEXAMPLEffp-ats.iot.us-west-2.amazonaws.com"
   }
   ```

1. Enter this command to create an AWS IoT thing resource for your Raspberry Pi.

   ```
   aws iot create-thing --thing-name "DevCliTestThing"
   ```

   If your AWS IoT thing resource was created, the command returns a response like this.

   ```
   {
       "thingName": "DevCliTestThing",
       "thingArn": "arn:aws:iot:us-west-2:57EXAMPLE833:thing/DevCliTestThing",
       "thingId": "8ea78707-32c3-4f8a-9232-14bEXAMPLEfd"
   }
   ```

1. In the terminal window:

   1. Open a text editor, such as `nano`.

   1. Copy this JSON policy document and paste it into your open text editor.  
****  

      ```
      {
          "Version":"2012-10-17",		 	 	 
          "Statement": [
              {
                  "Effect": "Allow",
                  "Action": [
                      "iot:Publish",
                      "iot:Subscribe",
                      "iot:Receive",
                      "iot:Connect"
                  ],
                  "Resource": [
                      "*"
                  ]
              }
          ]
      }
      ```
**Note**  
This policy document generously grants every resource permission to connect, receive, publish, and subscribe. Normally policies grant only permission to specific resources to perform specific actions. However, for the initial device connectivity test, this overly general and permissive policy is used to minimize the chance of an access problem during this test. In the subsequent tutorials, more narrowly scoped policy documents will be use to demonstrate better practices in policy design.

   1. Save the file in your text editor as **\$1/policies/dev\$1cli\$1test\$1thing\$1policy.json**. 

1. Run this command to use the policy document from the previous steps to create an AWS IoT policy.

   ```
   aws iot create-policy \
   --policy-name "DevCliTestThingPolicy" \
   --policy-document "file://~/policies/dev_cli_test_thing_policy.json"
   ```

   If the policy is created, the command returns a response like this.

   ```
   {
       "policyName": "DevCliTestThingPolicy",
       "policyArn": "arn:aws:iot:us-west-2:57EXAMPLE833:policy/DevCliTestThingPolicy",
       "policyDocument": "{\n    \"Version\": \"2012-10-17\",		 	 	 \n    \"Statement\": [\n        {\n            \"Effect\": \"Allow\",\n            \"Action\": [\n                \"iot:Publish\",\n                \"iot:Subscribe\",\n                \"iot:Receive\",\n                \"iot:Connect\"\n            ],\n            \"Resource\": [\n                \"*\"\n            ]\n        }\n    ]\n}\n",
       "policyVersionId": "1"
   }
   ```

1. Run this command to attach the policy to the device certificate. Replace `certificateArn` with the `certificateArn` value you saved earlier.

   ```
   aws iot attach-policy \
   --policy-name "DevCliTestThingPolicy" \
   --target "certificateArn"
   ```

   If successful, this command returns nothing.

1. Run this command to attach the device certificate to the AWS IoT thing resource. Replace `certificateArn` with the `certificateArn` value you saved earlier.

   ```
   aws iot attach-thing-principal \
   --thing-name "DevCliTestThing" \
   --principal "certificateArn"
   ```

   If successful, this command returns nothing.

After you successfully provisioned your device in AWS IoT, you're ready to continue to [Configure the AWS IoT Device Client to test connectivity](iot-dc-install-configure.md).

# Configure the AWS IoT Device Client to test connectivity
<a name="iot-dc-install-configure"></a>

The procedures in this section configure the AWS IoT Device Client to publish an MQTT message from your Raspberry Pi.

**Topics**
+ [Create the config file](#iot-dc-install-dc-configure-step1)
+ [Open MQTT test client](#iot-dc-install-dc-configure-step2)
+ [Run AWS IoT Device Client](#iot-dc-install-dc-configure-step3)

## Create the config file
<a name="iot-dc-install-dc-configure-step1"></a>

This procedure creates the config file to test the AWS IoT Device Client.

**To create the config file to test the AWS IoT Device Client**
+ In the terminal window on your local host computer that's connected to your Raspberry Pi:

  1. Enter these commands to create a directory for the config files and set the permission on the directory:

     ```
     mkdir ~/dc-configs
     chmod 745 ~/dc-configs
     ```

  1. Open a text editor, such as `nano`.

  1. Copy this JSON document and paste it into your open text editor.

     ```
     {
       "endpoint": "a3qEXAMPLEaffp-ats.iot.us-west-2.amazonaws.com",
       "cert": "~/certs/testconn/device.pem.crt",
       "key": "~/certs/testconn/private.pem.key",
       "root-ca": "~/certs/AmazonRootCA1.pem",
       "thing-name": "DevCliTestThing",
       "logging": {
         "enable-sdk-logging": true,
         "level": "DEBUG",
         "type": "STDOUT",
         "file": ""
       },
       "jobs": {
         "enabled": false,
         "handler-directory": ""
       },
       "tunneling": {
         "enabled": false
       },
       "device-defender": {
         "enabled": false,
         "interval": 300
       },
       "fleet-provisioning": {
         "enabled": false,
         "template-name": "",
         "template-parameters": "",
         "csr-file": "",
         "device-key": ""
       },
       "samples": {
         "pub-sub": {
           "enabled": true,
           "publish-topic": "test/dc/pubtopic",
           "publish-file": "",
           "subscribe-topic": "test/dc/subtopic",
           "subscribe-file": ""
         }
       },
       "config-shadow": {
         "enabled": false
       },
       "sample-shadow": {
         "enabled": false,
         "shadow-name": "",
         "shadow-input-file": "",
         "shadow-output-file": ""
       }
     }
     ```

  1. Replace the *endpoint* value with device data endpoint for your AWS account that you found in [Provision your device in AWS IoT Core](iot-dc-install-provision.md#iot-dc-install-dc-provision).

  1. Save the file in your text editor as **\$1/dc-configs/dc-testconn-config.json**.

  1. Run this command to set the permissions on the new config file.

     ```
     chmod 644 ~/dc-configs/dc-testconn-config.json
     ```

After you save the file, you're ready to continue to [Open MQTT test client](#iot-dc-install-dc-configure-step2).

## Open MQTT test client
<a name="iot-dc-install-dc-configure-step2"></a>

This procedure prepares the **MQTT test client** in the AWS IoT console to subscribe to the MQTT message that the AWS IoT Device Client publishes when it runs.

**To prepare the **MQTT test client** to subscribe to all MQTT messages**

1. On your local host computer, in the [AWS IoT console](https://console.aws.amazon.com//iot/home#/test), choose **MQTT test client**.

1. In the **Subscribe to a topic** tab, in **Topic filter**, enter **\$1** (a single pound sign), and choose **Subscribe** to subscribe to every MQTT topic.

1. Below the **Subscriptions** label, confirm that you see **\$1** (a single pound sign).

Leave the window with the **MQTT test client** open as you continue to [Run AWS IoT Device Client](#iot-dc-install-dc-configure-step3).

## Run AWS IoT Device Client
<a name="iot-dc-install-dc-configure-step3"></a>

This procedure runs the AWS IoT Device Client so that it publishes a single MQTT message that the **MQTT test client** receives and displays.

**To send an MQTT message from the AWS IoT Device Client**

1. Make sure that both the terminal window that's connected to your Raspberry Pi and the window with the **MQTT test client** are visible while you perform this procedure.

1. In the terminal window, enter these commands to run the AWS IoT Device Client using the config file created in [Create the config file](#iot-dc-install-dc-configure-step1).

   ```
   cd ~/aws-iot-device-client/build
   ./aws-iot-device-client --config-file ~/dc-configs/dc-testconn-config.json
   ```

   In the terminal window, the AWS IoT Device Client displays information messages and any errors that occur when it runs.

   If no errors are displayed in the terminal window, review the **MQTT test client**.

1. In the **MQTT test client**, in the Subscriptions window, see the *Hello World\$1* message sent to the `test/dc/pubtopic` message topic.

1. If the AWS IoT Device Client displays no errors and you see *Hello World\$1* sent to the `test/dc/pubtopic` message in the **MQTT test client**, you've demonstrated a successful connection.

1. In the terminal window, enter **^C** (Ctrl-C) to stop the AWS IoT Device Client.

After you've demonstrated that the AWS IoT Device Client is running correctly on your Raspberry Pi and can communicate with AWS IoT, you can continue to the [Tutorial: Demonstrate MQTT message communication with the AWS IoT Device Client](iot-dc-testconn.md).