简介
当我们的IoT设备使用MQTT协议接入到AWS IoT Core后,它们会实时的上报一些信息,比如一个环境温度传感器会以分钟为单位定时的上报自己周围的环境温度,当一个城市里面数万个温度传感器都进行环境温度的检测时,这些大量的数据就变得非常有价值,我们可以精确的绘制出该城市的市区温度热力图等。
IoT设备对数据的上报是一个必备的基础功能,接下来我们需要高效的将这些设备上报的大量的有价值的数据扭转其他的后端服务上去,比如传送到后端大数据平台做进一步的分析等,才能充分的发挥IoT领域数据的价值。对于这个场景AWS IoT解决方案提供了AWS IoT Core Rule,我们可以通过rule(规则)将消息做一个转发,比如转发到AWS SQS,AWS Lambda等,详情可以看rule actions,这样下游的服务就可以消费转发来的消息了。
参考rule actions,我们以AWS MSK(AWS托管的Kafka)为例来演示,怎么通过AWS IoT Core Rule功能将消息转发到Kafka中去。详细的架构图如下:
集成AWS IoT 与 AWS MSK
本次的演练的AWS MSK是运行在AWS VPC中的并且位于private subnet中,private subnet里面的服务可以通过NAT Gateway访问外部的互联网。
设置AWS IAM Role
让AWS IoT Core执行消息转发的操作,必须指导正确的权限,这里我们是转发到AWS MSK所以我创建了一个AWS IAM role并给了一个自定义的名称PoC_iot_rule_role
,我给这个role附加了2个关键性的policy,其中一个是AWS托管的AWSIoTRuleActions
,例外一个是我们自建的inline policy,名称为iot_rule_inline_kafka
,它专门负责管理AWS IoT Core rule操作AWS MSK相关的权限。
我的iot_rule_inline_kafka
的如下:
你需要将<your-aws-region>
和<your-aws-account-id>
替换为你自己的aws区域和账户id。
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"ec2:CreateNetworkInterface",
"ec2:DescribeNetworkInterfaces",
"ec2:CreateNetworkInterfacePermission",
"ec2:DeleteNetworkInterface",
"ec2:DescribeSubnets",
"ec2:DescribeVpcs",
"ec2:DescribeVpcAttribute",
"ec2:DescribeSecurityGroups"
],
"Resource": "*"
},
{
"Effect": "Allow",
"Action": [
"secretsmanager:GetSecretValue",
"secretsmanager:DescribeSecret"
],
"Resource": [
"arn:aws:secretsmanager:<your-aws-region>:<your-aws-account-id>:secret:kafka_client_truststore-*",
"arn:aws:secretsmanager:<your-aws-region>:<your-aws-account-id>:secret:kafka_keytab-*",
"arn:aws:secretsmanager:<your-aws-region>:<your-aws-account-id>:secret:AmazonMSK_*",
"arn:aws:secretsmanager:<your-aws-region>:<your-aws-account-id>:secret:*",
"arn:aws:secretsmanager:<your-aws-region>:<your-aws-account-id>:AmazonMSK_*"
]
},
{
"Effect": "Allow",
"Action": "ec2:CreateNetworkInterfacePermission",
"Resource": "*",
"Condition": {
"StringEquals": {
"ec2:ResourceTag/VPCDestinationENI": "true"
}
}
},
{
"Effect": "Allow",
"Action": [
"ec2:CreateTags"
],
"Resource": "*",
"Condition": {
"StringEquals": {
"ec2:CreateAction": "CreateNetworkInterface",
"aws:RequestTag/VPCDestinationENI": "true"
}
}
}
]
}
设置AWS KMS和AWS Secrets Manager
我后续搭建的Kafka是使用SCRAM/SASL
授权并开启了数据加密,所以我先需要使用AWS KMS和AWS Secrets Manager,其中AWS Secrets Manager做Kafka的username/password管理,AWS KMS做AWS MSK数据加密和对AWS Secrets Manager数据的加密。
设置AWS KMS
首先,我们打开AWS KMS控制台,请注意选择自己的服务区。
这是我的AWS KMS控制台
我们点击Customer managed keys,创建自己管理的key
选择symmetric key,按照我画红色方框的部分来设置,其他的默认,直接Next
填写下描述,然后Next
这里的Key administrators暂时先别写,全部用默认设置即可,直接Next
这里Define key usage permissions也是,使用默认设置,直接Next
接着我们直接创建KMS
创建完后我们可以看到自己的KMS Key,如红色方框部分
关联AWS IAM Role和AWS KMS
设置AWS Secrets Manager
我们接着打开AWS Secrets Manager,为AWS MSK提前设置好密码。
这是我的界面,我们直接创建
接下来选择Other type of secret
填入自己的username/password并选择使用上一步创建的KMS key,名称为kms-2022,然后点击Next
我们填入名字和描述,其中名字必须以AmazonMSK_
开头
其余的保持默认配置
创建好后的样子如下
设置AWS MSK
前面创建好了AWS KMS和AWS Secrets Manager后,我们接着创建AWS MSK
这是我的界面,我们直接创建
我们选择Custom create并给一个名称
我们选择Provisioned类型,版本我选择kafka 3.2.0
为了节约成本,我选择使用t3.small实例并设置数量为2
设置Number of brokers per zone=1,Storage=100G
其余的保持默认
我们接着指定AWS MSK的网络,这里我选择了一个VPC,并选择了First Zone位于us-east-1a可用区中的private subnet里面。
我们接着为自己的Second zone选择位于us-east-1b的private subnet里面。
通过将MSK分布在不同的可用区,可以显著的提升MSK的可用性。
我们接着为自己的MSK设置安全组
安全组的规则为
接下来我们选择MSK使用SASL/SCRAM
认证
接下来我们使用前面创建的KMS Key,名称为kms-2022
其余的保持默认配置,直接创建,等待15min左右就会创建完成。
AWS MSK关联AWS Secrets Manager
当我们的MSK创建完成后,需要继续关联AWS Secrets Manager
当AWS MSK创建完成后,进入到详情页会看到一个提示,我们直接将这个MSK和前面创建好的AWS Secrets Manager关联
效果如下
设置AWS IoT Core
设置destination
我们到AWS IoT Core的控制界面
然后创建destination
选择VPC,子网,安全组和AWS IAM Role。其中VPC,子网,安全组建议和MSK的保持一致,AWS IAM Role是前面我们已经创建过的PoC_iot_rule_role
然后直接创建,效果如下
设置rule
我们最后来创建rule
直接点击创建
接着填入rule的名称
然后编写自己的rule语句
选择action为AWS MSK
选择VPC并给一个kafka topic
将AWS MSK的Private endpoint填入AWS IoT core的bootstrap.servers中
SSL和SASL设置如下
为AWS IoT Core rule填入username/password,其中这些消息是从AWS Secrets Manager获取的。
我这里填入的字符如下,其中AmazonMSK_iot_rule
为前面创建的Secret的名称,arn:aws:iam::843xxx41269:role/PoC_iot_rule_role
是role的ARN
username: ${get_secret('AmazonMSK_iot_rule', 'SecretString', 'username', 'arn:aws:iam::843xxx41269:role/PoC_iot_rule_role')}
password: ${get_secret('AmazonMSK_iot_rule', 'SecretString', 'password', 'arn:aws:iam::843xxx41269:role/PoC_iot_rule_role')}
然后保存即可
调试与检查
我们接着可以使用一台AWS EC2,SSH远程连接到EC2,并使用EC2订阅AWS MSK,查看里面的消息是否由AWS IoT core转发到了AWS MSk,详情可以参考How to integrate AWS IoT Core with Amazon MSK中Testing the AWS IoT rule章节
生产者:
消费者: