AWS CLIを使用したS3操作入門

CLIを使ったS3操作入門

はじめに

データアナリティクス事業本部のおざわです。お客様からAWS CLIを使ってローカルからS3にファイルをコピーしたり、ダウンロードしたりといった操作を試してみたいとお話を伺ったので、今回はAWS CLIを使った簡単なS3の操作に関してチュートリアル形式でまとめてみました。

AWS CLIのインストールと初期設定

以下の記事を参考にインストールと設定を行ってください。 また、使用するアクセスキーについては最小権限のアクセス許可で払い出すようにしてください。

MFA(多要素認証)について

設定によってはコマンド実行時にMFA認証を求められます。 以下のような文言がプロンプトに表示されますが、一度入力すればセッションが有効な間は再入力する必要はありません。

Enter MFA code for arn:aws:iam::123456789012:mfa/cm-jozawa:

記事で使うディレクトリの構成

本記事では、以下のようなディレクトリ構成でファイルが存在すると仮定しています。

/test_folder
  ├── aaa.md
  ├── aaa.txt
  ├── aaa.xlsx
  ├── abc.xlsx
  ├── backups
  │   ├── aaa.txt
  │   ├── bbb.txt
  │   └── ccc.xlsx
  ├── bbb.xlsx
  └── ccc.xlsx

1. CLIとは

AWS CLIのCLIは「Command Line Interface」の略です。AWSの各種サービスに対する操作をコンソールから実行するツールになっています。サービスによっては、たまにマネジメントコンソールではできないけどCLIなら実行可能な操作があったりしますが、基本的にはマネジメントコンソールでできることをコマンドラインから実施します。

個人的に、CLIには以下のようなメリットとデメリットが存在すると思っています。

1.1. メリット

メリットとしては、各種操作をコード化しておける点です。たくさんの(面倒な)操作も一つのシェルにまとめておけばサッと実行できます。それからgitの操作などでもそうですが、CUIだと自分が指示した内容が実行されるので安心感があります。また、OS間の差異をCLIが吸収してくれるので、別のOSを使っている人も同じコードが使えます。

  • 頻繁に利用するコマンドはバッチ化しておくことが可能
  • 目視でコマンドやオプションを確認できる
  • OSが違っても同じコマンドが実行できる

1.2. デメリット

デメリットとしては、慣れるまでに少し時間がかかる点かと思います。また、GUIでも起こりえる話ですが、実行内容によっては、やらかしたときの被害が大きい点があります。大量のファイルを一括で処理する操作を行うときにオプションを間違えて実行してしまったら…と思うとゾッとしますね。

  • 慣れるまでの学習コスト
  • コマンド、パラメータの誤入力

2. テスト用S3バケットの作成

最初にテスト用のS3バケットを作成します。本記事では、バケット名を以下のものにしていますが、使用するバケットに合わせて変更してください。

this-is-my-test-bucket

本記事の内容を試すには既存のS3バケットでも問題ありませんが、記事の後半で削除操作を実行しますので、既存のバケットを使用する場合は十分ご注意ください。

S3バケットの作成にはmb (make bucket)を使用します。

aws s3 mb s3://this-is-my-test-bucket 
make_bucket: cm-da-jozawa-test2

作成されるとmake_bucket: バケット名 と表示されます。

3. ファイルのコピー

ファイルをS3にコピーするにはcpコマンドを使用します。ローカルからS3はもちろん、S3から別のS3にファイルをコピーするといった使い方もできます。

使い方は、以下のように送信元のソースのローカルパス、ターゲットとなるS3のURI、オプションを指定します。本記事ではdryrun、recursive、include、excludeといったオプションを試します。

aws s3 cp [localPath] [S3Uri] --options

3.1. 単一ファイルのコピーとdryrun

単一のファイルのコピーから試してみます。最初は、dryrunオプションを使用して以下のコマンドを実行します。dryrunオプションを付けると実際にはコマンドを実行しませんが、コマンドを実行した場合の対象ファイルであったり、処理内容を確認することができます。

aws s3 cp ./aaa.txt s3://this-is-my-test-bucket --dryun

以下のように (dryrun) と表示されます。どんな処理が実施されるのか目視できて安心です。

(dryrun) upload: ./aaa.txt to s3://this-is-my-test-bucket/aaa.txt

続いて、dryrunを外して同じコマンドを実行します。 upload: 「ファイル名」 to 「S3のURI」が表示されたら成功です。

aws s3 cp ./aaa.txt s3://this-is-my-test-bucket 
upload: ./aaa.txt to s3://this-is-my-test-bucket/aaa.txt

試しにもう一度実行してみてください。

aws s3 cp ./aaa.xlsx s3://this-is-my-test-bucket 
upload: ./aaa.txt to s3://this-is-my-test-bucket/aaa.txt

同じファイルをコピーした場合でも、エラーが表示されることはなく上書き保存されます。

3.2. 複数ファイルのコピーとrecursive

recursiveのオプションを使用して、サブディレクトリを含めて全てのファイルを再帰的にコピーする操作を見てみます。 pwd(cd)コマンドで現在のディレクトリを確認して、意図した場所になっていることを確認してください。

まず、dryrunオプションが付与されていることを確認して、コマンドを実行してください。

aws s3 cp . s3://this-is-my-test-bucket/ --dryrun --recursive

以下のように、すべてのファイルがコピー対象になっています。

(dryrun) upload: ./aaa.md to s3://this-is-my-test-bucket/aaa.md
(dryrun) upload: ./aaa.txt to s3://this-is-my-test-bucket/aaa.txt
(dryrun) upload: ./aaa.xlsx to s3://this-is-my-test-bucket/aaa.xlsx
(dryrun) upload: ./abc.xlsx to s3://this-is-my-test-bucket/abc.xlsx
(dryrun) upload: backups/aaa.txt to s3://this-is-my-test-bucket/backups/aaa.txt
(dryrun) upload: backups/bbb.txt to s3://this-is-my-test-bucket/backups/bbb.txt
(dryrun) upload: backups/ccc.xlsx to s3://this-is-my-test-bucket/backups/ccc.xlsx
(dryrun) upload: ./bbb.xlsx to s3://this-is-my-test-bucket/bbb.xlsx
(dryrun) upload: ./ccc.xlsx to s3://this-is-my-test-bucket/ccc.xlsx

3.3. exclude

次はexcludeオプションを使ってbackupsディレクトリを除外してみます。

aws s3 cp . s3://this-is-my-test-bucket/ --dryrun --recursive --exclude "backups/*"
(dryrun) upload: ./aaa.md to s3://this-is-my-test-bucket/aaa.md
(dryrun) upload: ./aaa.txt to s3://this-is-my-test-bucket/aaa.txt
(dryrun) upload: ./aaa.xlsx to s3://this-is-my-test-bucket/aaa.xlsx
(dryrun) upload: ./abc.xlsx to s3://this-is-my-test-bucket/abc.xlsx
(dryrun) upload: ./bbb.xlsx to s3://this-is-my-test-bucket/bbb.xlsx
(dryrun) upload: ./ccc.xlsx to s3://this-is-my-test-bucket/ccc.xlsx

フィルタ(excludeと次にご紹介するinclude)のオプションは、送信元のパスとして指定しているディレクトリを基準にして評価されます。例えば/tmp/fooをソースとして --exclude ".git/*" のようにオプションを指定した場合は /tmp/foo/.git/* が除外対象になります。

excludeオプションは複数指定することが可能です。上で試したbackupsディレクトリに加えて、拡張子がtxtのファイルを除外してみます。

aws s3 cp . s3://this-is-my-test-bucket/ --dryrun --recursive --exclude "backups/*" --exclude "*.txt"
(dryrun) upload: ./aaa.md to s3://this-is-my-test-bucket/aaa.md
(dryrun) upload: ./aaa.xlsx to s3://this-is-my-test-bucket/aaa.xlsx
(dryrun) upload: ./abc.xlsx to s3://this-is-my-test-bucket/abc.xlsx
(dryrun) upload: ./bbb.xlsx to s3://this-is-my-test-bucket/bbb.xlsx
(dryrun) upload: ./ccc.xlsx to s3://this-is-my-test-bucket/ccc.xlsx

確認できたらdryrunを外して実行してみてください。実行結果に以下のように表示されます。

upload: ./aaa.md to s3://this-is-my-test-bucket/aaa.md
upload: ./ccc.xlsx to s3://this-is-my-test-bucket/ccc.xlsx
upload: ./abc.xlsx to s3://this-is-my-test-bucket/abc.xlsx
upload: ./bbb.xlsx to s3://this-is-my-test-bucket/bbb.xlsx
upload: ./aaa.xlsx to s3://this-is-my-test-bucket/aaa.xlsx

3.4. include

続いてincludeオプションを試してみます。デフォルトではすべてのファイルが含まれますので、includeは単体で使うことはなく、excludeで除外対象になったファイルを再度含めるためにincludeを使用します。

backups内のxlsxファイルだけをコピー対象にしてみます(dryrun)。

aws s3 cp . s3://this-is-my-test-bucket/  --exclude "*" --include "backups/*.xlsx" --recursive --dryrun
(dryrun) upload: backups/ccc.xlsx to s3://this-is-my-test-bucket/backups/ccc.xlsx

確認できたらdryrunを外して実行してください。

exclude、includeを使ったフィルタは後から指定したオプションが優先されます。ですので、上のコマンドのexcludeとincludeの順番が逆になっている場合、本来コピー対象として含めたかったbackups/*.xlsxも除外されることになります。

aws s3 cp . s3://this-is-my-test-bucket/  --include "backups/*.xlsx" --exclude "*" --recursive --dryrun

3.5. ディレクトリ全体のコピー

ディレクトリの内容をS3をコピー(同期)するにはsyncコマンドが使えます。

まずdryrunで実行してみます。

aws s3 sync . s3://this-is-my-test-bucket/ --dryrun
(dryrun) upload: backups/aaa.txt to s3://this-is-my-test-bucket/backups/aaa.txt
(dryrun) upload: backups/bbb.txt to s3://this-is-my-test-bucket/backups/bbb.txt

ここまでの操作を上から実行している場合、上のような表示になるかと思います。

syncコマンドはソースとターゲットの差分を確認して差分をコピーするので、ソース側で更新があり、ファイルサイズやタイムスタンプが変更になったり、新規で追加されたファイルを同期に含めます。ソースで削除されたファイルをターゲットでも同期したい場合は--deleteオプションが使用できます。

オプションはcpと同じようにdryrun, include, excludeが使用できます。他にもたくさん使い方があるので詳しい使い方はマニュアルをご参照ください。

4. ファイル一覧の表示

S3バケットのファイル一覧を取得するにはlsコマンドを使用します。

aws s3 ls s3://this-is-my-test-bucket  --recursive
2023-10-10 10:01:44          4 aaa.md
2023-10-10 10:01:44          4 aaa.txt
2023-10-10 10:01:44       8533 aaa.xlsx
2023-10-10 10:01:44       8533 abc.xlsx
2023-10-10 10:01:44          4 backups/aaa.txt
2023-10-10 10:01:44          4 backups/bbb.txt
2023-10-10 10:01:44       8533 backups/ccc.xlsx
2023-10-10 10:01:44       8533 bbb.xlsx
2023-10-10 10:01:44       8533 ccc.xlsx

5. S3のファイルをローカルにコピーする

S3からファイルをコピーしてくる場合にもcpコマンドを使用できます。

上で使っていたcpコマンドと同じものですが、今回はソースがS3バケットになり、送信先のターゲットがローカルになっています。同じコマンドなので、includeとexcludeオプションも使い方は同じです。

最初にダウンロード用にローカルにディレクトリを作成してください。

mkdir downloads

以下のコマンドでは、テスト用バケットの全ファイルをdownloads以下にコピーしています(dryrun)

aws s3 cp s3://this-is-my-test-bucket ./downloads --dryrun  --recursive
(dryrun) download: s3://this-is-my-test-bucket/aaa.md to downloads/aaa.md
(dryrun) download: s3://this-is-my-test-bucket/aaa.txt to downloads/aaa.txt
(dryrun) download: s3://this-is-my-test-bucket/aaa.xlsx to downloads/aaa.xlsx
(dryrun) download: s3://this-is-my-test-bucket/abc.xlsx to downloads/abc.xlsx
(dryrun) download: s3://this-is-my-test-bucket/backups/aaa.txt to downloads/backups/aaa.txt
(dryrun) download: s3://this-is-my-test-bucket/backups/bbb.txt to downloads/backups/bbb.txt
(dryrun) download: s3://this-is-my-test-bucket/backups/ccc.xlsx to downloads/backups/ccc.xlsx
(dryrun) download: s3://this-is-my-test-bucket/bbb.xlsx to downloads/bbb.xlsx
(dryrun) download: s3://this-is-my-test-bucket/ccc.xlsx to downloads/ccc.xlsx

xlsx以外をコピーしてくるようにexcludeオプションを指定して、dryrunを外して実行してみます。

aws s3 cp s3://this-is-my-test-bucket ./downloads  --recursive --exclude "*.xlsx"
download: s3://this-is-my-test-bucket/aaa.md to downloads/aaa.md
download: s3://this-is-my-test-bucket/backups/bbb.txt to downloads/backups/bbb.txt
download: s3://this-is-my-test-bucket/aaa.txt to downloads/aaa.txt
download: s3://this-is-my-test-bucket/backups/aaa.txt to downloads/backups/aaa.txt

6. ファイルの削除

S3バケットからファイルを削除してみます。 既存バケットを使用している場合は、十分ご注意ください。

最初にxlsxだけを削除対象とします。S3バケットの名前がご自身が使っているテスト用のS3になっているか確認して、dryrunオプションを付けて実行してください。

aws s3 rm s3://this-is-my-test-bucket/ --recursive  --dryrun --exclude="*" --include "*.xlsx"
(dryrun) delete: s3://this-is-my-test-bucket/aaa.xlsx
(dryrun) delete: s3://this-is-my-test-bucket/abc.xlsx
(dryrun) delete: s3://this-is-my-test-bucket/backups/ccc.xlsx
(dryrun) delete: s3://this-is-my-test-bucket/bbb.xlsx
(dryrun) delete: s3://this-is-my-test-bucket/ccc.xlsx

対象ファイルが確認できてから、dryrunオプションを外して実行します。

続いてテストバケット内のすべてのファイルを削除します。dryrunで確認しつつ進めてください。

aws s3 rm s3://this-is-my-test-bucket/ --recursive  --dryrun

意図したファイルが削除対象になっているのが確認できたら、dryrunを外して実行してください。

delete: s3://this-is-my-test-bucket/aaa.md
delete: s3://this-is-my-test-bucket/backups/bbb.txt
delete: s3://this-is-my-test-bucket/backups/aaa.txt
delete: s3://this-is-my-test-bucket/aaa.txt

最後にrbコマンドでテスト用S3バケットの削除します。

対象バケット内に1つでもファイルが残っている場合は以下のようなエラーが出ます。

remove_bucket failed: s3://this-is-my-test-bucket An error occurred (BucketNotEmpty) when calling the DeleteBucket operation: The bucket you tried to delete is not empty

バケット名があっていることを確認してから実行してください。

aws s3 rb s3://this-is-my-test-bucket

おわりに

以上、S3の簡単なCLI操作をチュートリアル形式でまとめてみました。 どなたかの参考になれば幸いです。

参考リンク