Contents

How to create an IoT Thing Group using CDK?

How to create an IoT Thing Group using CDK?

By default, we can not manage IoT Thing Groups using AWS Cloud Development Kit (CDK). CDK deploys infrastructure using CloudFormation and CloudFormation does not support Thing Groups.

Today I want to share an elegant solution for this challenge.

CDK Constructor

I propose to create a custom CDK Constructor. Constructor represents a specific resource and enables the management of the corresponding AWS infrastructure. This way we can encapsulate complex logic with easy to use abstraction.

Please check the AWS documentation for additional information.

How Constructor manages infrastructure not supported by the CloudFormation?

Under the hood, CDK creates an AWS Lambda-backed custom resource that calls AWS APIs directly.

Custom Resources are often used in the CloudFormation templates. In my opinion, CDK encapsulates them in a very elegant way.

Let’s start by defining how we would like to manage the IoT Thing Group using CDK App.

I propose the following approach:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
class IotStack(Stack):

    def __init__(self, scope: Construct, construct_id: str, **kwargs) -> None:
        super().__init__(scope, construct_id, **kwargs)

        # create, update, delete operations
        thing_group = ThingGroup(self,"ThingGroup",
            name = "thing-group-0001"
        )
        
        # accessing the Name of our IoT Thing Group
        CfnOutput(self, "ThingGroup Name", value = thing_group.name)

        # accessing the ARN of our IoT Thing Group
        CfnOutput(self, "ThingGroup ARN", value=thing_group.arn)

That looks good, but how can we implement this Constructor?

Implementation

This is a sample implementation of a CDK Constructor that enables the management of IoT Thing Groups.

We implemented different AWS API calls for on_update and on_delete actions.
Additionally, we exposed the ARN (Amazon Resource Name) of the managed resource, so we can use it in our CDK App.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
from constructs import Construct
from aws_cdk import (
    custom_resources as cr,
)

class ThingGroup(Construct):
    '''
    ThingGroup Constructor based on AWS Custom Resource and AWS SDK Calls
    https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/Iot.html
    '''
    name: str
    '''
    ThingGroup name
    '''
    arn: str
    '''
    ThingGroup Arn
    '''

    def __init__(self, scope: Construct, id: str, name: str, **kwargs) -> None:
        '''
        :param scope: - scope in which this resource is defined.
        :param id: - scoped id of the resource.
        :param name: ThingGroup name. 
        '''
        super().__init__(scope, id, **kwargs)

        self.name = name
        thing_group = cr.AwsCustomResource(self, "GetParameter",
            on_update = cr.AwsSdkCall( # will also be called for the CREATE event
                service = "Iot",
                action = "createThingGroup",
                parameters = {
                    "thingGroupName": name,
                },
                physical_resource_id = cr.PhysicalResourceId.of(name)
            ),
            on_delete = cr.AwsSdkCall(
                service = "Iot",
                action = "deleteThingGroup",
                parameters = {
                    "thingGroupName": name,
                },
                physical_resource_id = cr.PhysicalResourceId.of(name)
            ),
            policy = cr.AwsCustomResourcePolicy.from_sdk_calls(
                resources = cr.AwsCustomResourcePolicy.ANY_RESOURCE
            ),
        )
        
        # expose the ARN of the managed resource
        self.arn = thing_group.get_response_field("thingGroupArn")

CDK Deployment

To create our IoT Thing Group, we need to deploy this CDK App:

1
cdk deploy

During deployment, we can review changes to be introduced in our infrastructure.

CDK Changes
CDK Changes

As you can see, CDK will create an IAM Policy that allows for the iot:CreateThingGroup and iot:DeleteThingGroup actions.

That IAM Policy will be used by a Lambda function to manage our resources (the IoT Thing Group in this case).

Deployment review

After a few seconds, our stack will be created. We can confirm that the Name and `ARN`` of our IoT Thing Group are accessible from the CDK App.
That is very convenient especially when one team implements Constructors and some other team uses those Constructors to deploy AWS infrastructure.

CDK Output
CDK Output

Let’s check our IoT Thing Group in the AWS Console:

AWS Console
AWS Console

Once we are in the AWS Console, we can check the CloudFormation stack created by our CDK App:

CloudFormation Stack
CloudFormation Stack

There is no IoT Thing Group resource, only the Custom Resource that represents the CDK Constructor we created.

Summary

This way we created an IoT Thing Group (a resource that is not supported by CDK/CloudFormation) using our CDK App.

It is just a simple example that shows how can we encapsulate complex logic and low-level AWS API calls using easy to use high-level object - a CDK Constructor.

Support quality content❤️ Donate💰

Sign up for news: (by subscribing you accept the privacy policy)