Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use CloudFormation import with substitution name in conditional expression with DeletionPolicy. #126

Open
garretwilson opened this issue Jun 15, 2023 · 3 comments

Comments

@garretwilson
Copy link

garretwilson commented Jun 15, 2023

See #58 for background. I'm using aws-cli/2.11.23 Python/3.11.3 Windows/10 exe/AMD64 prompt/off .

I'm trying to use an imported value from another CloudFormation stack to determine whether a resource should have a deletion policy of Delete or Retain. I've also opened Use CloudFormation import with substitution name in conditional expression with DeletionPolicy on Stack Overflow.

One of my AWS CloudFormation templates exports a value for "stage" (which can be e.g. "dev" or "prod") in a variable based upon the stack name, like this:

Export:
  
      Name: !Sub "${AWS::StackName}:stage"

The stack name is in the form foo-${Env}, where Env is some value such as "bar". This Env param is passed to another CloudFormation template. The other template should be able to access the stage of that Env like this, using the external export:

      SomeResourceProperty:
        Fn::ImportValue:
          !Sub "foo-${Env}:stage"

For example if the Env parameter is set to "bar", this would pull in the external variable foo-bar:stage. And that's no problem. It works fine. I import all sorts of variables from the first stack using this form.

I would like to create a condition based upon this variable, in order to set the retention of a resource based upon the stage. First I try this:

Conditions:
  IsStageProd: !Equals
    - Fn::ImportValue:
        !Sub "foo-${Env}:stage"
    - "prod"

CloudFormation tells me that it can't use imported values in conditions.

Never mind; I'll import the value directly in my !If function. As per Intrinsic function references in DeletionPolicy and UpdateReplacePolicy attributes, I add the AWS::LanguageExtensions transformation:

---
AWSTemplateFormatVersion: 2010-09-09
Transform: AWS::LanguageExtensions

Then I try to set the deletion policy of a log group:

    DeletionPolicy:
      Fn::If:
        - Fn::Equals:
            - Fn::ImportValue:
                !Sub "foo-${Env}:stage"
            - "prod"
        - Retain
        - Delete

CloudFormation doesn't like this either:

Failed to create the changeset: Waiter ChangeSetCreateComplete failed: Waiter encountered a terminal failure state: For expression "Status" we matched expected path: "FAILED" Status: FAILED. Reason: Transform AWS::LanguageExtensions failed with: Fn::If layout is incorrect

How can I conditionally retain a resource based upon the value of a variable imported from another stack, when the name of the variable depends on a parameter passed to the current template?

@garretwilson
Copy link
Author

So far my workaround is to use a Bash script to query the original CloudFormation stack, ask for value (like CloudFormation itself should be doing when I reference the exported value inside the Conditions section), and then manually pass it as a parameter to the second template, like this:

stage=$(aws cloudformation describe-stacks --stack-name foo-$env --query 'Stacks[0].Outputs[?OutputKey==`Stage`].OutputValue' --output text)
aws cloudformation deploy --stack-name foo-$env-stack2 --… --parameter-overrides Env=$env Stage=$stage

If I can look them up from Bash, then CloudFormation should be able to look up these references. If I have to do it myself in code, it's defeating the purpose of CloudFormation templates.

@MalikAtalla-AWS
Copy link
Contributor

Hey Garret, Using Fn::ImportValue in a DeletionPolicy is currently not supported for exactly the reasons you describe (ImportValue can't be used in Conditions and Fn::If needs a condition as input).

I'd like to take this down as a feature request. I have created this separate issue for that to make it easier to discover and upvote for other users.

@garretwilson
Copy link
Author

Thank you for getting back to me. The new ticket you created is nicely written. I'll follow the new ticket. Let me know if you need more info from me in the meantime. Have a great weekend.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants