2

I'm in the processes of adding SAM templates to an existing serverless application. I have a no. of Lambdas which invoke other lambdas, and the invoker has policies that specify the ARN of the "invokee", or the invoked lambda. In this case, policy creation can be done once since my function name is static, e.g.:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": "lambda:InvokeFunction",
            "Resource": "arn:aws:lambda:us-west-2:[acct-no]:function:MyLambda"
        }
    ]
}

I can give the invoker a role with this policy without needing to changing it when I update the invokee. Under the SAM/CloudFormations framework however, the created function is automatically appended a string to its name, (e.g. arn:aws:lambda:us-west-2:[acct-no]:function:MyLambda-3kx71lzkhge3) which nullifies previously created policies as the old ARN is no longer valid, which makes me think I need to create the policy ARN dynamically.

I'm not sure what the correct way to do this is. My understanding is that the ARN is an output of sam deploy, so currently, I have in mind first deploying the invokee, noting the ARN, then updating the sam template of the invoker with the ARN, and then deploying the invoker. This however feels incorrect as it is a manual intervention of a process designed to be automated. I was wondering if there's another way to go about this, and would appreciate any insight anyone could lend.

MyStackRunnethOver
  • 4,872
  • 2
  • 28
  • 42
humanlikely
  • 315
  • 3
  • 10

1 Answers1

3

Your intuition is correct, you should not have to do anything manually, or use multiple deployments. CloudFormation will let you do this using a GetAtt call for the ARN of the other lambda. Here's an example from another question's answer:

"MyFieldName": "Fn::GetAtt": ["MyLambdaFunc","Arn"]

So your JSON would be:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": "lambda:InvokeFunction",
            "Resource": "Fn::GetAtt": ["MyLambda","Arn"]
        }
    ]
}
MyStackRunnethOver
  • 4,872
  • 2
  • 28
  • 42
  • 1
    Ah I see. I was wondering if there is a way to do this with multiple deployments (I'm assuming `MyLambdaFunc` in your answer is declared in the same SAM template). Is it possible for the invokee was to have its own SAM template, while still being automated (e.g. sendMailLambda invoked by APILambda and CronLambda -- here it wouldn't necessarily be good to group them all under the same stack) – humanlikely Nov 02 '21 at 15:54
  • 1
    It's always easier to have your whole app in one stack, if you can manage it (it's also the logical grouping for small apps without big shared resources like network stacks). Nested stacks are a good way to separate stack components for reuse, but most likely you want wholly separate stacks, which means the way is [cross-stack references](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/best-practices.html#cross-stack). There are [good questions already answered on the topic](https://stackoverflow.com/search?q=cloudformation+cross+stack+reference) – MyStackRunnethOver Nov 02 '21 at 16:08