I have an AWS SAM application with a function that contains a schedule
event, and I wish to conditionally enable/disable the EventBridge rule that is generated for the event based on the value of a parameter.
To do this, I've done the following in template.yaml -
FunctionEnabled
parameter, which allows only [ 'true', 'false' ]
as its value.EnableFunction
condition, which checks whether !Equals [ !Ref FunctionEnabled, 'true' ]
.Enabled
property for the schedule
event using !If [ EnableFunction, true, false ]
.However, when I build the template and deploy it, the EventBridge rule is always enabled, regardless of the value of the FunctionEnabled
parameter.
foo@bar:~/sam-project$ sam build -u
foo@bar:~/sam-project$ sam deploy --parameter-overrides FunctionEnabled=true
foo@bar:~/sam-project$ sam deploy --parameter-overrides FunctionEnabled=false
Note that the FunctionEnabled
output correctly shows true
or false
based on the value of the parameter, suggesting that the correct boolean value is being passed to the Enabled
property.
So how can I enable/disable the EventBridge rule based on the value of a parameter?
I wondered if the !If
function might be returning a string rather than a Boolean, so I tried to use the following condition functions as the value of of the Enabled
property for the schedule
event.
!Condition EnableFunction
!Equals [ !Ref FunctionEnabled, 'true' ]
However the result is still the same in both cases, so the EventBridge rule is still always enabled.
When I hardcode the value of the Enabled
property for the schedule
event to be false
, the EventBridge rule is disabled as expected.
Does this mean that all of the condition functions return a string as opposed to a Boolean?
def lambda_handler(event, context) -> dict:
return {
'statusCode': 200,
'headers': {
'AWS-Request-ID': context.aws_request_id,
'Content-Type': 'application/json'
},
'body': '{"message": "Hello World!!"}'
}
version = 0.1
[default.deploy.parameters]
capabilities = "CAPABILITY_IAM"
confirm_changeset = true
AWSTemplateFormatVersion: 2010-09-09
Transform: AWS::Serverless-2016-10-31
Parameters:
FunctionEnabled:
Description: Whether the EventBridge rule is enabled.
Type: String
AllowedValues: [ 'true', 'false' ]
Schedule:
Description: The schedule on which the EventBridge rule triggers the Function.
Type: String
Default: cron(0 3 1 * ? *)
Conditions:
EnableFunction: !Equals [ !Ref FunctionEnabled, 'true' ]
Globals:
Function:
Architectures:
- x86_64
Handler: app.lambda_handler
Runtime: python3.8
Timeout: 1
Resources:
FunctionLogGroup:
Type: AWS::Logs::LogGroup
Properties:
LogGroupName: !Sub "/aws/lambda/${Function}"
RetentionInDays: 7
FunctionRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Principal:
Service:
- lambda.amazonaws.com
Action:
- sts:AssumeRole
Policies:
- PolicyName: CloudWatch
PolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Action:
- logs:CreateLogGroup
- logs:CreateLogStream
- logs:PutLogEvents
Resource: '*'
Function:
Type: AWS::Serverless::Function
Properties:
CodeUri: code/.
Events:
ScheduleEvent:
Type: Schedule
Properties:
Enabled: !If [ EnableFunction, true, false ]
Schedule: !Ref Schedule
RetryPolicy:
MaximumEventAgeInSeconds: 100
MaximumRetryAttempts: 3
Role: !GetAtt FunctionRole.Arn
Outputs:
FunctionEnabled:
Description: The value of the 'Resources.Function.Properties.Events.ScheduleEvent.Properties.Enabled'.
Value: !If [ EnableFunction, true, false ]
This is completely undocumented, but rather than using Enabled: true|false
, it's possible to simply use the CloudFormation AWS::Events::Rule property State: ENABLED|DISABLED
.
It seems that SAM ignores intrinsic functions, so when transforming to CF it see's a value for Enabled
which it assumes as true
, and thus the rule is enabled. Note that this behaviour in itself seems different to that described in the documentation.
If this property is set to true then AWS SAM passes ENABLED, otherwise it passes DISABLED.
As I didn't get any traction here, I also opened a GitHub issue.