Introduction
During this short article we will look at creating a cross account golang lambda.
To do this, we will:
- Explore permissions required
- Create our receiving lambda + resource policy
- Create our sending lambda + identity policy
- Test the lambda works as expected
Permissions!
Permissions are typically one of the hardest parts of any well designed system.
We will be using a resource-based policy to allow access to our Lambda from a second account. Resource based policies are a good way to grant other accounts and AWS services permission to use your Lambda.
While identity-based policies are attached to an IAM user, group or role. Resource-based policies are attached to the resource directly.
Resource policies are only supported on less than 10% of AWS services, for the full list please visit this link. You will find that a lot of the core AWS services support resource policies (Lambda, ECR, S3, SNS, SQS, etc.).
Since they support lambda, this makes them an ideal fit for invoking our lambda between different accounts.
Notes
Please note that during this article we will use two account ids to keep this easy to follow:
- Sending Lambda: 111122223333
- Receiving Lambda: 999988887777
You will need to replace these in your own examples.
Receiving Lambda Code + Resource Policy
Receiving Lambda Code
First up, we need to create the lambda that will be invoked. Visit this link if you need detailed instructions on deploying this HelloWorld style lambda.
package main
import (
"log"
"context"
"github.com/aws/aws-lambda-go/lambda"
)
func handler(ctx context.Context) error {
log.Println("HelloWorld from Golang Lambda")
return nil
}
func main() {
lambda.Start(handler)
}
Resource Policy
Next up we need to create the resource policy so that our sending account can trigger this lambda.
If you're working from the console then on your newly created Lambda goto Configuration -> Permissions -> Resource-based policy -> Add permissions

Then create the policy (make sure to replace the Account IDs with your own):
{
"Version": "2012-10-17",
"Id": "default",
"Statement": [
{
"Sid": "lambda-cross-account-invoke",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::111122223333:root"
},
"Action": "lambda:InvokeFunction",
"Resource": "arn:aws:lambda:eu-west-1:999988887777:function:ReceivingLambda"
}
]
}
Sending Lambda Code + Identity Policy
Sending Lambda Code
Now we need to trigger our lambda, so log in to the account that will be sending the request and create a second lambda:
package main
import (
"fmt"
"log"
"context"
"github.com/aws/aws-lambda-go/events"
"github.com/aws/aws-sdk-go-v2/aws"
"github.com/aws/aws-sdk-go-v2/config"
"github.com/aws/aws-sdk-go-v2/service/lambda"
gl "github.com/aws/aws-lambda-go/lambda"
)
func handler(ctx context.Context, request events.APIGatewayProxyRequest) error {
log.Println("Triggering request to second lambda")
cfg, err := config.LoadDefaultConfig(context.TODO(),
config.WithRegion("eu-west-1"),
)
if err != nil {
fmt.Printf(err.Error())
return nil
}
svc := lambda.NewFromConfig(cfg)
result, err := svc.Invoke(context.TODO(),
&lambda.InvokeInput{
FunctionName: aws.String("arn:aws:lambda:eu-west-1:999988887777:function:ReceivingLambda"),
Payload: []byte("{\"hello\": \"world\"}"),
},
)
if err != nil {
fmt.Println(err)
return nil
}
fmt.Println("StatusCode: ", result.StatusCode)
if result.StatusCode != 200 {
fmt.Println("Failed to invoke second lambda")
return nil
}
fmt.Println("Success! Second lambda invoked successfully")
return nil
}
func main() {
gl.Start(handler)
}
As you can see I have included the code needed to Invoke the receiving lambda we created earlier. Make sure to replace the arn link with your own.
Identity Policy
Now to add an identity-based policy to the sending lambda, to allow it to invoke the lambda in the receiving account.

Then add this policy to the existing role:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"lambda:InvokeFunction"
],
"Resource": [
"arn:aws:lambda:eu-west-1:999988887777:function:ReceivingLambda"
]
}
]
}
Testing our Lambda
To test this works, simply log into our sending account and test the lambda.
Now if it worked, you should see this output:
2022/07/24 14:34:07 HelloWorld from Golang Lambda
StatusCode: 200
Success! Second lambda invoked successfully
And that's it! You have now implemented a cross account golang lambda.