aws sam (Serverless Application Model)に入門する
Infrastructure as Code入門としてaws samでLambdaを作るところからはじめてみる
sample templateから基本的なアプリケーションをビルト
仕組み的には以下のような順序で作成される
- ローカルでsamコマンドでアプリケーションを作成
- ローカルから
sam deploy
でcloudformationを呼び出しアプリケーションをデプロイする - S3へテンプレートが保存される
- API GatewayとLambdaが作成される
aws samのアプリケーションを作成
$ sam init # まずはawsのtemplateを選択して使う # template一覧は以下 Which template source would you like to use? 1 - AWS Quick Start Templates 2 - Custom Template Location Choice: 1 # パッケージはシンプルに # lambda用のファイルはzipで固め # cloudformationでS3にアップロードされる # # 2のイメージはECR周りの知識が必要なのでそのうち試す What package type would you like to use? 1 - Zip (artifact is a zip uploaded to S3) 2 - Image (artifact is an image uploaded to an ECR image repository) Package type: 1 # go1.xで作っていく Which runtime would you like to use? 1 - nodejs14.x 2 - python3.8 3 - ruby2.7 4 - go1.x 5 - java11 6 - dotnetcore3.1 7 - nodejs12.x 8 - nodejs10.x 9 - python3.7 10 - python3.6 11 - python2.7 12 - ruby2.5 13 - java8.al2 14 - java8 15 - dotnetcore2.1 Runtime: 4 # cloudformation, API Gatewayの名前 # S3, Lambdaのprefixとして使われる Project name [sam-app]: Cloning from https://github.com/aws/aws-sam-cli-app-templates # まずは単独のLambdaで作るので1を選択 AWS quick start application templates: 1 - Hello World Example 2 - Step Functions Sample App (Stock Trader) Template selection: 1 ----------------------- Generating application: ----------------------- Name: sam-app Runtime: go1.x Dependency Manager: mod Application Template: hello-world Output Directory: . Next steps can be found in the README file at ./sam-app/README.md
この段階でgolangのLambdaに適した構成が作成される
template.yamlはcloudformationと共通フォーマット
将来的にaws samの範囲より拡張された場合はcloudformationで使う事もできる
$ tree sam-app sam-app ├── Makefile ├── README.md ├── hello-world │ ├── go.mod │ ├── go.sum │ ├── main.go │ └── main_test.go └── template.yaml 1 directory, 7 files
main.goは以下のようにLambdaでGetリクエストを受ける基本的な構成になっている
package main import ( "errors" "fmt" "io/ioutil" "net/http" "github.com/aws/aws-lambda-go/events" "github.com/aws/aws-lambda-go/lambda" ) var ( // DefaultHTTPGetAddress Default Address DefaultHTTPGetAddress = "https://checkip.amazonaws.com" // ErrNoIP No IP found in response ErrNoIP = errors.New("No IP in HTTP response") // ErrNon200Response non 200 status code in response ErrNon200Response = errors.New("Non 200 Response found") ) func handler(request events.APIGatewayProxyRequest) (events.APIGatewayProxyResponse, error) { resp, err := http.Get(DefaultHTTPGetAddress) if err != nil { return events.APIGatewayProxyResponse{}, err } if resp.StatusCode != 200 { return events.APIGatewayProxyResponse{}, ErrNon200Response } ip, err := ioutil.ReadAll(resp.Body) if err != nil { return events.APIGatewayProxyResponse{}, err } if len(ip) == 0 { return events.APIGatewayProxyResponse{}, ErrNoIP } return events.APIGatewayProxyResponse{ Body: fmt.Sprintf("Hello, %v", string(ip)), StatusCode: 200, }, nil } func main() { lambda.Start(handler) }
アプリケーションをbuild
$ sam build Building codeuri: ./sam-app/hello-world runtime: go1.x metadata: {} functions: ['HelloWorldFunction'] Running GoModulesBuilder:Build Build Succeeded Built Artifacts : .aws-sam/build Built Template : .aws-sam/build/template.yaml Commands you can use next ========================= [*] Invoke Function: sam local invoke [*] Deploy: sam deploy --guided
ローカルでアプリケーションを実行
sam local start-api
と実行する事で、ローカルでsamでbuildしたAPIを実行できる
$ sam local start-api Mounting HelloWorldFunction at http://127.0.0.1:3000/hello [GET] You can now browse to the above endpoints to invoke your functions. You do not need to restart/reload SAM CLI while working on your functions, changes will be reflected instantly/automatically. You only need to restart SAM CLI if you update your AWS SAM template 2021-08-08 23:37:49 * Running on http://127.0.0.1:3000/ (Press CTRL+C to quit)
この状態でリクエストを投げると、dockerイメージが作成&実行され、レスポンスを返す
$ curl http://127.0.0.1:3000/hello Hello, 11.111.111.111
sam local start-apiのログ
Invoking hello-world (go1.x) Image was not found. Building image...................................................................................................... Skip pulling image and use local one: amazon/aws-sam-cli-emulation-image-go1.x:rapid-1.27.2. Mounting ./sam-app/.aws-sam/build/HelloWorldFunction as /var/task:ro,delegated inside runtime container START RequestId: fa806430-6835-4b88-acd6-4e1b857bcd4a Version: $LATEST END RequestId: fa806430-6835-4b88-acd6-4e1b857bcd4a REPORT RequestId: fa806430-6835-4b88-acd6-4e1b857bcd4a Init Duration: 0.07 ms Duration: 1010.38 ms Billed Duration: 1100 ms Memory Size: 128 MB Max Memory Used: 128 MB No Content-Type given. Defaulting to 'application/json'. 2021-08-08 23:43:07 127.0.0.1 - - [08/Aug/2021 23:43:07] "GET /hello HTTP/1.1" 200 -
$ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES fa8dda6a0f15 amazon/aws-sam-cli-emulation-image-go1.x:rapid-1.27.2 "/var/rapid/aws-lamb…" 2 seconds ago Up 1 second 127.0.0.1:6436->8080/tcp vigorous_allen
アプリケーションをawsへデプロイする
--guided
をつけると会話形式で設定できる
$ sam deploy --guided Configuring SAM deploy ====================== Looking for config file [samconfig.toml] : Not found Setting default arguments for 'sam deploy' ========================================= Stack Name [sam-app]: AWS Region [ap-northeast-1]: #Shows you resources changes to be deployed and require a 'Y' to initiate deploy Confirm changes before deploy [y/N]: #SAM needs permission to be able to create roles to connect to the resources in your template Allow SAM CLI IAM role creation [Y/n]: HelloWorldFunction may not have authorization defined, Is this okay? [y/N]: y Save arguments to configuration file [Y/n]: SAM configuration file [samconfig.toml]: SAM configuration environment [default]: Looking for resources needed for deployment: Not found. Creating the required resources... Successfully created! Managed S3 bucket: aws-sam-cli-managed-default-samclisourcebucket-xarl3ki5fc62 A different default S3 bucket can be set in samconfig.toml Saved arguments to config file Running 'sam deploy' for future deployments will use the parameters saved above. The above parameters can be changed by modifying samconfig.toml Learn more about samconfig.toml syntax at https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-sam-cli-config.html Uploading to sam-app/7ad10cf1c8bd04b9d2c1ad18dd4297c0 4328737 / 4328737 (100.00%) Deploying with following values =============================== Stack name : sam-app Region : ap-northeast-1 Confirm changeset : False Deployment s3 bucket : aws-sam-cli-managed-default-samclisourcebucket-xarl3ki5fc62 Capabilities : ["CAPABILITY_IAM"] Parameter overrides : {} Signing Profiles : {} Initiating deployment ===================== Uploading to sam-app/17fb0b7caff4b6a85cdca466c28c1236.template 1154 / 1154 (100.00%) Waiting for changeset to be created.. CloudFormation stack changeset ---------------------------------------------------------------------------------------------------- Operation LogicalResourceId ResourceType Replacement ---------------------------------------------------------------------------------------------------- + Add HelloWorldFunctionCatchAllPermissionProd AWS::Lambda::Permission N/A + Add HelloWorldFunctionRole AWS::IAM::Role N/A + Add HelloWorldFunction AWS::Lambda::Function N/A + Add ServerlessRestApiDeployment47fc2d5f9d AWS::ApiGateway::Deployment N/A + Add ServerlessRestApiProdStage AWS::ApiGateway::Stage N/A + Add ServerlessRestApi AWS::ApiGateway::RestApi N/A ---------------------------------------------------------------------------------------------------- Changeset created successfully. arn:aws:cloudformation:ap-northeast-1:111111111111:changeSet/samcli-deploy1628426562/db1f0927-131d-4bf1-9b12-aacf949eacda 2021-08-08 21:42:54 - Waiting for stack create/update to complete CloudFormation events from changeset ------------------------------------------------------------------------------------------------------------------------------ ResourceStatus ResourceType LogicalResourceId ResourceStatusReason ------------------------------------------------------------------------------------------------------------------------------ CREATE_IN_PROGRESS AWS::IAM::Role HelloWorldFunctionRole - CREATE_IN_PROGRESS AWS::IAM::Role HelloWorldFunctionRole Resource creation Initiated CREATE_COMPLETE AWS::IAM::Role HelloWorldFunctionRole - CREATE_IN_PROGRESS AWS::Lambda::Function HelloWorldFunction - CREATE_IN_PROGRESS AWS::Lambda::Function HelloWorldFunction Resource creation Initiated CREATE_COMPLETE AWS::Lambda::Function HelloWorldFunction - CREATE_IN_PROGRESS AWS::ApiGateway::RestApi ServerlessRestApi - CREATE_IN_PROGRESS AWS::ApiGateway::RestApi ServerlessRestApi Resource creation Initiated CREATE_COMPLETE AWS::ApiGateway::RestApi ServerlessRestApi - CREATE_IN_PROGRESS AWS::Lambda::Permission HelloWorldFunctionCatchAllPermissionProd - CREATE_IN_PROGRESS AWS::Lambda::Permission HelloWorldFunctionCatchAllPermissionProd Resource creation Initiated CREATE_IN_PROGRESS AWS::ApiGateway::Deployment ServerlessRestApiDeployment47fc2d5f9d - CREATE_COMPLETE AWS::ApiGateway::Deployment ServerlessRestApiDeployment47fc2d5f9d - CREATE_IN_PROGRESS AWS::ApiGateway::Deployment ServerlessRestApiDeployment47fc2d5f9d Resource creation Initiated CREATE_IN_PROGRESS AWS::ApiGateway::Stage ServerlessRestApiProdStage - CREATE_IN_PROGRESS AWS::ApiGateway::Stage ServerlessRestApiProdStage Resource creation Initiated CREATE_COMPLETE AWS::ApiGateway::Stage ServerlessRestApiProdStage - CREATE_COMPLETE AWS::Lambda::Permission HelloWorldFunctionCatchAllPermissionProd - CREATE_COMPLETE AWS::CloudFormation::Stack sam-app - ------------------------------------------------------------------------------------------------------------------------------ CloudFormation outputs from deployed stack ----------------------------------------------------------------------------------------------------------- Outputs ----------------------------------------------------------------------------------------------------------- Key HelloWorldFunctionIamRole Description Implicit IAM Role created for Hello World function Value arn:aws:iam::111111111111:role/sam-app-HelloWorldFunctionRole-MGSTGE9WCIMR Key HelloWorldAPI Description API Gateway endpoint URL for Prod environment for First Function Value https://aaaaaaaaaa.execute-api.ap-northeast-1.amazonaws.com/Prod/hello/ Key HelloWorldFunction Description First Lambda Function ARN Value arn:aws:lambda:ap-northeast-1:111111111111:function:sam-app-HelloWorldFunction-pMOSVaxRjbuN ----------------------------------------------------------------------------------------------------------- Successfully created/updated stack - sam-app in ap-northeast-1
これにより API Gateway経由でLambdaを呼び出せるようところまで作成される
デプロイ結果の確認
Outputs
にあるHelloWorldAPI
へアクセスしてみると、レスポンスが返ってくる
$ curl - 'https://aaaaaaaaaa.execute-api.ap-northeast-1.amazonaws.com/Prod/hello/' HTTP/2 200 content-type: application/json content-length: 22 date: Sun, 08 Aug 2021 13:41:16 GMT Hello, 11.111.111.111