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
})
}