【AWS】AWS Simple Storage Service をpython で

# はじめに

これからAWSで使ったシステム構築を行うことになりそうです。(^^)/
そこでpython で端末からstorage に直接に、（WEBを通さずに）ファイルをやり取りできるか調査したので、そのまとめメモです。

## GCPとAWS

そもそも、おじさんはGCP で Google Cloud Storage を使ってきました。ユーザから見ると、AWS S3はCloud Storage とほとんど同じ感じがします。
GCPの解説ページでは、[分散オブジェクト ストレージ](https://cloud.google.com/docs/compare/aws/storage?hl=ja)でAWSとの比較を紹介しています。

- object (blob)としてデータを保存する 分散object storage である
- ファイルとmetadata でobject を構成。key value に対応する。
- オブジェクトのkey はファイルパスのようにする (e.g., foo/bar.txt)
- bucket にobject を入れて保存する

違いは権限の管理、課金方法にあるようです。今回の実装に関係する認証関係の設定は以下の通りです。

- GCPでは、私は担当サービス用のユーザをIAMで作り、そのユーザkey を使用しています。ユーザに対して bucket の権限を設定します。端末やサーバでは、ユーザのkey を用いて（ユーザの権限で)storage にアクセスします。
- AWSでは、まだ始めたばかりですが、IAMで作成した作業用ユーザに対して S3やbucket へのアクセスを設定するようです。端末では、アクセスIDとそれに対応するシークレット・アクセス・キーを指定しました。

## Storage の操作方法

コンソール（ブラウザ経由）で操作する方法以外に、実際に使うには、

- AWS SDKを使ったプログラムを書く（今回はこれ。python のboto3)
- [Rest APIを利用する](https://docs.aws.amazon.com/ja_jp/AmazonS3/latest/userguide/S3_Authentication2.html)

の２つの方法があるようです。

# 作業内容

## コンソールでの動作確認

これはチュートリアルに書いてある通りにできました。bucket を作り、ファイルをupload/download する操作は、ブラウザから行えます。Google と同じ。

https://docs.aws.amazon.com/AmazonS3/latest/userguide/creating-bucket.html

Google と違ったのは、bucket name に制約があることです。bucket を作る機会は少ないかもしれないので、プログラムでなくここで操作しても良いかも。使えない文字列だとすぐに教えてくれます。

## AWS SDKの用意

### AWS CLI

AWS CLIをインストールします。GCPのgcloud みたいなもののイメージです。
AWSのページに書かれている通り、Linux環境(Windows ノートPCで WSL2)に下記でインストールできました。割と時間がかかりました。

```
$ curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
$ unzip awscliv2.zip
$ sudo ./aws/install
```

こんな感じになりました。

```
$ aws --version
aws-cli/2.2.16 Python/3.8.8 Linux/5.4.72-microsoft-standard-WSL2 exe/x86_64.ubuntu.20 prompt/off
```
https://aws.amazon.com/cli/

### AWS SDK for python (boto3)

boto3 というのをpipするでけでした。

```
$ python -m pip install boto3
```

https://aws.amazon.com/sdk-for-python/

Access ID、それに対応する Secret Access Key をIAMで発行しましょう。これをセットします。

```
$ aws configure
```

でインタラクティブに入力しました。以下にあるファイルに設定が書かれるようです。

```bash
/home/user0001/.aws/
├── config
└── credentials
```

## コードを動かす

これもチュートリアルにとおりで、何事もありませんでした。

まず、アクセスIDとシークレットアクセスキーは設定してある状態です。

```SHELL
$ aws configure list
      Name                    Value             Type    Location
      ----                    -----             ----    --------
   profile                <not set>             None    None
access_key     ****************R7UK shared-credentials-file
secret_key     ****************/OCE shared-credentials-file
    region           ap-northeast-1      config-file    ~/.aws/config
```

以下で不通に作成したbucket のリストを表示できました。

```Python
import boto3
s3 = boto3.resource('s3')
for bucket in s3.buckets.all():
     print(bucket.name)
```

ファイルのupload も問題なくできました。

```Python
data = open('test.txt', 'rb')
ret = s3.Bucket('xxxx-yyyyy-bucket-20210704').put_object(Key='test.txt', Body=data)
print(ret)
```

で ```s3.Object(bucket_name='xxxx-yyyyy-bucket-20210704', key='test.txt')``` と表示されました。コンソール（ブラウザ）でbucket を除くと、確かにファイルがupload されていました。

# まとめ

AWS の分散object storageにpython スクリプトでファイルをアップロードすることができた。今後考えなければいけないのは、

- 複数の端末で実行するとき、アクセスキーをどうするのか。複製はしない方がよいとなると、それぞれ作るのかな。それらをdeploy するときにはどうしたらよいのだろう。きっとノウハウがあるんだろうな。
- 今回はAWS CLIで access IDの設定をしたが、プログラム内で行いたい。（AWS CLI無しで動かしたい)
- REST APIを試す。結局、RestAPIがプログラミング言語に依存せず、最強ではないかと思う。

とまぁ、いろいろあるが、とりあえず、python でプロト実装すると思います。
以上、おじさんメモでした。
(2021/07/04)