如何允许 VPC 内的 Lambda 函数在 AWS 中 VPC 外的 IoT-Core MQTT Broker 中发布?
How to allow a Lambda Function inside a VPC to Publish in the IoT-Core MQTT Broker outside the VPC in AWS?
场景 1:我有以下带有 lambda 的架构,它可以在 MQTT 代理 (IoT-Core) 中侦听事件 (1)
并且可以检索数据并将其保存在 RDS 中 (2)
。 RDS 和 Lambda 都在同一个 VPC 中。这里的问题是 lambda 无法在 Broker 中返回 (3)
交易结果。
场景 2:我有相同的 lambda,但它在 RDS VPC 之外。在此配置中,lambda 可以侦听 MQTT 代理 (IoT-Core) 内的事件 (1)
并发布回 (3)
。问题是 lambda 无法在 RDS (2)
中保存数据。
我想允许 lambda 在 场景 1 中的 MQTT 代理中发布。事实上,我不知道为什么 lambda 可能被代理中的事件触发但不允许发布回来如果 VPC 也无法收听的原因。
如何允许 lambda 在 场景 1 中发布?
这是serverless.yml
:
里面的配置
lambdaRSDInsert:
name: ${self:provider.stage}-${self:custom.fnLambdaRSDInsert}
handler: fnLambdaRSDInsert.fnLambdaRSDInsert
events:
- iot:
name: ${self:custom.fnLambdaRSDInsert}
sql: "SELECT *, topic() AS topic FROM 'company/sys/cmd/fnLambdaRSDInsert/#' "
memorySize: 256
iamRoleStatementsName: ${self:provider.stage}-${self:custom.fnLambdaRSDInsert}-iamFnLambdaRSDInsert
iamRoleStatements:
- Effect: 'Allow'
Action:
- 'rds:*'
Resource: 'arn:aws:rds:${self:provider.region}:xxxxxxx:db:${file(env.yml):rdsMySqlCluster-${self:provider.stage}}'
- Effect: 'Allow'
Action:
- 'logs:CreateLogGroup'
- 'logs:CreateLogStream'
- 'logs:PutLogEvents'
- 'ec2:CreateNetworkInterface'
- 'ec2:DescribeNetworkInterfaces'
- 'ec2:DeleteNetworkInterfaces'
Resource: "*"
- Effect: "Allow"
Action:
- "iot:*"
Resource: '*'
vpc: ${file(env.yml):vpc-${self:provider.stage}}
environment:
rdsMySqlDb: ${file(env.yml):rdsMySqlDb-${self:provider.stage}}
rdsMySqlHost: ${file(env.yml):rdsMySqlHost-${self:provider.stage}}
rdsMySqlUsername: ${file(env.yml):rdsMySqlUsername-${self:provider.stage}}
rdsMySqlPassword: ${file(env.yml):rdsMySqlPassword-${self:provider.stage}}
MQTT_ENDPOINT: '${file(env.yml):mqttEndPoint}${self:provider.region}.amazonaws.com'
您需要通过添加互联网网关将子网配置为在 VPC 仪表板中访问互联网。需要将网关添加到安全组,您可以在其中配置允许的 IP 和端口。
之后您需要创建一个弹性 IP,您需要在其中添加在子网关联期间创建的网络接口到 Lambda 函数(它们可以在 EC2 中找到)
我遵循了这两个指南:
https://aws.amazon.com/premiumsupport/knowledge-center/internet-access-lambda-function/
https://docs.aws.amazon.com/vpc/latest/userguide/VPC_Internet_Gateway.html
场景 1:我有以下带有 lambda 的架构,它可以在 MQTT 代理 (IoT-Core) 中侦听事件 (1)
并且可以检索数据并将其保存在 RDS 中 (2)
。 RDS 和 Lambda 都在同一个 VPC 中。这里的问题是 lambda 无法在 Broker 中返回 (3)
交易结果。
场景 2:我有相同的 lambda,但它在 RDS VPC 之外。在此配置中,lambda 可以侦听 MQTT 代理 (IoT-Core) 内的事件 (1)
并发布回 (3)
。问题是 lambda 无法在 RDS (2)
中保存数据。
我想允许 lambda 在 场景 1 中的 MQTT 代理中发布。事实上,我不知道为什么 lambda 可能被代理中的事件触发但不允许发布回来如果 VPC 也无法收听的原因。
如何允许 lambda 在 场景 1 中发布?
这是serverless.yml
:
lambdaRSDInsert:
name: ${self:provider.stage}-${self:custom.fnLambdaRSDInsert}
handler: fnLambdaRSDInsert.fnLambdaRSDInsert
events:
- iot:
name: ${self:custom.fnLambdaRSDInsert}
sql: "SELECT *, topic() AS topic FROM 'company/sys/cmd/fnLambdaRSDInsert/#' "
memorySize: 256
iamRoleStatementsName: ${self:provider.stage}-${self:custom.fnLambdaRSDInsert}-iamFnLambdaRSDInsert
iamRoleStatements:
- Effect: 'Allow'
Action:
- 'rds:*'
Resource: 'arn:aws:rds:${self:provider.region}:xxxxxxx:db:${file(env.yml):rdsMySqlCluster-${self:provider.stage}}'
- Effect: 'Allow'
Action:
- 'logs:CreateLogGroup'
- 'logs:CreateLogStream'
- 'logs:PutLogEvents'
- 'ec2:CreateNetworkInterface'
- 'ec2:DescribeNetworkInterfaces'
- 'ec2:DeleteNetworkInterfaces'
Resource: "*"
- Effect: "Allow"
Action:
- "iot:*"
Resource: '*'
vpc: ${file(env.yml):vpc-${self:provider.stage}}
environment:
rdsMySqlDb: ${file(env.yml):rdsMySqlDb-${self:provider.stage}}
rdsMySqlHost: ${file(env.yml):rdsMySqlHost-${self:provider.stage}}
rdsMySqlUsername: ${file(env.yml):rdsMySqlUsername-${self:provider.stage}}
rdsMySqlPassword: ${file(env.yml):rdsMySqlPassword-${self:provider.stage}}
MQTT_ENDPOINT: '${file(env.yml):mqttEndPoint}${self:provider.region}.amazonaws.com'
您需要通过添加互联网网关将子网配置为在 VPC 仪表板中访问互联网。需要将网关添加到安全组,您可以在其中配置允许的 IP 和端口。
之后您需要创建一个弹性 IP,您需要在其中添加在子网关联期间创建的网络接口到 Lambda 函数(它们可以在 EC2 中找到)
我遵循了这两个指南: https://aws.amazon.com/premiumsupport/knowledge-center/internet-access-lambda-function/ https://docs.aws.amazon.com/vpc/latest/userguide/VPC_Internet_Gateway.html