AWS SAMでアプリをデプロイする。ついでにSAM Localでローカルテストなどもしてみる
基本的にAWS Lambda等のデプロイはServerless Frameworkを使うことが多いのですが、Swaggerが使えるなどのメリットを感じるところが増えてきたので、SAMについても触ってみました。 スタックを […]
目次
基本的にAWS Lambda等のデプロイはServerless Frameworkを使うことが多いのですが、Swaggerが使えるなどのメリットを感じるところが増えてきたので、SAMについても触ってみました。
スタックを作成
以下のような形でLambdaをデプロイできます。
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: 'Example SAM stack'
Resources:
HelloSAM:
Type: AWS::Serverless::Function
Properties:
Handler: index.handler
Runtime: nodejs6.10
Lambdaのソースコードは、受け取ったイベントをそのまま返す形にしておきます。
index.js
const handler = (event, context, callback) => {
console.log(event) // eslint-disable-line no-console
return callback(null, {
event
})
}
module.exports.handler = handler
デプロイ先バケットの作成
$ aws s3 mb s3://YOUR_ORIGINAL_BUCKET_NAME --region us-east-1
make_bucket: YOUR_ORIGINAL_BUCKET_NAME
# S3バケット名はグローバルなので、既に誰かが使っている名前は利用できない
$ aws s3 mb s3://sam-test --region us-east-1
make_bucket failed: s3://sam-test An error occurred (BucketAlreadyExists) when calling the CreateBucket operation: The requested bucket name is not available. The bucket namespace is shared by all users of the system. Please select a different name and try again.
パッケージの作成
$ aws cloudformation package --template-file ./sam.yml --output-template-file sam-output.yml --s3-bucket YOUR_ORIGINAL_BUCKET_NAME
Uploading to 58d19799e9bd53029cc4a5fecf6e1370 13277 / 13277.0 (100.00%)
Successfully packaged artifacts and wrote output template to file sam-output.yml.
Execute the following command to deploy the packaged template
aws cloudformation deploy --template-file /Users/develop/sam/example/sam-output.yml --stack-name <YOUR STACK NAME>
“Uploading to 58d19799e9bd53029cc4a5fecf6e1370″と表示されている名前と同じものがS3の該当バケットにアップロードされている。
AWSへのデプロイ
$ aws cloudformation deploy --template-file ./sam-output.yml --stack-name hello-sam
たまにこうなる
Failed to create the changeset: Waiter ChangeSetCreateComplete failed: Waiter encountered a terminal failure state Status: FAILED. Reason: Requires capabilities : [CAPABILITY_IAM]
--capabilities CAPABILITY_IAM
をつければOK
デプロイがこける場合
たまにデプロイがこけることがあります。
$ aws cloudformation deploy --template-file ./sam-output.yml --stack-name hello-sam --capabilities CAPABILITY_IAM
Waiting for changeset to be created..
Waiting for stack create/update to complete
Failed to create/update the stack. Run the following command
to fetch the list of events leading up to the failure
aws cloudformation describe-stack-events --stack-name hello-sam
「aws cloudformation describe-stack-events
で原因調べろ」ということみたいですね。jqを使ってサクッとこけたときのメッセージだけ拾いましょう。
$ aws cloudformation describe-stack-events --stack-name hello-sam | jq '.StackEvents[] | select(.ResourceStatus == "CREATE_FAILED") | .ResourceStatusReason' -r
Error occurred while GetObject. S3 Error Code: PermanentRedirect. S3 Error Message: The bucket is in this region: us-east-1. Please use this region to retry the request
S3のバケットとCloudFormationのリージョンが一致していないみたいです。
ということで、aws cloudformation deploy
に--region us-east-1
を追加してリトライしてみます。
$ aws cloudformation deploy --template-file ./sam-output.yml --stack-name hello-sam --capabilities CAPABILITY_IAM
Waiting for changeset to be created..
Waiting for stack create/update to complete
Successfully created/updated stack - hello-sam
成功しました。aws cloudformation describe-stacks
でも、情報がとれています。
$ aws cloudformation describe-stacks --stack-name hello-sam --region us-east-1 | jq .
{
"Stacks": [
{
"StackId": "arn:aws:cloudformation:us-east-1:99999:stack/hello-sam/xxxx-xxxx-xxxx-xxxx-xxxx",
"Description": "Example SAM stack",
"Tags": [],
"CreationTime": "2018-05-08T00:25:41.478Z",
"Capabilities": [
"CAPABILITY_IAM"
],
"StackName": "hello-sam",
"NotificationARNs": [],
"StackStatus": "CREATE_COMPLETE",
"DisableRollback": false,
"ChangeSetId": "arn:aws:cloudformation:us-east-1:999999:changeSet/awscli-cloudformation-package-deploy-1525739139/xxxx-xxxx-xxxx-xxxx-xxxx",
"LastUpdatedTime": "2018-05-08T00:25:53.008Z"
}
]
}
SAMで構築したアプリをローカルで実行する
デプロイして確認だと少し時間がかかるので、ローカルで検証しましょう。SAM LocalというツールがAWSから提供されています。2018/05/06時点ではまだβ版ですが、ローカルで軽く試す程度ならまぁ大丈夫でしょう。
$ npm i -g aws-sam-local
$ sam --version
sam version 0.2.11
YAMLファイルはtemplate.yml
に
SAM Localを使うには、スタック情報がtemplate.yml
に記述されている必要があります。他のファイル名だと、エラーになる様子でした。
$ sam local invoke HelloSAM
2018/05/07 23:21:02 Failed to parse template: open template.yml: no such file or directory
eventパラメータファイルを用意する
event.jsonなどでファイルを用意しましょう。
{
"hello": "world"
}
実行する
sam local invoke FUNCTION_NAME
で実行できます。Dockerイメージを落としてくるため、初回は時間がかかります。
$ sam local invoke HelloSAM --event ./event.json
2018/05/07 23:26:31 Successfully parsed template.yml
2018/05/07 23:26:31 Connected to Docker 1.37
2018/05/07 23:26:31 Fetching lambci/lambda:nodejs6.10 image for nodejs6.10 runtime...
nodejs6.10: Pulling from lambci/lambda
Digest: sha256:56205b1ec69e0fa6c32e9658d94ef6f3f5ec08b2d60876deefcbbd72fc8cb12f
Status: Image is up to date for lambci/lambda:nodejs6.10
2018/05/07 23:26:36 Invoking index.handler (nodejs6.10)
2018/05/07 23:26:36 Mounting /Users/develop/sam/example as /var/task:ro inside runtime container
START RequestId: 3e7cfb67-c2d0-1295-9e38-257f28a25ced Version: $LATEST
2018-05-07T14:27:04.155Z 3e7cfb67-c2d0-1295-9e38-257f28a25ced { hello: 'world' }
END RequestId: 3e7cfb67-c2d0-1295-9e38-257f28a25ced
REPORT RequestId: 3e7cfb67-c2d0-1295-9e38-257f28a25ced Duration: 36.54 ms Billed Duration: 100 ms Memory Size: 128 MB Max Memory Used: 29 MB
{"event":{"hello":"world"}}