AWS CloudFormation - 两个网络接口,一个带有 EIP

AWS CloudFormation - 两个网络接口,一个带有 EIP

我是 AWS 新手。尝试创建一个具有两个网络接口的 EC2 实例,一个是公共的,另一个是私有的。

这是我在 YAML 模板中尝试过的内容:

  1. 创建具有两个子网的 VPC
  2. 仅使用私有网络接口创建实例
  3. 创建第二个(公共)网络接口作为另一个 YAML 实体
  4. 将第二个网络接口附加到实例
  5. 创建 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: Host1Eth1AttachmentElasticIPAssociation以确保顺序与我在控制台中关联 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

相关内容