无法从VPC中的Lambda连接到AWS Keyspace

时间:2020-09-21 17:50:16

标签: amazon-web-services terraform terraform-provider-aws amazon-keyspaces

我已按照here的说明进行操作,并创建了我认为需要使用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
    ]
  }
}

我在这里做什么错了?

1 个答案:

答案 0 :(得分:0)

问题是Lambda代码中的SSL配置。

调用SetHostNameResolver很重要,但显然只有在VPC内部时才调用:

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