Is it possible to perform some sort of mathematical operation in a CloudFormation template?
There are two areas that I've encountered where this would be useful:
There are two general solutions to performing custom logic in CloudFormation templates not supported by Intrinsic Functions, such as mathematical operations:
Write a Custom Resource to execute your mathematical operation, passing inputs as Properties and outputs as Values. Here's a self-contained working example that returns Result: 13
as a Stack Output:
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
Use a full-featured templating language/platform of your choice to write a 'source' template that produces a valid CloudFormation-template as output. You can use a full-featured CloudFormation-specific library like troposphere, but it's also easy enough to write a simple preprocessor layer to suit your use-case and programming-language/library preferences.
My current choice is embedded Ruby (ERB), mostly because I'm already familiar with it. Here's an example template.yml.erb
file using embedded Ruby syntax to perform a mathematical operation that returns Result: 13
as a Stack Output:
Resources:
# CloudFormation stacks require at least one resource
Dummy:
Type: AWS::SNS::Topic
Outputs:
Result:
Description: Result
Value: <%= 8 + 5 %>
To process the template, run cat template.yml.erb | ruby -rerb -e "puts ERB.new(ARGF.read, nil, '-').result" > template.yml
, which will write the following CloudFormation-ready template to template.yml
:
Resources:
# CloudFormation stacks require at least one resource
Dummy:
Type: AWS::SNS::Topic
Outputs:
Result:
Description: Result
Value: 13
Much later in 2022...
This is one reason for using CDK, which provides a code wrapper (e.g. Javascript, Typescript etc.) over CloudFormation and makes calculations, conditionals sharing etc. much simpler than is possible when only using CloudFormation templates.
Is it still a hack if you limit the range of the 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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With