如何解决在无服务器 yaml 配置中使用 fn::split 不起作用
我正在使用无服务器框架在 AWS 上部署 API。我的 serverless.yml
文件中有以下内容:
custom:
vpcSettings:
private:
securityGroupIds:
private:
fn::split:
delimiter: ','
value: ${env:VPC_SG_ID}
VPC_SG_ID
包含以下字符串:sg-1111111111,sg-222222222,sg-3333333333
但是,在部署应用程序时,出现以下错误:
An error occurred: MyLambdaFunction - Value of property SecurityGroupIds must be of type List of String.
如果我对 SG 列表进行硬编码,则它可以正常工作:
custom:
vpcSettings:
private:
securityGroupIds:
private:
- "sg-1111111111"
- "sg-2222222222"
- "sg-3333333333"
为什么 fn::split 函数不返回字符串列表?
编辑:
以下配置导致同样的错误
custom:
vpcSettings:
private:
securityGroupIds:
private:
Fn::Split:
- ','
- ${env:VPC_SG_ID}
解决方法
如果安全组作为输入参数添加到模板
Parameters:
VPCSGID:
Type: String
Description: Comma separated Security Groups
安全组可以用 !Split
as 分割
SecurityGroupIds: !Split [",",!Ref VPCSGID]
可以用 Fn:Split
as 分割
SecurityGroupIds: { "Fn::Split": [",!Ref VPCSGID] }
sam deploy 的参数可以作为
sam deploy --parameter-overrides 'ParameterKey=VPCSGID,ParameterValue=sg-011111,sg-222222'
,
我正在尝试实现相同的目标,但我很确定您不能在 Fn::Split
中使用 CloudFormation 函数 (serverless.yml
)。
替代方案 1
通过 env vars 传递 YAML 列表/数组对于无服务器似乎是不可能的,因为我们无法编写代码来解析来自 env vars 的字符串。也许你可以写一个无服务器插件,但我还没有研究过。
我假设您需要能够传递可变长度和任意值的列表,因此以下解决方案可能不适合您。
如果您有已知值,您可以将列表保存在 serverless.yml
中并选择一个带有环境变量的列表:
custom:
sgLists:
list1:
- sg-11
- sg-22
list2:
- sg-33
- sg-44
vpcSettings:
private:
securityGroupIds:
private: ${self:custom.sgLists.${env:LIST_SELECTOR}}
...然后您选择一个列表:
LIST_SELECTOR=list1 sls print
LIST_SELECTOR=list2 sls print
如果您需要任意值,并且您的列表不会太长,那么您可能会变得非常笨拙,并将每个列表项设为 env var:
custom:
sgLists:
twoItems:
- ${env:SG1}
- ${env:SG2}
threeItems:
- ${env:SG1}
- ${env:SG2}
- ${env:SG3}
vpcSettings:
private:
securityGroupIds:
private: ${self:custom.sgLists.${env:LIST_SELECTOR}}
..并提供所有内容作为环境变量:
LIST_SELECTOR=twoItems SG1=sg-11 SG2=sg-22 sls print
LIST_SELECTOR=threeItems SG1=sg-11 SG2=sg-22 SG3-33 sls print
替代方案 2
您还可以利用无服务器功能reference properties in other files。您可以创建一个小的 YAML 文件(从版本控制中忽略):
cd `dirname "$0"`
cat <<EOF > ../sgConfig.yml
groups:
- sg-11
- sg-22
EOF
...然后在您的 serverless.yml
中引用该文件:
custom:
vpcSettings:
private:
securityGroupIds:
private: ${file(./sgConfig.yml):groups}
解释错误信息
我认为您的错误消息是指您在需要 YAML 列表/数组时将 YAML 对象/字典传递到 private
中。关键是这与 YAML 语法有关。 Fn::Split
函数是 specific to AWS CloudFormation 函数,我猜这个函数的“执行”发生在 AWS 基础设施中。
我们可以通过更改您的代码来提供一个列表来测试这个理论:
private:
- fn::split: # add the "-" for a list
delimiter: ','
...然后你会看到一个类似
的错误Configuration error at 'custom.vpcSettings.private.securityGroupIds.private[0]': should be string
这意味着我们修复了之前的错误,但现在我们遇到了同样的问题,但降低了一级,因为 fn::split:
是一个 YAML 对象/字典。您还可以添加另一个列表项,例如:
private:
- blah # add this line
- fn::split:
delimiter: ','
..并且您将看到错误消息更改为引用索引 [1]
。要证明 fn::split
值并不特殊,请将其更改为其他值,例如:
private:
- blah
- asdf: # change this line
delimiter: ','
...你会看到错误信息没有改变。这是因为 Serverless 不关心 CloudFormation 函数,它只是检查 YAML 模式匹配。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。