Reputation: 377
i have piece of cloudFormation code
"dareMeXDevCloudwatchMissingPayoutsJob": {
"Type": "AWS::Events::Rule",
"DependsOn": [
"xxx"
],
"Properties": {
"Description": "xxxxx)",
"RoleArn": {
"Fn::GetAtt": [
"xxxxx",
"Arn"
]
},
"Name": "xxxxx",
"ScheduleExpression": "cron(0 8 ? * 6 *)",
"State": "ENABLED",
"Targets": [
{
"Arn": {
"Fn::GetAtt": [
"xxxxxxx",
"Arn"
]
},
"Id": "xxxx",
"Input": "{\"val1\":\"val1\",\"secretVal\":\"??????????????????\"}"
}
]
}
}
the thing I want to accomplish, is passing Secrets Manager value to variable secretVal
I tried to do this by setting secretVal value to {{resolve:secretsmanager:{arn of secret}:SecretString}}
, but then on cloudWatch event I have optput like {"val1": "val1", "secretVal": "{{resolve:secretsmanager:{arn of secret}:SecretString}}"}
When I tried to set for example Name to {{resolve:secretsmanager:{arn of secret}:SecretString}}
, then everything worked as it should, but with Input it just doesn't works. Do I do something wrong? Or maybe there is some other way of passing secret values to cloudWatch event body? Thanks from advance!
Upvotes: 5
Views: 13202
Reputation: 377
@RobS this wouldn't work in my use case anyways. the goal was to make normal api lambda for handling users requests also available to:
-be invoked periodically based on fixed cron expression
-be invoked by itself, but at some future point of time
this key was just a protection from end users. as I get response from AWS, this is possible by making child CloudFormation stack
Parent stack snippet
"Resources": {
"MySecretB": {
"Type": "AWS::SecretsManager::Secret",
"Properties": {
"Name": "MySecretForAppA",
"Description": "This secret has a hardcoded password in SecretString (use GenerateSecretString instead)",
"SecretString": "{\"username\":\"MasterUsername\",\"password\":\"secret-password\"}"
}
},
"Test": {
"DependsOn" : "MySecretB",
"Type": "AWS::CloudFormation::Stack",
"Properties": {
"Parameters": {
"Key": {
"Fn::Sub": ["${value1}", {
"value1": "{{resolve:secretsmanager:MySecretForAppA:SecretString:username}}"
}]
}
},
"TemplateURL" : "https://s3.amazonaws.com/mybucketname/childstack.json "
}
}
}
Child stack snippet
"Parameters": {
"Key":{
"Type":"String"
}
},
"Resources": {
"ScheduledRule": {
"Type": "AWS::Events::Rule",
"Properties": {
"ScheduleExpression": "rate(1 minute)",
"Description": "ScheduledRule",
"Targets": [
{
"Arn": "arn:aws:lambda:us-east-1:380574440275:function:LambdaFunction",
"Id": "TargetFunctionV1",
"Input": {"Fn::Sub": "{\"Input\": \"${Key}\"}"}
}
]
}
}
}
Like you told, passing a secret into a CW event is probably not a good idea
, so I just made another lambda function, which is unavailable to end users. it's possible to invoke it only from cloudWatch events
Upvotes: 2
Reputation: 69
Instead of passing the secret in as a input, you could just call GetSecretValue directly in the lambda function you are trying to invoke. If you need to differentiate the secret on per event rule, pass in the secret name to the target input and skip the resolve syntax altogether.
Passing a secret into a CW event is probably not a good idea. Even if this worked (it didn't work when I tried it), you'd be be able to see the secret in plain text in the CW Events console, which you'd probably not want.
Edit: Secrets Manager provided a helpful guide on best practices with lambda functions. Ideally, the lambda would run a caching client instead of calling GetSecretValue every time it is invoked.
Upvotes: 1