简体   繁体   中英

AWS EC2 - multiple (public / private) network interfaces

AWS newbie here. I'm trying to create a stack with multiple EC2 nodes, each of which should have two network interfaces.

One interface should be public and connected to the Internet, the other interface should be private. The interfaces should belong to different subnets so they can be routed independently (data plane / control plane).

Here is what I've tried in CloudFormation:

Resources:
[.....]
  Host1:
    Type: 'AWS::EC2::Instance'
    Properties:
      ImageId: 'ami-02541b8af977f6cdd' # Amazon Linux x86
      InstanceType: 't2.micro'
      KeyName: !Ref KeyName
      NetworkInterfaces:
      - SubnetId: !Ref SubnetPublic
        AssociatePublicIpAddress: true
        DeleteOnTermination: true
        DeviceIndex: '0'
        GroupSet:
        - !Ref SecurityGroup
      - SubnetId: !Ref SubnetPrivate
        AssociatePublicIpAddress: false
        DeleteOnTermination: true
        DeviceIndex: '1'
        GroupSet:
        - !Ref SecurityGroup

This however results in an error:

The associatePublicIPAddress parameter cannot be specified when launching with multiple network interfaces.

Full YAML file available here: https://gist.github.com/kmansoft/39f7be10553195f41b8201e5638073f2

How can I resolve this?

I'm not at all a CloudFormation guy but, I think I see a problem here. There is just one instance being specified. correct? But you're specifying two subnets. An instance can only be in one subnet.

All instances, regardless of whether they are in a public or private subnet, will have a private IP address. If they are in a public subnet, they will also have a public IP. However, the public IP will not be visible at the O/S level, ie, not visible by ifconfig or ip. The public IP is handled by AWS at the network level, out of sight of you or the O/S.

So, first design a VPC, and the VPC will have both public and private subnets. Any instance launched in a private subnet will automatically only get a private IP address. An instance launched in a public subnet will automatically be assigned a private IP address and a public IP address. Further, for your public IP addresses, if you wish, you can assign an Elastic IP, which will allow you to have a static public IP address. If you don't have an Elastic IP assigned, then every time the instance is stopped/started, it will get a new public IP address, though the private IP address will remain static.

Finally, an instance in the public subnet will, as previously mentioned, have both a public and private IP address. So, if you're copying files from one instance to another in the same VPC, just use the private IP address. To service, for example, web traffic from the Internet, you can use the public IP address. Lastly, you can enhance security by defining that all incoming SSH traffic must come in on the private IP address. That way, you'll either need to be in your local office (which presumably has point-to-point VPN) or you must start VPN to login to an instance via SSH.

How all this translates to CloudFormation, I have no idea.

Got things to work.

The trick was to only specify one network interface in the EC2 Instance - then it's possible to set AssociatePublicIpAddress: true - and add the second network interface separately.

Resources:
[...]
  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 SubnetPublic
        AssociatePublicIpAddress: true
        DeleteOnTermination: true
        DeviceIndex: '0'
        GroupSet:
        - !Ref SecurityGroup
      Tags:
      - Key: Name
        Value: 'simple - host1'
  Host1Eth1:
    Type: 'AWS::EC2::NetworkInterface'
    Properties:
      SubnetId: !Ref SubnetPrivate
      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

In my config, eth0 is allocated from 30.0.1.0/24, and eth1 is allocated from 30.0.2.0/24.

Here is the routing table right after the Instance is created:

default via 30.0.1.1 dev eth0 
default via 30.0.2.1 dev eth1 metric 10001 
30.0.1.0/24 dev eth0 proto kernel scope link src 30.0.1.145 
30.0.2.0/24 dev eth1 proto kernel scope link src 30.0.2.251 
169.254.169.254 dev eth0 

This is pretty close to what I need, just needs to be tweaked a little bit with an Instance UserData.

Full YAML script: https://gist.github.com/kmansoft/c490e7958b8ff8f1d2eb14a6cd115f08

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM