GitHub Actions部署的RDS Postgres实例无法连接问题
问题排查:CDKTF本地部署Postgres可连接,GitHub Actions部署后无法访问
问题现象
本地通过Terraform CDKTF部署Postgres实例后,能正常从本地连接;但使用完全相同的代码通过GitHub Actions部署后,无法通过测试命令连接到实例。
部署代码(Java)
public PostgresStack(final Construct scope, final String id) { super(scope, id); final String REGION = "eu-central-1"; final String TAG_NAME = "Name"; final String TAG_CREATED_BY = "Created By"; AwsProvider awsProvider = AwsProvider.Builder.create(this, "AWS") .region(REGION) .defaultTags(List.of(AwsProviderDefaultTags.builder() .tags(Collections.singletonMap(TAG_CREATED_BY, "CDKTF")) .build())) .build(); Vpc vpc = Vpc.Builder.create(this, "postgres_vpc") .cidrBlock("10.0.0.0/16") .enableDnsSupport(true) // 支持DNS解析和主机名 .enableDnsHostnames(true) .build(); SecurityGroupIngress securityGroupIngress = SecurityGroupIngress.builder() .fromPort(5432) .toPort(5432) .protocol("tcp") .cidrBlocks(List.of("0.0.0.0/0")) .build(); SecurityGroupEgress securityGroupEgress = SecurityGroupEgress.builder() .fromPort(0) .toPort(0) .protocol("tcp") .cidrBlocks(List.of("0.0.0.0/0")) .build(); // 创建安全组,允许任意IP通过5432端口(Postgres默认端口)入站 SecurityGroup securityGroup = SecurityGroup.Builder.create(this, "postgres_sg") .namePrefix("postgres-sg-") .vpcId(vpc.getId()) .ingress(List.of(securityGroupIngress)) .egress(List.of(securityGroupEgress)) .tags(Collections.singletonMap(TAG_NAME, "postgres-sg")) .build(); // 私有子网(未关联互联网网关) Subnet privateSubnet = Subnet.Builder.create(this, "postgres_private_subnet") .vpcId(vpc.getId()) .cidrBlock("10.0.2.0/24") .availabilityZone(REGION + "a") .tags(Collections.singletonMap(TAG_NAME,"postgres_private_subnet")) .dependsOn(List.of(vpc)) .build(); // 公有子网(关联互联网网关) Subnet publicSubnet = Subnet.Builder.create(this, "postgres_public_subnet") .vpcId(vpc.getId()) .cidrBlock("10.0.1.0/24") .availabilityZone(REGION + "b") // 启用公网IP自动分配,使子网内资源可公开访问 .mapPublicIpOnLaunch(true) .tags(Collections.singletonMap(TAG_NAME,"postgres_public_subnet")) .dependsOn(List.of(vpc)) .build(); // 互联网网关,用于访问公有子网内的资源 InternetGateway internetGateway = InternetGateway.Builder.create(this, "postgres_internet_gateway") .vpcId(vpc.getId()) .tags(Collections.singletonMap(TAG_NAME, "postgres_internet_gateway")) .dependsOn(List.of(vpc)) .build(); RouteTableRoute route = new RouteTableRoute.Builder() .cidrBlock("0.0.0.0/0") .gatewayId(internetGateway.getId()) .build(); // 路由表,将默认路由指向互联网网关 RouteTable routeTable = RouteTable.Builder.create(this, "postgres_public_route_table") .vpcId(vpc.getId()) .route(List.of(route)) .tags(Collections.singletonMap(TAG_NAME, "postgres_public_route_table")) .dependsOn(List.of(vpc)) .build(); // 公有子网与路由表关联 RouteTableAssociation routeTableAssociation = RouteTableAssociation.Builder.create(this, "postgres_public_route_table_association") .subnetId(publicSubnet.getId()) .routeTableId(routeTable.getId()) .dependsOn(List.of(publicSubnet, routeTable)) .build(); final String DB_SUBNET_GROUP_NAME = "postgres_db_subnet_group"; DbSubnetGroup dbSubnetGroup = DbSubnetGroup.Builder.create(this, DB_SUBNET_GROUP_NAME) .name(DB_SUBNET_GROUP_NAME) .subnetIds(List.of(privateSubnet.getId(), publicSubnet.getId())) .tags(Collections.singletonMap(TAG_NAME, DB_SUBNET_GROUP_NAME)) .dependsOn(List.of(privateSubnet, publicSubnet)) .build(); // 创建Postgres类型的RDS实例 DbInstance rdsInstance = DbInstance.Builder.create(this, "MyRdsInstance") .allocatedStorage(20) // 存储容量:20GB .dbName("my_terraform_cdktf_db") .username("my_terraform_cdktf_user") .password("my_terraform_cdktf_password") .engine("postgres") .engineVersion("15.2") .instanceClass("db.t3.micro") .port(5432) .dependsOn(List.of(dbSubnetGroup, securityGroup, vpc, routeTable, privateSubnet, publicSubnet, routeTable, routeTableAssociation)) .dbSubnetGroupName(dbSubnetGroup.getName()) .vpcSecurityGroupIds(List.of(securityGroup.getId())) .skipFinalSnapshot(true) .publiclyAccessible(true) .tags(Collections.singletonMap(TAG_NAME, "postgres_instance")) .build(); // 输出RDS实例的连接地址 TerraformOutput.Builder.create(this, "rds_endpoint") .value(rdsInstance.getEndpoint()) .build(); }
测试命令
nc -zv <db_endpoint> <db_port>
VPC配置截图

实用排查方向
- RDS子网分配检查:GitHub Actions部署时,RDS可能被分配到私有子网。即使
publiclyAccessible设为true,私有子网内的实例也无法直接从公网访问。建议查看RDS实例的实际子网归属,确保子网组内的公有子网优先级正常。 - DNS解析验证:虽然VPC开启了DNS支持,但部署环境可能存在解析异常。可以用
nslookup <db_endpoint>确认解析结果是否正确,或直接ping端点测试连通性。 - AWS权限与区域一致性:确认GitHub Actions使用的AWS凭证与本地凭证的区域配置一致,且没有组织级VPC策略、IP白名单等额外限制。
- 资源依赖清理:代码中
dependsOn列表存在重复项(如重复的routeTable),可能导致资源创建顺序异常,比如路由表关联未在RDS创建前完成。建议清理重复依赖,确保路由配置优先完成。
内容的提问来源于stack exchange,提问作者Shridutt Kothari
相关产品推荐
相关产品推荐

