DependsOn best practices in AWS Cloud Formation (example included)

Solution 1:

In general, any resource in a CloudFormation template that refers to another resource will automatically have an implied DependsOn.

For example:

  PrivateRouteTable1:
    Type: AWS::EC2::RouteTable
    Properties:
      VpcId: !Ref VPC
      Tags:
        - Key: Name
          Value: !Sub ${EnvironmentName} Private Routes (AZ1)

  DefaultPrivateRoute1:
    Type: AWS::EC2::Route
    Properties:
      RouteTableId: !Ref PrivateRouteTable1
      DestinationCidrBlock: 0.0.0.0/0
      NatGatewayId: !Ref NatGateway1

DefaultPrivateRoute1 will have an implied DependsOn with PrivateRouteTable1 and NatGateway1.

So, the only time you particularly need to add a DependsOn is when there is no direct relationship, but there is an order of creation required. Here's an example of that:

  InternetGateway:
    Type: AWS::EC2::InternetGateway
    Properties:
      Tags:
        - Key: Name
          Value: !Ref EnvironmentName

  NatGateway1EIP:
    Type: AWS::EC2::EIP
    DependsOn: InternetGatewayAttachment
    Properties:
      Domain: vpc

In this case, a DependsOn was defined between the Elastic IP Address and the InternetGateway. This is helpful because there is no direct relationship between an Elastic IP address and an Internet Gateway (which is linked to a VPC).

I have seen situations where an Amazon EC2 instance had failures in its User Data script because other resources were not 'ready', so the script was unable to access the Internet. It can be difficult to diagnose such situations because they can be transient. Therefore, you might want to specifically add some DependsOn references where there is no directly reference between required resources.