## 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.
```