The Internet of Things on AWS – Official Blog

Automate global device provisioning with AWS IoT Core and Amazon Route 53

Introduction

Use AWS IoT Core together with Amazon Route 53 to choose an AWS Region based on geo location or latency and register your devices automatically when they connect for the first time to AWS IoT Core.

Time to read 10 minutes
Learning level 300
Services used AWS IoT Core,Amazon Route53, Amazon Certificate Manager Private Certificate Authority

Background

In an earlier version of a similar blog, we demonstrated how to use AWS IoT Core, AWS Lambda, Amazon DynamoDB and Amazon API Gateway. With the new approach you can now create a setup with a less complex architecture.

Since the earlier blog, AWS IoT Core has launched new features like fleet provisioning (April 2020) and configurable endpoints (March 2021). Combining these features with Amazon Route 53 traffic policies allows you to provision your devices globally without the need to write code. Devices only use the light weight Message Queuing Telemetry Transport (MQTT) protocol as opposed to the HTTPS approach covered in the earlier blog.

Solution

To provision your devices with AWS IoT Core or to interact with the service you need to have an endpoint. You can build configurable endpoints for AWS IoT Core with a custom domain configuration. This blog post uses the Fully Qualified Domain Name (FQDN) global.iot.example.com. You can replace the FQDN with your own when creating your setup. With Amazon Route 53 you can create a traffic based policy to resolve the FQDN, for example you can use geolocation or latency-based routing.

This blog uses geolocation routing where Amazon Route 53 responds to Domain Name System (DNS) queries based on the location of your devices. The examples in this blog use two AWS Regions:

  1. Ireland (eu-west-1)
  2. N. Virginia (us-east-1)

For devices in North America (NA), the FQDN resolves them to the IoT endpoint in us-east-1. The endpoint in eu-west-1 is the default endpoint for devices which are not based in NA.

Architecture

The following architecture diagram shows the provisioning workflow:

  1. (Optional) When you use just-in-time Provisioning (JITP), register your Certificate Authority (CA), for example Amazon Certificate Manger Private CA with AWS IoT Core in both regions.
  2. Your IoT device uses Amazon Route 53 to resolve your custom IoT endpoint global.iot.example.com. The DNS lookup returns an IoT endpoint from one of both regions depending on your device location.
  3. The IoT device connects to the AWS IoT Core endpoint it received from the DNS resolution. The device is then automatically registered in the related AWS Region.

Figure 1: Architecture diagram

Create custom domain configurations

Create your own custom domain configuration for the two regions as described in the AWS IoT Core developer guide. You must register your server certificates in AWS Certificate Manager (ACM) in both regions. After registering your server certificates, create a custom domain configuration for AWS IoT Core in both regions.

Configure Amazon Route 53 geolocation

This blog assumes that the domain example.com is served by Amazon Route 53 as a public hosted zone. The domain example.com serves as a sample domain name for this blog. To setup your environment, replace example.com with your domain. DNS records are created as type CNAME pointing to the AWS IoT endpoint. Use the following commands to get your AWS IoT endpoints.

For the us-east-1 region: aws iot describe-endpoint –endpoint-type iot:Data-ATS –region us-east-1

For the eu-west-1 region:
aws iot describe-endpoint –endpoint-type iot:Data-ATS –region eu-west-1

To create DNS geolocation based records in Amazon Route 53 which resolve to your IoT endpoints depending on your geographical location:

  1. Navigate to the Amazon Route 53 console.
  2. In the left menu, choose Hosted zones.
  3. Under Hosted zones, choose example.com and then choose Create record.
  4. Under Record name, enter global.iot.
  5. Under Record type, choose CNAME.
  6. Under Value, enter your AWS IoT Core endpoint for us-east-1 which looks similar to 123456aaaaaaaa-ats.iot.us-east-1.amazonaws.com.
  7. Under Routing policy, choose Geolocation.
  8. Under Location, choose North America.
  9. Under Record ID, enter US East IoT Global Endpoint.
  10. Choose Add another record.
  11. Under Record name, enter global.iot.
  12. Under Record type, choose CNAME.
  13. Under Value, enter your AWS IoT Core endpoint for us-east-1 which looks similar to 123456aaaaaaaa-ats.iot.eu-west-1.amazonaws.com.
  14. Under Routing policy, choose Geolocation.
  15. Under Location, choose Default.
  16. Under Record ID, enter Default IoT Global Endpoint.
  17. Choose Create records.
  18. When records have been created you will see a message stating Records for example.com were successfully created.


To verify if your IoT endpoint is resolved as expected, you can use the checking tool in the
Amazon Route 53 console or use tools like host, dig or nslookup on systems in different geo locations. Depending on which location you resolve the FQDN global.iot.example.com it should either resolve to the endpoint in us-east-1 if you are in North America or to the endpoint in eu-west-1 otherwise.

When you use the Amazon Route 53 checking tool, enter Resolver IP address from a geolocation from where you want to perform the lookup. You can find for example AWS IP address ranges for AWS Regions in the AWS General Reference.

You can also use AWS CloudShell to test if your FQDN global.iot.example.com resolves according to the location you are in. Open an AWS CloudShell for example in us-west-2 and eu-central-1.

Install the package bind-utils in both AWS CloudShell environments:

sudo yum -y install bind-utils

When you resolve global.iot.example.com in AWS CloudShell in the us-west-2 region it should resolve to your IoT endpoint in us-east-1. In AWS CloudShell in eu-central-1 it shoud resolve to the IoT endpoint in eu-west-1. The output of the DNS lookup should look similar to the examples below.

AWS CloudShell in us-west-2:

$ host global.iot.example.com
global.iot.example.com is an alias for 123456aaaaaaaa-ats.iot.us-east-1.amazonaws.com.
123456aaaaaaaa-ats.iot.us-east-1.amazonaws.com has address 18.213.191.210
123456aaaaaaaa-ats.iot.us-east-1.amazonaws.com has address 34.199.197.35
123456aaaaaaaa-ats.iot.us-east-1.amazonaws.com has IPv6 address 2406:da00:ff00::2cc1:6e4b
123456aaaaaaaa-ats.iot.us-east-1.amazonaws.com has IPv6 address 2406:da00:ff00::3403:e3c

AWS CloudShell in eu-central-1:

$ host global.iot.example.com 
global.iot.example.com is an alias for 123456aaaaaaaa-ats.iot.eu-west-1.amazonaws.com.
123456aaaaaaaa-ats.iot.eu-west-1.amazonaws.com has address 34.246.55.152
123456aaaaaaaa-ats.iot.eu-west-1.amazonaws.com has address 52.214.209.63
123456aaaaaaaa-ats.iot.eu-west-1.amazonaws.com has IPv6 address 2a01:578:3::34d6:9eb8
123456aaaaaaaa-ats.iot.eu-west-1.amazonaws.com has IPv6 address 2a01:578:3::22f3:3c77

Provisioning

AWS IoT Core provides various options to provision your devices. You can provision your devices in advance or just-in-time when they connect for the first time to your IoT endpoint. When you use global device provisioning together with registering your devices in advance, you need to create your device resources in every region where the device can potentially connect to.

If you want your devices to only be provisioned when they come online and only want to provision them in the region where they operate, you can use just-in-time provisioning. This blog post describes two just-in-time provisioning approaches, fleet provisioning and just-in-time provisioning.

To walk through the provisioning process, you can use the fleet and just-in-time provisioning exercises from the AWS IoT Device Management workshop. You can launch two workshop environments, one in a US region and another in a region outside the US to test provisioning scenarios with your global IoT endpoint.

Setup fleet provisioning

With AWS IoT fleet provisioning, AWS IoT can generate and securely deliver device certificates and private keys to your devices when they connect to AWS IoT for the first time. This blog covers the approach on how to provision by claim. Each device can store the same claim certificate and private key. When devices connect for the first time to AWS IoT Core they are provisioned and receive their final key and certificate.

To use the same claim certificate in multiple regions, use the RegisterCertificateWithoutCA Application Programming Interface (API). With this API you can register your claim certificate without a Certificate Authority (CA). Assuming you add your claim certificate into the file provision-claim.certificate.pem you can use the following AWS Command Line Interface (AWS CLI) commands to register the certificate in both regions:

eu-west-1:

aws iot register-certificate-without-ca \
    --certificate-pem \
    file://provision-claim.certificate.pem \
    --region eu-west-1

us-east-1:

aws iot register-certificate-without-ca \
    --certificate-pem \
    file://provision-claim.certificate.pem \
    --region us-east-1

Different from the instructions in the workshop:

  • Register the claim certificate in both regions
  • Create the required resources, thing-group, provisioning template, IoT policy in both regions. Resources in the IoT policy include the AWS Region. Replace the AWS Region with the region where you are creating the policy.
  • When you start the fleet provisioning process with the command fleetprovisioning.py, replace $IOT_ENDPOINT with your global IoT endpoint, in this blog global.iot.example.com.

After you perform the steps from the exercise, your IoT device will be automatically registered with AWS IoT Core based on your device geolocation.

Use just-in-time provisioning

You can register your devices when they first attempt to connect to AWS IoT with JITP. To use JITP you must bring your own certification authority and register it with AWS IoT Core. Then you must enable automatic registration for your CA and associate a provisioning template with it.

You must register your CA in both regions. Your device stores one device certificate issued by your CA regardless of the connecting region.

Different from the instructions in the workshop:

  • You only need one CA and it must not be setup in any of your global provisioning regions.
  • Register your CA in both global regions.
  • Enable JITP for your CA in both regions
  • When you connect with the mosquitto_pub command to AWS IoT Core replace $IOT_ENDPOINT with your global IoT endpoint, in this blog global.iot.example.com.

After you perform the steps from the exercise, your IoT device can automatically register with AWS IoT Core based on your device geolocation.

Conclusion

In this post, you learned how to provision your IoT devices globally with Amazon Route 53 traffic policies, AWS IoT Core configurable endpoints and automatic provisioning options. This approach is not limited to two AWS Regions, you can use more regions based on your use-case. You can choose to use geolocation-based routing in Amazon Router 53 or any other traffic policies. With the architecture referenced in the post, you can reduce your implementation time for just-in-time device registration, thereby accelerating your time-to-market for your IoT solution. For further reading, refer to AWS IoT product page or the AWS IoT Device Management workshop.

About the author

Philipp Sacha is a Specialist Solutions Architect for IoT at Amazon Web Services supporting customers in the IoT area. He joined AWS in 2015 as a general Solutions Architect and moved in 2018 into the role of a Specialist in the IoT area.