首页 > 解决方案 > 无法从 VPC 中的 Lambda 连接到 AWS Keyspaces

问题描述

我已按照此处的说明使用 Terraform 创建了我认为需要的基础架构。但是,尝试连接时出现此错误:

{
  "errorType": "AggregateException",
  "errorMessage": "One or more errors occurred. (All hosts tried for query failed (tried 172.31.41.121:9142: AuthenticationException 'The remote certificate is invalid according to the validation procedure.'; 172.31.18.20:9142: AuthenticationException 'The remote certificate is invalid according to the validation procedure.'))",
  "stackTrace": [
    "at lambda_method(Closure , Stream , Stream , LambdaContextInternal )"
  ],
  "cause": {
    "errorType": "NoHostAvailableException",
    "errorMessage": "All hosts tried for query failed (tried 172.31.41.121:9142: AuthenticationException 'The remote certificate is invalid according to the validation procedure.'; 172.31.18.20:9142: AuthenticationException 'The remote certificate is invalid according to the validation procedure.')",
    "stackTrace": [
      "at Cassandra.Connections.Control.ControlConnection.Connect(Boolean isInitializing)",
      "at Cassandra.Connections.Control.ControlConnection.InitAsync()",
      "at Cassandra.Tasks.TaskHelper.WaitToCompleteAsync(Task task, Int32 timeout)",
      "at Cassandra.Cluster.Init()",
      "at Cassandra.Cluster.ConnectAsync(String keyspace)"
    ]
  },
  "causes": [
    {
      "errorType": "NoHostAvailableException",
      "errorMessage": "All hosts tried for query failed (tried 172.31.41.121:9142: AuthenticationException 'The remote certificate is invalid according to the validation procedure.'; 172.31.18.20:9142: AuthenticationException 'The remote certificate is invalid according to the validation procedure.')",
      "stackTrace": [
        "at Cassandra.Connections.Control.ControlConnection.Connect(Boolean isInitializing)",
        "at Cassandra.Connections.Control.ControlConnection.InitAsync()",
        "at Cassandra.Tasks.TaskHelper.WaitToCompleteAsync(Task task, Int32 timeout)",
        "at Cassandra.Cluster.Init()",
        "at Cassandra.Cluster.ConnectAsync(String keyspace)"
      ]
    }
  ]
}

我创建了一个aws_vpc_endpoint_service,所以我很惊讶这不起作用。

# Security group for resources that want to access Keyspaces from the VPC
resource "aws_security_group" "keyspaces_endpoint_vpc_access" {
  name   = "keyspaces-endpoint-access"
  vpc_id = aws_default_vpc.default.id
}

resource "aws_security_group" "keyspaces_endpoint" {
  name   = "keyspaces-endpoint"
  vpc_id = aws_default_vpc.default.id

  ingress {
    from_port       = 9142
    to_port         = 9142
    protocol        = "tcp"
    security_groups = [ aws_security_group.keyspaces_endpoint_vpc_access.id ]
  }
}

data "aws_vpc_endpoint_service" "keyspaces" {
  service = "cassandra"
}

resource "aws_vpc_endpoint" "keyspaces_endpoint" {
  vpc_id              = aws_default_vpc.default.id
  vpc_endpoint_type   = "Interface"
  service_name        = data.aws_vpc_endpoint_service.keyspaces.service_name
  security_group_ids  = [ aws_security_group.keyspaces_endpoint.id ]
  private_dns_enabled = true

  subnet_ids = [
    data.aws_subnet.selected.id,
    aws_default_subnet.subnet_a.id,
    aws_default_subnet.subnet_b.id
  ]

  policy  = <<EOF
      {
        "Statement": [
          {
            "Sid": "keyspaces-full-access",
            "Principal": "*",
            "Action": "cassandra:*",
            "Effect": "Allow",
            "Resource": "*"
          }
        ]
      }
    EOF
}

resource "aws_security_group" "my_func" {
  vpc_id      = aws_default_vpc.default.id

  egress {
    from_port   = 0
    to_port     = 65535
    protocol    = "tcp"
    cidr_blocks = [ "0.0.0.0/0" ]
  }

  lifecycle {
    create_before_destroy = true
  }
}

resource "aws_lambda_function" "my_func" {
  runtime          = "dotnetcore3.1"
  timeout          = 900
  memory_size      = 512

  # etc.

  vpc_config {
    subnet_ids         = [ data.aws_subnet.selected.id ]
    security_group_ids = [
      aws_security_group.my_func.id,
      aws_security_group.keyspaces_endpoint_vpc_access.id
    ]
  }
}

我在这里做错了什么?

标签: amazon-web-servicesterraformterraform-provider-awsamazon-keyspaces

解决方案


问题在于 Lambda 代码中的 SSL 配置。

调用 至关重要SetHostNameResolver,但显然仅在 VPC 内部时:

    let sslOptions =
      SSLOptions()
        .SetCertificateCollection(certCollection)
        .SetHostNameResolver (fun _ -> sprintf "cassandra.%s.amazonaws.com" region)

推荐阅读