Intro

Source documentation for fleet provisioning can be found in Amazon AWS’ Greengrass V2 documentation, here.

Prerequisites

1. Install NANO in AWS console

Instructions for installing Nano in AWS console can be found here.

2. Personalize

  1. When provisioning new devices, you’ll want to decide on a personalized naming convention. In these examples the example “my_” will be appended to filenames and other arguments. Utilizing a personalized naming convention will help keep things organized as opposed to the default names provided by the AWS documentation. Note: commands and filenames are all case sensitive.

  2. Open “CloudShell” in your AWS Console

  3. Create a working directory, this way the files you create are not sitting in the root folder:

     mkdir my_files
    
     cd my_files
    

Set up AWS IOT Fleet Provisioning

The following instructions will allow you to use AWS IOT Fleet provisioning to install Greengrass V2 to any device in your “Things” Group.

Create an Identity Access Management (IAM) role

A “Role” is simply a set of rules that can be applied to an individual device or group of devices.

  1. Create a file that “allows” the “assume role” action for “credentials.iot.amazonaws.com”

     nano my_device-role-trust-policy.json
    

    Provide the following contents:

    
     {
     "Version": "2012-10-17",
     "Statement": [
         {
         "Effect": "Allow",
         "Principal": {
             "Service": "credentials.iot.amazonaws.com"
         },
         "Action": "sts:AssumeRole"
         }
     ]
     }
    
    

    Commit this information to the cloud:

     aws iam create-role --role-name my_tokenexchangerole --assume-role-policy-document file://my_device-role-trust-policy.json
    

    If the operation is successful output will be produced reflecting the arguments provided.

    You can check a “role” has been created by navigating AWS Console to IAM, on this page under “Access management”, select “Roles”, then search for the name of your role.

  2. Create the access policy document. A “Policy” defines permissions for IAM.

    In GreenGrassV2 everything is a component. The component artifact files are usually stored in an S3 bucket (file share). This policy will not allow devices to pull those artifacts down by default. If you would like to enable S3 buckets for component artifacts click here. This feature does not need to be enabled to get your device checked in, but will be necessary in more involved applications.

     nano my_device-role-access-policy.json
    
     {
     "Version": "2012-10-17",
     "Statement": [
         {
         "Effect": "Allow",
         "Action": [
             "logs:CreateLogGroup",
             "logs:CreateLogStream",
             "logs:PutLogEvents",
             "logs:DescribeLogStreams",
             "s3:GetBucketLocation"
         ],
         "Resource": "*"
         }
     ]
     }
    
  3. Create an IAM role for this token exchange access policy.

     aws iam create-policy --policy-name my_tokenexchangeroleaccess --policy-document file://my_device-role-access-policy.json
    

    The output of this command will provide the Amazon Resource Name (ARN) of the IAM role. This can also be viewed under IAM > Policies > then select the token exchange role that was created, the ARN will be listed in the Summary pane.

  4. Attach the IAM policy to the token exchange role.

     aws iam attach-role-policy --role-name my_tokenexchangerole --policy-arn arn:aws:iam::123456789012:policy/my_tokenexchangeroleaccess
    
    • The “–role-name” is the IAM role created in step one. In our example we used “my_tokenexchangerole”.
    • The “–policy-arn” is the ARN from the output of step 3.
    • This command doesn’t have any output if the request succeeds.
  5. Create a role alias that points to the token exchange role.

     aws iot create-role-alias --role-alias my_coretokenexchangerolealias --role-arn arn:aws:iam::123456789012:role/my_tokenexchangerole
    
    • The “–role-alias” can be any name.
    • The “–role-arn” is the ARN of the role from step 1. This can be viewed under IAM > roles > then the name of the token exchange role that was created.
    • Successful execution of this command will produce output containing the name and location of the role alias.

Create an AWS IoT policy

These steps will create a policy which will be applied to your fleet of devices. All devices added as “Things” in this group will be provisioned this way.

Although “Nano” can be used, it’s much easier to make the following edits on your Desktop workstation.

  1. In your preferred text editor edit the following file contents to use the role alias created in step 5 of the previous section. The ARN argument will need to be replaced with the ARN of your “Role Alias”. To locate this, navigate to: IoT Core > Security (under “Manage”) > Role Aliases > then select your role alias. Be sure to copy the “Role alias ARN”, not the “Role ARN” as both are available on this page.

     {
     "Version": "2012-10-17",
     "Statement": [
         {
         "Effect": "Allow",
         "Action": [
             "iot:Publish",
             "iot:Subscribe",
             "iot:Receive",
             "iot:Connect",
             "greengrass:*"
         ],
         "Resource": [
             "*"
         ]
         },
         {
         "Effect": "Allow",
         "Action": "iot:AssumeRoleWithCertificate",
         "Resource": "arn:aws:iot:us-east-1:123456789012:rolealias/my_coretokenexchangerolealias"
         }
     ]
     }
    

    Back in the CloudShell terminal create a file to contain this policy:

     nano my_iotpolicy.json
    

    Paste the contents of your Desktop text editor into this file so they both share the same information.

  2. Commit the above IoT policy to the cloud:

     aws iot create-policy --policy-name my_iotthingpolicy --policy-document file://my_iotpolicy.json
    

    Output from this command will approximately represent the contents of the file.

Create a Fleet Provisioning Template

This is a template to create the identity for, and define access permission of, a device when it first provisions with AWS.

  1. Create a trust policy document. This will allow “iot.amazonaws.com” to assume a fleet provisioning role.

     nano my_trustpolicy.json
    
     {
     "Version": "2012-10-17",
     "Statement": [
         {
         "Effect": "Allow",
         "Principal": {
             "Service": "iot.amazonaws.com"
         },
         "Action": "sts:AssumeRole"
         }
     ]
     }
    
  2. Create a role with the trust policy document.

     aws iam create-role --role-name my_fleetprovisioningrole --assume-role-policy-document file://my_trustpolicy.json
    
    • ”–role-name” can be any name
    • ”–assume-role-policy-document” is the file created in step previously.
    • Successful execution of this command will result in output providing the role name, role ID, and ARN for this policy. This information can be reviewed under IAM > Access Management > Roles > your fleet provisioning role name.
  3. AWS already has a Things registration policy that allows access to all permissions AWS IoT may use when provisioning devices. Here we instantiate this policy. Provide the same fleet provisioning role name as used in the previous step.

     aws iam attach-role-policy --role-name my_fleetprovisioningrole --policy-arn arn:aws:iam::aws:policy/service-role/AWSIoTThingsRegistration
    
    • If you would like to review the permissions this policy grants follow this link
    • This command has no output if it succeeds.
  4. Create a file to contain the provisioning template document.

     nano my_fleetprovisioningtemplate.json
    

    In this document define the thing policy variable “PolicyName” with a string that is the IoT thing Policy name. This string is the value that was defined in step 2 of “Create an AWS IoT policy” section, in the example “my_iotthingpolicy”. All other values can be left as default.

     {
         "Parameters": {
             "ThingName": {
                 "Type": "String"
             },
             "ThingGroupName": {
                 "Type": "String"
             },
             "AWS::IoT::Certificate::Id": {
                 "Type": "String"
             }
         },
         "Resources": {
             "MyThing": {
                 "OverrideSettings": {
                     "AttributePayload": "REPLACE",
                     "ThingGroups": "REPLACE",
                     "ThingTypeName": "REPLACE"
                 },
                 "Properties": {
                     "AttributePayload": {},
                     "ThingGroups": [
                         {
                             "Ref": "ThingGroupName"
                         }
                     ],
                     "ThingName": {
                         "Ref": "ThingName"
                     }
                 },
                 "Type": "AWS::IoT::Thing"
             },
             "MyPolicy": {
                 "Properties": {
                     "PolicyName": "my_iotthingpolicy"
                 },
                 "Type": "AWS::IoT::Policy"
             },
             "MyCertificate": {
                 "Properties": {
                     "CertificateId": {
                         "Ref": "AWS::IoT::Certificate::Id"
                     },
                     "Status": "Active"
                 },
                 "Type": "AWS::IoT::Certificate"
             }
         }
     }
    
  5. Commit the information contained in the document above to the cloud. Because of the line breaks in the following syntax it may be best to compose these commands in a text editor on your workstation, then copy them to the command line.

    • Replace the –template-name, this could be my_fleetprovisioningtemplate
    • (Optional) Edit the –description
    • Replace the –provisioning-role-arn with the ARN of your fleet provisioning role which was created in step 2 of the “Create a Fleet Provisioning Template” section. This ARN is located under IAM > Roles > the name provided for this fleet provisioning role, in the ARN pane.
     aws iot create-provisioning-template \
         --template-name my_fleetprovisioningtemplate \
         --description "A provisioning template for Greengrass core devices." \
         --provisioning-role-arn "arn:aws:iam::123456789012:role/my_fleetprovisioningrole" \
         --template-body file://my_fleetprovisioningtemplate.json \
         --enabled
    

Create Claim Certificate

These are the keys that will allow devices to register securely as AWS IoT things. These claim certificates utilize X.509 cryptography. Claim certificates should always be secured.

In this step we create a claim certificate we push down to the device using EdgeIQ. The device uses this certificate to communicate with AWS for provisioning, in the fleet provisioning process a unique device certificate is generated.

  1. Create a folder to contain the Claim Certificates.

     mkdir claim-certs
    

    Execute the following command:

     aws iot create-keys-and-certificate \
         --certificate-pem-outfile "claim-certs/claim.pem.crt" \
         --public-key-outfile "claim-certs/claim.public.pem.key" \
         --private-key-outfile "claim-certs/claim.private.pem.key" \
         --set-as-active
    

    Copy the output generated by this command to a text document on your workstation. The ARN provided in this output will be required for the final step of this section. The “claim-certs” folder now contains your claim certificates.

  2. Create a file that contains the AWS IoT provisioning claim policy.

     nano my_provisioningclaimiotpolicy.json
    

    In the text below replace the following items in the Resource arrays with the appropreate arguments.

    • region - Region is the region you’re using. This information is located in the upper right of the AWS Cloud Shell, for example “us-east-1”.
    • account-id - With AWS Console open click in the upper right corner on your name, a drop down will appear with an Account ID number. The account ID is this number WITHOUT the dashes.
    • GreengrassFleetProvisioningTemplate - This is the name of the fleet provisioning template that you created in the previous section without the .json file extension. In our example we used “my_fleetprovisioningtemplate”.
     {
     "Version": "2012-10-17",
     "Statement": [
         {
             "Effect": "Allow",
             "Action": "iot:Connect",
             "Resource": "*"
         },
         {
             "Effect": "Allow",
             "Action": [
                 "iot:Publish",
                 "iot:Receive"
             ],
             "Resource": [
                 "arn:aws:iot:region:account-id:topic/$aws/certificates/create/*",
                 "arn:aws:iot:region:account-id:topic/$aws/provisioning-templates/GreengrassFleetProvisioningTemplate/provision/*"
             ]
         },
         {
             "Effect": "Allow",
             "Action": "iot:Subscribe",
             "Resource": [
                 "arn:aws:iot:region:account-id:topicfilter/$aws/certificates/create/*",
                 "arn:aws:iot:region:account-id:topicfilter/$aws/provisioning-templates/GreengrassFleetProvisioningTemplate/provision/*"
             ]
         }
     ]
     }
    
  3. Create a policy from the document.

     aws iot create-policy --policy-name my_provisioningclaimpolicy --policy-document file://my_provisioningclaimiotpolicy.json
    

    The response from this command will reflect the data entered.

  4. Attach the policy to the provisioning claim certificate using the ARN we saved to a document in step 1 of this section.

     aws iot attach-policy --policy-name my_provisioningclaimpolicy --target arn:aws:iot:us-west-2:123456789012:cert/aa0b7958770878eabe251d8a7ddd547f4889c524c9b574ab9fbf65f32248b1d4
    

    There will be no output if this request succeeds.

Fleet provisioning is now configured!

Copy the claim certificates from the cloud to your desktop

cd claim-certs
tar -czf resources.tar.gz claim.pem.crt claim.private.pem.key claim.public.pem.key 
pwd

Select Actions (top right), “Download File” provide the path and filename.