Skip to main content

Using Lambda with IAM roles

As documented on the Permissions page, the default way of using Remotion Lambda involves creating a Remotion user and assign it policies.

These policies give permission to Lambda to render a video with renderMediaOnLambda(). These credentials are considered long-term which is less secure and are disallowed in some companies.

Additionally, there might be requirements to execute renderMediaOnLambda() on services such as Lambda, EC2, and other computing services where the use of long-term credentials is not an option.

AWS offers the concept of IAM Roles as a solution to the problem above. When a role is assigned to an AWS service, AWS gives any elevated privileges based on the attached policies and the role is empowered to execute activities such as putting a file to an S3 bucket.

The role is given temporary AWS credentials such as AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, and AWS_SESSION_TOKEN to generate the video. This approach enhances security as there are no long-term credentials lingering around and the need to keep track of their rotation is eliminated.

The steps below provide authorization for the Lambda function to execute renderMediaOnLambda() without permission issues.

Prerequisites

  1. A deployed Lambda function running on AWS. An example using CDK is available here. It gives you an idea how to call renderMediaOnLambda() inside another Lambda function. The function is triggered by API Gateway. The example assumes that you have knowledge of using CDK, a write up is also available.
  2. An execution role that is assigned to the Lambda function.
  3. A user policy with the necessary user permissions.

Setup

1. Create role policy

  • Go to the IAM policies section in the AWS Management Console
  • Click on "Create policy"
  • Click on JSON
  • Copy the JSON policy template below:
    Show full role permissions JSON file for latest Remotion Lambda version
    {
      "Version": "2012-10-17",
      "Statement": [
        {
          "Sid": "HandleQuotas",
          "Effect": "Allow",
          "Action": [
            "servicequotas:GetServiceQuota",
            "servicequotas:GetAWSDefaultServiceQuota",
            "servicequotas:RequestServiceQuotaIncrease",
            "servicequotas:ListRequestedServiceQuotaChangeHistoryByQuota"
          ],
          "Resource": [
            "*"
          ]
        },
        {
          "Sid": "PermissionValidation",
          "Effect": "Allow",
          "Action": [
            "iam:SimulatePrincipalPolicy"
          ],
          "Resource": [
            "*"
          ]
        },
        {
          "Sid": "LambdaInvokation",
          "Effect": "Allow",
          "Action": [
            "iam:PassRole"
          ],
          "Resource": [
            "arn:aws:iam::*:role/remotion-lambda-role"
          ]
        },
        {
          "Sid": "Storage",
          "Effect": "Allow",
          "Action": [
            "s3:GetObject",
            "s3:DeleteObject",
            "s3:PutObjectAcl",
            "s3:PutObject",
            "s3:CreateBucket",
            "s3:ListBucket",
            "s3:GetBucketLocation",
            "s3:PutBucketAcl",
            "s3:DeleteBucket",
            "s3:PutBucketOwnershipControls",
            "s3:PutBucketPublicAccessBlock"
          ],
          "Resource": [
            "arn:aws:s3:::remotionlambda-*"
          ]
        },
        {
          "Sid": "BucketListing",
          "Effect": "Allow",
          "Action": [
            "s3:ListAllMyBuckets"
          ],
          "Resource": [
            "*"
          ]
        },
        {
          "Sid": "FunctionListing",
          "Effect": "Allow",
          "Action": [
            "lambda:ListFunctions",
            "lambda:GetFunction"
          ],
          "Resource": [
            "*"
          ]
        },
        {
          "Sid": "FunctionManagement",
          "Effect": "Allow",
          "Action": [
            "lambda:InvokeAsync",
            "lambda:InvokeFunction",
            "lambda:CreateFunction",
            "lambda:DeleteFunction",
            "lambda:PutFunctionEventInvokeConfig",
            "lambda:PutRuntimeManagementConfig"
          ],
          "Resource": [
            "arn:aws:lambda:*:*:function:remotion-render-*"
          ]
        },
        {
          "Sid": "LogsRetention",
          "Effect": "Allow",
          "Action": [
            "logs:CreateLogGroup",
            "logs:PutRetentionPolicy"
          ],
          "Resource": [
            "arn:aws:logs:*:*:log-group:/aws/lambda/remotion-render-*"
          ]
        },
        {
          "Sid": "FetchBinaries",
          "Effect": "Allow",
          "Action": [
            "lambda:GetLayerVersion"
          ],
          "Resource": [
            "arn:aws:lambda:*:678892195805:layer:remotion-binaries-*"
          ]
        }
      ]
    }
  • Click next. On the tags page, you don't need to fill in anything. Click next again.
  • Give the policy the name remotion-executionrole-policy. The other fields can be left as they are.

2. Assign the policy to the Lambda execution role

  • Go to the AWS Management Console
    • Navigate to Lambda (change to your function region)
    • Select Functions
    • Select your Lambda function
    • Select the "Configuration" tab
    • Select the "Permissions" tab
    • Click the role under Execution role
    • When redirected, click "Permissions" tab
    • Click on Add permissions
    • Attach policy
    • Find the policy, i.e. remotion-executionrole-policy
    • Select the policy
    • Click the Attach policies button.

With the assignment of the policy to the Lambda execution role, it is now empowered to execute the renderMediaOnLambda() API without permission issues.

In the background, when the Lambda function is executed, it is provided with environment variables such as AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY and AWS_SESSION_TOKEN that has temporary permission to AWS resources that renderMediaOnLambda() requires to render the video. The elevated powers come from the policy statements in remotion-executionrole-policy.

note

This procedure can be also applied to other AWS compute services such as EC2, Fargate etc..

Render into a different bucket

Optionally, if you want to move the video to another S3 bucket after it is rendered, the Lambda function also needs permission to do so. The process is similar to the previous steps, but you will need to create a new policy statement that defines the bucket that Lambda needs to transfer the rendered video to.

Example

Use the outName property to select a different bucket. See: Custom output destination

my-function.ts
ts
import { renderMediaOnLambda } from "@remotion/lambda/client";
 
const { bucketName, renderId } = await renderMediaOnLambda({
region: "us-east-1",
functionName: "remotion-render-bds9aab",
composition: "MyVideo",
serveUrl:
"https://remotionlambda-qg35eyp1s1.s3.eu-central-1.amazonaws.com/sites/bf2jrbfkw",
codec: "h264",
outName: {
key: "my-output",
bucketName: "output-bucket",
},
});
my-function.ts
ts
import { renderMediaOnLambda } from "@remotion/lambda/client";
 
const { bucketName, renderId } = await renderMediaOnLambda({
region: "us-east-1",
functionName: "remotion-render-bds9aab",
composition: "MyVideo",
serveUrl:
"https://remotionlambda-qg35eyp1s1.s3.eu-central-1.amazonaws.com/sites/bf2jrbfkw",
codec: "h264",
outName: {
key: "my-output",
bucketName: "output-bucket",
},
});

In the example above, the renderMediaOnLambda() is configured to output the rendered video to transfer-to-this-bucket-after-render bucket. The following steps allow Lambda to move the file to another bucket.

Steps

  • Again we assign the policy to the Lambda execution role. Go to the AWS Management Console and:
    • Navigate to Lambda (change to your function region)
    • Functions
    • Select your Lambda function
    • Configuration tab
    • Permissions tab
    • Click the role under Execution role
    • When redirected, click Permissions tab
    • Click on Add permissions
    • Click "Create inline policy"
    • Click the "JSON" tab

Add a policy statement similar to the one below, which is defining the bucket Lambda needs to transfer the rendered video to.

json
{
"Version": "2012-10-17",
"Statement": [
{
"Action": ["s3:PutObject"],
"Resource": ["arn:aws:s3:::{bucketname}", "arn:aws:s3:::{bucketname}/*"],
"Effect": "Allow"
}
]
}
json
{
"Version": "2012-10-17",
"Statement": [
{
"Action": ["s3:PutObject"],
"Resource": ["arn:aws:s3:::{bucketname}", "arn:aws:s3:::{bucketname}/*"],
"Effect": "Allow"
}
]
}
  • Replace {bucketname} with the name of the bucket where you want to move the rendered video to.
  • Click on Review policy
  • Click Save changes

The Lambda function can now move the rendered video to the other bucket when the render process is completed.

See also