如何通过AWS CDK为私有隔离子网中的EC2实例配置EC2 Instance Connect Endpoint
如何通过AWS CDK为私有隔离子网中的EC2实例配置EC2 Instance Connect Endpoint
你之前踩的坑我刚用CDK做项目的时候也碰到过!一开始我也误以为用VPC的addInterfaceEndpoint就能搞定,后来才发现完全搞错了——EC2 Instance Connect Endpoint(简称EICE)是独立的AWS资源,不是传统的VPC接口端点,所以不能用vpc.addInterfaceEndpoint来创建,得用CDK里专门的Ec2InstanceConnectEndpoint构造。
下面我给你一步步捋清楚怎么改代码,还有必须注意的细节:
核心问题说明
vpc.addInterfaceEndpoint是用来创建类似SSM、EC2 Messages这类AWS服务的VPC端点,让私有子网里的实例能通过内网访问这些服务;但EICE是专门用来帮你SSH连接私有子网实例的中转资源,属于完全不同的资源类型,所以得用单独的CDK类来创建。
代码修改示例
我把你的现有代码整合并改成可直接运行的版本,关键改动都标出来了:
import { Stack, StackProps } from 'aws-cdk-lib'; import { Construct } from 'constructs'; import { Vpc, Instance, InstanceType, InstanceClass, InstanceSize, MachineImage, SubnetType, IpAddresses, Ipv6Addresses, DefaultInstanceTenancy, IpProtocol, Ec2InstanceConnectEndpoint, SecurityGroup, Port, Peer } from 'aws-cdk-lib/aws-ec2'; export class NetworkingStack extends Stack { constructor(scope: Construct, id: string, props?: StackProps) { super(scope, id, props); // 你的原有VPC配置,完全不用改 const vpc = new Vpc(this, "VPC", { vpcName: "a4l-vpc1", maxAzs: 1, ipAddresses: IpAddresses.cidr("10.16.0.0/16"), defaultInstanceTenancy: DefaultInstanceTenancy.DEFAULT, ipProtocol: IpProtocol.DUAL_STACK, ipv6Addresses: Ipv6Addresses.amazonProvided(), subnetConfiguration: [ { name: "Web", subnetType: SubnetType.PRIVATE_ISOLATED, cidrMask: 20, }, ], }); // 1. 先创建EICE的安全组:允许你的客户端IP通过HTTPS访问EICE // 这里记得把'192.168.1.0/24'替换成你实际的公网IP段,别用0.0.0.0/0(不安全) const eiceSecurityGroup = new SecurityGroup(this, 'EiceSecurityGroup', { vpc: vpc, allowAllOutbound: true, description: 'Allow HTTPS from client IPs to EICE', }); eiceSecurityGroup.addIngressRule(Peer.ipv4('192.168.1.0/24'), Port.tcp(443), 'Allow client HTTPS access to EICE'); // 2. 创建EC2 Instance Connect Endpoint,部署在私有隔离子网 const eice = new Ec2InstanceConnectEndpoint(this, 'Ec2InstanceConnectEndpoint', { vpc: vpc, subnets: { subnetType: SubnetType.PRIVATE_ISOLATED, }, securityGroup: eiceSecurityGroup, }); // 3. 创建实例的安全组,专门用来允许来自EICE的SSH流量 const instanceSecurityGroup = new SecurityGroup(this, 'InstanceSecurityGroup', { vpc: vpc, allowAllOutbound: true, description: 'Allow SSH from EICE', }); // 4. 你的原有实例配置,指定我们刚创建的自定义安全组 const instance = new Instance(this, "NetworkingInstance", { instanceType: InstanceType.of(InstanceClass.T3, InstanceSize.MICRO), machineImage: MachineImage.latestAmazonLinux2(), vpcSubnets: { subnetType: SubnetType.PRIVATE_ISOLATED }, requireImdsv2: true, vpc, securityGroup: instanceSecurityGroup, }); // 5. 最关键的一步:给实例安全组加规则,允许EICE的SSH流量 instance.connections.allowFrom(eice, Port.tcp(22), 'Allow SSH from EC2 Instance Connect Endpoint'); } }
关键细节解释
- EICE的安全组:必须允许你的客户端公网IP通过443端口访问,因为你是通过HTTPS和EICE建立连接的,这是EICE的访问入口。
- 实例的安全组:必须允许来自EICE的22端口流量,EICE会把你的SSH请求转发到实例,这一步要是漏了,实例根本收不到连接请求。
- IAM权限:你用来连接实例的IAM用户/角色,需要有这几个权限:
ec2-instance-connect:SendSSHPublicKey、ec2:DescribeInstances、ec2-instance-connect:OpenTunnel——这些权限是用来把你的公钥临时发送到实例,以及建立加密隧道的。 - 实例兼容性:你用的Amazon Linux 2是默认支持EC2 Instance Connect的,不需要额外安装任何包,这点完全没问题。
排查小技巧
如果部署后还是连接不上,先检查这几点:
- 去AWS控制台的EC2 → Instance Connect Endpoints,看EICE的状态是不是
available; - 检查实例安全组的入站规则,是不是真的包含了来自EICE的22端口允许;
- 确认你的客户端IP确实在EICE安全组的允许范围内;
- 检查你的IAM用户有没有上面提到的那几个权限。
内容来源于stack exchange
相关产品推荐
相关产品推荐

