我是 AWS 新手。尝试创建一个具有两个网络接口的 EC2 实例,一个是公共的,另一个是私有的。
这是我在 YAML 模板中尝试过的内容:
- 创建具有两个子网的 VPC
- 仅使用私有网络接口创建实例
- 创建第二个(公共)网络接口作为另一个 YAML 实体
- 将第二个网络接口附加到实例
- 创建 EIP 并将其与第二个网络接口关联
必须将公共网络接口创建为单独的实体,因为我需要在 EIP 关联节中对其进行引用。
Properties:
[...]
Host1:
Type: 'AWS::EC2::Instance'
Properties:
ImageId: 'ami-02541b8af977f6cdd' # Amazon Linux x86
InstanceType: 't2.micro'
AvailabilityZone: !Select [0, !GetAZs '']
KeyName: !Ref KeyName
NetworkInterfaces:
- SubnetId: !Ref SubnetPrivate
DeleteOnTermination: true
DeviceIndex: '0'
GroupSet:
- !Ref SecurityGroup
Tags:
- Key: Name
Value: 'simple - host1'
Host1Eth1:
Type: 'AWS::EC2::NetworkInterface'
Properties:
SubnetId: !Ref SubnetPublic
GroupSet:
- !Ref SecurityGroup
Tags:
- Key: Name
Value: 'simple - host1 eth1'
Host1Eth1Attachment:
Type: 'AWS::EC2::NetworkInterfaceAttachment'
Properties:
DeleteOnTermination: true
DeviceIndex: 1
NetworkInterfaceId: !Ref Host1Eth1
InstanceId: !Ref Host1
ElasticIP:
Type: 'AWS::EC2::EIP'
Properties:
Domain: vpc
DependsOn: VPCGatewayAttachment
ElasticIPAssociation:
Type: 'AWS::EC2::EIPAssociation'
Properties:
EIP: !Ref ElasticIP
InstanceId: !Ref Host1
NetworkInterfaceId: !Ref Host1Eth1
完整的 YAML 文件可以在这里获得:https://gist.github.com/kmansoft/6b90b33bcf91eb0d493414ed6c3d9754
问题:
一旦创建了堆栈,实例就会在控制台中将 EIP 列为其公共 IP,并且有一个 DNS 名称。但是,我无法使用 SSH(通过主机名或 IP)连接到实例。
奇怪的是,如果我从 YAML 文件中省略 EIP 并使用 AWS 控制台手动创建和关联它,那么一切都会正常。
关于如何使用 YAML 使公共 EIP 工作,有什么建议吗?
更新:我尝试添加到DependsOn: Host1Eth1Attachment
,ElasticIPAssociation
以确保顺序与我在控制台中关联 EIP 时的顺序相同。
出现此错误:
实例“i-020622d0cf13e5185”上附加了多个接口。请为操作指定一个接口 ID。
即使我的ElasticIPAssociation
确实指定了a NetworkInterfaceId
(和a InstanceId
)。
更新 2:我尝试将我的更改ElasticIPAssociation
为如下形式:
ElasticIPAssociation:
Type: 'AWS::EC2::EIPAssociation'
Properties:
EIP: !Ref ElasticIP
NetworkInterfaceId: !Ref Host1Eth1
DependsOn: Host1Eth1Attachment
删除InstanceId
。出现另一个错误:
属性中未找到 InstanceId
这很奇怪,文档AWS::EC2::EIPAssociation
说这InstanceId
是“必需的:条件” - “对于 EC2-VPC,您可以指定实例 ID 或网络接口 ID,但不能同时指定两者。”
看起来像是 CloudFormation 错误?
更新 3
根据 EC2 文档,这是有效的。
PublicEIPAssociate:
Type: 'AWS::EC2::EIPAssociation'
Properties:
AllocationId: !GetAtt PublicEIP.AllocationId
NetworkInterfaceId: !Ref InterfacePublic
请注意,这里没有InstanceId
(因为实例有两个网络接口,所以它不起作用)。
还请注意,这使用AllocationId
而不是EIP
引用 EIP。
文档中这样说AllocationId
:“这是 EC2-VPC 所必需的”。因为EIP
它说“这是 EC2-Classic 所必需的”。我正在使用 EC2-VPC,因此切换到 EC2-VPC 是AllocationId
有意义的,并且最终成功了。
答案1
经过快速测试,我认为您可能发现了一个错误。我可能错了,我没有花很长时间。报告此错误的最简单方法是前往EIPAsociation CloudFormation 页面并提供反馈。请提供您的示例电子邮件,或参考 SF 上的此问题。
您说得对,文档中说要指定 InstanceID 或 NetworkInterfaceID,但当您仅提供接口 ID 时,它会要求提供 Instance ID。如果您添加 InstanceID,它会告诉您将其删除。
小问题,根据文档,EIP 的 NetworkInterfaceID 需要引用“网络接口的 ID”。!Ref 对 AWS::EC2::NetworkInterface 的返回值是名称,因此您需要获取 ID 属性。如果 CloudFormation 中没有错误,这将很重要。
ElasticIPAssociation:
Type: 'AWS::EC2::EIPAssociation'
Properties:
EIP: !Ref ElasticIP
InstanceId: !Ref Host1
NetworkInterfaceId: !GetAtt Host1Eth1.Id