constructor()

in deployment/custom-deployment/lib/smart-product-telemetry.ts [27:154]


  constructor(parent: cdk.Construct, name: string, props: SmartProductTelemetryProps) {
    super(parent, name);

    //=============================================================================================
    // Resources
    //=============================================================================================
    const smartProductTelemetryChannel = new iotAnalytics.CfnChannel(this, 'Channel', {
      channelName: 'smartproduct_channel'
    })

    const smartProductTelemetryRole = new iam.Role(this, 'SmartProductTelemetryRole', {
      assumedBy: new iam.ServicePrincipal('iot.amazonaws.com')
    });
    new iot.CfnTopicRule(this, 'StorageRule', {
      ruleName: 'SmartProductTelemetryRule',
      topicRulePayload: {
        actions: [{
          iotAnalytics: {
            channelName: `${smartProductTelemetryChannel.ref}`,
            roleArn: `${smartProductTelemetryRole.roleArn}`
          }
        }],
        description: 'Persistent storage of smart product telemetry data',
        ruleDisabled: false,
        sql: `select * from '${props.telemetryTopic}/#'`
      }
    });

    const smartProductLambdaRole = new iam.Role(this, 'LambdaRole', {
      assumedBy: new iam.ServicePrincipal('lambda.amazonaws.com')
    });
    const smartProductTelemetryService = new lambda.CfnFunction(this, 'Service', {
      functionName: generateName(`${name}-service`, 64),
      description: "Smart Product Solution telemetry microservice",
      code: {
        s3Bucket: process.env.BUILD_OUTPUT_BUCKET,
        s3Key: `smart-product-solution/${props.solutionVersion}/smart-product-telemetry-service.zip`
      },
      handler: 'index.handler',
      runtime: 'nodejs12.x',
      role: smartProductLambdaRole.roleArn,
      timeout: 60,
      memorySize: 256
    });

    const smartProductTelemetryDatastore = new iotAnalytics.CfnDatastore(this, 'DataStore', {
      datastoreName: 'smartproduct_datastore'
    })

    const smartProductTelemetryPipeline = new iotAnalytics.CfnPipeline(this, 'Pipeline', {
      pipelineName: 'smartproduct_pipeline',
      pipelineActivities: [{
        channel: {
          name: "SmartProductChannelActivity",
          channelName: smartProductTelemetryChannel.ref,
          next: "SmartProductLambdaActivity"
        },
        lambda: {
          name: "SmartProductLambdaActivity",
          lambdaName: smartProductTelemetryService.ref,
          batchSize: 10,
          next: "SmartProductDatastoreActivity"
        },
        datastore: {
          name: "SmartProductDatastoreActivity",
          datastoreName: smartProductTelemetryDatastore.ref
        }
      }]
    });

    new iotAnalytics.CfnDataset(this, 'Dataset', {
      datasetName: 'smartproduct_dataset',
      actions:
        [
          {
            actionName: "SmartProductSqlAction",
            queryAction: {
              sqlQuery: 'select * from ' + smartProductTelemetryDatastore.ref
            }
          }
        ],
      triggers: [{
        schedule: { scheduleExpression: "rate(1 hour)" }
      }]
    });

    //=============================================================================================
    // Permissions and Policies
    //=============================================================================================
    const telemetryPolicy = new iam.Policy(this, 'TelemetryPolicy', {
      statements: [new iam.PolicyStatement({
        actions: [
          'iotanalytics:BatchPutMessage'
        ],
        resources: [`arn:aws:iotanalytics:${cdk.Aws.REGION}:${cdk.Aws.ACCOUNT_ID}:channel/${smartProductTelemetryChannel.ref}`]
      })]
    })
    telemetryPolicy.attachToRole(smartProductTelemetryRole);

    const serviceLogPolicy = new iam.Policy(this, 'serviceLogPolicy', {
      statements: [new iam.PolicyStatement({
        actions: [
          'logs:CreateLogGroup',
          'logs:CreateLogStream',
          'logs:PutLogEvents'
        ],
        resources: [`arn:aws:logs:${cdk.Aws.REGION}:${cdk.Aws.ACCOUNT_ID}:log-group:/aws/lambda/${smartProductTelemetryService.functionName}:*`]
      })]
    })
    const serviceLogPolicyResource = serviceLogPolicy.node.findChild('Resource') as iam.CfnPolicy;
    serviceLogPolicyResource.cfnOptions.metadata = {
      cfn_nag: {
        rules_to_suppress: [{
          id: 'W12',
          reason: `The * resource allows ${smartProductLambdaRole.roleName} to access its own logs.`
        }]
      }
    }
    serviceLogPolicy.attachToRole(smartProductLambdaRole);

    new lambda.CfnPermission(this, 'LambdaInvokeTelemetryPermission', {
      functionName: `${smartProductTelemetryService.attrArn}`,
      action: 'lambda:InvokeFunction',
      principal: 'iotanalytics.amazonaws.com',
      sourceArn: `arn:aws:iotanalytics:${cdk.Aws.REGION}:${cdk.Aws.ACCOUNT_ID}:pipeline/${smartProductTelemetryPipeline.ref}`,
      sourceAccount: cdk.Aws.ACCOUNT_ID
    })
  }