mephi42
mephi42

Reputation: 485

Updating dependent stacks

I have the stack called stack-layer, which exports an ARN of a Lambda layer, and another stack called stack-lambda, which contains a Lambda, which references that Lambda layer.

When I try to update stack-layer, I get an error: Export layer-arn cannot be deleted as it is in use by stack-lambda, which is totally understandable. However, I don't see how to proceed with an update from here.

Is there any way to update such dependent stacks? Amazon's walkthrough does not seem to touch this topic at all.

Upvotes: 16

Views: 9663

Answers (4)

Jerry
Jerry

Reputation: 1

You can try to use SSM to avoid importing or exporting in the stack

## Importing resources created in other stacks
## using their SSM Parameter Keys
Parameters:
  MyEmptyBucket:
    Type: AWS::SSM::Parameter::Value<AWS::EC2::Image::Id>
    Default: my_app/s3/archive_bucket
    Description: The archive bucket created by the storage stack
  MainVPC:
    Description: VpcId of the Network Stack
    Type: 'AWS::SSM::Parameter::Value<String>'
    Default: '/app_network/plain/resources/ec2/vpc_id'
  PublicSubnetOne:
    Description: Public Subnet One of the Network Stack
    Type: 'AWS::SSM::Parameter::Value<String>'
    Default: '/app_network/plain/resources/ec2/public_subnet_1_id'

Resources:
  MyEC2SecurityGroup:
    Type: AWS::EC2::SecurityGroup
    Properties:
      VpcId: !Ref MainVPC

Upvotes: 0

Daniel Gibson
Daniel Gibson

Reputation: 11

I found a built-in CDK method on core.Stack that handles this exact issue:

export_value()

Link to Python CDK docs here https://docs.aws.amazon.com/cdk/api/v1/python/aws_cdk.core/Stack.html?highlight=export_value#aws_cdk.core.Stack.export_value

One of the uses for this method is to remove the relationship between two Stacks established by automatic cross-stack references. It will temporarily ensure that the CloudFormation Export still exists while you remove the reference from the consuming stack. After that, you can remove the resource and the manual export.

My example is needing to replace an old DB stack with a new one (changing from serverless to provisioned RDS). I simply rename the old DB stack variable name and below it add the following:

self.export_value(old_cluster.cluster_identifier)

Within export_value() I pass in the exported output value that was causing the dependency issue. I can either hardcode it as a string or better yet can find where it is getting it from and reference that instead, in this case the value was from cluster_identifier.

After the stack has been updated I can remove the old DB cluster and this export_value() line.

Upvotes: 0

miradham
miradham

Reputation: 2355

As the other answer suggested method looks a bit longer, here is what I did to overcome this problem after reading this guide:

  1. I have updated importing stack (i.e. stack-lambda) to use actual value of exported parameter(I did that using AWS console so that I don't have to make change in my yml code, submit and deploy)
  2. Deploy exporting stack (i.e. stack-layer) and make sure that the issue is gone
  3. Deploy importing stack from code base.

This was done quite quickly w/o changing source code and interrupting service run. Hope this will be useful, feel free to comment your questions.

Upvotes: 5

wjordan
wjordan

Reputation: 20400

As described in Fn::ImportValue documentation, being unable to modify a referenced output is indeed expected behavior:

Note

The following restrictions apply to cross-stack references:

[...]

  • You can't modify or remove an output value that is referenced by another stack.

In order to work around this when updating the output, you can use a second, temporary Output value to handle the transition:

  1. Update stack-layer to add a second Output containing the new value (e.g., layer-arn-2);
  2. Update stack-lambda, changing the "Fn::ImportValue": "layer-arn" reference to instead reference layer-arn-2.
  3. Update stack-layer to remove the now-unused layer-arn Output.
    (Or alternately: update stack-layer to set layer-arn to the same value as layer-arn-2; update stack-lambda to reference layer-arn; then finally update stack-layer to remove the layer-arn-2 Output.

It's a bit tedious, but it should work.

Upvotes: 6

Related Questions