【问题标题】:AWS CloudFormation - using !Ref inside !SubAWS CloudFormation - 在 !Sub 中使用 !Ref
【发布时间】:2020-11-26 23:41:00
【问题描述】:

我正在编写创建 AWS Service Catalog 产品的 AWS CloudFormation 模板(使用 yaml)。 我正在使用参数 S3FilePath 获取产品的模板,该参数的值类似于上述路径:https://bucket.s3-eu-west-1.amazonaws.com/template.yml。 文件的 URL 需要以 JSON 格式发送,如下所示(此示例有效):

Resources:
    Type: AWS::ServiceCatalog::CloudFormationProduct
    Properties: 
      Description: Example Product
      Distributor: xyz
      Name: ExampleProduct
      Owner: xyz
      ProvisioningArtifactParameters: 
        - Description: Example Product
          Info: { "LoadTemplateFromURL": "https://bucket.s3-eu-west-1.amazonaws.com/template.yml" }
          Name: Version1

我尝试使用 !Sub 和 !Ref 替换 URL,如下所示:

Parameters:
  S3FilePath:
      Type: String
      Description: file name
Resources:
    Type: AWS::ServiceCatalog::CloudFormationProduct
    Properties: 
      Description: Example Product
      Distributor: xyz
      Name: ExampleProduct
      Owner: xyz
      ProvisioningArtifactParameters: 
        - Description: Example Product
          Info: !Sub
            - '{ "LoadTemplateFromURL": "${FILEPATH}" }'
            - {FILEPATH: !Ref S3FilePath}
          Name: Version1

但 CloudFormation 堆栈失败并出现错误:“无效输入”。 我想我以错误的方式构建 JSON,我尝试在每个 '"' 之前使用 \ 但它也没有帮助,我找不到解释如何正确构建它的示例。没有问题S3FilePath 参数。

您能否建议如何正确使用 !Sub 和 !Ref 来构建 JSON?谢谢。

【问题讨论】:

    标签: json amazon-web-services yaml amazon-cloudformation aws-service-catalog


    【解决方案1】:

    我觉得应该很简单:

         ProvisioningArtifactParameters: 
            - Description: Example Product
              Info: 
                LoadTemplateFromURL: !Ref S3FilePath
              Name: Version1
    

    这至少是我自己的AWS::ServiceCatalog::CloudFormationProduct 模板中的内容。

          ProvisioningArtifactParameters: 
            - DisableTemplateValidation: false
              Info: 
                LoadTemplateFromURL: !Ref S3FilePath
    

    【讨论】:

    • 嗨,我已经尝试过,但仍然得到 UPDATE_ROLLBACK_COMPLETE: ["Invalid Input."]
    • @YuvalPodoksik 所以原因可能在其他地方。这是我使用的形式,它有效。 S3FilePath 长什么样子?
    • 在上面的场景中它的值是“bucket.s3-eu-west-1.amazonaws.com/template.yml”,我试过带引号和不带引号,你能告诉我这个值在你的代码中是什么样子的吗?
    • @YuvalPodoksik 在我的情况下,它是完整的 url,以 https:// 开头,例如https://my-service-catalog-bucket.s3.amazonaws.com/template.yaml.
    • 我在上面的评论中错误地粘贴了它,它的值是“bucket.s3-eu-west-1.amazonaws.com/template.yml”所以我仍然不确定是什么问题..
    【解决方案2】:

    您可以直接在 !Sub 中引用任何参数或 LogicalResourceId,如下所示:

      ProvisioningArtifactParameters: 
        - Description: Example Product
          Info: !Sub '{ "LoadTemplateFromURL": "${S3FilePath}" }'
          Name: Version1
    

    这应该工作得很好。当您想在 !Sub 中使用条件和/或映射时,您进行替换的方式很有用。

    【讨论】:

    • 嗨,我试过了。然而,得到同样的错误:[属性值 {/ProvisioningArtifactParameters/0/Info} 与类型 {Map} 不匹配]。收到 EOF,停止接收循环:err="rpc 错误:代码 = 不可用 desc = 传输正在关闭" UPDATE_ROLLBACK_COMPLETE: ["无效输入。"]
    • 我的错,但请接受我对!Sub 的建议,这样使用起来更容易。让我看看我是否还能提供帮助,我过去已经遇到过类似的错误。
    【解决方案3】:

    这里是一个例子:https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/intrinsic-function-reference-sub.html#w2ab1c25c28c59c11

    尽管文档说 Info 参数是 JSON,但该示例仅显示了一个名称/值对(映射):https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-servicecatalog-cloudformationproduct-provisioningartifactproperties.html

    尝试将字符串格式化为

    Info: !Sub
      - "LoadTemplateFromURL": "${FILEPATH}"
      - {FILEPATH: !Ref S3FilePath}
    

    【讨论】:

    • 您好,我已尝试这样做,但仍然出现错误。这次我启用了跟踪,但出现以下扩展错误:属性验证失败:[属性值 {/ProvisioningArtifactParameters/0/Info} 与类型 {Map} 不匹配]
    • 我更新了示例以匹配docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/…中列出的示例
    • 嗨,也尝试了更新的示例,但是,得到相同的错误:[属性值 {/ProvisioningArtifactParameters/0/Info} 与类型 {Map} 不匹配]。收到 EOF,停止 recv 循环:err="rpc 错误:代码 = 不可用 desc = 传输正在关闭" UPDATE_ROLLBACK_COMPLETE: ["无效输入。"]
    猜你喜欢
    • 2018-12-25
    • 2020-07-20
    • 2020-08-29
    • 2020-06-13
    • 2019-12-13
    • 2018-01-24
    • 2017-01-11
    • 2019-12-02
    • 2019-05-13
    相关资源
    最近更新 更多