如何在CloudFormation中执行数学运算?

14

在CloudFormation模板中是否可以执行某种数学运算?

我遇到了两个这将会很有用的领域:

  1. 设置需要是磁盘大小比率的IOPS。
  2. 为RDS免费存储空间设置CloudWatch警报。将其设置为磁盘大小的百分比将会很有用。
4个回答

16

有两种通用解决方案可以在CloudFormation模板中执行自定义逻辑,这些逻辑不受内置函数的支持,例如数学运算:

1. 自定义资源

编写自定义资源来执行您的数学运算,将输入作为属性传递,并将输出作为值返回。以下是一个自包含的工作示例,它将Result: 13作为堆栈输出返回:

Launch Stack

Resources:
  LambdaExecutionRole:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Version: '2012-10-17'
        Statement:
        - Effect: Allow
          Principal: {Service: [lambda.amazonaws.com]}
          Action: ['sts:AssumeRole']
      Path: "/"
      ManagedPolicyArns:
      - arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole
  AddFunction:
    Type: AWS::Lambda::Function
    Properties:
      Handler: index.handler
      Role: !GetAtt LambdaExecutionRole.Arn
      Code:
        ZipFile: !Sub |
          var response = require('cfn-response');
          exports.handler = function(event, context) {
            var result = parseInt(event.ResourceProperties.Op1) + parseInt(event.ResourceProperties.Op2);
            response.send(event, context, response.SUCCESS, {Value: result});
          };
      Runtime: nodejs
  AddTest:
    Type: Custom::Add
    Properties:
      ServiceToken: !GetAtt AddFunction.Arn
      Op1: 8
      Op2: 5
Outputs:
  Result:
    Description: Result
    Value: !GetAtt AddTest.Value

2. 模板预处理器

使用您选择的全功能模板语言/平台编写一个“源”模板,以产生有效的CloudFormation模板作为输出。您可以使用类似troposphere的全功能CloudFormation特定库,但也很容易编写一个简单的预处理层以适应您的用例和编程语言/库偏好。

我目前的选择是嵌入式Ruby(ERB),主要是因为我已经熟悉它。这里有一个使用嵌入式Ruby语法执行数学运算并将Result:13作为Stack输出返回的示例template.yml.erb文件:

Resources:
  # CloudFormation stacks require at least one resource
  Dummy:
    Type: AWS::SNS::Topic
Outputs:
  Result:
    Description: Result
    Value: <%= 8 + 5 %>

要处理模板,请运行cat template.yml.erb | ruby -rerb -e "puts ERB.new(ARGF.read, nil, '-').result" > template.yml,这将把以下适用于CloudFormation的模板写入template.yml
Resources:
  # CloudFormation stacks require at least one resource
  Dummy:
    Type: AWS::SNS::Topic
Outputs:
  Result:
    Description: Result
    Value: 13

4
在第一个例子中,是否会启动一个完整的 Lambda 函数来执行 5+8? - Paula T
@PaulaT 你懂了 - Drewry Pope
如果服务需要频繁部署,这似乎有点过度和昂贵。 - Paula T
1
Lambda的费用是每百万次调用大约22美分,因此如果这个成本对您的使用情况来说过高,请优先选择选项2。 - wjordan

3

2022年后期...

这是使用CDK的一个原因,它提供了一个代码包装器(例如JavaScript、TypeScript等),可以比仅使用CloudFormation模板时更简单地进行计算、条件共享等。


1

如果您限制StartingValue的范围,那么这仍然是一种黑客攻击吗?

Parameters:
  StartingValue:
    MinValue: 0
    MaxValue: 7
    Type: Number
Outputs:
  MinusOne:
    Value: !Select [ !Ref StartingValue, ["-1","0","1","2","3","4","5","6"] ]
  PlusOne:
    Value: !Select [ !Ref StartingValue, ["1","2","3","4","5","6","7","8"] ]
  TimesTwo:
    Value: !Select [ !Ref StartingValue, ["0","2","4","6","8","10","12","14"] ] 

https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/intrinsic-function-reference-select.html


0

我使用预处理系统取得了很好的成功。通常,我会查看模板和变量数据,并根据这些数据做出决策。

以下是关于该问题的博客文章:

http://krogebry.blogspot.com/2014/12/cloudformation-discovery-and.html

在撰写本文时,我们遇到了许多VPC和非常复杂的帐户管理系统问题。您所说的似乎是类似思路,即您有一些复杂(而且很棒!)的要求,可能需要类似的方法。此外,编译这样的堆栈还具有能够根据您的用例强制执行某些规则(例如,在dev中没有0.0.0.0:22或没有IOPS>x阈值)的附加好处。


很遗憾,这个链接不再可用。 - nofinator

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接