2019-12-07

aws-sdk-s3 for Rubyを使ってみた

今更感があるが、Rubyのaws-sdk-s3 gemを使ってS3と戯れた記録を残す。

事前準備

Gemとしては aws-sdk-s3 だけ使えれば良いので、これをGemfileに書く。

# ./Gemfile
source "https://rubygems.org"

git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }

gem 'aws-sdk-s3'

bundle install を実行。Gemのセットアップはこれで完了。

bundle install --path vendor/bundle

次、sdkからAWSにアクセスするためにはアクセスキーを作成する必要があるので、マネジメントコンソールから作成する。作成方法は省略するが、下記のドキュメントを見て行った。
https://aws.amazon.com/jp/premiumsupport/knowledge-center/create-access-key/

入手したアクセスキーとシークレットアクセスキーをaws cliを使ってセットアップする。awscliはhomebrewを使ってインストールした。

brew install awscli

awscliをインストールしたら、aws configure で対話的に認証情報の設定ができる。

$ aws configure
AWS Access Key ID [None]: xxx(入手したアクセスキーを入力)
AWS Secret Access Key [None]: yyy(入手したシークレットアクセスキーを入力)
Default region name [None]:(Enter)
Default output format [None]:(Enter)

実行後、~/.aws/credentials~/.aws/config が作られているはず。これで事前準備は完了。 なお、認証情報の設定については以下のドキュメントが参考になった。
https://docs.aws.amazon.com/ja_jp/sdk-for-ruby/v3/developer-guide/setup-config.html

バケットの作成

まずはバケットの作成から。Aws::S3::Resource#create_bucket で作ることができる。
ここでは mogulla3 という名称のバケットを作った。

require 'aws-sdk-s3'

s3 = Aws::S3::Resource.new
bucket = s3.create_bucket(acl: 'private', bucket: 'mogulla3') 
# => #<Aws::S3::Bucket:0x00007fae70403be0 ..>

バケットの存在確認

バケットの存在は Aws::S3::Bucket#exists? で確認できる。

require 'aws-sdk-s3'

s3 = Aws::S3::Resource.new
bucket = s3.bucket('mogulla3')
bucket.exists?
# => true

バケットの一覧を取得する

Aws::S3::Resource#buckets でバケットの一覧(Aws::S3::Bucket::Collection)を取得できる。

require 'aws-sdk-s3'

s3 = Aws::S3::Resource.new
s3.buckets.each do |bucket|
  pp bucket
  # => #<Aws::S3::Bucket:0x00007fd06f0d3ee0 ..>
end

ローカルのファイルをパス指定でS3にアップロードする

ローカルPC上にあるファイルをS3上にアップロードしたいようなケースを想定。
Aws::S3::Object.upload_file と使うとアップロードできる。

require 'aws-sdk-s3'

file = File.new('./sample.txt') 
s3 = Aws::S3::Resource.new
obj = s3.bucket('mogulla3').object('sample.txt') # S3オブジェクトのキー名
obj.upload_file(file.path)

ローカルのファイルのコンテンツを読み込んでS3にアップロードする

今度は、ローカルPC上にあるファイルのコンテンツを直接渡して、S3上にアップロードしたいようなケースを想定。 Aws::S3::Bucket#put_object を使うとアップロードできる。

require 'aws-sdk-s3'

file = File.new('./sample.txt') 

s3 = Aws::S3::Resource.new
bucket = s3.bucket('mogulla3')
bucket.put_object(acl: 'private', body: file.read, key: 'sample2.txt')
# => #<Aws::S3::Object:0x00007fae6ecaa4f8 ..>

S3オブジェクトのダウンロード & 読み込み

S3上にあるファイルをローカルPC上にダウンロードして、そのコンテンツを読み込む。

require 'aws-sdk-s3'

s3 = Aws::S3::Resource.new
bucket = resource.bucket('mogulla3')
obj = bucket.object('sample.txt')
get_object_output = obj.get
io = get_object_output.body

puts io.read
# => ファイルの中身が出力される

Aws::S3::Object#getAws::S3::Types::GetObjectOutput のインスタンスを取得し、そのインスタンスに対して #body を呼び出すと StringIO 形式でコンテンツを取得できる。

https://docs.ruby-lang.org/ja/latest/class/StringIO.html

同じことは、Aws::S3::Client を使うと少しスッキリ書けそうだった。

require 'aws-sdk-s3'
 
client = Aws::S3::Client.new
obj = client.get_object(bucket: 'mogulla3', key: 'sample.txt')
io = obj.body 
 
puts io.read
# => ファイルの中身が出力される

オブジェクトを削除する

オブジェクトの削除は Aws::S3::Bucket#delete_objects でやる。引数に渡すHashの構造が地味に面倒。

require 'aws-sdk-s3'
 
s3 = Aws::S3::Resource.new
bucket = resource.bucket('mogulla3')
res =  bucket.delete_objects(
  delete: {
    objects: [
      { key: 'sample.txt' },
    ]
  }
)

バケットを削除する

バケットの削除はAws::S3::Bucket#deleteAws::S3::Bucket#delete! を使うとできるが、#delete はオブジェクトが空じゃないと実行できない。ここでは delete! を使う。

require 'aws-sdk-s3'
 
s3 = Aws::S3::Resource.new
bucket = s3.bucket('mogulla3')

bucket.delete!
# => #<struct Aws::EmptyStructure>

終わりに

以上、使ってみた記録を残した。APIドキュメントとにらめっこしながら実行してみたログなので、適切な使い方かはちょっと自信がない。
Clientオブジェクトを使っても色々できそうだったが、今回は基本的に Resource からたどる形式でやってみた。

参考URL