In this tutorial, we will look at how we can use the AWS Go SDK to perform various operations on AWS S3.

Table of contents

Prerequisites

  • Install AWS Go SDK: Run go get -u github.com/aws/aws-sdk-go/... to install the SDK
  • AWS Credentials: If you haven’t set up AWS credentials before, this resource from AWS is helpful.

How to create an S3 bucket?

We will use the CreateBucket method from the AWS SDK to create a new S3 bucket.

Note: AWS has some restrictions and guidelines when it comes to naming an S3 bucket. This document lists all the rules for naming an S3 bucket.

package main

import (
	"os"

	"github.com/aws/aws-sdk-go/aws"
	"github.com/aws/aws-sdk-go/aws/session"
	"github.com/aws/aws-sdk-go/service/s3"

	"fmt"
)

func CreateBucket(client *s3.S3, bucketName string) error {
	_, err := client.CreateBucket(&s3.CreateBucketInput{
		Bucket: aws.String(bucketName),
	})

	return err
}

func main() {
	sess, err := session.NewSessionWithOptions(session.Options{
		Profile: "default",
		Config: aws.Config{
			Region: aws.String("us-west-2"),
		},
	})

	if err != nil {
		fmt.Printf("Failed to initialize new session: %v", err)
		return
	}

	s3Client := s3.New(sess)

	bucketName := "learnaws-go-sdk-tutorial"
	err = CreateBucket(s3Client, bucketName)
	if err != nil {
		fmt.Printf("Couldn't create bucket: %v", err)
		return
	}

	fmt.Println("Successfully created bucket")
}

Output:

Successfully created bucket

How to list all S3 buckets?

We can use the ListBuckets method to retrieve the list of all buckets in AWS.


package main

import (
	"os"

	"github.com/aws/aws-sdk-go/aws"
	"github.com/aws/aws-sdk-go/aws/session"
	"github.com/aws/aws-sdk-go/service/s3"

	"fmt"
)

func ListBuckets(client *s3.S3) (*s3.ListBucketsOutput, error) {
	res, err := client.ListBuckets(nil)
	if err != nil {
		return nil, err
	}

	return res, nil
}

func main() {
	sess, err := session.NewSessionWithOptions(session.Options{
		Profile: "default",
		Config: aws.Config{
			Region: aws.String("us-west-2"),
		},
	})

	if err != nil {
		fmt.Printf("Failed to initialize new session: %v", err)
		return
	}

	s3Client := s3.New(sess)

	buckets, err := ListBuckets(s3Client)
	if err != nil {
		fmt.Printf("Couldn't list buckets: %v", err)
		return
	}

	for _, bucket := range buckets.Buckets {
		fmt.Printf("Found bucket: %s, created at: %s\n", *bucket.Name, *bucket.CreationDate)
	}
}

Output:

Found bucket: learnaws-go-sdk-tutorial, created at: 2021-10-18 03:00:27 +0000 UTC


How to list objects within an S3 bucket?

We will use the ListObjectsV2 method to fetch objects from the S3 bucket.

Important Parameters:

  • Bucket: name of the bucket
  • Prefix: prefix for the objects (optional)
package main

import (
	"os"

	"github.com/aws/aws-sdk-go/aws"
	"github.com/aws/aws-sdk-go/aws/session"
	"github.com/aws/aws-sdk-go/service/s3"

	"fmt"
)

func ListItems(client *s3.S3, bucketName string, prefix string) (*s3.ListObjectsV2Output, error) {
	res, err := client.ListObjectsV2(&s3.ListObjectsV2Input{
		Bucket: aws.String(bucketName),
		Prefix: aws.String(prefix),
	})

	if err != nil {
		return nil, err
	}

	return res, nil
}

func main() {
	sess, err := session.NewSessionWithOptions(session.Options{
		Profile: "default",
		Config: aws.Config{
			Region: aws.String("us-west-2"),
		},
	})

	if err != nil {
		fmt.Printf("Failed to initialize new session: %v", err)
		return
	}

	s3Client := s3.New(sess)

	bucketName := "learnaws-go-sdk-tutorial"
	prefixName := ""

	bucketObjects, err := ListItems(s3Client, bucketName, prefixName)
	if err != nil {
		fmt.Printf("Couldn't retrieve bucket items: %v", err)
		return
	}

	for _, item := range bucketObjects.Contents {
		fmt.Printf("Name: %s, Last Modified: %s\n", *item.Key, *item.LastModified)
	}
}

Output:

Name: cat.jpeg, Last Modified: 2021-10-18 03:15:25 +0000 UTC


How to upload a file to S3?

The AWS SDK provides the s3manager package that contains an Uploader that can upload content to S3 by taking advantage of S3’s Multipart APIs.

package main

import (
	"os"

	"github.com/aws/aws-sdk-go/aws"
	"github.com/aws/aws-sdk-go/aws/session"
	"github.com/aws/aws-sdk-go/service/s3"
	"github.com/aws/aws-sdk-go/service/s3/s3manager"

	"fmt"
)

func UploadFile(uploader *s3manager.Uploader, filePath string, bucketName string, fileName string) error {
	file, err := os.Open(filePath)
	if err != nil {
		return err
	}

	defer file.Close()

	_, err = uploader.Upload(&s3manager.UploadInput{
		Bucket: aws.String(bucketName),
		Key:    aws.String(fileName),
		Body:   file,
	})

	return err
}

func main() {
	sess, err := session.NewSessionWithOptions(session.Options{
		Profile: "default",
		Config: aws.Config{
			Region: aws.String("us-west-2"),
		},
	})

	if err != nil {
		fmt.Printf("Failed to initialize new session: %v", err)
		return
	}

	bucketName := "learnaws-go-sdk-tutorial"
	uploader := s3manager.NewUploader(sess)
	filename := "cat.jpeg"

	err = UploadFile(uploader, "cat.jpeg", bucketName, filename)
	if err != nil {
		fmt.Printf("Failed to upload file: %v", err)
	}

	fmt.Println("Successfully uploaded file!")
}

Successfully uploaded file!

How to download a file from S3?

We will be using the Downloader from the s3manager package to download a file from the S3 bucket.

package main

import (
	"os"

	"github.com/aws/aws-sdk-go/aws"
	"github.com/aws/aws-sdk-go/aws/session"
	"github.com/aws/aws-sdk-go/service/s3/s3manager"

	"fmt"
)

func DownloadFile(downloader *s3manager.Downloader, bucketName string, key string) error {
	file, err := os.Create(key)
	if err != nil {
		return err
	}

	defer file.Close()

	_, err = downloader.Download(
		file,
		&s3.GetObjectInput{
			Bucket: aws.String(bucketName),
			Key:    aws.String(key),
		},
	)

	return err
}

func main() {
	sess, err := session.NewSessionWithOptions(session.Options{
		Profile: "default",
		Config: aws.Config{
			Region: aws.String("us-west-2"),
		},
	})

	if err != nil {
		fmt.Printf("Failed to initialize new session: %v", err)
		return
	}

	bucketName := "learnaws-go-sdk-tutorial"
	downloader := s3manager.NewDownloader(sess)
	key := "cat.jpeg"
	err = DownloadFile(downloader, bucketName, key)

	if err != nil {
		fmt.Printf("Couldn't download file: %v", err)
		return
	}

	fmt.Println("Successfully downloaded file")

}

Successfully downloaded file