[小ネタ][Golang]s3syncでローカルとS3を同期してみた

2023.07.07

GolangでローカルからS3へ同期的にアップロードする方法について考えていたとき、s3syncというライブラリを見つけました。 使い方自体はREADMEを見れば分かるのですが、自分なりに試したいと思いサンプルプログラムを書いてみました。

以下、そのサンプルプログラムについてとなります。

プログラムと実行について

Golangを実行できる環境にて、今回使用する以下のライブラリをインストールしておきます。

github.com/aws/aws-sdk-go
github.com/seqsense/s3sync

今回書いたプログラムは以下となります。

アプリに組み込むことを想定し、ローカルからS3に同期する処理(syncManager.Sync)はgoroutineで実行します。 これによりアプリ(と想定したプログラム)実行中にローカルのフォルダにファイルが配置されたらS3にアップロードするようにします。

アプリ(と想定したプログラム)本体はCtrl+Cで終了のシグナルを受け取るまで実行し続けます。

package main

import (
	"fmt"
	"os"
	"os/signal"
	"time"

	"github.com/aws/aws-sdk-go/aws"
	"github.com/aws/aws-sdk-go/aws/credentials"
	"github.com/aws/aws-sdk-go/aws/session"
	"github.com/seqsense/s3sync"
)

const profile = "your-profile"
const localdir = "your-local/dir/path"
const s3dest = "s3://your-favorite-bucket/foler"

func main() {

	sess := session.Must(session.NewSession(&aws.Config{
		Region:      aws.String("ap-northeast-1"),
		Credentials: credentials.NewSharedCredentials("", profile),
	}))
	syncManager := s3sync.New(sess)

	go func() {
		for {
			time.Sleep(5 * time.Second)
			syncManager.Sync(localdir, s3dest)
		}
	}()

	sig := make(chan os.Signal, 1)
	signal.Notify(sig, os.Interrupt)
	<-sig

	fmt.Println("finish")
}

「go run」でプログラムを実行してみます。

$ go run main.go

プログラムの「localdir」で指定したローカルフォルダに、sample1〜3.csvをそれぞれ時間を開けて配置してみます。 配置後、プログラムを実行したターミナルを見ると、時間を開けてアップロードした旨が表示されています。

$ go run main.go
2023/07/xx 17:21:27 Uploading sample1.csv to s3://your-favorite-bucket/foler/sample1.csv
2023/07/xx 17:22:03 Uploading sample2.csv to s3://your-favorite-bucket/foler/sample2.csv
2023/07/xx 17:23:13 Uploading sample3.csv to s3://your-favorite-bucket/foler/sample3.csv

S3のバケットを見ると、こちらも時間を開けてアップロードされていることが確認できました。

まとめ

このような感じでGolangでローカルからS3へ同期的にアップロードすることができることわかりました。 今回は試さなかったのですが、ローカルからS3へのアップロード以外にも

  • S3からローカル
  • S3からS3

への同期もできるようです。

小ネタではありますが、何かの役に立てば幸いです。