Viet
Viet

Reputation: 6953

CloudFormation cross-stack vs nested-stack

I'm facing a decision to Use Cross-Stack References to Export Shared Resources or to Use Nested Stacks to Reuse Common Template Patterns following AWS CloudFormation best practices.

However, they seem the same to me apart from a few differences:

There's no clear pros and cons between them as far as I could search.

My goal is to create a parent stack that passes some core variables like stackName to the child stacks, then the child stacks create the resources sharing some variables between them like ARN or Policies, using the stackName to name their resources like stackNameDynamoDBTable.

Upvotes: 18

Views: 9630

Answers (4)

X.Mitry
X.Mitry

Reputation: 15

With cross stacks, you pass a reference to a bunch existing components X to stacks A and B when you want A and B to reuse these very same existing components. With nested stacks, when you nest a nested stack Y in stacks C and D, Y shall create a new set of components Y is describing individually for C and for D. It is similar to concepts 'passing by reference' and 'passing by value' in programming.

Upvotes: 1

rohith
rohith

Reputation: 753

Nested stacks: if you need to manage your stacks from a single point, you should use nested stacks. example: assume that you have load balancer configuration that you use for most of your stacks. Instead of copying and pasting the same configurations into your templates you can create a dedicated template for load balancer.

cross-stack : Alternatively, if you need to manage your stacks as separate entities, you should use cross-stack references.(AWS limits the number of VPCs you can create in an AWS region to five.) example : You might have a network stack that includes a VPC, a security group, and a subnet. You want all public web apps to use these resources. By exporting the resources, you allow all stacks with public web applications to use them.

Upvotes: 4

twitu
twitu

Reputation: 625

There is a way to get the best of both worlds. The trick is to use cross-stack resource sharing but make it depend on a parameter that is passed using Nested stack.

Here's an example from how I used this, consider two stacks IAMRoleStack and ComputeStack. The former contains all the necessary IAM roles and the latter contains a bunch of Lambda functions that those roles are applied to.

Resources:
  IAMCustomAdminRoleForLambda:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
      Policies:

Output:
  IAMRoleArnForLambda:
    Description: Returns the Amazon Resource Name for the newly created IAM Custom
      Role for Lambda function
    Value: !GetAtt 'IAMCustomAdminRoleForLambda.Arn'
    Export:
      Name: !Sub '${AWS::StackName}-IAMRoleArnForLambda'

  StackName:
    Description: Returns name of stack after deployment
    Value: !Sub ${AWS::StackName}

As you can see I've exported the IAM role but it's Name depends on the stack name that is calculated once the stack is deployed. You can read more about exporting outputs in the docs.

In the ComputeStack, I use this role by importing it.

Resources:
  LambdaForCompute:
    Type: AWS::Lambda::Function
    Properties:
      Role: !ImportValue
        Fn::Sub: ${StackNameOfIAMRole}-IAMRoleArnForLambda

The parent stack that "nests" both ComputeStack and IAMRoleStack orchestrates passing the stack name parameter.

Resources:

  IAMRoleStack:
    Type: AWS::CloudFormation::Stack
    Properties:
      TemplateURL: !Ref IAMRoleStackURL

  ComputeStack:
    Type: AWS::CloudFormation::Stack
    Properties:
      TemplateURL: !Ref ComputeStackURL
      Parameters:
        StackNameOfIAMRole: !GetAtt IAMRoleStack.Outputs.StackName

I can't attest to best practice but this style allows me to pick and choose where I want orchestrated deployment and where I want to do the deployments individually.

I also want to point out that this kind of modularization based on type of resources is not very feasible for nested stacks. For e.g. in this scenario, if I had 10 different roles for 10 different Lambda functions, I would have to pass each of those 10 roles through parameters. Using this hybrid style, I only need to pass one parameter the stack name.

Upvotes: 1

NHol
NHol

Reputation: 2125

You should use cross-stack references as it was created for your use case of passing between stacks.

Whereas nested stacks would work, it’s primary purpose is for reuse of modular components, like a template of a resource you use in lots of stacks to save copy pasting and updating the stacks independently.

Upvotes: 10

Related Questions