2
votes

I am writing a cloud formation template and the creation of a resource in my stack it depends on the environment.
Therefore, I check the value of a parameter (Environment), and based on it I create that resource (Condition: ISProduction).
However, my problem is that in case that resource is created (MyProductionResource) another resource (AnotherResource) becomes dependent on it and needs to use an output attribute from the other (MyProductionResource).
Here the code:

Conditions:
  ISProduction:
    "Fn::Equals":
      - !Ref Environment
      - production
 ...

 MyProductionResource:
    Type: AWS::CloudFormation::Stack
    Condition: ISProduction
    Properties:
    [.. properties..]

 AnotherResource:
    Type: AWS::CloudFormation::Stack
    DependsOn:
      - AResource
      - MyProductionResource
    Properties:
      TemplateURL: whatever
      Parameters:
        AParameter: !GetAtt MyProductionResource.Outputs.SomeString

My problem is that I want AnotherResource to be dependent on MyProductionResource only when ISProduction is true. An idea is to add some kind of conditions in the DependsOn item, or anything that would bring to the same result.
How can I do that on AWS Cloud Formation?
Also I am not sure what happen when the resource that is listed in the dependsOn list is not created. Would the cloud formation template generate an error? How can I make this attribute read safety !GetAtt MyProductionResource.Outputs.SomeString ?

2

2 Answers

5
votes

you can use !If for the parameter

AParameter: !If [ISProduction, !GetAtt MyProductionResource.Outputs.SomeString, "default value?!?"]

but unfortunately DependsOn does not allow Fn::If.

So you could create to resource twice.

AnotherProductionResource:
  Type: AWS::CloudFormation::Stack
  Condition: ISProduction
  DependsOn:
  - AResource
  - MyProductionResource
  Properties:
    [...]
AnotherNonProductionResource:
  Type: AWS::CloudFormation::Stack
  Condition: ISNotProduction
  DependsOn:
  - AResource
  Properties:
    [...]

But having so many ifs is kind of against the idea that your environments should be as similar as possible. So maybe you can get rid of this whole thing?

1
votes

Here's a alternative for "DependsOn does not allow Fn::If."

Conditions:
  CreateConfigRecorder: !Equals [ !Ref ConfigRecorderExists, 'false' ]

Resource:
#my 1st AWS Resource
  ConfigRecorder: 
    Condition: CreateConfigRecorder
    Type: AWS::Config::ConfigurationRecorder
    *more codes below*

#added, since DependsOn: !If is not possible, trigger by WaitCondition if CreateConfigRecorder is true
#Hacks: https://garbe.io/blog/2017/07/17/cloudformation-hacks/
  ConfigRecorderWaitHandle: 
    Condition: CreateConfigRecorder
    DependsOn: ConfigRecorder
    Type: "AWS::CloudFormation::WaitConditionHandle"
#added, since DependsOn: !If is not possible, trigger by WaitCondition if CreateConfigRecorder is false
  WaitHandle: 
    Type: "AWS::CloudFormation::WaitConditionHandle"
#added, since DependsOn: !If is not possible
  WaitCondition: 
    Type: "AWS::CloudFormation::WaitCondition"
    Properties: 
      Handle: !If [CreateConfigRecorder, !Ref ConfigRecorderWaitHandle, !Ref WaitHandle]
      Timeout: "1"
      Count: 0
#my 2nd AWS Resource that requires DependsOn Attribute
  AWSConfigRule:
    Type: AWS::Config::ConfigRule
    DependsOn: WaitCondition #added, since DependsOn: !If is not possible
    *more codes below*

Basically my 2nd resource only has DependsOn attribute if my 1st resource is non-existent, before running the CFN. I got this from: https://garbe.io/blog/2017/07/17/cloudformation-hacks/