使用 CDK 创建 AWS EC2 实例后如何获取 public DNS?

How do I get public DNS after creating AWS EC2 instance with CDK?

有没有办法获取 AWS CDK 创建的新(或现有)实例的 public IP 或 public DNS(或两者)?

我想针对新实例使用 SSH 或 运行 ansible 脚本,不想每次都去 AWS 控制台。

这是我拥有的:

class WebsiteStack(core.Stack):

    def __init__(self, scope: core.Construct, id: str, **kwargs) -> None:
        super().__init__(scope, id, **kwargs)

        self.vpc = aws_ec2.Vpc.from_lookup(self, 'default_vpc', is_default=True)

        self.sg_ssh = aws_ec2.SecurityGroup(
            self,
            'ssh',
            vpc=self.vpc,
            description="Allow SSH from anywhere",
            security_group_name="SSH from anywhere"
        )
        self.sg_ssh.add_ingress_rule(aws_ec2.Peer.any_ipv4(), aws_ec2.Port.tcp(22))

        ami = aws_ec2.LookupMachineImage(
            name="ubuntu/images/hvm-ssd/ubuntu-bionic-18.04-amd64-server-*",
            owners=["099720109477"],
        )

        ec2 = aws_ec2.Instance(
            self,
            'website',
            instance_type=aws_ec2.InstanceType('t3a.micro'),
            machine_image=ami,
            vpc=self.vpc,
            security_group=self.sg_ssh,
            key_name="autoscaled",
            user_data=self.change_ssh_port,
        )
        print(ec2.instance_public_dns_name)

但是 cdk deploycdk synthcdk diff 的输出总是这样的:

${Token[TOKEN.41]}

这可能吗?有人成功了吗?

一种方法是为您想要获取的每个值创建一个 CloudFormation 输出。 您可以使用 aws_cdk.aws_ec2.Instance class.

的以下属性
  • instance_public_ip
  • instance_public_dns_name
core.CfnOutput(
   scope=self,
   id="PublicIp",
   value=my_instance.instance_public_ip, 
   description="public ip of my instance", 
   export_name="ec2-public-ip")

CDK 部署命令在成功运行时打印出堆栈输出。

# cdk deploy
...
Outputs:

mystack.PublicDns = ec2-19-174-49-175.eu-west-1.compute.amazonaws.com
mystack.PublicIp = 19.174.49.175

您还需要根据文档在您的实例定义中指定一个 public 子网。默认情况下,CDK 选择私有子网。

vpc_subnets (Optional[SubnetSelection]) – Where to place the instance within the VPC. Default: - Private subnets.

ec2 = aws_ec2.Instance(self,
        ...
        vpc_subnets=aws_ec2.SubnetSelection(subnet_type=aws_ec2.SubnetType.PUBLIC)
)