#author("2024-08-21T17:34:42+09:00","default:dex","dex") #author("2024-08-22T10:21:06+09:00","default:dex","dex") #contents *S3 [#uf17b9b4] - バケット作成:LocationConstraintを指定しないとus-east-1に作成される #geshi(bash){{ aws s3api create-bucket --bucket mybucket --create-bucket-configuration LocationConstraint=ap-northeast-1 }} - その他 #geshi(bash){{ # バケット一覧 aws s3 ls s3://mybucket # s3バケットを再帰的にローカルにコピー aws s3 cp s3://mybucket/myfolder myfolder --recursive # s3バケットとローカルを同期 aws s3 sync s3://mybucket/myfolder myfolder --exclude *.tmp aws s3 sync s3://mybucket/myfolder myfolder --exclude *.tmp --exact-timestamps # デフォルトに指定したリージョン以外の操作には --region オプションを付ける aws s3 cp s3://mybucket/myfolder myfolder --recursive --region ap-northeast-1 }} -バケット内一括削除。''確認は無いので注意'' #geshi(bash){{ aws s3 rm s3://mybucket/ --recursive }} -バケットライフサイクルの指定。JSONが複雑なのでManagement Consoleで設定して、その値を取得すると楽 #geshi(bash){{ aws s3api get-bucket-lifecycle --bucket mybucket > bucket-lifecycle.30.json cat bucket-lifecycle.30.json { "Rules": [ { "Status": "Enabled", "Prefix": "", "Expiration": { "Days": 30 }, "ID": "lifecycle-30" } ] } aws s3api put-bucket-lifecycle --bucket mybucket --lifecycle-configuration file://bucket-lifecycle.30.json }} --- ** bucket間でのコピー [#m5c31e00] - [[Amazon S3 バケット間でオブジェクトをコピーする:https://aws.amazon.com/jp/premiumsupport/knowledge-center/move-objects-s3-bucket/]] - cp, syncが使える。 - syncの場合、ループしないように注意したほうが良さそう - 例 dir1/ 以下を /へ移動したい #geshi(text){{ s3://example /dir1 /dummy1.txt /dummy1.txt }} #geshi(bash){{ aws s3 sync s3://example/dir1/ s3://example/ --profile example aws s3 sync s3://example/dir1/ s3://example/ --profile example --exact-timestamps }} ---- ** objectのタイムゾーンを表示する [#j5946c46] 要望は上がっている - [[Show timezone in "s3 ls" output · Issue #5242 · aws/aws-cli:https://github.com/aws/aws-cli/issues/5242]] - 環境 -- aws-cli/2.1.27 Python/3.7.3 Linux/5.4.72-microsoft-standard-WSL2 exe/x86_64.ubuntu.18 prompt/off - s3 lsだと、タイムゾーンが非表示。デフォルトではlocal TZのようだ #geshi(bash){{ # TZ=JSTの場合 aws s3 ls s3://my-bucket/ --profile example 2021-08-25 12:05:23 5 example1.html 2021-03-04 17:35:57 38 index.html # TZ=UTCの場合 TZ=UTC aws s3 ls s3://my-bucket/ --profile example 2021-08-25 03:05:23 5 example1.html 2021-03-04 08:35:57 38 index.html }} - s3apiだとiso-8601形式で表示される。 "--prefix i" とすると、index.htmlだけ表示される。 #geshi(bash){{ aws s3api list-objects --query 'Contents[].[Key, LastModified]' --bucket my-bucket --profile example --output text example1.html 2021-08-25T03:05:23+00:00 index.html 2021-03-04T08:35:57+00:00 }} ---- ** aws s3 lsでバケット作成日がregion指定で異なる値を返す [#u57ebc25] - 環境 -- aws-cli/2.1.0 Python/3.7.3 Linux/4.19.128-microsoft-standard exe/x86_64.ubuntu.18 -- aws-cli/1.18.176 Python/3.6.8 Linux/4.19.128-microsoft-standard botocore/1.19.16 - 確認 #geshi(bash){{ aws s3 ls --profile example --region us-east-1 | grep my-old-bucket 2014-10-24 16:06:51 my-old-bucket aws s3 ls --profile example --region ap-northeast-1 | grep my-old-bucket 2020-06-20 03:46:31 my-old-bucket }} - 原因 -- [[list-buckets s3api showing different creation dates ? · Issue #3597 · aws/aws-cli:https://github.com/aws/aws-cli/issues/3597#issuecomment-424167129]] -- AWS consoleでの作成日はus-east-1リージョンの値を表示している ---- ** keyの部分一致したobjectを抽出 [#h3ac69cd] - [[list-objects-v2 — AWS CLI 1.18.174 Command Reference:https://docs.aws.amazon.com/cli/latest/reference/s3api/list-objects-v2.html]] #geshi(bash){{ aws s3api list-objects-v2 --bucket <bucket> --query "Contents[?contains(Key, '<key name>')]" --profile <profile> }} - 前方一致で良い場合は「--prefix <key name>」が使える ---- ** ls: key名だけの取得 [#j434447e] - s3を使う方法 #geshi(bash){{ aws s3 ls s3://example/ --output text | awk '{print $4;}' }} - s3apiを使う方法 -- --prefixを付ける場合、先頭に"/"を付けない #geshi(bash){{ aws s3api list-objects-v2 \ --bucket example \ --prefix prefix/ \ --query 'Contents[].[Key]' \ --output text }} ---- ** object数と合計ファイルサイズ [#i515cbac] - [[Amazon CloudWatch を使用したメトリクスのモニタリング - Amazon Simple Storage Service:https://docs.aws.amazon.com/ja_jp/AmazonS3/latest/dev/cloudwatch-monitoring.html]] -- BucketSizeBytes, NumberOfObjectsで取得できる。 -- StorageType = * (必須。StandardStorage, GlacierStorage等個別に分かれている。) -- 更新頻度は1日1回 - 記事 --[[S3のバケット毎の使用量が欲しいんです | DevelopersIO:https://dev.classmethod.jp/cloud/aws/sugano-003-s3/]] CloudWatchのメトリクスから計算する方法 - awscli cloudwatchから取得。速い #geshi(bash){{ aws_profile=example region=ap-northeast-1 bucket_name=example-bucket start_time="$(date +%Y-%m-%d -d '-1 day')T00:00:00Z" end_time="$(date +%Y-%m-%d -d '-1 day')T23:59:59Z" period=86400 bucket_size_info=$(aws cloudwatch get-metric-statistics \ --profile ${aws_profile} \ --region ${region} \ --namespace AWS/S3 \ --metric-name BucketSizeBytes \ --dimensions Name=BucketName,Value=${bucket_name} Name=StorageType,Value=StandardStorage \ --statistics Sum \ --start-time ${start_time} \ --end-time ${end_time} \ --period ${period}) bucket_size=$(echo ${bucket_size_info} | jq -r '.Datapoints[].Sum') bucket_size_gb=$(echo "scale=2; ${bucket_size} / 1024 / 1024 / 1024" | bc) }} - ファイル数が欲しい場合 #geshi(bash){{ bucket_objects=$(aws cloudwatch get-metric-statistics \ --profile ${aws_profile} \ --region ${region} \ --namespace AWS/S3 \ --metric-name NumberOfObjects \ --dimensions Name=BucketName,Value=${bucket_name} Name=StorageType,Value=AllStorageTypes \ --statistics Average \ --start-time ${start_time} \ --end-time ${end_time} \ --period ${period}) bucket_objects_count=$(echo ${bucket_objects} | jq -r '.Datapoints[].Average') }} - awscli s3: このコマンドはオブジェクトが多いと非常に遅い。CloudWatchのメトリクスを参照した方が良い #geshi(bash){{ aws s3 ls s3://my-bucket/ --recursive --human --sum --profile example ... Total Objects: 14 Total Size: 56.5 KiB }} ---- **署名付オブジェクトURLの有効期限 [#c55fc0d3] - awscliのpresignはダウンロードのみ対応。 - boto3の s3.generate_presigned_url()でput可能なpresign urlを払い出せるようだ。 - 使用したアクセスキーの有効期限により、指定した有効期限より短い時間で切れる事がある。 -- IAM user: max 7 days -- IAM instance profile: max 6 hour --- URLがIAM userより遥かに長い -- STS: max 36 hour --- URLがIAM userより遥かに長い - 記事 -- [[【AWS S3】S3 Presigned URLの仕組みを調べてみた - Qiita:https://qiita.com/tmiki/items/87697d3d3d5330c6fc08]] -- [[S3 バケットの署名付き URL が、指定した有効期限より前に失効する:https://aws.amazon.com/jp/premiumsupport/knowledge-center/presigned-url-s3-bucket-expiration/]] -- [[[小ネタ]S3の署名付きURLを利用して、非AWSユーザにWindows PCからファイルをアップロードしてもらった話 | DevelopersIO:https://dev.classmethod.jp/cloud/aws/upload-file-by-non-aws-user-with-s3-presigned-url/]] -- [[Boto3でS3のpre-signed URLを生成する | DevelopersIO:https://dev.classmethod.jp/cloud/aws/generate-pre-signed-url-for-s3-with-boto3/]] ---- **署名付きオブジェクトURLの生成 [#fd5e9533] - [[署名付きオブジェクトURLの生成 - AWS:https://docs.aws.amazon.com/ja_jp/AmazonS3/latest/dev/ShareObjectPreSignedURL.html]] -- S3オブジェクトをダウンロードするための期限付きURLを生成できる -- AWS CLI v1.10.59以降で対応 -- AWS SDKで可能 - AWS CLI v1.10.59から presign が実装された。例:1時間で有効期限が切れるURLを発行。IAMでS3Readonly権限を付与したアカウントを用意した後、 #geshi(bash){{ aws s3 presign s3://mybucket/example.txt --expires-in 3600 }} - AWS CLI(2015-10-15)では未実装だが、botoに実装済みなので、短いスクリプトで生成できるようだ --[[Support generation of signed URL's for S3 access Issue #462 aws/aws-cli GitHub:https://github.com/aws/aws-cli/issues/462]] - 例: [[複数アカウントの管理>Memo/AmazonWebServices/IAM#tfb76382]] account1でIAM userを管理している。AssumeRoleでaccount2のs3 bucket上のpre-signed URLを作る。 -- IAM role: assumerole-exampleに設定した最大セッション秒が有効期限の上限になるので延長しておく。 #geshi(bash){{ profile=default s3_path=s3://example-bucket/example1.gz expires_in=$((8*3600)) aws sts assume-role \ --role-arn "arn:aws:iam::012345678901:role/assumerole-example" \ --role-session-name "session1" \ --duration-seconds $expires_in \ --profile account1 > session1.json export AWS_REGION=ap-northeast-1 export AWS_ACCESS_KEY_ID=$(cat session1.json | jq -r '.Credentials.AccessKeyId') export AWS_SECRET_ACCESS_KEY=$(cat session1.json | jq -r '.Credentials.SecretAccessKey') export AWS_SESSION_TOKEN=$(cat session1.json | jq -r '.Credentials.SessionToken') aws s3 presign $s3_path --expires-in $expires_in }} -- 環境変数AWS_が残っていると、--profileより優先されるため掃除 #geshi(bash){{ unset $(env | grep -o -P '^AWS_[\w\d]+') }} - 記事 --[[【小ネタ】AWS CLIでS3のPre-Signed URLを生成できるようになっていました! | Developers.IO:http://dev.classmethod.jp/cloud/aws/generate-s3-pre-signed-url-by-aws-cli/]] --[[S3 の事前署名付き(期限付き)URL を生成する | cloudpack技術情報サイト:http://blog.cloudpack.jp/2014/07/08/aws-s3-url-with-expiration-using-php-ruby/]] ---- ** S3 cp: ワイルドカードを使う [#l6740e2b] -[[Use of Exclude and Include Filters:https://docs.aws.amazon.com/cli/latest/reference/s3/index.html#use-of-exclude-and-include-filters]] -記事 --[[[小ネタ] S3に保存されているログファイルをAWS CLIでまとめてコピーする | Developers.IO:https://dev.classmethod.jp/cloud/aws/s3-logfile-copy-by-awscli/]] - 以下のような指定はできない。 #geshi(bash){{ aws s3 cp s3://mybucket/logs/*.log ./ }} - --recursive --exclude "*" --include "..." を使う #geshi(bash){{ aws s3 cp s3://mybucket/ ./ --recursive --exclude "*" --include "*.log" }}} ---- **S3 sync [#t3d81d53] - [[sync — AWS CLI 2.17.28 Command Reference:https://awscli.amazonaws.com/v2/documentation/api/latest/reference/s3/sync.html]] - デフォルトではsync時、''ファイルサイズが同じだとスキップされる''。"--exact-timestamps" を付けるとファイルのタイムスタンプが異なるものも同期してくれる。 -例: test01とtest02だけをダウンロードしたい #geshi(,number=off){{ mybucket |-test01 |-test02 |-test03 }} #geshi(bash){{ aws s3 sync s3://mybucket/ ./ --exclude "*" --include "test01/*" --include "test02/*" aws s3 sync s3://mybucket/ ./ --exclude "*" --include "test01/*" --include "test02/*" --exact-timestamps }} - 記事 -- [[AWS CLI S3 Configurationを試したら想定以上にaws s3 syncが速くなった話 | DevelopersIO:https://dev.classmethod.jp/cloud/aws/aws-s3-sync-with-aws-cli-s3-configuration/]] -- [[Amazon S3 データ転送を最適化する:https://aws.amazon.com/jp/premiumsupport/knowledge-center/s3-optimize-transfer/]] ---- **S3のbucket policy取得 [#id6f3826] #geshi(bash){{{ AWS_PROFILE=default for bucket in $(aws --profile $AWS_PROFILE s3api list-buckets --query "Buckets[].[Name]" --output text); do \ region=$(aws --profile $AWS_PROFILE s3api get-bucket-location --bucket $bucket --output text); \ echo "---- $bucket"; \ aws --profile $AWS_PROFILE --region $region s3api get-bucket-policy --bucket $bucket; \ done > $AWS_PROFILE.s3.bucket-policy.json }}}