在 Cloudformation YAML 中,在多行字符串中使用 Ref(?使用 Fn:Sub)

Posted

技术标签:

【中文标题】在 Cloudformation YAML 中,在多行字符串中使用 Ref(?使用 Fn:Sub)【英文标题】:In Cloudformation YAML, use a Ref in a multiline string (? use Fn:Sub) 【发布时间】:2018-10-08 18:09:58 【问题描述】:

假设您有一个 aws 资源,例如

  Resources:
    IdentityPool:
      Type: "AWS::Cognito::IdentityPool"
      Properties:
        IdentityPoolName: $self:custom.appName_$self:provider.stage_identity
        CognitoIdentityProviders:
          - ClientId:
              Ref: UserPoolClient

“AWS::Cognito::IdentityPool”的 Ref 返回此资源的 ID。现在假设我想在多行字符串中引用该 id。我试过了

Outputs:  
  AmplifyConfig:
    Description: key/values to be passed to Amplify.configure(config);
    Value: |
      
        'aws_cognito_identity_pool_id': $Ref: IdentityPool, ##<------ Error
        'aws_sign_in_enabled': 'enable',
        'aws_user_pools_mfa_type': 'OFF',
      

我也尝试过使用 Fn:Sub 但没有运气。

   AmplifyConfig:
      Description: key/values to be passed to Amplify.configure(config);
      Value: 
        Fn::Sub 
          - |
            
              'aws_cognito_identity_pool_id': '$Var1Name',
              'aws_sign_in_enabled': 'enable',
            
          - Var1Name:
              Ref: IdentityPool

有什么办法吗?

【问题讨论】:

【参考方案1】:

我发现了如何使用 Join 来做到这一点

AmplifyConfig:
  Description: key/values to be passed to Amplify.configure(config);
  Value:
    Fn::Join:
      - ''
      - - ""
        - "\n  'aws_cognito_identity_pool_id':"
        - Ref : IdentityPool
        - "\n  'aws_user_pools_id':"
        - Ref : UserPool
        - "\n  'aws_user_pools_web_client_id':"
        - Ref : UserPoolClient
        - ",\n  'aws_cognito_region': '$self:provider.region'"
        - ",\n  'aws_sign_in_enabled': 'enable'"
        - ",\n  'aws_user_pools': 'enable'"
        - ",\n  'aws_user_pools_mfa_type': 'OFF'"
        - "\n"

这可行,但有点难看。我将暂时不接受这个答案,看看是否有人可以展示如何使用 Fn::Sub 执行此操作。

【讨论】:

考虑通过切换已接受的答案来表彰 Clorichel 的解决方案【参考方案2】:

在 YAML 中使用管道符号 | 会将以下所有缩进的行转换为多行字符串。

一个管道,结合!Sub 可以让你使用:

您的资源Ref 轻松返回值,如$YourResource 他们的Fn::GetAtt 返回值只有一个句点$YourResource.TheAttribute 任何伪参数就像$AWS:region

就像!Sub | 一样简单,跳转到下一行并添加适当的缩进。示例:

Resources:
  YourUserPool:
    Type: AWS::Cognito::UserPool
    Properties:
      UserPoolName: blabla

Outputs:
  AmplifyConfig:
    Description: key/values to be passed to Amplify.configure(config);
    Value: !Sub |
      
        'aws_cognito_identity_pool_id': '$YourUserPool',
        'aws_sign_in_enabled': 'enable',
        'aws_user_pools_mfa_type': 'OFF',
      
  AdvancedUsage:
    Description: use Pseudo Parameters and/or resources attributes
    Value: !Sub |
      
        'aws_region': '$AWS::Region',
        'user_pool_arn': '$YourUserPool.Arn',
      

【讨论】:

你如何对 JSON 做同样的事情? @San 您可以使用CloudFormation designer 来转换 YAML 和 JSON,请参阅 docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/… :只需粘贴上面的模板 sn-p 然后从 YAML 切换“选择模板语言”输入单选转 JSON 如果您需要使用 !FindInMap 怎么办?我知道我可以使用 !Sub ['$var', var: !FindInMap [...] ] 当 '$var' 只有 1 行长,但当它是多行时?跨度> 【参考方案3】:

使用 YAML 你可以简单地编写这个:

Outputs:  
  AmplifyConfig:
    Description: key/values to be passed to Amplify.configure(config);
    Value: !Sub '
      
        "aws_cognito_identity_pool_id": "$IdentityPool",
        "aws_sign_in_enabled": "enable",
        "aws_user_pools_mfa_type": "OFF",
      '

【讨论】:

【参考方案4】:

因为我在执行类似操作时遇到 Base64 编码错误并且在搜索 一个解决方案。

在我的情况下,我使用多行字符串 + !Sub 填充 UserData 并在 AWS Cloudformation 中收到以下错误。

错误:

用户数据的 BASE64 编码无效。 (服务:AmazonEC2;状态 代码:400;错误代码:InvalidUserData.Malformed;请求编号:*; 代理:空)

解决方案:

可以通过结合两个内置的 Cloudformation 函数来解决; Fn::Base64!Sub:

UserData: 
    Fn::Base64: !Sub | 
    #!/bin/bash
    echo $SomeVar

【讨论】:

以上是关于在 Cloudformation YAML 中,在多行字符串中使用 Ref(?使用 Fn:Sub)的主要内容,如果未能解决你的问题,请参考以下文章

使用 Python 加载 CloudFormation YAML

在 CloudFormation yaml 中创建 BucketPolicy 时出错

如何在 AWS CloudFormation YAML 模板中转义策略变量

AWS Cloudformation-如何在 json/yaml 模板中处理字符串大写或小写

在 Cloudformation YAML 中,在多行字符串中使用 Ref(?使用 Fn:Sub)

yaml中的Cloudformation嵌套堆栈输出