How to run a lambda cross account in AWS
Tags: aws, lambda, iam, python
Published: 2020-03-15 13:58:35

This article was also posted on [razcodes.dev](https://razcodes.dev "razcodes.dev").

## 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](https://dsc.cloud/blackpanda/lambdaCrossAccount.png)


## 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.

```js
{
  "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**.

```js
{
    "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.