How to run a lambda cross account in AWS

Posted on Sun 15 March 2020

aws lambda iam

Case Scenario:

We want to be able to run a set of actions in AWS using a lambda function from one account by accesing the data in another account. We want the lambda to be created in Account A where we have control to create and update the function. We want the lambda to run against Account B where all the data we need is (ex: a client's account). For this example I will use a case scenario where we have to operate on data in a S3 bucket.

We are assuming here that Account A is where the lambda lives and Account B is the account that the action is taking place so the account that lambda runs against.

Account A -> Source Account

Account B -> Target Account

Accounts

Creating Roles

Create a new role in Account B under IAM -> Roles, select Another AWS account on the first screen, and fill in the Account ID of Account A in the box without the dashes. The account id can be found on the IAM main page.

Under permissions add the necessary permissions for the lambda to run, in this case AmazonS3ReadOnlyAccess. You can get more granular here now or later and target just one S3 Bucket.

Add tags (ex: purpose, owner), give the role a name and description and click Create role.

Create a new role in Account A with AWSLambdaBasicExecutionRole. This will be the role that the lambda will use to run and assume the role in Account B.

Go back to Account B and edit the Trust Relationship of the role you have created there and replace the Principal with the full arn of the role you created in Account A, so instead of root, you only give access to a specific entity.

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "AWS": "arn:aws:iam::<acc number>:<role name>"
      },
      "Action": "sts:AssumeRole",
      "Condition": {}
    }
  ]
}

Now in Account A create a new policy and attach it to the lambda role that was created earlier. The policy will allow the lambda to assume the role from the target Account B. Make sure to replace the arn with the one of the role created in Account B.

{
    "Version": "2012-10-17",
    "Statement": {
        "Effect": "Allow",
        "Action": "sts:AssumeRole",
        "Resource": "arn:aws:iam::<acc number>:<role name>"
    }
}

Now to recap:

Account A has a new role with 2 policies attached, AWSLambdaBasicExecutionRole that allows a lambda to run and another one that allows it to assume a role in Account B.

Account B has a new role with an AmazonS3ReadOnlyAccess and a Trust Relationship established, allowing only the role in Account A to connect and do the work.

Creating the Lambda

In Account A, under Services -> Compute -> Lambda -> Create function.

Chose Author from scratch and give the function a name. For the execution role, chose the one that was already created above. Click Create function.

Now you can edit the code in the console or upload it from your computer.