首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >YAML中的CloudFormation多行替换有可能吗?

YAML中的CloudFormation多行替换有可能吗?
EN

Stack Overflow用户
提问于 2019-03-20 20:43:37
回答 1查看 2.6K关注 0票数 1

我正试图在CFT中做一个多行替换,但这并没有发生。我所犯的错误是

An error occurred (ValidationError) when calling the ValidateTemplate operation: Template format error: unsupported structure.

这是非常难以描述的。我有用于intellij的CFT插件,它没有给我任何语法错误。这样的东西支持吗?问题线在Fn::Sub

根据这份文件的说法是这样的。

这是我正在处理的样品。我让整个CFT使用硬编码值,但我希望它处理从CFT导入的值,CFT创建了我要查看的堆栈的各个部分。

代码:

代码语言:javascript
复制
AWSTemplateFormatVersion: 2010-09-09
Description: "Per ticket: CLOUD-1284"
Parameters:
  LogGroupName:
    Type: String
    Default: "ct/dev-logs"
    AllowedValues: ["ct/dev-logs","ct/prod-logs"]
    Description: Enter CloudWatch Logs log group name. Default is ct/dev-logs

  Email:
    Type: String
    Description: Email address to notify when an API activity has triggered an alarm
    Default: cloudops@
Resources:
  PolicyUpdates:
    Type: AWS::Logs::MetricFilter
    Properties:
      FilterPattern:
        Fn::Sub:
        - >-
        { ($.eventSource = iam.amazonaws.com) &&
          (($.eventName = Update*) || ($.eventName = Attach*) || ($.eventName = Delete*) || ($.eventName = Detach*) ||($.eventName = Put*)) &&
          (($.requestParameters.roleName = ${Ec2Role}) || ($.requestParameters.roleName = ${RdsRole})) }
        - Ec2Role: !ImportValue infra-Ec2IamRole
        - RdsRole: !ImportValue infra-RdsIamRole

      LogGroupName: !Ref LogGroupName
      MetricTransformations:
      - MetricValue: 1
        MetricNamespace: SpecialMetrics
        MetricName: PolicyUpdateMetrics

  PolicyUpdatesAlarm:
    Type: AWS::CloudWatch::Alarm
    Properties:
      AlarmDescription: " Policies have have been updated"
      AlarmActions:
      - Ref: AlarmNotificationTopic
      MetricName: PolicyUpdateMetrics
      Namespace: SpecialMetrics
      Statistic: Sum
      Period: 10
      EvaluationPeriods: 1
      Threshold: 1
      ComparisonOperator: GreaterThanOrEqualToThreshold
      TreatMissingData: notBreaching

  S3BucketPolicyUpdates:
    Type: AWS::Logs::MetricFilter
    Properties:
      FilterPattern: >-
        { ($.eventSource = s3.amazonaws.com) && (($.eventName = Put*) || ($.eventName = Delete*)) &&
        (($.requestParameters.bucketName = assets-us-east-1) || ($.requestParameters.bucketName = logs-us-east-1)) }
      LogGroupName: !Ref LogGroupName
      MetricTransformations:
      - MetricValue: 1
        MetricNamespace: SpecialMetrics
        MetricName: S3BucketPolicyUpdateMetric

  S3BucketPolicyUpdatesAlarm:
    Type: AWS::CloudWatch::Alarm
    Properties:
      AlarmDescription: " S3 bucket security settings have been updated"
      AlarmActions:
      - Ref: AlarmNotificationTopic
      MetricName: S3BucketPolicyUpdateMetric
      Namespace: SpecialMetrics
      Statistic: Sum
      Period: 10
      EvaluationPeriods: 1
      Threshold: 1
      ComparisonOperator: GreaterThanOrEqualToThreshold
      TreatMissingData: notBreaching

  AlarmNotificationTopic:
    Type: AWS::SNS::Topic
    Properties:
      Subscription:
      - Endpoint: !Ref Email
        Protocol: email
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-03-21 03:13:29

是的,但你只需要修正语法。

修复:

下面是代码的简化版本,显示了正确的语法:

代码语言:javascript
复制
---
AWSTemplateFormatVersion: 2010-09-09
Description: Test Stack
Resources:
  PolicyUpdates:
    Type: AWS::Logs::MetricFilter
    Properties:
      FilterPattern:
        Fn::Sub:
        - >-
          { ($.eventSource = iam.amazonaws.com) &&
          (($.eventName = Update*) || ($.eventName = Attach*) || ($.eventName = Delete*) || ($.eventName = Detach*) ||($.eventName = Put*)) &&
          (($.requestParameters.roleName = ${Ec2Role}) || ($.requestParameters.roleName = ${RdsRole})) }
        - {Ec2Role: MyEc2Role, RdsRole: MyRdsRole}
      LogGroupName: !Ref LogGroup
      MetricTransformations:
      - MetricValue: 1
        MetricNamespace: SpecialMetrics
        MetricName: PolicyUpdateMetrics

  LogGroup:
    Type: AWS::Logs::LogGroup

在创建该堆栈时,将创建以下度量过滤器:

代码语言:javascript
复制
▶ aws logs describe-metric-filters --query 'metricFilters[].filterPattern' 
[
    "{ ($.eventSource = iam.amazonaws.com) && (($.eventName = Update*) || ($.eventName = Attach*) || ($.eventName = Delete*) || ($.eventName = Detach*) ||($.eventName = Put*)) && (($.requestParameters.roleName = MyEc2Role) || ($.requestParameters.roleName = MyRdsRole)) }"
]

因此,需要将Fn::Sub更改为:

代码语言:javascript
复制
FilterPattern:
  Fn::Sub:
    - >-
      { ($.eventSource = iam.amazonaws.com) &&
        (($.eventName = Update*) || ($.eventName = Attach*) || ($.eventName = Delete*) || ($.eventName = Detach*) ||($.eventName = Put*)) &&
        (($.requestParameters.roleName = ${Ec2Role}) || ($.requestParameters.roleName = ${RdsRole})) }
    - {Ec2Role: !ImportValue infra-Ec2IamRole, RdsRole: !ImportValue infra-RdsIamRole}

如何获得更好的错误消息:

我所做的第一件事是运行cloudformation template:

代码语言:javascript
复制
▶ aws cloudformation validate-template --template-body file://cloudformation.yml

An error occurred (ValidationError) when calling the ValidateTemplate operation:
  Template format error: YAML not well-formed. (line 23, column 45)                    

由于这是YAML格式问题,所以亚姆林特实用程序通常提供更多信息:

代码语言:javascript
复制
▶ yamllint cloudformation.yml 
cloudformation.yml
  23:45     error    syntax error: could not find expected ':'

进入vim编辑器并发出命令:

代码语言:javascript
复制
:cal cursor(23,45)

带我到第23行,第45列,在那里我找到字符串${Ec2Role}的开头。

我看到的第一个问题是缩进是错误的。这就是那个信息的真正原因。

通过缩进第21-23行×2个空格,使模板有效。然后,我得到了来自cloudformation template的更有帮助的响应:

代码语言:javascript
复制
▶ aws cloudformation validate-template --template-body file://cloudformation.yml 

An error occurred (ValidationError) when calling the ValidateTemplate operation:
  Template error: One or more Fn::Sub intrinsic functions don't specify expected
  arguments. Specify a string as first argument, and an optional second argument
  to specify a mapping of values to replace in the string

此时,从文档中可以看出,对Fn::Sub的调用在语法上是错误的。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/55269856

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档