Amazon web services AWS RDS代理不可用-如何调试?
我已经使用Terraform创建了一个RDS代理。然而,它似乎不起作用 我的应用程序代码无法连接到代理超时,aws rds DESCRIPE db proxy targets提供以下信息: { 目标:[ { 终点:mydb.aaaa.eu-west-2.rds.amazonaws.com, RdsResourceId:mydb, 港口:5432, 类型:RDS\U实例, TargetHealth:{ 状态:不可用, 说明:由于内部错误,DBProxy目标不可用 } } ] } 我如何进行调试 下面是代理的Terraform脚本。RDS实例在别处有描述,但正在工作Amazon web services AWS RDS代理不可用-如何调试?,amazon-web-services,terraform,amazon-rds,amazon-rds-proxy,Amazon Web Services,Terraform,Amazon Rds,Amazon Rds Proxy,我已经使用Terraform创建了一个RDS代理。然而,它似乎不起作用 我的应用程序代码无法连接到代理超时,aws rds DESCRIPE db proxy targets提供以下信息: { 目标:[ { 终点:mydb.aaaa.eu-west-2.rds.amazonaws.com, RdsResourceId:mydb, 港口:5432, 类型:RDS\U实例, TargetHealth:{ 状态:不可用, 说明:由于内部错误,DBProxy目标不可用 } } ] } 我如何进行调试 下
data "aws_subnet" "mydb_rds" {
filter {
name = "availability-zone"
values = [ aws_db_instance.mydb.availability_zone ]
}
}
resource "aws_secretsmanager_secret" "mydb_rds_proxy" {
name = "mydb-rds-proxy"
}
resource "aws_secretsmanager_secret_version" "mydb_rds_proxy" {
secret_id = aws_secretsmanager_secret.mydb_rds_proxy.id
secret_string = var.db_password
}
resource "aws_iam_role" "mydb_rds_proxy" {
name = "mydb-rds-proxy"
assume_role_policy = <<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "",
"Action": "sts:AssumeRole",
"Effect": "Allow",
"Principal": {
"Service": "rds.amazonaws.com"
}
}
]
}
EOF
}
resource "aws_iam_policy" "mydb_rds_proxy_policy" {
name = "mydb-rds-proxy"
policy = <<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "GetSecretValue",
"Action": [
"secretsmanager:GetSecretValue"
],
"Effect": "Allow",
"Resource": [
"${aws_secretsmanager_secret.mydb_rds_proxy.arn}"
]
},
{
"Sid": "DecryptSecretValue",
"Action": [
"kms:Decrypt"
],
"Effect": "Allow",
"Resource": [
"${aws_secretsmanager_secret.mydb_rds_proxy.arn}"
]
}
]
}
EOF
}
resource "aws_iam_role_policy_attachment" "mydb_rds_proxy_policy_attachment" {
role = aws_iam_role.mydb_rds_proxy.name
policy_arn = aws_iam_policy.mydb_rds_proxy_policy.arn
}
resource "aws_db_proxy" "mydb" {
name = "mydb-rds-proxy"
debug_logging = false
engine_family = "POSTGRESQL"
idle_client_timeout = 1800
require_tls = true
role_arn = aws_iam_role.mydb_rds_proxy.arn
vpc_security_group_ids = [ aws_security_group.mydb_rds.id ]
vpc_subnet_ids = [
data.aws_subnet.mydb_rds.id,
aws_default_subnet.subnet_a.id,
aws_default_subnet.subnet_b.id
]
auth {
auth_scheme = "SECRETS"
iam_auth = "DISABLED"
secret_arn = aws_secretsmanager_secret.mydb_rds_proxy.arn
}
}
resource "aws_db_proxy_default_target_group" "mydb" {
db_proxy_name = aws_db_proxy.mydb.name
connection_pool_config {
connection_borrow_timeout = 120
max_connections_percent = 100
max_idle_connections_percent = 50
}
}
resource "aws_db_proxy_target" "mydb" {
db_instance_identifier = aws_db_instance.mydb.id
db_proxy_name = aws_db_proxy.mydb.name
target_group_name = aws_db_proxy_default_target_group.mydb.name
}
locals {
proxied_pg_connection_string = "postgres://${aws_db_instance.mydb.username}:${var.db_password}@${aws_db_proxy.mydb.endpoint}:5432/postgres?client_encoding=UTF8"
}
要使其正常工作,您需要做几件事: 密码中存储的用户名/密码 来自Lambda->RDS代理的安全组规则 来自RDS代理->RDS的安全组规则 同一VPC中的RDS代理、Lambda和RDS RDS代理角色可以访问密钥 一个有用的调试查询是: aws rds描述数据库代理目标-数据库代理名称 要了解它返回的错误消息,请参阅 用户名/密码是最难发现的,因为Terraform还不支持它。您需要做的是在Terraform中构造一个JSON字符串,该字符串与RDS代理可以理解的内容相匹配:
resource "aws_secretsmanager_secret_version" "my_db_proxy" {
secret_id = aws_secretsmanager_secret.my_db_proxy.id
secret_string = jsonencode({
"username" = aws_db_instance.my_db.username
"password" = var.db_password
"engine" = "postgres"
"host" = aws_db_instance.my_db.address
"port" = 5432
"dbInstanceIdentifier" = aws_db_instance.my_db.id
})
}
然后,您需要确保这些安全组规则允许Postgres端口5432上的TCP通信存在:
进入Lambda到RDS代理
进入RDS代理到RDS
出口RDS代理到0.0.0.0/0
RDS代理角色应具有如下策略:
resource "aws_iam_policy" "my_rds_proxy_policy" {
name = "my-rds-proxy"
policy = <<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "",
"Action": [
"rds:*"
],
"Effect": "Allow",
"Resource": [
"${aws_db_instance.my_db.arn}"
]
},
{
"Sid": "GetSecretValue",
"Action": [
"secretsmanager:GetSecretValue"
],
"Effect": "Allow",
"Resource": [
"${aws_secretsmanager_secret.my_rds_proxy.arn}"
]
},
{
"Sid": "DecryptSecretValue",
"Action": [
"kms:Decrypt"
],
"Effect": "Allow",
"Resource": [
"*"
]
},
{
"Sid": "DecryptKms",
"Effect": "Allow",
"Action": "kms:Decrypt",
"Resource": "*",
"Condition": {
"StringEquals": {
"kms:ViaService": "secretsmanager.${var.aws_region}.amazonaws.com"
}
}
}
]
}
EOF
}
祝你好运 要想让它正常工作,您需要做几件事: 密码中存储的用户名/密码 来自Lambda->RDS代理的安全组规则 来自RDS代理->RDS的安全组规则 同一VPC中的RDS代理、Lambda和RDS RDS代理角色可以访问密钥 一个有用的调试查询是: aws rds描述数据库代理目标-数据库代理名称 要了解它返回的错误消息,请参阅 用户名/密码是最难发现的,因为Terraform还不支持它。您需要做的是在Terraform中构造一个JSON字符串,该字符串与RDS代理可以理解的内容相匹配:
resource "aws_secretsmanager_secret_version" "my_db_proxy" {
secret_id = aws_secretsmanager_secret.my_db_proxy.id
secret_string = jsonencode({
"username" = aws_db_instance.my_db.username
"password" = var.db_password
"engine" = "postgres"
"host" = aws_db_instance.my_db.address
"port" = 5432
"dbInstanceIdentifier" = aws_db_instance.my_db.id
})
}
然后,您需要确保这些安全组规则允许Postgres端口5432上的TCP通信存在:
进入Lambda到RDS代理
进入RDS代理到RDS
出口RDS代理到0.0.0.0/0
RDS代理角色应具有如下策略:
resource "aws_iam_policy" "my_rds_proxy_policy" {
name = "my-rds-proxy"
policy = <<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "",
"Action": [
"rds:*"
],
"Effect": "Allow",
"Resource": [
"${aws_db_instance.my_db.arn}"
]
},
{
"Sid": "GetSecretValue",
"Action": [
"secretsmanager:GetSecretValue"
],
"Effect": "Allow",
"Resource": [
"${aws_secretsmanager_secret.my_rds_proxy.arn}"
]
},
{
"Sid": "DecryptSecretValue",
"Action": [
"kms:Decrypt"
],
"Effect": "Allow",
"Resource": [
"*"
]
},
{
"Sid": "DecryptKms",
"Effect": "Allow",
"Action": "kms:Decrypt",
"Resource": "*",
"Condition": {
"StringEquals": {
"kms:ViaService": "secretsmanager.${var.aws_region}.amazonaws.com"
}
}
}
]
}
EOF
}
祝你好运 使用descripe db proxy targets非常有用,在某些情况下可以为您提供所需的答案。由于问题中所述的内部错误,我使DBProxy目标不可用。非常令人沮丧!在我的例子中,这是由于不正确的安全组设置导致端点无法访问目标。在我的测试中,我认为在代理上使用与RDS集群相同的安全组是有意义的,只是我忘记了该组不允许从其自己的组进行访问。希望AWS能够在将来捕获此错误并改进错误消息传递。使用Descripte db proxy targets非常有用,在某些情况下可以为您提供所需的答案。由于问题中所述的内部错误,我使DBProxy目标不可用。非常令人沮丧!在我的例子中,这是由于不正确的安全组设置导致端点无法访问目标。在我的测试中,我认为在代理上使用与RDS集群相同的安全组是有意义的,只是我忘记了该组不允许从其自己的组进行访问。希望AWS能够在将来捕获此错误并改进错误消息传递。