Provisioning with the API

In this exercise you will execute all the required commands to create and register a device with AWS IoT. Furthermore you will experience how registry events work.

A device that should be able to communicate with AWS IoT needs to have a X.509 certificate which is registered with AWS IoT as well as a IoT policy. X.509 certificates are used for authentication and the IoT policy for authorisation.

Several API calls are required to provision a device. The output for some commands is stored in files in /tmp because values from it are required for further steps in the provisioning chain.

In the previous section you have enable IoT Events. To see the messages that the device registry publishes subscribe to the related topic hierarchy. Use the builtin MQTT client in the AWS console to subscribe to topics.

Go to the AWS IoT Core console

  1. Test
  2. Subscribe to a topic
  3. Subscription topic: $aws/events/#
  4. Subscribe to topic


Use the directory ~/provisioning for the exercises in this chapter.

cd ~/provisioning

Create a device

In a Cloud9 terminal:

# assigning your thing name to a shell variable makes the next steps easier

# create a thing in the thing registry
aws iot create-thing --thing-name $THING_NAME

Go to the AWS IoT Core console

You should see a message that has been posted to the topic $aws/events/thing/$THING_NAME/created.

In a Cloud9 terminal:

# create key and certificate for your device and active the device
aws iot create-keys-and-certificate --set-as-active \
  --public-key-outfile $THING_NAME.public.key \
  --private-key-outfile $THING_NAME.private.key \
  --certificate-pem-outfile $THING_NAME.certificate.pem > /tmp/create_cert_and_keys_response

# look at the output from the previous command
cat /tmp/create_cert_and_keys_response

# output values from the previous call needed in further steps
CERTIFICATE_ARN=$(jq -r ".certificateArn" /tmp/create_cert_and_keys_response)
CERTIFICATE_ID=$(jq -r ".certificateId" /tmp/create_cert_and_keys_response)

# create an IoT policy
aws iot create-policy --policy-name $POLICY_NAME \
  --policy-document '{"Version":"2012-10-17","Statement":[{"Effect":"Allow","Action": "iot:*","Resource":"*"}]}'

# attach the policy to your certificate
aws iot attach-policy --policy-name $POLICY_NAME \

# attach the certificate to your thing
aws iot attach-thing-principal --thing-name $THING_NAME \
  --principal $CERTIFICATE_ARN

List things in the device registry. Don’t trust the AWS IoT Core console. It might not be aware of every update made through the API because it caches results.

aws iot list-things

Update a device

To update the device you just created add an attribute. Also this modification of the device causes the device registry to publish an event message.

Update the device

aws iot update-thing --thing-name $THING_NAME --attribute-payload '{"attributes": {"type": "ws-device"}}'

List your devices

aws iot list-things

Go to the AWS AWS IoT Core console
You should see a message that was posted to the topic $aws/events/thing/$THING_NAME/updated.

Publish a message with you newly created device

After your device has been provisioned you will publish a message to AWS IoT. To publish a message the command mosquitto_pub is used. This command requires the iot endpoint to talk to.

Subscribe to the topic iot/ws

In a Cloud9 terminal:

# the iot endpoint has been already assigned to the shell variable $IOT_ENDPOINT but you can retrieve it with the following command:
aws iot describe-endpoint --endpoint-type iot:Data-ATS

# during setup of the EC2 instance the iot endpoint has already been assigned to the shell variable IOT_ENDPOINT

# publish a message
mosquitto_pub --cafile ~/ \
--cert $THING_NAME.certificate.pem \
--key $THING_NAME.private.key -h $IOT_ENDPOINT -p 8883 \
-q 0 -t iot/ws -i $THING_NAME --tls-version tlsv1.2 \
-m "{\"prov\": \"first\", \"date\": \"$(date)\"}" -d

Go to the AWS IoT Core console and validate if the message has been published.