ニュース&ブログ
「AWS Lambda for Python」で署名付きURLを自動生成する
投稿日:2016/10/5
こんにちは。クラウドコンサルティング事業部の関口です。
今回は、S3へファイルをアップロードしたタイミングで「AWS Lambda」を使って署名付きURLを自動生成する方法です。
もう既に利用されていると思うので今さらな感じなのかもしれませんが、なかなか設定方法がまとまったものが無かったのでブログに掲載したいと思います。
(ほぼ私の備忘録です。)
やりたい事
① S3にファイルをアップロードする
② 「AWS Lambda」で署名付きURLが生成
③ 「AWS SNS」で生成した署名付きURLをメール通知
④ メール通知を受けたユーザがファイルをダウンロードする
⑤ 一定時間経過後にダウンロード不可にする
前提条件
今回は、以下は準備されていることを前提とします。・ファイルアップロード先のS3バケット
・AWS Lambda用のIAM Role
・AWS SNS Topic・Subscriptions
また、Lambdaに設定するコードは、Pythonで作成しました。
AWS Lambdaの設定
「AWS Lambda」の設定を行っていきます。
1.AWSマネジメントコンソールにログインし、AWS Lambdaの設定画面の「Get Start Now」を押下します。(既に別のLambda functionがある場合は「Create a Lambda function」を押下します。)
2.今回はBlueprintを使わない為、スキップします。

3.Triggerを設定します。“Bucket”名と“Event Type”を選択し、「Next」を押下します。
(S3にファイルがアップロードされたタイミングでLambdaを実行したいので、“”Event Type“を「Put」にしています。)
4.“Configure function”“で実行するスクリプト等の設定をして、「Next」を押下します。
■Configure function
・Name: ※適当な名前を設定
・Description: ※説明文を入力。
・Runtime: ※“Python2.7”を選択する。
■Lambda function code
以下の様なコードを設定しました。ダウンロード可能な期限は10分としました。
import boto3
import urllib
def lambda_handler(event, context):
## Generate a pre-signed URL for an Amazon S3 object.
s3 = boto3.client('s3')
bucket = event['Records'][0]['s3']['bucket']['name']
key = urllib.unquote_plus(event['Records'][0]['s3']['object']['key'].encode('utf8'))
presigned_url = s3.generate_presigned_url(
ClientMethod = 'get_object',
Params = {'Bucket' : bucket, 'Key' : key},
ExpiresIn = 600, # ダウンロード期限:10分
HttpMethod = 'GET')
print ( presigned_url )
## Publish to AWS SNS.
topic = 'arn:aws:sns:ap-northeast-1:<Account ID>:<Topic Name> #TopicのARN
subject = 'Generated a pre-signed URL for an Amazon S3 object.'
sns = boto3.client('sns')
mail = {'TopicArn': topic ,'Message': presigned_url ,'Subject': subject}
sns.publish(**mail)
■Lambda function handler and role
・Handler:lambda_function.lambda_handler ※デフォルトのまま
・Role: ※作成したRoleを選択する
■Advanced settings
・Memory (MB):128MB ※といあえずデフォルトの最小値を設定
・Timeout:30sec ※適当な値に調整
5.設定内容を確認し、「Create function」を押下します。

テスト実行
AWS Lambdaの設定が完了したので、動作確認を行ってみます。
1.”Lambda” -> “Functions” -> <設定した“Lamda Function”名>へ移動します。
2.”Action” -> “Configure test event”へ移動し、Eventを発生させるテストコードを作成します。
以下の様なコードを設定しました。
{
"Records": [
{
"eventVersion": "2.0",
"eventTime": "1970-01-01T00:00:00.000Z",
"requestParameters": {
"sourceIPAddress": "127.0.0.1"
},
"s3": {
"configurationId": "testConfigRule",
"object": {
"eTag": "0123456789abcdef0123456789abcdef",
"sequencer": "0A1B2C3D4E5F678901",
"key": "<ダウンロードするファイル名>", #テスト用にファイルは予めS3に置いておいてください!!
"size": 1024
},
"bucket": {
"arn": "arn:aws:lambda:ap-northeast-1::function:< Functions name>", #Lambda FunctionのARN
"name": "test-presignedurl",
"ownerIdentity": {
"principalId": "EXAMPLE"
}
},
"s3SchemaVersion": "1.0"
},
"responseElements": {
"x-amz-id-2": "EXAMPLE123/5678abcdefghijklambdaisawesome/mnopqrstuvwxyzABCDEFGH",
"x-amz-request-id": "EXAMPLE123456789"
}
"awsRegion": "ap-northeast-1",
"eventName": "ObjectCreated:Put",
"userIdentity": {
"principalId": "EXAMPLE"
},
"eventSource": "aws:s3"
}
]
}
3.テストコード入力後、「Save and test」を押下し、テスト実行します。
4.「Execution result succeeded」と表示されれば成功です。

また、問題なければバックアップ完了のメールもAWS SNSで設定したメール送信先に届いていると思います。
S3にファイルをアップロードしてみる
では、実際にS3のバケットにファイルをアップロードしてみて署名付きURLが生成される事を確認します。
1.S3のバケットにファイルをアップロードします。

2.署名付きURLが発行され、メールで通知されました。

3.URLをクリックすると、無事にダウンロードできました。

4.10分経過後に再度URLをクリックするとアクセスが拒否されています。

以上です。それではまた次回。