AWS CloudFormation函数调用失败:Fn :: ImportValue不得依赖任何资源,导入的值或Fn :: GetAZ

时间:2018-09-09 01:00:11

标签: amazon-cloudformation

我有一个云形成模板(mainVPC),可以在VPC中创建几个子网,并导出名称为“ PrivateSubnetA”,“ PrivateSubnetB”的子网... 我有另一个创建DBSubnetGroup的云形成模板。如果用户不提供数据,我想使用“ PrivateSubnetA”,“ PrivateSubnetB”作为默认值。 CloundFormation不支持参数中的导入值。因此,我输入了一些默认值(XXXX)并有一个条件部分,以查看用户是否提供了一些输入

Conditions:
  userNotProvidedSubnetA: !Equals 
    - !Ref PrivateSubnetA
    - XXXX
  userNotProvidedSubnetB: !Equals 
    - !Ref PrivateSubnetB
    - XXXX

这可以帮助我确定用户是否提供了数据。现在,我想使用默认值,如果用户未提供值,则使用用户提供的值。 下面是该代码

 DBSubnetGroup:
    Type: 'AWS::RDS::DBSubnetGroup'
    Properties:
      DBSubnetGroupDescription: RDS Aurora Cluster Subnet Group
      SubnetIds:
        - !If 
          - userNotProvidedSubnetA
          - Fn::ImportValue:
                !Sub  '${fmMainVpc}-PrivateSubnetA'
          - !Ref PrivateSubnetA
        - !If 
          - userNotProvidedSubnetB
          - Fn::ImportValue:
                !Sub '${fmMainVpc}-PrivateSubnetB'
          - !Ref PrivateSubnetB

此操作失败,并显示错误“模板错误:Fn :: ImportValue中的属性不得依赖于任何资源,导入的值或Fn :: GetAZs”。 ImportValue不在模板中的其他任何地方使用。

有没有一种方法可以使用导出的值作为默认值(默认值无法进行硬编码,它们是来自另一个堆栈运行的导出值),同时为用户提供了提供自己的值(创建资源)。

谢谢。

3 个答案:

答案 0 :(得分:2)

当前,Cloudformation不支持动态默认值。 CloudFormation不可能具有动态默认值。由于在收集所有参数时尚未执行模板。但是,您可以使用SSM参数作为解决方法,如下所示。

Parameters
    PagerDutyUrl:
        Type: AWS::SSM::Parameter::Value<String>
        Description: The Pagerduty url

回到您当前的cloudformation,我认为值$ {fmMainVpc}可能未正确初始化。

答案 1 :(得分:0)

这也可能是由于在Fn::ImportValue内部引用了错误的参数而引起的。例如,如果我定义了以下参数NetworkStackName,并且在Fn::ImportValue语句中错误引用了它(如NetworkName),则会出现此错误。我需要更改NetworkName以匹配Parameters中的值,NetworkStackName以解决错误。

Parameters:
  NetworkStackName:
      Type: String
      Default: happy-network-topology
Resources:
  MySQLDatabase:
    Type: AWS::RDS::DBInstance
    Properties:
      Engine: MySQL
      DBSubnetGroupName:
        Fn::ImportValue:
          !Sub "${NetworkName}-DBSubnetGroup"

答案 2 :(得分:0)

我遇到了一个问题,需要从必备堆栈中获取我的工件存储桶名称,我尝试这样做:

Fn::ImportValue:
    - 'arn:aws:s3:::${ArtifactStore}/*'

事实证明您可以执行此操作,并且可以正常工作。希望他有一天能帮助某人!

    - !Sub

        - 'arn:aws:s3:::${BucketName}/*'

        - BucketName : !ImportValue 'ArtifactStore'