Skip to content

Fleet provisioning docs #213

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 9 commits into from
Jul 16, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/stale-issue.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ name: "Close stale issues"
# Controls when the action will run.
on:
schedule:
- cron: "*/60 * * * *"
- cron: "0 0 * * *"

jobs:
cleanup:
Expand Down
22 changes: 20 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ to Python by the `awscrt` package ([PyPI](https://pypi.org/project/awscrt/)) ([G
* [Samples](samples)
* [Getting Help](#Getting-Help)
* [Giving Feedback and Contributions](#Giving-Feedback-and-Contributions)
* [More Resources](#More-Resources)


## Installation

Expand Down Expand Up @@ -56,6 +58,7 @@ sudo apt-get install cmake
sudo apt-get install python3-dev
```


## Mac-Only TLS Behavior

Please note that on Mac, once a private key is used with a certificate, that certificate-key pair is imported into the Mac Keychain. All subsequent uses of that certificate will use the stored private key and ignore anything passed in programmatically. Beginning in v1.3.2, when a stored private key from the Keychain is used, the following will be logged at the "info" log level:
Expand All @@ -64,6 +67,7 @@ Please note that on Mac, once a private key is used with a certificate, that cer
static: certificate has an existing certificate-key pair that was previously imported into the Keychain. Using key from Keychain instead of the one provided.
```


## Samples

[Samples README](samples)
Expand All @@ -88,10 +92,24 @@ is provided by code that been generated from a model of the service.

We need your help in making this SDK great. Please participate in the community and contribute to this effort by submitting issues, participating in discussion forums and submitting pull requests through the following channels.

* [Contributions Guidelines](CONTRIBUTING.md)
* [Contributions Guidelines](/CONTRIBUTING.md)
* Articulate your feature request or upvote existing ones on our [Issues](https://github.com/aws/aws-iot-device-sdk-python-v2/issues?q=is%3Aissue+is%3Aopen+label%3Afeature-request) page.
* Submit [Issues](https://github.com/aws/aws-iot-device-sdk-python-v2/issues)

# License

## More Resources

* [AWS IoT Core Documentation](https://docs.aws.amazon.com/iot/)
* [Developer Guide](https://docs.aws.amazon.com/iot/latest/developerguide/what-is-aws-iot.html) ([source](https://github.com/awsdocs/aws-iot-docs))
* [Issues](https://github.com/aws/aws-iot-device-sdk-python-v2/issues)
* [Dev Blog](https://aws.amazon.com/blogs/?awsf.blog-master-iot=category-internet-of-things%23amazon-freertos%7Ccategory-internet-of-things%23aws-greengrass%7Ccategory-internet-of-things%23aws-iot-analytics%7Ccategory-internet-of-things%23aws-iot-button%7Ccategory-internet-of-things%23aws-iot-device-defender%7Ccategory-internet-of-things%23aws-iot-device-management%7Ccategory-internet-of-things%23aws-iot-platform)

Integration with AWS IoT Services such as
[Device Shadow](https://docs.aws.amazon.com/iot/latest/developerguide/iot-device-shadows.html)
and [Jobs](https://docs.aws.amazon.com/iot/latest/developerguide/iot-jobs.html)
is provided by code that been generated from a model of the service.


## License

This library is licensed under the Apache 2.0 License.
148 changes: 84 additions & 64 deletions samples/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@
* [basic discovery](#basic-discovery)
* [IPC with AWS IoT Greengrass to publish to AWS IoT Core](#ipc-with-aws-iot-greengrass-to-publish-to-aws-iot-core)

## pubsub
## Pubsub

This sample uses the
[Message Broker](https://docs.aws.amazon.com/iot/latest/developerguide/iot-message-broker.html)
for AWS IoT to send and receive messages
Expand All @@ -19,7 +20,7 @@ Status updates are continually printed to the console.
Source: `samples/pubsub.py`

Run the sample like this:
```
``` sh
python3 pubsub.py --endpoint <endpoint> --root-ca <file> --cert <file> --key <file>
```

Expand Down Expand Up @@ -67,7 +68,7 @@ and receive.
</pre>
</details>

## shadow
## Shadow

This sample uses the AWS IoT
[Device Shadow](https://docs.aws.amazon.com/iot/latest/developerguide/iot-device-shadows.html)
Expand All @@ -90,7 +91,7 @@ value.
Source: `samples/shadow.py`

Run the sample like this:
```
``` sh
python3 shadow.py --endpoint <endpoint> --root-ca <file> --cert <file> --key <file> --thing-name <name>
```

Expand Down Expand Up @@ -151,7 +152,7 @@ and receive.
</pre>
</details>

## jobs
## Jobs

This sample uses the AWS IoT
[Jobs](https://docs.aws.amazon.com/iot/latest/developerguide/iot-jobs.html)
Expand All @@ -176,7 +177,7 @@ sample will be continually prompted to try another job until none remain.
Source: `samples/jobs.py`

Run the sample like this:
```
``` sh
python3 jobs.py --endpoint <endpoint> --root-ca <file> --cert <file> --key <file> --thing-name <name>
```

Expand Down Expand Up @@ -236,7 +237,7 @@ and receive.
</pre>
</details>

## fleet provisioning
## Fleet Provisioning

This sample uses the AWS IoT
[Fleet provisioning](https://docs.aws.amazon.com/iot/latest/developerguide/provision-wo-cert.html)
Expand All @@ -248,12 +249,12 @@ publishes the request to corresponding topic and calls RegisterThing.
Source: `samples/fleetprovisioning.py`

Run the sample using createKeysAndCertificate:
```
``` sh
python3 fleetprovisioning.py --endpoint <endpoint> --root-ca <file> --cert <file> --key <file> --templateName <name> --templateParameters <parameters>
```

Run the sample using createCertificateFromCsr:
```
``` sh
python3 fleetprovisioning.py --endpoint <endpoint> --root-ca <file> --cert <file> --key <file> --templateName <name> --templateParameters <parameters> --csr <csr file>
```

Expand Down Expand Up @@ -304,102 +305,121 @@ and receive.
</pre>
</details>

#### Fleet Provisioning Detailed Instructions
### Fleet Provisioning Detailed Instructions

##### Aws Resource Setup
Fleet provisioning requires some additional AWS resources be set up first. This section documents the steps you need to take to
get the sample up and running. These steps assume you have the AWS CLI installed and the default user/credentials has
sufficient permission to perform all of the listed operations. These steps are based on provisioning setup steps
that can be found at [Embedded C SDK Setup](https://docs.aws.amazon.com/freertos/latest/lib-ref/c-sdk/provisioning/provisioning_tests.html#provisioning_system_tests_setup)
#### Aws Resource Setup

First, create the IAM role that will be needed by the fleet provisioning template. Replace `RoleName` with a name of the role you want to create.
<pre>
Fleet provisioning requires some additional AWS resources be set up first. This section documents the steps you need to take to
get the sample up and running. These steps assume you have the AWS CLI installed and the default user/credentials has
sufficient permission to perform all of the listed operations. These steps are based on provisioning setup steps
that can be found at [Embedded C SDK Setup](https://docs.aws.amazon.com/freertos/latest/lib-ref/c-sdk/provisioning/provisioning_tests.html#provisioning_system_tests_setup).

First, create the IAM role that will be needed by the fleet provisioning template. Replace `RoleName` with a name of the role you want to create.
``` sh
aws iam create-role \
--role-name [RoleName] \
--assume-role-policy-document '{"Version":"2012-10-17","Statement":[{"Action":"sts:AssumeRole","Effect":"Allow","Principal":{"Service":"iot.amazonaws.com"}}]}'
</pre>
```
Next, attach a policy to the role created in the first step. Replace `RoleName` with the name of the role you created previously.
<pre>
``` sh
aws iam attach-role-policy \
--role-name [RoleName] \
--policy-arn arn:aws:iam::aws:policy/service-role/AWSIoTThingsRegistration
</pre>
Finally, create the template resource which will be used for provisioning by the demo application. This needs to be done only
once. To create a template, the following AWS CLI command may be used. Replace `TemplateName` with the name of the fleet
provisioning template you want to create. Replace `RoleName` with the name of the role you created previously. Replace
`TemplateJSON` with the template body as a JSON string (containing escape characters). Replace `account` with your AWS
account number.
<pre>
```
Finally, create the template resource which will be used for provisioning by the demo application. This needs to be done only
once. To create a template, the following AWS CLI command may be used. Replace `TemplateName` with the name of the fleet
provisioning template you want to create. Replace `RoleName` with the name of the role you created previously. Replace
`TemplateJSON` with the template body as a JSON string (containing escape characters). Replace `account` with your AWS
account number.
``` sh
aws iot create-provisioning-template \
--template-name [TemplateName] \
--provisioning-role-arn arn:aws:iam::[account]:service-role/[RoleName] \
--provisioning-role-arn arn:aws:iam::[account]:role/[RoleName] \
--template-body "[TemplateJSON]" \
--enabled
</pre>
--enabled
```
The rest of the instructions assume you have used the following for the template body:
<pre>
``` sh
{\"Parameters\":{\"DeviceLocation\":{\"Type\":\"String\"},\"AWS::IoT::Certificate::Id\":{\"Type\":\"String\"},\"SerialNumber\":{\"Type\":\"String\"}},\"Mappings\":{\"LocationTable\":{\"Seattle\":{\"LocationUrl\":\"https://example.aws\"}}},\"Resources\":{\"thing\":{\"Type\":\"AWS::IoT::Thing\",\"Properties\":{\"ThingName\":{\"Fn::Join\":[\"\",[\"ThingPrefix_\",{\"Ref\":\"SerialNumber\"}]]},\"AttributePayload\":{\"version\":\"v1\",\"serialNumber\":\"serialNumber\"}},\"OverrideSettings\":{\"AttributePayload\":\"MERGE\",\"ThingTypeName\":\"REPLACE\",\"ThingGroups\":\"DO_NOTHING\"}},\"certificate\":{\"Type\":\"AWS::IoT::Certificate\",\"Properties\":{\"CertificateId\":{\"Ref\":\"AWS::IoT::Certificate::Id\"},\"Status\":\"Active\"},\"OverrideSettings\":{\"Status\":\"REPLACE\"}},\"policy\":{\"Type\":\"AWS::IoT::Policy\",\"Properties\":{\"PolicyDocument\":{\"Version\":\"2012-10-17\",\"Statement\":[{\"Effect\":\"Allow\",\"Action\":[\"iot:Connect\",\"iot:Subscribe\",\"iot:Publish\",\"iot:Receive\"],\"Resource\":\"*\"}]}}}},\"DeviceConfiguration\":{\"FallbackUrl\":\"https://www.example.com/test-site\",\"LocationUrl\":{\"Fn::FindInMap\":[\"LocationTable\",{\"Ref\":\"DeviceLocation\"},\"LocationUrl\"]}}}
</pre>
```
If you use a different body, you may need to pass in different template parameters.
##### Running the sample and provisioning using a certificate-key set from a provisioning claim

To run the provisioning sample, you'll need a certificate and key set with sufficient permissions. Provisioning certificates are normally
created ahead of time and placed on your device, but for this sample, we will just create them on the fly. You can also
#### Running the sample and provisioning using a certificate-key set from a provisioning claim

To run the provisioning sample, you'll need a certificate and key set with sufficient permissions. Provisioning certificates are normally
created ahead of time and placed on your device, but for this sample, we will just create them on the fly. You can also
use any certificate set you've already created if it has sufficient IoT permissions and in doing so, you can skip the step
that calls `create-provisioning-claim`.

We've included a script in the utils folder that creates certificate and key files from the response of calling
`create-provisioning-claim`. These dynamically sourced certificates are only valid for five minutes. When running the command,
`create-provisioning-claim`. These dynamically sourced certificates are only valid for five minutes. When running the command,
you'll need to substitute the name of the template you previously created, and on Windows, replace the paths with something appropriate.

(Optional) Create a temporary provisioning claim certificate set:
<pre>
aws iot create-provisioning-claim --template-name [TemplateName] | python3 ../utils/parse_cert_set_result.py --path /tmp --filename provision
</pre>
``` sh
aws iot create-provisioning-claim \
--template-name [TemplateName] \
| python3 ../utils/parse_cert_set_result.py \
--path /tmp \
--filename provision
```

The provisioning claim's cert and key set have been written to `/tmp/provision*`. Now you can use these temporary keys
to perform the actual provisioning. If you are not using the temporary provisioning certificate, replace the paths for `--cert`
The provisioning claim's cert and key set have been written to `/tmp/provision*`. Now you can use these temporary keys
to perform the actual provisioning. If you are not using the temporary provisioning certificate, replace the paths for `--cert`
and `--key` appropriately:

<pre>
python3 fleetprovisioning.py --endpoint [your endpoint]-ats.iot.[region].amazonaws.com --root-ca [pathToRootCA] --cert /tmp/provision.cert.pem --key /tmp/provision.private.key --templateName [TemplateName]--templateParameters "{\"SerialNumber\":\"1\",\"DeviceLocation\":\"Seattle\"}"
</pre>
``` sh
python3 fleetprovisioning.py \
--endpoint [your endpoint]-ats.iot.[region].amazonaws.com \
--root-ca [pathToRootCA] \
--cert /tmp/provision.cert.pem \
--key /tmp/provision.private.key \
--templateName [TemplateName] \
--templateParameters "{\"SerialNumber\":\"1\",\"DeviceLocation\":\"Seattle\"}"
```

Notice that we provided substitution values for the two parameters in the template body, `DeviceLocation` and `SerialNumber`.

##### Run the sample using the certificate signing request workflow
#### Run the sample using the certificate signing request workflow

To run the sample with this workflow, you'll need to create a certificate signing request.

First create a certificate-key pair:
<pre>
``` sh
openssl genrsa -out /tmp/deviceCert.key 2048
</pre>
```

Next create a certificate signing request from it:
<pre>
``` sh
openssl req -new -key /tmp/deviceCert.key -out /tmp/deviceCert.csr
</pre>
```

(Optional) As with the previous workflow, we'll create a temporary certificate set from a provisioning claim. This step can
(Optional) As with the previous workflow, we'll create a temporary certificate set from a provisioning claim. This step can
be skipped if you're using a certificate set capable of provisioning the device:

<pre>
aws iot create-provisioning-claim --template-name [TemplateName] | python3 ../utils/parse_cert_set_result.py --path /tmp --filename provision
</pre>
``` sh
aws iot create-provisioning-claim \
--template-name [TemplateName] \
| python3 ../utils/parse_cert_set_result.py \
--path /tmp \
--filename provision
```

Finally, supply the certificate signing request while invoking the provisioning sample. As with the previous workflow, if
Finally, supply the certificate signing request while invoking the provisioning sample. As with the previous workflow, if
using a permanent certificate set, replace the paths specified in the `--cert` and `--key` arguments:
<pre>
python3 fleetprovisioning.py --endpoint [your endpoint]-ats.iot.[region].amazonaws.com --root-ca [pathToRootCA] --cert /tmp/provision.cert.pem --key /tmp/provision.private.key --templateName [TemplateName]--templateParameters "{\"SerialNumber\":\"1\",\"DeviceLocation\":\"Seattle\"}" --csr /tmp/deviceCert.csr
</pre>

## basic discovery

This sample is intended for use directly with the
[Getting Started with AWS IoT Greengrass](https://docs.aws.amazon.com/greengrass/latest/developerguide/gg-gs.html) guide.

## IPC with AWS IoT Greengrass to publish to AWS IoT Core
``` sh
python3 fleetprovisioning.py \
--endpoint [your endpoint]-ats.iot.[region].amazonaws.com \
--root-ca [pathToRootCA] \
--cert /tmp/provision.cert.pem \
--key /tmp/provision.private.key \
--templateName [TemplateName] \
--templateParameters "{\"SerialNumber\":\"1\",\"DeviceLocation\":\"Seattle\"}" \
--csr /tmp/deviceCert.csr
```

This sample is intended to be deployed as an AWS IoT Greengrass component and it will publish MQTT messages from the device to AWS IoT Core.
## Greengrass Discovery

Source: `samples/ipc_greengrass.py`
This sample intended for use directly with the
[Getting Started with AWS IoT Greengrass](https://docs.aws.amazon.com/greengrass/latest/developerguide/gg-gs.html) guide.