You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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配置截图

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.24 01:09:56