はじめに
この記事は、S3の署名付きURLの学習のために署名付きURLを利用してS3のオブジェクトをPUT/GETしたときの手順をまとめたものです。
ポイントは以下のとおりです。
手順
環境準備
プロファイル設定
#プロファイルとリージョン設定 PROFILE="<利用したいプロファイル名:デフォルトの場合はdefaultを指定>" REGION="<実行したいリージョン:ap-northeast-1など>" aws --profile ${PROFILE} --region ${REGION} sts get-caller-identity
S3バケット作成
#S3バケット作成 GET_BUCKET="xxxxx-get-bucket" PUT_BUCKET="xxxxx-put-bucket" OBJECT="hello-world.txt" aws --profile ${PROFILE} --region ${REGION} s3api create-bucket --bucket "${GET_BUCKET}" --create-bucket-configuration "LocationConstraint=${REGION}" aws --profile ${PROFILE} --region ${REGION} s3api create-bucket --bucket "${PUT_BUCKET}" --create-bucket-configuration "LocationConstraint=${REGION}" #GET用バケットへのオブジェクト配置 echo 'Hello World!!' > ${OBJECT} aws s3 --profile ${PROFILE} --region ${REGION} cp "${OBJECT}" "s3://${GET_BUCKET}" aws s3 --profile ${PROFILE} --region ${REGION} ls "s3://${GET_BUCKET}"
EC2用のインスタンスロール作成
#S3アクセス用のインスタンスロール作成 #IAMロール作成 POLICY='{ "Version": "2012-10-17", "Statement": [ { "Sid": "", "Effect": "Allow", "Principal": { "Service": "ec2.amazonaws.com" }, "Action": "sts:AssumeRole" } ] }' aws --profile ${PROFILE} \ iam create-role \ --role-name "EC2-PreSignS3Test" \ --assume-role-policy-document "${POLICY}" \ --max-session-duration 43200 # SSM用カスタマー管理ポリシーのアタッチ(SSMでインスタンスログインするためで検証自体としては不要) aws --profile ${PROFILE} \ iam attach-role-policy \ --role-name "EC2-PreSignS3Test" \ --policy-arn arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore #S3アクセス用のインラインポリシー追加 InlinePolicyDocument='{ "Version": "2012-10-17", "Statement": [ { "Sid": "ForGetBucket", "Effect": "Allow", "Action": [ "s3:ListBucket", "s3:GetObject" ], "Resource": [ "arn:aws:s3:::'"${GET_BUCKET}"'", "arn:aws:s3:::'"${GET_BUCKET}"'/*" ] }, { "Sid": "ForPutBucket", "Effect": "Allow", "Action": [ "s3:ListBucket", "s3:PutObject" ], "Resource": [ "arn:aws:s3:::'"${PUT_BUCKET}"'", "arn:aws:s3:::'"${PUT_BUCKET}"'/*" ] } ] }' aws --profile ${PROFILE} \ iam put-role-policy \ --role-name "EC2-PreSignS3Test" \ --policy-name "AllowS3Bucket" \ --policy-document "${InlinePolicyDocument}" #インスタンスプロファイルの作成 aws --profile ${PROFILE} \ iam create-instance-profile \ --instance-profile-name "EC2-PreSignS3Test"; aws --profile ${PROFILE} \ iam add-role-to-instance-profile \ --instance-profile-name "EC2-PreSignS3Test" \ --role-name "EC2-PreSignS3Test" ;
|
EC2用インスタンス作成
PubSubnetID="<インスタンスを作成するパブリックサブネットのID: subnet-xxxx>" SgId="<インスタンスに付与するサブネットID>" KEYNAME="<SSH接続する場合はキーペア指定>" #最新のAmazon Linux2のAMI IDを取得します。 AL2_AMIID=$(aws --profile ${PROFILE} --region ${REGION} --output text \ ec2 describe-images \ --owners amazon \ --filters 'Name=name,Values=amzn2-ami-hvm-2.0.????????.?-x86_64-gp2' \ 'Name=state,Values=available' \ --query 'reverse(sort_by(Images, &CreationDate))[:1].ImageId' ) ; echo -e "PubSubnetID = ${PubSubnetID}\nSgId = ${SgId}\nKEYNAME = ${KEYNAME}\nAL2_AMIID = ${AL2_AMIID}" #インスタンスの作成 #インスタンスタイプ設定 INSTANCE_TYPE="t2.micro" #タグ設定 TAGJSON=' [ { "ResourceType": "instance", "Tags": [ { "Key": "Name", "Value": "PreSignS3Test" } ] } ]' # サーバの起動 aws --profile ${PROFILE} --region ${REGION} \ ec2 run-instances \ --image-id ${AL2_AMIID} \ --instance-type "t2.micro" \ --subnet-id ${PubSubnetID} \ --security-group-ids ${SgId} \ --associate-public-ip-address \ --tag-specifications "${TAGJSON}" \ --iam-instance-profile "Name=EC2-PreSignS3Test" \ --key-name ${KEYNAME} ; #SSH接続しない場合はこの行を削除する
インスタンス上でのAWS CLI設定
#AWS CLI環境の設定 REGION=$(TOKEN=`curl -X PUT "http://169.254.169.254/latest/api/token" -H "X-aws-ec2-metadata-token-ttl-seconds: 21600"` \ && curl -H "X-aws-ec2-metadata-token: $TOKEN" -s http://169.254.169.254/latest/meta-data/placement/availability-zone | sed -e 's/.$//') aws configure set region ${REGION} aws configure set output json #接続確認 aws sts get-caller-identity
S3署名付きURLでのオブジェクト取得(GET)
AWS CLIでのオブジェクト取得確認
#S3バケット情報の設定 GET_BUCKET="xxxxx-get-bucket" OBJECT="hello-world.txt" #AWS CLIでのオブジェクト確認(ファイル一覧にオブジェクトが表示されること) aws s3 ls "s3://${GET_BUCKET}" #AWS CLIでのオブジェクト取得確認 aws s3 cp "s3://${GET_BUCKET}/${OBJECT}" .
署名付きURLでのオブジェクト取得用のpythonスクリプト配置
- python3とboto3のセットアップ
sudo yum -y install python3
sudo pip3 install boto3
get.py
というファイル名で以下のファイルを格納
#!/usr/bin/env python3 import sys import boto3 #引数からバケットとオブジェクト情報を取得 BUCKET_NAME = sys.argv[1] OBJECT_KEY = sys.argv[2] EXPIRESIN = sys.argv[3] url = boto3.client('s3').generate_presigned_url( ClientMethod='get_object', Params={'Bucket': BUCKET_NAME, 'Key': OBJECT_KEY }, ExpiresIn=EXPIRESIN) print(url)
- 以下のコマンドを実行して署名付きURLを生成
python3 get.py ${GET_BUCKET} ${OBJECT} 60
put.py
というファイル名で以下のファイルを格納
#!/usr/bin/env python3 import sys import boto3 #引数からバケットとオブジェクト情報を取得 BUCKET_NAME = sys.argv[1] OBJECT_KEY = sys.argv[2] EXPIRESIN = sys.argv[3] url = boto3.client('s3').generate_presigned_url( ClientMethod='put_object', Params={'Bucket': BUCKET_NAME, 'Key': OBJECT_KEY }, ExpiresIn=EXPIRESIN) print(url)
python3 put.py ${PUT_BUCKET} ${OBJECT} 60
curl -X PUT --upload-file <ファイルパス> "<取得したPre-Signed URL>"