Canot assign EIP from Nat Gatway to Instance

0

Hello AWS, I'm facing an issue deploying via SAM and AWS CloudFormation. I have a YAML file set up, and I want to use a condition where deleting a NAT gateway that already has an EIP associated and transferring the IP to a NAT instance will trigger a new creation. However, I'm encountering the error 'resource eipalloc-03610b31f2b24f490 is already associated with associate-id eipassoc'.

NatGateway: Type: AWS::EC2::NatGateway Condition: UseVPCNatGateway Properties: AllocationId: !GetAtt EIP.AllocationId SubnetId: !Ref PublicSubnet EIP: Type: AWS::EC2::EIP Condition: UseVPC DependsOn: InternetGatewayAttachment EniAssociation: Type: AWS::EC2::EIPAssociation Condition: UseVPCNatInstance Properties: AllocationId: !GetAtt EIP.AllocationId InstanceId: !Ref NatInstance

2 Answers
0

Try this. You can create the stack with the NatGateway option, for example, then update the stack with the "none" option, and finally update it with the NatInstance option. Note that your AWS::EC2::Instance declaration is missing AMI, subnet, and other essential configurations, so you'll need to add them.

Keep in mind that if you try to switch directly from NatGateway to NatInstance or the other way around, that will fail, because CloudFormation will attempt to attach the EIP to the destination resource before the old one has been detached. You'll have to do the switch in two steps, first removing the current NAT solution by specifying "none", and then updating the stack again with the new NAT solution.

---
AWSTemplateFormatVersion: '2010-09-09'

Parameters:
  NatPlatform:
    Type: 'String'
    AllowedValues: ['NatGateway','NatInstance','none']
    Default: 'none'
  PublicSubnet:
    Type: 'AWS::EC2::Subnet::Id'

Conditions:
  IsNatGatewayRequested: !Equals [!Ref NatPlatform, 'NatGateway']
  IsNatInstanceRequested: !Equals [!Ref NatPlatform, 'NatInstance']

Resources:
  EIP:
    Type: AWS::EC2::EIP

  NatInstance:
    Type: AWS::EC2::Instance
    Condition: IsNatInstanceRequested
    Properties:
      InstanceType: 't3.nano'
      ...add the rest of the instance declaration...

  NatGateway:
    Type: AWS::EC2::NatGateway
    Condition: IsNatGatewayRequested
    Properties:
      SubnetId: !Ref PublicSubnet
      AllocationId: !GetAtt EIP.AllocationId

  EniAssociation:
    Type: AWS::EC2::EIPAssociation
    Condition: IsNatInstanceRequested
    Properties:
      AllocationId: !GetAtt EIP.AllocationId
      InstanceId: !Ref NatInstance
EXPERT
answered 7 months ago
  • I have implemented the same as you, but when performing the case of deleting the Nat Gateway and assigning an IP to the Nat Instance, it seems that it has not yet deleted the Nat Gateway but has updated the EIP for the Nat Instance. This seems to be related to the CloudFormation stack.

  • That's why you have to update the stack first with the "none" selection, so that the NAT gateway gets deleted and the EIP released, and only after that, update the stack again with the NAT instance selection.

  • This is error: returned message:
    "resource eipalloc-036 10b31f2b24f490 is
    already associated
    with associate-id eipa ssoc-09b2d0b323bc2a9a4

  • No, you won't get that error when there is no resource in existence to be attached to the EIP. You just need to update the stack with the "none" selection first for the NatPlatform parameter.

  • Like I said in my first response, that is not possible with CloudFormation. To perform a two-step operation, you have to update the stack two separate times. First, update it to use "none" to delete the NAT gateway and its EIP attachment. Then, update the stack again with the "NatInstance" option to create the NAT instance and attach the EIP to it.

0

I doubt that's possible to accomplish in one step with CloudFormation, except perhaps with some overly complex trickery, like nested stacks.

You can do that cleanly by parameterising the stack to allow the operator to choose between deploying a NAT gateway, NAT instance, and additionally the new option of neither. Maybe make that into a String parameter with those three options. You would always declare the elastic IP in your template but provision neither a NAT gateway nor a NAT instance when the "neither" option is selected.

To switch from a NAT gateway to a NAT instance, for example, the operator would first update the stack to have "neither", leaving only the elastic IP behind. They would update the stack again and select the NAT instance to deploy it an attach to the elastic IP that is still waiting.

EXPERT
answered 7 months ago
  • Thank Leo K! Could you provide an example of deleting a NAT gateway and transferring the Allocation ID of an Elastic IP to a NAT instance?

  • If you include your current template here (redacting any sensitive data you might have in it), I or someone else can probably take a look at adjusting it.

  • @Leo K This is an error case

    NatInstance: Type: AWS::EC2::Instance Condition: true Properties: InstanceType: 't3.nano'

    NatGateway: Type: AWS::EC2::NatGateway Condition: false Properties: SubnetId: !Ref PublicSubnet AllocationId: !GetAtt EIP.AllocationId

    EIP: Type: AWS::EC2::EIP Condition: true

    EniAssociation: Type: AWS::EC2::EIPAssociation Condition: true Properties: AllocationId: !GetAtt EIP.AllocationId InstanceId: !Ref NatInstance

  • Is there any way I can delete NatGateway and then attach EIP?

You are not logged in. Log in to post an answer.

A good answer clearly answers the question and provides constructive feedback and encourages professional growth in the question asker.

Guidelines for Answering Questions