From 161edea67f1aae7c414dac84870c3b7464cc3a68 Mon Sep 17 00:00:00 2001 From: Alfred G <28123637+alfred2g@users.noreply.github.com> Date: Tue, 3 Oct 2023 09:06:04 -0700 Subject: [PATCH 1/6] Fix Readme remove unnecessary dot (#639) --- samples/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/samples/README.md b/samples/README.md index 3ca1ed425..7c837dafb 100644 --- a/samples/README.md +++ b/samples/README.md @@ -48,7 +48,7 @@ cmake --build . --config "" Change directory to the `aws-iot-device-sdk-cpp-v2/samples` directory and then run the following commands: ```sh -cmake -B build -S . -DCMAKE_PREFIX_PATH="" -DCMAKE_BUILD_TYPE="" . +cmake -B build -S . -DCMAKE_PREFIX_PATH="" -DCMAKE_BUILD_TYPE="" cmake --build build --config "" ``` From e24ad054d53388be17af4ceaf9a13308bc5b19fc Mon Sep 17 00:00:00 2001 From: Zhihui Xia Date: Tue, 3 Oct 2023 17:32:01 -0700 Subject: [PATCH 2/6] test doxygen --- crt/aws-crt-cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crt/aws-crt-cpp b/crt/aws-crt-cpp index 363d09e8a..8699e9d4c 160000 --- a/crt/aws-crt-cpp +++ b/crt/aws-crt-cpp @@ -1 +1 @@ -Subproject commit 363d09e8a3509f663327d6e8414d0b2e052c815d +Subproject commit 8699e9d4c58611f253b9788661307f8b3c20d922 From 3076cca1e67a9e4ccd5968d556072804135bbdff Mon Sep 17 00:00:00 2001 From: Zhihui Xia Date: Wed, 4 Oct 2023 09:46:03 -0700 Subject: [PATCH 3/6] Revert "test doxygen" This reverts commit e24ad054d53388be17af4ceaf9a13308bc5b19fc. --- crt/aws-crt-cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crt/aws-crt-cpp b/crt/aws-crt-cpp index 8699e9d4c..363d09e8a 160000 --- a/crt/aws-crt-cpp +++ b/crt/aws-crt-cpp @@ -1 +1 @@ -Subproject commit 8699e9d4c58611f253b9788661307f8b3c20d922 +Subproject commit 363d09e8a3509f663327d6e8414d0b2e052c815d From e29e42a0b3ee114a4d1808fa5d94db81e9cb544c Mon Sep 17 00:00:00 2001 From: Vera Xia Date: Thu, 5 Oct 2023 17:34:59 -0700 Subject: [PATCH 4/6] Service Client Codegen (#641) * identity codegen * job service client * shadow codegen * secure tunneling codegen * update identity cmake * job cmake * update shadow code gen * Revert "secure tunneling codegen" This reverts commit 177963477a6ddbb6fb3759540b00845d89d0973a. * update crt to 0.24.0 * update crt * update aws-crt-cpp * update aws-crt-cpp * update cmake codegen * update crt * update cmake code-gen * Mqtt5 Service Client samples (#642) * shadow sample * update jobs sample * identity sample * Revert "secure tunneling codegen" This reverts commit 177963477a6ddbb6fb3759540b00845d89d0973a. * setup mqtt5 service client samples cmake * setup builder step to build samples * test doc gen * update test doc gen * update doxygen comment * test with latest doxygen update * update crt to latest cmake fix --- .builder/actions/build_samples.py | 3 + .github/workflows/ci.yml | 12 + .../ci_run_fleet_provisioning_mqtt5_cfg.json | 30 ++ .github/workflows/ci_run_jobs_mqtt5_cfg.json | 30 ++ .../workflows/ci_run_shadow_mqtt5_cfg.json | 30 ++ crt/aws-crt-cpp | 2 +- identity/CMakeLists.txt | 4 +- identity/cmake/iotidentity-cpp-config.cmake | 2 + .../aws/iotidentity/IotIdentityClient.h | 2 + identity/source/IotIdentityClient.cpp | 5 + jobs/CMakeLists.txt | 4 +- jobs/include/aws/iotjobs/IotJobsClient.h | 2 + jobs/source/IotJobsClient.cpp | 5 + samples/CMakeLists.txt | 3 + .../mqtt5_fleet_provisioning/CMakeLists.txt | 28 ++ .../mqtt5_fleet_provisioning/README.md | 348 +++++++++++++ .../mqtt5_fleet_provisioning/main.cpp | 468 +++++++++++++++++ .../CMakeLists.txt | 28 ++ .../mqtt5_describe_job_execution/README.md | 123 +++++ .../mqtt5_describe_job_execution/main.cpp | 182 +++++++ .../shadow/mqtt5_shadow_sync/CMakeLists.txt | 28 ++ samples/shadow/mqtt5_shadow_sync/README.md | 127 +++++ samples/shadow/mqtt5_shadow_sync/main.cpp | 474 ++++++++++++++++++ shadow/CMakeLists.txt | 4 +- shadow/cmake/iotshadow-cpp-config.cmake | 2 + .../include/aws/iotshadow/IotShadowClient.h | 2 + shadow/source/IotShadowClient.cpp | 5 + 27 files changed, 1947 insertions(+), 6 deletions(-) create mode 100644 .github/workflows/ci_run_fleet_provisioning_mqtt5_cfg.json create mode 100644 .github/workflows/ci_run_jobs_mqtt5_cfg.json create mode 100644 .github/workflows/ci_run_shadow_mqtt5_cfg.json create mode 100644 samples/fleet_provisioning/mqtt5_fleet_provisioning/CMakeLists.txt create mode 100644 samples/fleet_provisioning/mqtt5_fleet_provisioning/README.md create mode 100644 samples/fleet_provisioning/mqtt5_fleet_provisioning/main.cpp create mode 100644 samples/jobs/mqtt5_describe_job_execution/CMakeLists.txt create mode 100644 samples/jobs/mqtt5_describe_job_execution/README.md create mode 100644 samples/jobs/mqtt5_describe_job_execution/main.cpp create mode 100644 samples/shadow/mqtt5_shadow_sync/CMakeLists.txt create mode 100644 samples/shadow/mqtt5_shadow_sync/README.md create mode 100644 samples/shadow/mqtt5_shadow_sync/main.cpp diff --git a/.builder/actions/build_samples.py b/.builder/actions/build_samples.py index 78cd1032a..e23ad2fc2 100644 --- a/.builder/actions/build_samples.py +++ b/.builder/actions/build_samples.py @@ -16,7 +16,9 @@ def run(self, env): 'samples/greengrass/basic_discovery', 'samples/greengrass/ipc', 'samples/fleet_provisioning/fleet_provisioning', + 'samples/fleet_provisioning/mqtt5_fleet_provisioning', 'samples/jobs/describe_job_execution', + 'samples/jobs/mqtt5_describe_job_execution', 'samples/mqtt/basic_connect', 'samples/mqtt/custom_authorizer_connect', 'samples/mqtt/pkcs11_connect', @@ -33,6 +35,7 @@ def run(self, env): 'samples/secure_tunneling/secure_tunnel', 'samples/secure_tunneling/tunnel_notification', 'samples/shadow/shadow_sync', + 'samples/shadow/mqtt5_shadow_sync', ] defender_samples = [] diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 18075ada7..c66dfe69a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -509,6 +509,9 @@ jobs: - name: run Shadow sample run: | python3 ${{ env.CI_UTILS_FOLDER }}/run_sample_ci.py --file ${{ env.CI_SAMPLES_CFG_FOLDER }}/ci_run_shadow_cfg.json + - name: run Mqtt5 Shadow sample + run: | + python3 ${{ env.CI_UTILS_FOLDER }}/run_sample_ci.py --file ${{ env.CI_SAMPLES_CFG_FOLDER }}/ci_run_shadow_mqtt5_cfg.json - name: configure AWS credentials (Jobs) uses: aws-actions/configure-aws-credentials@v1 with: @@ -517,6 +520,9 @@ jobs: - name: run Jobs sample run: | python3 ${{ env.CI_UTILS_FOLDER }}/run_sample_ci.py --file ${{ env.CI_SAMPLES_CFG_FOLDER }}/ci_run_jobs_cfg.json + - name: run Mqtt5 Jobs sample + run: | + python3 ${{ env.CI_UTILS_FOLDER }}/run_sample_ci.py --file ${{ env.CI_SAMPLES_CFG_FOLDER }}/ci_run_jobs_mqtt5_cfg.json - name: configure AWS credentials (Fleet provisioning) uses: aws-actions/configure-aws-credentials@v1 with: @@ -528,6 +534,12 @@ jobs: Sample_UUID=$(python3 -c "import uuid; print (uuid.uuid4())") python3 ${{ env.CI_UTILS_FOLDER }}/run_sample_ci.py --file ${{ env.CI_SAMPLES_CFG_FOLDER }}/ci_run_fleet_provisioning_cfg.json --input_uuid ${Sample_UUID} python3 ${{ env.CI_UTILS_FOLDER }}/delete_iot_thing_ci.py --thing_name "Fleet_Thing_${Sample_UUID}" --region "us-east-1" + - name: run Mqtt5 Fleet Provisioning sample + run: | + echo "Generating UUID for IoT thing" + Sample_UUID=$(python3 -c "import uuid; print (uuid.uuid4())") + python3 ${{ env.CI_UTILS_FOLDER }}/run_sample_ci.py --file ${{ env.CI_SAMPLES_CFG_FOLDER }}/ci_run_fleet_provisioning_mqtt5_cfg.json --input_uuid ${Sample_UUID} + python3 ${{ env.CI_UTILS_FOLDER }}/delete_iot_thing_ci.py --thing_name "Fleet_Thing_${Sample_UUID}" --region "us-east-1" - name: configure AWS credentials (Secure tunneling) uses: aws-actions/configure-aws-credentials@v1 with: diff --git a/.github/workflows/ci_run_fleet_provisioning_mqtt5_cfg.json b/.github/workflows/ci_run_fleet_provisioning_mqtt5_cfg.json new file mode 100644 index 000000000..bc4408d3a --- /dev/null +++ b/.github/workflows/ci_run_fleet_provisioning_mqtt5_cfg.json @@ -0,0 +1,30 @@ +{ + "language": "CPP", + "sample_file": "./aws-iot-device-sdk-cpp-v2/build/samples/fleet_provisioning/mqtt5_fleet_provisioning/mqtt5-fleet-provisioning", + "sample_region": "us-east-1", + "sample_main_class": "", + "arguments": [ + { + "name": "--endpoint", + "secret": "ci/endpoint" + }, + { + "name": "--cert", + "secret": "ci/FleetProvisioning/cert", + "filename": "tmp_certificate.pem" + }, + { + "name": "--key", + "secret": "ci/FleetProvisioning/key", + "filename": "tmp_key.pem" + }, + { + "name": "--template_name", + "data": "CI_FleetProvisioning_Template" + }, + { + "name": "--template_parameters", + "data": "{\"SerialNumber\":\"$INPUT_UUID\"}" + } + ] +} diff --git a/.github/workflows/ci_run_jobs_mqtt5_cfg.json b/.github/workflows/ci_run_jobs_mqtt5_cfg.json new file mode 100644 index 000000000..23d48c2b1 --- /dev/null +++ b/.github/workflows/ci_run_jobs_mqtt5_cfg.json @@ -0,0 +1,30 @@ +{ + "language": "CPP", + "sample_file": "./aws-iot-device-sdk-cpp-v2/build/samples/jobs/mqtt5_describe_job_execution/mqtt5-describe-job-execution", + "sample_region": "us-east-1", + "sample_main_class": "", + "arguments": [ + { + "name": "--endpoint", + "secret": "ci/endpoint" + }, + { + "name": "--cert", + "secret": "ci/Jobs/cert", + "filename": "tmp_certificate.pem" + }, + { + "name": "--key", + "secret": "ci/Jobs/key", + "filename": "tmp_key.pem" + }, + { + "name": "--thing_name", + "data": "CI_Jobs_Thing" + }, + { + "name": "--job_id", + "data": "CI_Jobs_Thing_Job_1" + } + ] +} diff --git a/.github/workflows/ci_run_shadow_mqtt5_cfg.json b/.github/workflows/ci_run_shadow_mqtt5_cfg.json new file mode 100644 index 000000000..8f173b5e1 --- /dev/null +++ b/.github/workflows/ci_run_shadow_mqtt5_cfg.json @@ -0,0 +1,30 @@ +{ + "language": "CPP", + "sample_file": "./aws-iot-device-sdk-cpp-v2/build/samples/shadow/mqtt5_shadow_sync/mqtt5-shadow-sync", + "sample_region": "us-east-1", + "sample_main_class": "", + "arguments": [ + { + "name": "--endpoint", + "secret": "ci/endpoint" + }, + { + "name": "--cert", + "secret": "ci/Shadow/cert", + "filename": "tmp_certificate.pem" + }, + { + "name": "--key", + "secret": "ci/Shadow/key", + "filename": "tmp_key.pem" + }, + { + "name": "--thing_name", + "data": "CI_Shadow_Thing" + }, + { + "name": "--is_ci", + "data": "true" + } + ] +} diff --git a/crt/aws-crt-cpp b/crt/aws-crt-cpp index 363d09e8a..a4af67ca4 160000 --- a/crt/aws-crt-cpp +++ b/crt/aws-crt-cpp @@ -1 +1 @@ -Subproject commit 363d09e8a3509f663327d6e8414d0b2e052c815d +Subproject commit a4af67ca4e33f2670f491147518397707044ce3e diff --git a/identity/CMakeLists.txt b/identity/CMakeLists.txt index e0f146bfa..e843c0ff5 100644 --- a/identity/CMakeLists.txt +++ b/identity/CMakeLists.txt @@ -1,8 +1,10 @@ +# This file is generated + cmake_minimum_required(VERSION 3.1) project(IotIdentity-cpp LANGUAGES CXX) if (DEFINED SIMPLE_VERSION) - message("Identity version is ${SIMPLE_VERSION}") + message("IotIdentity version is ${SIMPLE_VERSION}") set(PROJECT_VERSION ${SIMPLE_VERSION}) endif() diff --git a/identity/cmake/iotidentity-cpp-config.cmake b/identity/cmake/iotidentity-cpp-config.cmake index 67aff5946..e46a3ee38 100644 --- a/identity/cmake/iotidentity-cpp-config.cmake +++ b/identity/cmake/iotidentity-cpp-config.cmake @@ -1,3 +1,5 @@ +# This file is generated + include(CMakeFindDependencyMacro) find_dependency(aws-crt-cpp) diff --git a/identity/include/aws/iotidentity/IotIdentityClient.h b/identity/include/aws/iotidentity/IotIdentityClient.h index b38594564..f8c4ac590 100644 --- a/identity/include/aws/iotidentity/IotIdentityClient.h +++ b/identity/include/aws/iotidentity/IotIdentityClient.h @@ -11,6 +11,7 @@ #include #include +#include #include namespace Aws @@ -60,6 +61,7 @@ namespace Aws { public: IotIdentityClient(const std::shared_ptr &connection); + IotIdentityClient(const std::shared_ptr &mqtt5Client); operator bool() const noexcept; int GetLastError() const noexcept; diff --git a/identity/source/IotIdentityClient.cpp b/identity/source/IotIdentityClient.cpp index 524c5cd41..42227faa1 100644 --- a/identity/source/IotIdentityClient.cpp +++ b/identity/source/IotIdentityClient.cpp @@ -26,6 +26,11 @@ namespace Aws { } + IotIdentityClient::IotIdentityClient(const std::shared_ptr &mqtt5Client) + { + m_connection = Aws::Crt::Mqtt::MqttConnection::NewConnectionFromMqtt5Client(mqtt5Client); + } + IotIdentityClient::operator bool() const noexcept { return m_connection && *m_connection; } int IotIdentityClient::GetLastError() const noexcept { return aws_last_error(); } diff --git a/jobs/CMakeLists.txt b/jobs/CMakeLists.txt index 4059f09fa..b1d054924 100644 --- a/jobs/CMakeLists.txt +++ b/jobs/CMakeLists.txt @@ -59,9 +59,7 @@ else () target_compile_options(IotJobs-cpp PRIVATE -Wall -Wno-long-long -pedantic -Werror) endif () -if (CMAKE_BUILD_TYPE STREQUAL "" OR CMAKE_BUILD_TYPE MATCHES Debug) - target_compile_definitions(IotJobs-cpp PRIVATE "-DDEBUG_BUILD") -endif () +target_compile_definitions(IotJobs-cpp PRIVATE $<$:DEBUG_BUILD>) if (BUILD_SHARED_LIBS) target_compile_definitions(IotJobs-cpp PUBLIC "-DAWS_IOTJOBS_USE_IMPORT_EXPORT") diff --git a/jobs/include/aws/iotjobs/IotJobsClient.h b/jobs/include/aws/iotjobs/IotJobsClient.h index ab7c7248b..e4027c171 100644 --- a/jobs/include/aws/iotjobs/IotJobsClient.h +++ b/jobs/include/aws/iotjobs/IotJobsClient.h @@ -11,6 +11,7 @@ #include #include +#include #include namespace Aws @@ -80,6 +81,7 @@ namespace Aws { public: IotJobsClient(const std::shared_ptr &connection); + IotJobsClient(const std::shared_ptr &mqtt5Client); operator bool() const noexcept; int GetLastError() const noexcept; diff --git a/jobs/source/IotJobsClient.cpp b/jobs/source/IotJobsClient.cpp index f99ef2b52..4dd8819d5 100644 --- a/jobs/source/IotJobsClient.cpp +++ b/jobs/source/IotJobsClient.cpp @@ -33,6 +33,11 @@ namespace Aws { } + IotJobsClient::IotJobsClient(const std::shared_ptr &mqtt5Client) + { + m_connection = Aws::Crt::Mqtt::MqttConnection::NewConnectionFromMqtt5Client(mqtt5Client); + } + IotJobsClient::operator bool() const noexcept { return m_connection && *m_connection; } int IotJobsClient::GetLastError() const noexcept { return aws_last_error(); } diff --git a/samples/CMakeLists.txt b/samples/CMakeLists.txt index 494efb564..0b306e384 100644 --- a/samples/CMakeLists.txt +++ b/samples/CMakeLists.txt @@ -6,7 +6,9 @@ add_subdirectory(device_defender/basic_report) add_subdirectory(greengrass/ipc) add_subdirectory(greengrass/basic_discovery) add_subdirectory(fleet_provisioning/fleet_provisioning) +add_subdirectory(fleet_provisioning/mqtt5_fleet_provisioning) add_subdirectory(jobs/describe_job_execution) +add_subdirectory(jobs/mqtt5_describe_job_execution) add_subdirectory(mqtt/basic_connect) add_subdirectory(mqtt/custom_authorizer_connect) add_subdirectory(mqtt/pkcs11_connect) @@ -22,3 +24,4 @@ add_subdirectory(pub_sub/cycle_pub_sub) add_subdirectory(secure_tunneling/secure_tunnel) add_subdirectory(secure_tunneling/tunnel_notification) add_subdirectory(shadow/shadow_sync) +add_subdirectory(shadow/mqtt5_shadow_sync) diff --git a/samples/fleet_provisioning/mqtt5_fleet_provisioning/CMakeLists.txt b/samples/fleet_provisioning/mqtt5_fleet_provisioning/CMakeLists.txt new file mode 100644 index 000000000..b13a3f34d --- /dev/null +++ b/samples/fleet_provisioning/mqtt5_fleet_provisioning/CMakeLists.txt @@ -0,0 +1,28 @@ +cmake_minimum_required(VERSION 3.1) +# note: cxx-17 requires cmake 3.8, cxx-20 requires cmake 3.12 +project(mqtt5-fleet-provisioning CXX) + +file(GLOB SRC_FILES + "*.cpp" + "../../utils/CommandLineUtils.cpp" + "../../utils/CommandLineUtils.h" +) + +add_executable(${PROJECT_NAME} ${SRC_FILES}) + +set_target_properties(${PROJECT_NAME} PROPERTIES + CXX_STANDARD 14) + +#set warnings +if (MSVC) + target_compile_options(${PROJECT_NAME} PRIVATE /W4 /WX) +else () + target_compile_options(${PROJECT_NAME} PRIVATE -Wall -Wno-long-long -pedantic -Werror) +endif () + +find_package(aws-crt-cpp REQUIRED) +find_package(IotIdentity-cpp REQUIRED) + +install(TARGETS ${PROJECT_NAME} DESTINATION bin) + +target_link_libraries(${PROJECT_NAME} PRIVATE AWS::aws-crt-cpp AWS::IotIdentity-cpp) diff --git a/samples/fleet_provisioning/mqtt5_fleet_provisioning/README.md b/samples/fleet_provisioning/mqtt5_fleet_provisioning/README.md new file mode 100644 index 000000000..9746f5d41 --- /dev/null +++ b/samples/fleet_provisioning/mqtt5_fleet_provisioning/README.md @@ -0,0 +1,348 @@ +# Fleet provisioning + +[**Return to main sample list**](../../README.md) + +This sample uses the AWS IoT [Fleet provisioning](https://docs.aws.amazon.com/iot/latest/developerguide/provision-wo-cert.html) to provision devices using either a CSR or Keys-And-Certificate and subsequently calls RegisterThing. This allows you to create new AWS IoT Core things using a Fleet Provisioning Template. + +On startup, the script subscribes to topics based on the request type of either CSR or Keys topics, publishes the request to corresponding topic and calls RegisterThing. + +Your IoT Core Thing's [Policy](https://docs.aws.amazon.com/iot/latest/developerguide/iot-policies.html) must provide privileges for this sample to connect, subscribe, publish, and receive. Below is a sample policy that can be used on your IoT Core Thing that will allow this sample to run as intended. + +
+(see sample policy) +
+{
+  "Version": "2012-10-17",
+  "Statement": [
+    {
+      "Effect": "Allow",
+      "Action": "iot:Publish",
+      "Resource": [
+        "arn:aws:iot:region:account:topic/$aws/certificates/create/json",
+        "arn:aws:iot:region:account:topic/$aws/certificates/create-from-csr/json",
+        "arn:aws:iot:region:account:topic/$aws/provisioning-templates/templatename/provision/json"
+      ]
+    },
+    {
+      "Effect": "Allow",
+      "Action": [
+        "iot:Receive"
+      ],
+      "Resource": [
+        "arn:aws:iot:region:account:topic/$aws/certificates/create/json/accepted",
+        "arn:aws:iot:region:account:topic/$aws/certificates/create/json/rejected",
+        "arn:aws:iot:region:account:topic/$aws/certificates/create-from-csr/json/accepted",
+        "arn:aws:iot:region:account:topic/$aws/certificates/create-from-csr/json/rejected",
+        "arn:aws:iot:region:account:topic/$aws/provisioning-templates/templatename/provision/json/accepted",
+        "arn:aws:iot:region:account:topic/$aws/provisioning-templates/templatename/provision/json/rejected"
+      ]
+    },
+    {
+      "Effect": "Allow",
+      "Action": [
+        "iot:Subscribe"
+      ],
+      "Resource": [
+        "arn:aws:iot:region:account:topicfilter/$aws/certificates/create/json/accepted",
+        "arn:aws:iot:region:account:topicfilter/$aws/certificates/create/json/rejected",
+        "arn:aws:iot:region:account:topicfilter/$aws/certificates/create-from-csr/json/accepted",
+        "arn:aws:iot:region:account:topicfilter/$aws/certificates/create-from-csr/json/rejected",
+        "arn:aws:iot:region:account:topicfilter/$aws/provisioning-templates/templatename/provision/json/accepted",
+        "arn:aws:iot:region:account:topicfilter/$aws/provisioning-templates/templatename/provision/json/rejected"
+      ]
+    },
+    {
+      "Effect": "Allow",
+      "Action": "iot:Connect",
+      "Resource": "arn:aws:iot:region:account:client/test-*"
+    }
+  ]
+}
+
+ +Replace with the following with the data from your AWS account: +* ``: The AWS IoT Core region where you created your AWS IoT Core thing you wish to use with this sample. For example `us-east-1`. +* ``: Your AWS IoT Core account ID. This is the set of numbers in the top right next to your AWS account name when using the AWS IoT Core website. +* ``: The name of your AWS Fleet Provisioning template you want to use to create new AWS IoT Core Things. + +Note that in a real application, you may want to avoid the use of wildcards in your ClientID or use them selectively. Please follow best practices when working with AWS on production applications using the SDK. Also, for the purposes of this sample, please make sure your policy allows a client ID of `test-*` to connect or use `--client_id ` to send the client ID your policy supports. + +
+ +## How to run + +There are many different ways to run the Fleet Provisioning sample because of how many different ways there are to setup a Fleet Provisioning template in AWS IoT Core. **The easiest and most common way is to run the sample with the following**: + +``` sh +./mqtt5-fleet-provisioning --endpoint --cert --key --template_name