AWS Lambda function から S3 へアップロードする [Serverless Framework 編]
- 2018 12/22
- カテゴリー : Amazon Web Services
- AWS Lambda . AWS S3 . Serverless Framework
- コメントを書く
Serverless Framework で AWS Lambda へ deploy した function から S3 へアップロードする方法をご紹介します。
前提
本サイトの記事 Serverless Framework で AWS Lambda へ deploy する | CodeNote を元にセットアップしているとします。
初期状態だと InvalidAccessKeyId エラー
Serverless Framework のデフォルト設定のままだと Lambda function から S3 を使おうとすると InvalidAccessKeyId: The AWS Access Key Id you provided does not exist in our records. というエラーが発生してしまいます。
{ InvalidAccessKeyId: The AWS Access Key Id you provided does not exist in our records. at Request.extractError (/var/task/node_modules/aws-sdk/lib/services/s3.js:585:35) at Request.callListeners (/var/task/node_modules/aws-sdk/lib/sequential_executor.js:106:20) at Request.emit (/var/task/node_modules/aws-sdk/lib/sequential_executor.js:78:10) at Request.emit (/var/task/node_modules/aws-sdk/lib/request.js:683:14) at Request.transition (/var/task/node_modules/aws-sdk/lib/request.js:22:10) at AcceptorStateMachine.runTo (/var/task/node_modules/aws-sdk/lib/state_machine.js:14:12) at /var/task/node_modules/aws-sdk/lib/state_machine.js:26:10 at Request.<anonymous> (/var/task/node_modules/aws-sdk/lib/request.js:38:9) at Request.<anonymous> (/var/task/node_modules/aws-sdk/lib/request.js:685:12) at Request.callListeners (/var/task/node_modules/aws-sdk/lib/sequential_executor.js:116:18) message: 'The AWS Access Key Id you provided does not exist in our records.', code: 'InvalidAccessKeyId', region: null, time: 2018-12-22T15:40:48.422Z, requestId: 'A7BA76D679AA0908', extendedRequestId: 'BgpkYpdh88xEFW1IOdb6E1hKS484X3ZVcsymi0TL2S/x5nTF0CNsZQ18MkIE5yYn/6WjJz2KaSc=', cfId: undefined, statusCode: 403, retryable: false, retryDelay: 41.81325093666113 } |
AWS Lambda から S3 を利用する手順
私が開発してる Set up AWS S3 / Crawling the target site and save as HTML to S3 · Pull Request #4 に沿って、手順をご紹介します。
npm install aws-sdk
npm install --save aws-sdk |
S3 bucket を環境変数へ定義
serverless.yml の provider: に environment: を以下のように定義することで、serverless.yml からは ${self:provider.environment.S3_BUCKET} というように環境変数を利用できます。
provider: # you can define service wide environment variables here environment: S3_BUCKET: your-bucket-name-${opt:stage, self:provider.stage} |
S3 bucket 作成
S3 Management Console から S3 bucket を作成するのでもいいですが、せっかく Serverless Framework を利用してるなら serverless.yml に以下のような設定を追加して CloudFormation 経由で S3 bucket を作成するのがおすすめです。
# you can add CloudFormation resource templates here resources: Resources: S3BucketResource: Type: AWS::S3::Bucket Properties: BucketName: ${self:provider.environment.S3_BUCKET} Outputs: S3BucketOutput: Description: "Description for the output" Value: S3BucketResource |
S3 bucket への IAM 権限付与
上記までだと S3 bucket 作成しただけで、Lambda function から作成した S3 bucket への権限がなにもありません。
serverless.yml の provider: iamRoleStatements: を以下のように修正すると、Lambda function から S3 へアクセス
provider: # you can add statements to the Lambda function's IAM Role here iamRoleStatements: - Effect: "Allow" Action: - "s3:ListBucket" - "s3:GetObject" - "s3:PutObject" - "s3:DeleteObject" Resource: Fn::Join: - "" - - "arn:aws:s3:::" - ${self:provider.environment.S3_BUCKET} - "/*" |
Lambda から S3 へ upload
最後に、上記で作成、IAM 権限付与した S3 bucket へ Lambda function から HTML ファイルをアップロードするサンプルコードをご紹介します。
'use strict'; const AWS = require('aws-sdk'); module.exports.putS3 = async (event, context) => { try { const html = '<h1>Hello world</h1>'; AWS.config.update({ accessKeyId: process.env.AWS_ACCESS_KEY_ID, secretAccessKey: process.env.AWS_SEECRET_ACCESS_KEY, region: process.env.AWS_REGION }); const s3 = new AWS.S3(); const response = await s3.putObject({ Bucket: process.env.S3_BUCKET, Key: `${Date.now()}.html`, ContentType: 'text/html', Body: html }).promise(); console.log({ result: 'OK', s3response: response }); } catch (err) { console.error(err); console.log({ result: 'NG' }); } }; |
以上、Serverless Framework で deploy した AWS Lambda function から S3 を操作したい、現場からお送りしました。
参考情報
- Serverless Framework – AWS Lambda Events – S3
- Referencing Environment Variables – Serverless Variables
- Serverless FrameworkでLambdaとS3を作成する | Fusic Tech Blog