CloudFormation: How to solve Circular Dependency between an Elastic IP and an EC2 Instance

When writing a CloudFormation Template that needs to use the value of an Elastic IP to a file inside an EC2 Instance, you will most likely encounter a Circular dependency between resources error.

I encountered this when configuring OpenSwan IPSec VPN in CloudFormation.

You can try the CloudFormation template below to see the error above.

CloudFormation Template with Circular Dependency Error

Parameters:
  AmazonLinux2AMIID:
    Type: AWS::SSM::Parameter::Value<AWS::EC2::Image::Id>
    Default: /aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-gp2

  KeyName:
    Type: AWS::EC2::KeyPair::KeyName

Resources:
  ElasticIP:
    Type: 'AWS::EC2::EIP'
    Properties:
      Domain: vpc
      InstanceId: !Ref EC2Instance
  
  EC2Instance:
    Type: AWS::EC2::Instance
    Properties: 
      ImageId: !Ref AmazonLinux2AMIID
      InstanceType: t2.micro
      KeyName: !Ref KeyName
      UserData: 
        Fn::Base64:
          !Sub |
            #!/bin/bash -ex
            echo "${ElasticIP}" >> /EIPAddress.txt

The issue issue happens because the ElasticIP and the EC2Instance resource needs each other.

  • ElasticIP needs EC2Instance.
  • EC2Instance needs ElasticIP.

CloudFormation will not know which one it needs to create first, therefore it throws a Circular Dependency error.

How to solve Circular Dependency between an Elastic IP and an EC2 Instance

To solve the issue within a single CloudFormation Template we need to use the AWS::EC2::EIPAssociation resource type to go in between the Elastic IP and the EC2 Instance.

CloudFormation Template with Fixed Circular Dependency Error

Parameters:
  AmazonLinux2AMIID:
    Type: AWS::SSM::Parameter::Value<AWS::EC2::Image::Id>
    Default: /aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-gp2

  KeyName:
    Type: AWS::EC2::KeyPair::KeyName

Resources:
  ElasticIP:
    Type: 'AWS::EC2::EIP'
    Properties:
      Domain: vpc

  ElasticIPAssociation:
    Type: AWS::EC2::EIPAssociation
    Properties: 
      EIP: !Ref ElasticIP
      InstanceId: !Ref EC2Instance
  
  EC2Instance:
    Type: AWS::EC2::Instance
    Properties: 
      ImageId: !Ref AmazonLinux2AMIID
      InstanceType: t2.micro
      KeyName: !Ref KeyName
      UserData: 
        Fn::Base64:
          !Sub |
            #!/bin/bash -ex
            echo "${ElasticIP}" >> /EIPAddress.txt

From the above CloudFormation template, the ElasticIP is no longer dependent on the EC2Instance. Therefore, CloudFormation knows how to sequence resource creation, eliminating the Circular Dependency error.

The creation sequence would be like the list below.

  1. Create ElasticIP.
  2. Create EC2Instance – using the ElasticIP value.
  3. Create ElasticIPAssociation – this will associate the ElasticIP to the EC2Instance.

Try the corrected CloudFormation Template above and see if it works.

With that we have corrected the Circular Dependency Error.

Have you encountered the Circular Dependency Error when writing CloudFormation Templates? Let me know the situation in the comments below and I will help you solve it.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.