无法通过 cloudformation yaml 创建 AWS::ECS::Service,模型验证失败

Posted

技术标签:

【中文标题】无法通过 cloudformation yaml 创建 AWS::ECS::Service,模型验证失败【英文标题】:Could not create AWS::ECS::Service via cloudformation yaml, got Model validation failed 【发布时间】:2021-01-22 13:38:30 【问题描述】:

在通过 cloudformation 创建 AWS::ECS::Service 期间出现错误:Model validation failed

错误与#HealthCheckGracePeriodSeconds 和其他一些属性有关。错误详情为:expected type: Number, found: String

在 yaml 中它已经是一个数字。我不清楚出了什么问题。已经尝试将其声明为字符串或 Number 类型的参数。

我需要一些提示,因为此时我陷入了困境。

错误是:

Model validation failed 
    (
    #/HealthCheckGracePeriodSeconds: expected type: Number, found: String 
    #/DesiredCount: expected type: Number, found: String 
    #/DeploymentConfiguration/MaximumPercent: expected type: Number, found: String 
    #/DeploymentConfiguration/MinimumHealthyPercent: expected type: Number, found: String
    )

template.yaml 中的定义是:

ServiceDefinition:
  Type: AWS::ECS::Service
  Properties:
    ServiceName: !Ref ServiceName
    Cluster: !Ref ClusterName
    TaskDefinition: !Ref TaskDefinition
    DeploymentConfiguration:
      MinimumHealthyPercent: 100
      MaximumPercent: 200
    DesiredCount: 1
    HealthCheckGracePeriodSeconds: 60
    LaunchType: FARGATE
    NetworkConfiguration:
      AwsVpcConfiguration:
        AssignPublicIP: ENABLED
        SecurityGroups: !FindInMap [Env2SecurityGroups, !Ref AWS::AccountId, securitygroup]
        Subnets: !FindInMap [Env2PublicSubnets, !Ref AWS::AccountId, subnets]

【问题讨论】:

这看起来不错。您确定这是给出错误的资源吗? 类似于***.com/questions/64327964/… 【参考方案1】:

该错误是因为SecurityGroupsSubnets 导致格式错误。

要提取subnetssecuritygroups,使用了FindInMap 函数。这个结果必须是一个列表。这可以使用Split 函数来实现。

不幸的是,错误的格式会导致完全误导的错误消息。

像这样声明映射:

Mappings
  Env2SecurityGroups:
    '111111111111':
      securitygroup: 'sg-1111111111111111'
    '222222222222':
      securitygroup: 'sg-2222222222222222'
    '333333333333':
      securitygroup: 'sg-3333333333333333'

  Env2PublicSubnets:
    '111111111111':
      subnets: subnet-1111111111111111,subnet-22222222222222222,subnet-33333333333333333
    '222222222222':
      subnets: subnet-1111111111111111,subnet-22222222222222222,subnet-33333333333333333
    '333333333333':
      subnets: subnet-1111111111111111,subnet-22222222222222222,subnet-33333333333333333

使用!Split 结合!FindInMap 得到一个列表:

SecurityGroups: !Split [",", !FindInMap [ Env2SecurityGroups, !Ref AWS::AccountId, securitygroup] ]
Subnets: !Split [",", !FindInMap [ Env2PublicSubnets, !Ref AWS::AccountId, subnets] ]

【讨论】:

我很好奇您是如何解决“预期类型:数字”错误的,因为我在设置任务定义时遇到了同样的错误。目前尚不清楚这个答案与问题中的错误有何关系。 其实我想我现在明白了。似乎该错误具有误导性。数字转换实际上不是失败的原因。故障在别处,CF 错误报告。 CloudFormation 的另一个问题。错误不一定与问题相关。 在我的情况下,我需要在错误列表中进一步查看,以找到更有意义并解决误导性错误的错误 我认为这可能与错误完全相关,但方式不同。模板某些部分的无效值可能会导致只能在运行时知道的其他副作用。例如,当 Import 语句返回特殊字符(如不均匀引号)时,它可能会损坏整个文件,导致运行时出现意外错误

以上是关于无法通过 cloudformation yaml 创建 AWS::ECS::Service,模型验证失败的主要内容,如果未能解决你的问题,请参考以下文章

AWS Cloudformation遇到不受支持的属性类型

yaml中的Cloudformation嵌套堆栈输出

如何在 cloudformation 策略文档中引用资源 ARN? (yaml)

使用 Python 加载 CloudFormation YAML

在 CloudFormation yaml 中创建 BucketPolicy 时出错

python 将Cloudformation JSON转换为YAML