Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

aws_iot: Bug in Generated CloudFormation Template when Creating IoT Job Templates #32459

Open
1 task
Adesanya-Toba opened this issue Dec 10, 2024 · 2 comments
Open
1 task
Labels
@aws-cdk/aws-iot Related to AWS IoT bug This issue is a bug. effort/medium Medium work item – several days of effort p2

Comments

@Adesanya-Toba
Copy link

Describe the bug

I tried adding IoT Job Templates to my CDK code but I get the following errors when using the code snippets from the doc.

Regression Issue

  • Select this option if this issue appears to be a regression.

Last Known Working CDK Version

No response

Expected Behavior

A new job template is created in IoT Core.

Current Behavior

I get the following error (The ******* is me hiding confidential stuff):

Failed resources:
IoTProvisioningStack | 11:38:08 AM | CREATE_FAILED        | AWS::IoT::JobTemplate   | DeviceProvisioning/JobTemplate******* (DeviceProvisioningJobTemplate******* ) Properties validation failed for resource DeviceProvisioningJobTemplate*******  with message:
#/PresignedUrlConfig: required key [RoleArn] not found
#/PresignedUrlConfig: extraneous key [expiresInSec] is not permitted
#/PresignedUrlConfig: extraneous key [roleArn] is not permitted
❌  IoTProvisioningStack failed: Error: The stack named IoTProvisioningStack failed to deploy: UPDATE_ROLLBACK_COMPLETE: Properties validation failed for resource DeviceProvisioningJobTemplate****** with message:
#/PresignedUrlConfig: required key [RoleArn] not found
#/PresignedUrlConfig: extraneous key [expiresInSec] is not permitted
#/PresignedUrlConfig: extraneous key [roleArn] is not permitted

Reproduction Steps

Try out this code snippet in a Construct class!

from aws_cdk import (
    aws_iot as iot,
    aws_iam as iam,
)

def create_job_template(self, name: str, description: str):
  pre_signed_role = iam.Role(
              self,
              id=f"Role-{name}",
              assumed_by=iam.ServicePrincipal(IOT_SERVICE_PRINCIPAL).grant_principal,
              description="IAM Role to create pre-signed S3 URL for job payload.",
          )
  
  
  iot.CfnJobTemplate(
              self,
              id=f"JobTemplate-{name}",
              description=description,
              job_template_id="xxxx",
              document="",
              presigned_url_config=iot.CfnJobTemplate.PresignedUrlConfigProperty(
                  role_arn=pre_signed_role.role_arn,
                  expires_in_sec=300,
              ),
          )

Possible Solution

Manually update this bit of the generated Cloudformation template, as the CF docs refer to roleArn as RoleArn. Please note that expires_in_sec has the same issue.

"PresignedUrlConfig": {
     "roleArn": {
      "Fn::GetAtt": [
       "DeviceProvisioningRole*****",
       "Arn"
      ]
     }
    }

Additional Information/Context

No response

CDK CLI Version

2.172.0 (build 0f666c5)

Framework Version

No response

Node.js Version

v20.14.0

OS

Ubuntu 22.04.5 LTS

Language

Python

Language Version

Python (3.10.12)

Other information

No response

@Adesanya-Toba Adesanya-Toba added bug This issue is a bug. needs-triage This issue or PR still needs to be triaged. labels Dec 10, 2024
@github-actions github-actions bot added the @aws-cdk/aws-iot Related to AWS IoT label Dec 10, 2024
@ashishdhingra ashishdhingra self-assigned this Dec 10, 2024
@ashishdhingra ashishdhingra added p2 needs-reproduction This issue needs reproduction. and removed needs-triage This issue or PR still needs to be triaged. labels Dec 10, 2024
@ashishdhingra
Copy link
Contributor

ashishdhingra commented Dec 10, 2024

Reproducible using CDK version 2.172.0 (build 0f666c5). Below code (in TypeScript):

import * as cdk from 'aws-cdk-lib';
import * as iot from 'aws-cdk-lib/aws-iot';
import * as iam from 'aws-cdk-lib/aws-iam';

export class CdktestStackNew extends cdk.Stack {
  constructor(scope: cdk.App, id: string, props?: cdk.StackProps) {
    super(scope, id, props);

    const presignedRole = new iam.Role(this, 'TestIotRole', {
      assumedBy: new iam.ServicePrincipal('iot.amazonaws.com'),
      description: 'IAM Role to create pre-signed S3 URL for job payload.',
    });

    new iot.CfnJobTemplate(this, 'TestIotJobTemplate', {
      description: 'Test IoT job Template',
      jobTemplateId: 'test-iot-job-template',
      document: '',
      presignedUrlConfig: {
        roleArn: presignedRole.roleArn,
        expiresInSec: 300
      }
    });
  }
}

synthesizes to below CloudFormation template:

Resources:
  TestIotRoleBD9EE0EE:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Statement:
          - Action: sts:AssumeRole
            Effect: Allow
            Principal:
              Service: iot.amazonaws.com
        Version: "2012-10-17"
      Description: IAM Role to create pre-signed S3 URL for job payload.
    Metadata:
      aws:cdk:path: CdktestStackNew/TestIotRole/Resource
  TestIotJobTemplate:
    Type: AWS::IoT::JobTemplate
    Properties:
      Description: Test IoT job Template
      Document: ""
      JobTemplateId: test-iot-job-template
      PresignedUrlConfig:
        roleArn:
          Fn::GetAtt:
            - TestIotRoleBD9EE0EE
            - Arn
        expiresInSec: 300
    Metadata:
      aws:cdk:path: CdktestStackNew/TestIotJobTemplate
  CDKMetadata:
    Type: AWS::CDK::Metadata
    Properties:
      Analytics: v2:deflate64:H4sIAAAAAAAA/y3KsQ6CMBCA4Wdhb09oTHRnc6zsppQjOWh7hisyNH13Y3D6/uE30N0MtI07RPtp1YFGKM/s/KrcIa9CLkKxHFD1c/pZFXGGfk4PHgeM7+AyVmVReN/8ef27qsQTwiKXT3cH08K1WYRIb3vKFBHs6RcL0ovBggAAAA==
    Metadata:
      aws:cdk:path: CdktestStackNew/CDKMetadata/Default
Parameters:
  BootstrapVersion:
    Type: AWS::SSM::Parameter::Value<String>
    Default: /cdk-bootstrap/hnb659fds/version
    Description: Version of the CDK Bootstrap resources in this environment, automatically retrieved from SSM Parameter Store. [cdk:skip]

The PresignedUrlConfig > roleArn and expiresInSec starts with lowercase character.

Few Findings:

  • AWS::IoT::JobTemplate PresignedUrlConfig defines properties ExpiresInSec and RoleArn, with 1st letter capitalized per convention.
  • CloudFormationSchema > aws-iot-jobtemplate.json also defines properties ExpiresInSec and RoleArn, with 1st letter capitalized.
  • Visual Studio Code doesn't show Intellisense while defining properties for presignedUrlConfig in above CDK code. So, it could be the case that bindings for presignedUrlConfig in CDK aws-iot package might be broken.
    • The type of presignedUrlConfig? is any in decompiled code.

@Adesanya-Toba Please defines properties ExpiresInSec and RoleArn with 1st letter in upper case as expected by CloudFormation as a workaround.

@ashishdhingra ashishdhingra added effort/medium Medium work item – several days of effort and removed needs-reproduction This issue needs reproduction. labels Dec 10, 2024
@ashishdhingra
Copy link
Contributor

Related issue #32258 (comment).

Also refer #32285 for the reasoning behind it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
@aws-cdk/aws-iot Related to AWS IoT bug This issue is a bug. effort/medium Medium work item – several days of effort p2
Projects
None yet
Development

No branches or pull requests

2 participants