## Creating a thing programatically using AWS Lambda Here are the steps to follow to create a AWS IoT thing programatically: * Create a IAM Role that has access to IoT services. * Assign the role to our Lambda function. * Write the Lambda function ### Creating an IAM Role To create a IoT thing programatically, first we will need an IAM role, that can act on our behalf and has appropriate permissions. We can do that by following these steps: * First, we go into IAM Management Console, by searching for IAM in the services bar. * Then we go into **Roles** under **Access management** in the left side pane. * Under **Select type of trusted entity**, we have to select for what/whom we are creating a role for. For now, we want to create Lambda functions that can access our IoT service. So we will select AWS Service as trusted entry and under **Choose a use case** we will select **Lambda** and click **Next**. * Now we have to give appropriate permissions to our role. We want our Lambda fanction to create things in IoT, so we will give our Lambda function full access to IoT. To do this, type **iot** in the search box, and choose **AWSIoTFullAccess** from the results and click **Next**. This will give the Lambda function, we assign this role to full access to our AWS IoT services. * We don't want to add any tags to our role for now, so we click **Next**. * On the next page, we have to review the role to be created and give it a name. We will name it *IoTPowerUser* for now. ### Attaching role to lambda function Now we have to create a Lambda function with the assigned role. * To do this, first we head over to AWS Lambda and create a new function. * Under basic information, we give a name to our function and choose Python from the Runtime and x86_64 as architecture. * Now under **Change default execution role** we click **Use an existing role** and from the drop-down menu below it, we choose the role we created in the above step, i.e. *IoTPowerUser*, and click create function. * Now our Lambda function has full access to our IoT resources and we can use the Boto3 python module to do what we want. ### Code The following code uses the Boto3 module to create a thing and attach a policy to it. The name of the thing to be created and the name of the policy to be attached is considered to be passed along with the event. ```python import json import boto3 iot = boto3.client('iot') def lambda_handler(event, context): name = event['thingName'] policy_name = event['policyName'] # Create thing thing = iot.create_thing(thingName=name) thing_name = thing['thingName'] # Create certificates cert = iot.create_keys_and_certificate(setAsActive=True) cert_name = cert['certificateArn'] cert_pem = cert['certificatePem'] pub_key = cert['keyPair']['PublicKey'] priv_key = cert['keyPair']['PrivateKey'] # Attach policy to certificate iot.attach_policy(policyName=policy_name, target=cert_name) # Attach certificate to thing iot.attach_thing_principal(thingName=thing_name, principal=cert_name) return { 'statusCode': 200, 'body': json.dumps({ 'pubKey': pub_key, 'privKey': priv_key, 'deviceCert': cert_pem }) } ``` We can test this lambda function by creating a test event like this: ```json { "thingName": "first_thing", "policyName": "policy123", } ``` After the test event is run, we can check our AWS IoT things section and we will notice a thing named *first_thing* has been created along with the certificates. However, this assumes that a policy name *palicy123* alredy exists. This program will throw an error if the policy does not exits. ## Creating Cognito User Pool and authenticating Users (Python) ### Creating cognito user pool In this section we will create a AWS Cognito user pool and build a simple Python application to add user and authenticate them. * First we need an user pool to work with. To set it up, we first go to the Cognito console by searching Cognito in AWS Console homepage. * Next we click on **Manage User Pools** and then **Create a user pool**. * In the first page, we give the user pool a name, and then click on **Review defaults**. This will create an user pool which requires users to sign up using e-mail which will be verified with a code sent to the e-mail. * We also want to add an app client to authenticate from our python app. So we will click on **Add app client**, in the second to last section, and then **Add an app client**, give it a name and click on **Create app client**. * Now we can create the pool by clicking on **Create pool**. ### Authenticating with the pool To connect with the user pool we will use Boto3 SDK for python. To use Boto3 in our local machine we will need `access_key_id` and `secret_access_key` stored in `~/.aws/credentials` which will be used by Boto3 to authorize the connection. These keys are formed only when creating the IAM user. Here is the format of how it should look: ``` [default] aws_access_key_id = <access-key> aws_secret_access_key = <secret-access-key> ``` More info on how to configure Boto3 [here](https://boto3.amazonaws.com/v1/documentation/api/latest/guide/credentials.html). We will alse also need app client id which we can get by clicking on the user pool in **Manage user pools** section of AWS Cognito, and then clicking on **App clients** under **General Settings**. #### Code ```python # Import boto3 import boto3 client_id = '<insert-client-id>' username = 'abcdefghei@something.com' password = '@_$TR1nG' # Create client for our cognito identity provider client = boto3.client('cognito-idp') # Sign up the user client.sign_up(ClientId=client_id, Username=username, Password=password) # The above command will send a verification code to the e-mail specified in # username section. After we get the code we can do the following verify_code = '<put-code-here>' client.confirm_sign_up(ClientId=client_id, Username=username, ConfirmationCode=verify_code) # Now the user will be confirmed and can be logged in. ```