The Amazon Web Services Internet-of-Things (AWS IoT) sample demonstrates how to connect an nRF91 Series or nRF70 Series device to the AWS IoT Core service over MQTT to publish and receive messages. This sample showcases the use of the AWS IoT library, which includes support for FOTA using the AWS FOTA library.

Before this sample can be used, an AWS IoT server instance needs to be setup in order for the device to connect to it. Refer to Setup to complete the necessary steps.


The sample supports the following development kits:

Hardware platforms


Board name

Build target





nRF9160 DK




nRF7002 DK




Additionally, the sample supports emulation using QEMU x86.

When built for an _ns build target, the sample is configured to compile and run as a non-secure application with Cortex-M Security Extensions enabled. Therefore, it automatically includes Trusted Firmware-M that prepares the required peripherals and secure services to be available for the application.


The sample publishes messages in the JSON string format to the AWS IoT Device Shadow Service, addressed to the AWS IoT Device Shadow Topic: $aws/things/<thingname>/shadow/update. Messages are published once at an interval set by the CONFIG_AWS_IOT_SAMPLE_PUBLICATION_INTERVAL_SECONDS Kconfig option. The message has the following structure:

             "state": {
                     "reported": {
                             "app_version": "v1.0.0",
                             "modem_version": "nrf9160-1.3.4", /* Not present for Wi-Fi builds */
                             "uptime": 2469

The message comprises of three parameters the application version, the modem version string, and an uptime timestamp. The firmware version strings can be used to verify that the device has updated the corresponding image post FOTA DFU. See the AWS FOTA library for information on how to create FOTA jobs.

In addition to publishing data to the AWS IoT shadow, the sample also subscribes to the following topics:


Kconfig option




Topic that receives the difference between the reported and desired shadow states. Can be used for run-time configuration of the device.



Topic that receives the shadow document whenever it is requested by the device. Auto-requesting of the shadow document after an established connection can be enabled by setting the CONFIG_AWS_IOT_AUTO_DEVICE_SHADOW_REQUEST option.



Topic that receives an error status message if requesting the device shadow failed.


NA - Non-shadow topic

Dummy application-specific topic. Can be used for anything.


NA - Non-shadow topic

Dummy application-specific topic. Can be used for anything.

The application-specific topics are not part of the AWS IoT shadow service and must therefore be passed to the AWS IoT library using the aws_iot_subscription_topics_add() function before connecting. How to add application-specific topics is documented in the AWS IoT library usage section.


See Configuring your application for information about how to permanently or temporarily change the configuration.


To run this sample and connect to AWS IoT, complete the steps described in the Setup and configuration section of the AWS IoT library documentation. This is to obtain the AWS IoT broker hostname and the client ID of the device and provision a device certificate to a security tag.

The corresponding options that must be set for each of these values are:

Set these options in the project configuration file located at samples/net/aws_iot/prj.conf. For documentation related to FOTA DFU, see AWS FOTA.


For nRF70 Series devices, certificates must be provisioned at runtime. This is achieved by pasting the PEM content into the respective files in the certs/ subdirectory and ensuring the CONFIG_AWS_IOT_PROVISION_CERTIFICATES Kconfig option is enabled.

Configuration options

Check and configure the following Kconfig options:

General options

The following lists the application-specific configurations used in the sample. They are located in samples/net/aws_iot/Kconfig.


This configuration option sets the application version number.


This configuration option sets the maximum size of JSON messages that are sent to AWS IoT.


This configuration option configures the time interval between each message publication.


This configuration option configures the number of seconds between each AWS IoT connection retry. If the connection is lost, the sample attempts to reconnect at the frequency set by this option.


This configuration option configures the sample to use the HW ID (IMEI, MAC) as the device ID in the MQTT connection.

Wi-Fi options

Configuration files

The sample includes preconfigured configuration files for the development kits that are supported:

  • prj.conf - General configuration file for all devices.

  • boards/nrf9160dk_nrf9160_ns.conf - Configuration file for the nRF9160 DK.

  • boards/thingy91_nrf9160_ns.conf - Configuration file for the Thingy:91.

  • boards/nrf7002dk_nrf5340_cpuapp.conf - Configuration file for the nRF7002 DK.

  • boards/qemu_x86.conf - Configuration file for QEMU x86.

The following configuration and DTS overlay files are included to host the MCUboot secondary image slot on external flash for the nRF7002 DK:

  • boards/nrf7002dk_nrf5340_cpuapp.overlay - DTS overlay file for the application image.

  • child_image/mcuboot/nrf7002dk_nrf5340_cpuapp.overlay - DTS overlay file for the MCUboot child image.

  • child_image/mcuboot/nrf7002dk_nrf5340_cpuapp.conf - Configuration file for the MCUboot child image.

Files that are located under the /boards folder are automatically merged with the prj.conf file when you build for the corresponding target. Files that are located under the /child_image/mcuboot folder are used to configure the MCUboot child image. To read more about child images, see Multi-image builds.

Sending traces over UART on an nRF91 Series DK

To send modem traces over UART on an nRF91 Series DK, configuration must be added for the UART device in the devicetree and Kconfig. This is done by adding the modem trace UART snippet when building and programming.

Use the Cellular Monitor app for capturing and analyzing modem traces.

Building and running

This sample can be found under samples/net/aws_iot in the nRF Connect SDK folder structure.

When built as firmware image for the _ns build target, the sample has Cortex-M Security Extensions (CMSE) enabled and separates the firmware between Non-Secure Processing Environment (NSPE) and Secure Processing Environment (SPE). Because of this, it automatically includes the Trusted Firmware-M (TF-M). To read more about CMSE, see Processing environments.

To build the sample with Visual Studio Code, follow the steps listed on the How to build an application page in the nRF Connect for VS Code extension documentation. See Building and programming an application for other building and programming scenarios and Testing and debugging an application for general information about testing and debugging in the nRF Connect SDK.


After programming the sample to your development kit, complete the following steps to test it:

  1. Connect the kit to the computer using a USB cable. The kit is assigned a COM port (Windows) or ttyACM device (Linux), which is visible in the Device Manager.

  2. Connect to the kit with a terminal emulator (for example, PuTTY). See How to connect with PuTTY for the required settings.

  3. Reset your board.

  4. Observe that the board connects to the network and the AWS IoT broker. After the connection has been established, the device starts to publish messages to the AWS IoT shadow service. The frequency of the messages that are published to the broker can be set by CONFIG_AWS_IOT_SAMPLE_PUBLICATION_INTERVAL_SECONDS.

Sample output

The following serial UART output is displayed in the terminal emulator when running the sample. The modem_version parameter in messages published to AWS IoT will not be present for Wi-Fi builds.

*** Booting Zephyr OS build v3.3.99-ncs1-12-g2f5e820792d1 ***
[00:00:00.253,204] <inf> aws_iot_sample: The AWS IoT sample started, version: v1.0.0
[00:00:00.253,234] <inf> aws_iot_sample: Bringing network interface up and connecting to the network
[00:00:03.736,450] <inf> aws_iot_sample: Network connectivity established
[00:00:08.736,572] <inf> aws_iot_sample: Connecting to AWS IoT
[00:00:08.736,633] <inf> aws_iot_sample: Next connection retry in 30 seconds
[00:00:08.736,663] <inf> aws_iot_sample: AWS_IOT_EVT_CONNECTING
[00:00:12.855,072] <inf> aws_iot_sample: AWS_IOT_EVT_CONNECTED
[00:00:12.856,323] <inf> aws_iot_sample: Publishing message: {"state":{"reported":{"uptime":12855,"app_version":"v1.0.0","modem_version":"nrf9160_1.3.4"}}} to AWS IoT shadow
[00:00:13.228,881] <inf> aws_iot_sample: AWS_IOT_EVT_READY
[00:00:13.244,781] <inf> aws_iot_sample: AWS_IOT_EVT_PUBACK, message ID: 32367
[00:01:12.867,675] <inf> aws_iot_sample: Publishing message: {"state":{"reported":{"uptime":72858,"app_version":"v1.0.0","modem_version":"nrf9160_1.3.4"}}} to AWS IoT shadow
[00:02:12.883,789] <inf> aws_iot_sample: Publishing message: {"state":{"reported":{"uptime":132874,"app_version":"v1.0.0","modem_version":"nrf9160_1.3.4"}}} to AWS IoT shadow


For nRF91 Series devices, the output differs from the above example output. This is because the sample enables the AT Host library using the CONFIG_AT_HOST_LIBRARY option. This library makes it possible to send AT commands to the cellular modem and receive responses using the Cellular Monitor app from nRF Connect for Desktop. The additional logs are AT command responses that the modem sends to the application core that are forwarded over UART to be displayed on any of these nRF Connect for Desktop apps.

To observe incoming messages in the AWS IoT console, follow the steps documented in Testing and debugging.


The sample can run on QEMU x86, which simplifies development and testing and removes the need for hardware. Before you build and run on QEMU x86, you need to perform the steps documented in Networking with QEMU.

When these steps are completed, you can build and run the sample by using the following commands:

west build -b qemu_x86 samples/net/mqtt
west build -t run


To enable more verbose logging from the AWS IoT library, enable the CONFIG_AWS_IOT_LOG_LEVEL_DBG option.


This sample uses the following nRF Connect SDK and Zephyr libraries: