simpleCoder
simpleCoder

Reputation: 202

AWS Cloudformation conditionally add resource property

I am expanding our cloudformation stack to a new region but wanted to enable encryption in our elasticsearch cluster. However, I only want to enable it for new regions

I tried this:

Conditions:
  EnableEnhancedSecurity:
    !Not
      - !Equals
        - 'us-east-1'
        - { Ref: AWS::Region }

Resources:
  MyTestingElasticSearchStore:
    Type: "AWS::Elasticsearch::Domain"
    Properties:
      DomainName:
        Fn::Sub: 'stack-${AWS::Region}-${Stage}'
      ElasticsearchVersion: '7.1'
      ElasticsearchClusterConfig:
        EncryptionAtRestOptions:
            Enabled:
              !If
                - EnableEnhancedSecurity
                - 'true'
                - 'false'
          NodeToNodeEncryptionOptions:
            Enabled:
              !If
                - EnableEnhancedSecurity
                - 'true'
                - 'false'
         ...

but I'm getting the following error when I try to update my test stack: CloudFormation cannot update a stack when a custom-named resource requires replacing. Rename stack-us-west-1-test and update the stack again.

I think this is because I'm adding the properties (even if they're, "false") So I'm trying to understand how I would conditionally add the properties.

I am trying:


Conditions:
  EnableEnhancedSecurity:
    !Not
      - !Equals
        - 'us-east-1'
        - { Ref: AWS::Region }

Resources:
  MyTestingElasticSearchStore:
    Type: "AWS::Elasticsearch::Domain"
    Properties:
      DomainName:
        Fn::Sub: 'stack-${AWS::Region}-${Stage}'
      ElasticsearchVersion: '7.1'
      ElasticsearchClusterConfig:
         ...
      Fn::If:  # only add the properties if needed
        - EnableEnhancedSecurity
        -
          EncryptionAtRestOptions:
            Enabled: 'true'
          NodeToNodeEncryptionOptions:
            Enabled: 'true'
       - { Ref: AWS::NoValue }

but am running into the following error:

YAML Errors:
while parsing a block mapping
  in "<unicode string>", line 76, column 5:
        Type: "AWS::Elasticsearch::Domain"
        ^
expected <block end>, but found '<block sequence start>'
  in "<unicode string>", line 148, column 6:
         - { Ref: AWS::NoValue }

Is this even possible? if so, how do I even set this up in just the new regions without touching the existing one via cloudformation?

Upvotes: 2

Views: 3096

Answers (1)

Marcin
Marcin

Reputation: 238209

The error happens because you provided name for your domain using DomainName. From docs:

If you specify a name, you cannot perform updates that require replacement of this resource. You can perform updates that require no or some interruption. If you must replace the resource, specify a new name.

Both EncryptionAtRestOptions and EncryptionAtRestOptions require replacement. This means that since you used DomainName, you can't modify these properties.

You would have to tear down the current ES domain, and recreate it without DomainName for replacement updates to be possible. You can rename the domain to do it as well if you want to use different DomainName which will also delete existing ES domain and create new one.

Update regarding conditions

You should be able achieve what you want using the following syntax:

Resources:
  MyTestingElasticSearchStore:
    Type: "AWS::Elasticsearch::Domain"
    Properties:
      DomainName:
        Fn::Sub: 'stack-${AWS::Region}-${Stage}'
      ElasticsearchVersion: '7.1'
      ElasticsearchClusterConfig:
      EnableEnhancedSecurity:
        Fn::If: 
          - EnableEnhancedSecurity
          - { Enabled: 'true' }
          - !Ref "AWS::NoValue"
      EncryptionAtRestOptions:
        Fn::If: 
          - EnableEnhancedSecurity
          - { Enabled: 'true' }
          - !Ref "AWS::NoValue"

Upvotes: 4

Related Questions