How to write to S3 bucket from Lambda function

building beside shore
Reading Time: 2 minutes

AWS Lambda functions are a great way to automate certain tasks and processes in the cloud. They can be triggered by events, such as a file upload to an S3 bucket or a message sent to an SNS topic, allowing you to execute some code in response.

In this post, we’ll show you how to write data to an S3 bucket from a Lambda function. This can be useful for a variety of tasks, such as archiving log files or uploading data to a data lake.


S3 (Simple Storage Service) is Amazon’s cloud storage solution that allows you to store and access data from anywhere in the world. Writing to an S3 bucket from a Lambda function is a simple way to store and access data in the cloud.

In this post, I’ll walk you through how to write to an S3 bucket from a Lambda function. We’ll use the AWS SDK for Node.js to access S3.

Take this example as a starting point. This is not a production-ready code, probably some tweaks for permissions will be necessary to meet your requirements.

AWS resources we need

  • Lambda Function
  • S3 Bucket
  • Lambda Role
  • Bucket Policy

The Lambda function

const AWS = require("aws-sdk");
const s3 = new AWS.S3({
    region: "us-east-1",
});
let response;

exports.lambdaHandler = async (event, context) => {
    try {
        console.log(event);
        const params = {
            Bucket: process.env.MY_BUCKET,
            Key: 'test-file.txt',
            Body: "test content"
        }
        console.log('writing to s3', params);
        const result =  await s3.putObject(params).promise();
        console.log(result);

        response = {
            'statusCode': 200,
        }
    } catch (err) {
        console.log(err);
        return err;
    }

    return response
};

The SAM template

For the sake of simplicity, we are going to use Principal: “*” which makes your bucket 100% public!

AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: >
  Sample SAM Template for Lambda and S3
Parameters:
  Environment:
    Type: String
    Description: Environment name. Example, staging
Resources:
  MyLambda:
    Type: AWS::Serverless::Function
    DependsOn:
      - "MyBucket"
    Properties:
      CodeUri: hello-world/
      Handler: app.lambdaHandler
      Runtime: nodejs12.x
      Environment:
        Variables:
          MY_BUCKET:
            Ref: "MyBucket"
      Role:
        Fn::GetAtt:
          - "MyLambdaRole"
          - "Arn"
    Tags:
      Name: !Sub "${Environment}-my-test-lambda"

  MyBucket:
    Type: AWS::S3::Bucket
    Properties:
      BucketName: !Sub "${Environment}-my-test-bucket"

  MyBucketPolicy:
    Type: AWS::S3::BucketPolicy
    Properties:
      PolicyDocument:
        Id: BucketPolicy
        Version: 2012-10-17
        Statement:
          - Sid: AccessAll
            Action: s3:*
            Effect: Allow
            # Beware: this makes your bucket public!
            Principal: "*"
            Resource: !Join
              - ''
              - - 'arn:aws:s3:::'
                - !Ref MyBucket
                - /*
      Bucket: !Ref MyBucket

  MyLambdaRole:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Statement:
          - Effect: Allow
            Action: "sts:AssumeRole"
            Principal:
              Service:
                - "lambda.amazonaws.com"
        Version: "2012-10-17"
      ManagedPolicyArns:
        - arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole
      Policies:
        - PolicyName: MyLambdaPolicy
          PolicyDocument:
            Statement:
              - Effect: Allow
                Action: "s3:*"
                Resource:
                  - Fn::GetAtt:
                      - "MyBucket"
                      - "Arn"
            Version: "2012-10-17"

As a good practice, always receive the environment as a parameter. This way, all your resources will be easier to identify.

Deploy

Build our lambda and template. This will check also the syntax of your template

$ sam build

Only for the first time run and follow the steps:

$ sam deploy --guided

The second time and so on you can execute:

$ sam deploy --no-confirm-changeset

Clean up your test AWS resources. Delete unused lambdas, buckets, etc to keep your account organized and the most important: no extra costs

Resources

,

About the author

Andrés Canavesi
Andrés Canavesi

Software Engineer with 15+ experience in software development, specialized in Salesforce, Java and Node.js.


Related posts


Leave a Reply

%d bloggers like this: