在 Cloudformation YAML 中,在多行字符串中使用 Ref(?使用 Fn:Sub)
In Cloudformation YAML, use a Ref in a multiline string (? use Fn:Sub)
假设您有一个 aws 资源,例如
Resources:
IdentityPool:
Type: "AWS::Cognito::IdentityPool"
Properties:
IdentityPoolName: ${self:custom.appName}_${self:provider.stage}_identity
CognitoIdentityProviders:
- ClientId:
Ref: UserPoolClient
Ref for "AWS::Cognito::IdentityPool" returns 此资源的 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
有什么办法吗?
我找到了如何使用 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.
展示如何做到这一点
在 YAML 中使用管道符号 |
将以下所有缩进行转换为多行字符串。
一个管道,结合 !Sub
可以让你使用:
- 你的资源
Ref
return很值${YourResource}
- 他们的
Fn::GetAtt
return 值只有一个句点 ${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}',
}
使用 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",
}'
留在这里是因为我在做类似的事情时遇到了 Base64 编码错误,并且在搜索时出现了这个问题
一个解决方案。
在我的例子中,我使用多行字符串 + !Sub
来填充 UserData 并在 AWS Cloudformation 中收到以下错误。
错误:
Invalid BASE64 encoding of user data. (Service: AmazonEC2; Status
Code: 400; Error Code: InvalidUserData.Malformed; Request ID: *;
Proxy: null)
解法:
可以通过组合两个内置的 Cloudformation 函数来解决; Fn::Base64
和 !Sub
:
UserData:
Fn::Base64: !Sub |
#!/bin/bash
echo ${SomeVar}
假设您有一个 aws 资源,例如
Resources:
IdentityPool:
Type: "AWS::Cognito::IdentityPool"
Properties:
IdentityPoolName: ${self:custom.appName}_${self:provider.stage}_identity
CognitoIdentityProviders:
- ClientId:
Ref: UserPoolClient
Ref for "AWS::Cognito::IdentityPool" returns 此资源的 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
有什么办法吗?
我找到了如何使用 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.
展示如何做到这一点在 YAML 中使用管道符号 |
将以下所有缩进行转换为多行字符串。
一个管道,结合 !Sub
可以让你使用:
- 你的资源
Ref
return很值${YourResource}
- 他们的
Fn::GetAtt
return 值只有一个句点${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}',
}
使用 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",
}'
留在这里是因为我在做类似的事情时遇到了 Base64 编码错误,并且在搜索时出现了这个问题 一个解决方案。
在我的例子中,我使用多行字符串 + !Sub
来填充 UserData 并在 AWS Cloudformation 中收到以下错误。
错误:
Invalid BASE64 encoding of user data. (Service: AmazonEC2; Status Code: 400; Error Code: InvalidUserData.Malformed; Request ID: *; Proxy: null)
解法:
可以通过组合两个内置的 Cloudformation 函数来解决; Fn::Base64
和 !Sub
:
UserData:
Fn::Base64: !Sub |
#!/bin/bash
echo ${SomeVar}