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

AWS CDK如何同时实现ECS服务发现与Route53 CNAME记录配置?

解决方案

核心思路

不需要手动查询CloudMap自动生成的私有托管区域,aws_servicediscovery.PrivateDnsNamespace 构造对象本身会直接暴露自动生成的托管区域属性,你可以直接在CDK栈之间传递该属性,同时满足手动添加CNAME和自动注册ECS服务发现的需求。

实现步骤

步骤1:在VPC栈中创建私有DNS命名空间并暴露核心属性

直接在创建VPC的栈里初始化私有DNS命名空间,同时导出自动生成的托管区域和命名空间对象给后续栈使用:

from aws_cdk import (
    Stack,
    Duration,
    aws_ec2 as ec2,
    aws_servicediscovery as servicediscovery,
    aws_route53 as route53
)
from constructs import Construct

class VpcStack(Stack):
    def __init__(self, scope: Construct, construct_id: str, **kwargs) -> None:
        super().__init__(scope, construct_id, **kwargs)
        # 创建VPC
        self.vpc = ec2.Vpc(self, "CustomVpc", max_azs=2)
        # 创建私有DNS命名空间,CloudMap会自动生成对应私有托管区域
        self.private_dns_namespace = servicediscovery.PrivateDnsNamespace(
            self, "CustomPrivateNamespace",
            name="domain.com",
            vpc=self.vpc
        )
        # 直接获取自动生成的托管区域,暴露给其他栈调用
        self.private_hosted_zone: route53.IPrivateHostedZone = self.private_dns_namespace.hosted_zone

步骤2:在数据库栈中添加数据库CNAME记录

接收VPC栈传递的托管区域对象,直接添加指向数据库端点的CNAME记录:

from aws_cdk import (
    Stack,
    Duration,
    aws_rds as rds,
    aws_route53 as route53,
    aws_ec2 as ec2
)
from constructs import Construct

class DbStack(Stack):
    def __init__(self, scope: Construct, construct_id: str, vpc: ec2.Vpc, hosted_zone: route53.IPrivateHostedZone, **kwargs) -> None:
        super().__init__(scope, construct_id, **kwargs)
        # 创建RDS实例(其他数据库同理)
        db_instance = rds.DatabaseInstance(
            self, "PostgresDb",
            engine=rds.DatabaseInstanceEngine.postgres(version=rds.PostgresEngineVersion.VER_15),
            vpc=vpc,
            # 其余配置省略
        )
        # 新增db.domain.com的CNAME记录
        route53.CnameRecord(
            self, "DbDnsRecord",
            zone=hosted_zone,
            record_name="db.domain.com",
            domain_name=db_instance.db_instance_endpoint_address,
            ttl=Duration.minutes(5)
        )

步骤3:在ECS服务栈中配置服务发现

接收VPC栈传递的私有DNS命名空间,直接配置ECS服务的服务发现规则,CDK会自动生成对应DNS记录:

from aws_cdk import (
    Stack,
    Duration,
    aws_ecs as ecs,
    aws_servicediscovery as servicediscovery,
    aws_ec2 as ec2
)
from constructs import Construct

class EcsServiceStack(Stack):
    def __init__(self, scope: Construct, construct_id: str, vpc: ec2.Vpc, dns_namespace: servicediscovery.IPrivateDnsNamespace, **kwargs) -> None:
        super().__init__(scope, construct_id, **kwargs)
        # ECS集群、任务定义创建逻辑省略
        cluster = ecs.Cluster(self, "EcsCluster", vpc=vpc)
        task_def = ecs.FargateTaskDefinition(self, "ServiceATaskDef")
        task_def.add_container("ServiceAContainer", image=ecs.ContainerImage.from_registry("amazon/amazon-ecs-sample"))
        
        # 创建ECS服务并配置服务发现,自动生成serviceA.domain.com记录
        ecs.FargateService(
            self, "ServiceA",
            cluster=cluster,
            task_definition=task_def,
            cloud_map_options=ecs.CloudMapOptions(
                name="serviceA",
                cloud_map_namespace=dns_namespace,
                dns_record_type=servicediscovery.DnsRecordType.A,
                dns_ttl=Duration.minutes(1)
            )
        )

步骤4:在CDK入口配置栈依赖

在app.py中按顺序初始化三个栈,传递对应的属性即可:

from aws_cdk import App
from vpc_stack import VpcStack
from db_stack import DbStack
from ecs_service_stack import EcsServiceStack

app = App()
vpc_stack = VpcStack(app, "VpcStack")
DbStack(app, "DbStack", vpc=vpc_stack.vpc, hosted_zone=vpc_stack.private_hosted_zone)
EcsServiceStack(app, "EcsServiceStack", vpc=vpc_stack.vpc, dns_namespace=vpc_stack.private_dns_namespace)

app.synth()

原报错原因说明

你之前使用PrivateHostedZone.from_lookup报错,是因为该方法用于查询当前CDK应用之外已经存在的托管区域,需要在synth阶段就拿到所有参数的实际值(比如VPC ID)。如果你的VPC是同个CDK应用下其他栈创建的,synth阶段vpc.vpc_id是未解析的Token占位符,无法用来查询AWS账户的现有资源,因此会触发报错。
使用同个CDK应用内生成的PrivateDnsNamespace的hosted_zone属性,走的是CDK内部的引用传递逻辑,不需要提前知道资源的实际ID,部署时会自动解析,完全不会出现Token相关的错误。

内容的提问来源于stack exchange,提问作者Claus Agerskov

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 12:21:01