AWS Cloudformation 有条件地添加资源属性

时间:2021-01-27 23:30:42

标签: amazon-web-services yaml amazon-cloudformation

我正在将我们的 cloudformation 堆栈扩展到一个新区域,但希望在我们的 elasticsearch 集群中启用加密。但是,我只想为新区域启用它

我试过了:

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'
         ...

但是当我尝试更新我的测试堆栈时出现以下错误:CloudFormation cannot update a stack when a custom-named resource requires replacing. Rename stack-us-west-1-test and update the stack again.

我认为这是因为我正在添加属性(即使它们是“false”)所以我试图了解我将如何有条件地添加属性。

我正在尝试:


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 }

但我遇到了以下错误:

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 }

这甚至可能吗?如果是这样,我如何在不通过 cloudformation 触及现有区域的情况下仅在新区域中进行设置?

1 个答案:

答案 0 :(得分:1)

发生错误是因为您使用 DomainName 为您的域提供了名称。来自docs

<块引用>

如果您指定名称,则无法执行需要替换此资源的更新。您可以执行不需要中断或一些中断的更新。如果您必须替换资源,请指定一个新名称。

EncryptionAtRestOptionsEncryptionAtRestOptions 都需要更换。这意味着,由于您使用了 DomainName,因此您无法修改这些属性。

您必须拆除当前的 ES 域,然后在没有 DomainName 的情况下重新创建它才能进行替换更新。如果您想使用不同的 DomainName,您也可以重命名域来执行此操作,这也会删除现有的 ES 域并创建新的域。

关于条件的更新

您应该能够使用以下语法实现您想要的:

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"