我正在尝试使用 API Gateway、Lambda(Go 中)和 RDS 设置一个简单的 API。我已经让 API 网关和 lambda 函数正常通信,但是我不知道如何从 Go 代码内部访问我的数据库。我正在使用 Terraform 创建基础设施。
这是我的 RDS 设置(硬编码的用户名和密码只是为了本文的简单起见):
resource "aws_db_instance" "bl-db" {
allocated_storage = 5 # gigabytes
engine = "postgres"
engine_version = "16.4"
identifier = "main"
instance_class = "db.t3.micro"
username = "myname"
password = "mypassword"
publicly_accessible = false
}
这是我的 lambda IAM 角色:
resource "aws_iam_role" "hello" {
name = "hello"
assume_role_policy = <<POLICY
{
"Version": "2012-10-17",
"Statement": {
"Action": "sts:AssumeRole",
"Principal": {
"Service": "lambda.amazonaws.com"
},
"Effect": "Allow"
}
}
POLICY
}
对于我的 lambda 代码,这就是我目前所拥有的,但我假设我还很遥远。
package main
import (
"fmt"
"net/http"
"log"
"github.com/aws/aws-lambda-go/events"
"github.com/aws/aws-lambda-go/lambda"
"github.com/jmoiron/sqlx"
_ "github.com/lib/pq"
)
// The input type and the output type are defined by the API Gateway.
func handleRequest(req events.APIGatewayProxyRequest) (events.APIGatewayProxyResponse, error) {
db, err := sqlx.Connect("postgres", "user=postgres dbname=main sslmode=disable password=mypassword host=myhost")
if err != nil {
log.Fatalln(err)
}
defer db.Close()
// Test the connection to the database
if err := db.Ping(); err != nil {
log.Fatal(err)
} else {
log.Println("Successfully Connected")
}
db.Queryx("some sql query")
res := events.APIGatewayProxyResponse{
StatusCode: http.StatusOK,
Headers: map[string]string{"Content-Type": "text/plain; charset=utf-8"},
Body: fmt.Sprintf("Hello!\n"),
}
return res, nil
}
func main() {
lambda.Start(handleRequest)
}
由于您的 RDS 实例不可公开访问
(publicly_accessible = false)
,您的 Lambda 函数需要与 RDS 实例位于同一 VPC 中。 resource "aws_lambda_function" "my_lambda" {
function_name = "my_lambda"
role = aws_iam_role.hello.arn
handler = "main"
runtime = "go1.x"
filename = "main.zip"
vpc_config {
subnet_ids = ["subnet-12345678"] # replace with your subnet IDs
security_group_ids = ["sg-12345678"] # replace with your security group IDs
}
}
db, err := sqlx.Connect("postgres", "host=<RDS-ENDPOINT> port=5432 user=myname dbname=main password=mypassword sslmode=disable")
package main
import (
"fmt"
"log"
"net/http"
"github.com/aws/aws-lambda-go/events"
"github.com/aws/aws-lambda-go/lambda"
"github.com/jmoiron/sqlx"
_ "github.com/lib/pq"
)
func handleRequest(req events.APIGatewayProxyRequest) (events.APIGatewayProxyResponse, error) {
db, err := sqlx.Connect("postgres", "host=<RDS-ENDPOINT> port=5432 user=myname dbname=main password=mypassword sslmode=disable")
if err != nil {
log.Fatalln("Error connecting to the database:", err)
}
defer db.Close()
if err := db.Ping(); err != nil {
log.Fatal("Error pinging the database:", err)
} else {
log.Println("Successfully Connected to the database")
}
rows, err := db.Queryx("SELECT * FROM your_table_name")
if err != nil {
log.Fatal("Error executing query:", err)
}
defer rows.Close()
res := events.APIGatewayProxyResponse{
StatusCode: http.StatusOK,
Headers: map[string]string{"Content-Type": "text/plain; charset=utf-8"},
Body: fmt.Sprintf("Hello!\n"),
}
return res, nil
}
func main() {
lambda.Start(handleRequest)
}
output "rds_endpoint" {
value = aws_db_instance.bl-db.endpoint
}