Go+SAMでLambda Layersのテンプレートを作成

Go+SAMでLambda Layersのテンプレートを作成:


GoでLambda Layers

re:Invent2018で発表されたLambda Layersですが、どのサイトを見てもPythonの記事ばかりなので、実際にGoを使ってLambda Layersに挑戦してみます。


環境準備

SAMがインストールされていることを確認します。ローカル環境でライブラリのインストールがうまくいかない場合や、Windowsを使用しているけどLinuxコマンドを使ってやりたい場合は、Cloud9上で開発すると便利です。ローカルPCのモジュールが肥大化しすぎないという利点もあります。

samのバージョン確認
$ sam --version 
SAM CLI, version 0.8.1 
※仮にSAMがない場合は、pipコマンドでインストールします。

pipでsam-cliをインストール
$ pip install aws-sam-cli 


Goプロジェクトの作成

sam initを使用して、Goのプロジェクトを作成していきます。

今回は「cancer」という名前のプロジェクト名にします。

プロジェクト作成
$ sam init --runtime go1.x --name cancer 
$ ls 
cancer  README.md 
デフォルトの状態からビルドして実行確認をしていきます。
Makefilebuildコマンドがデフォルトで用意されているため、そのまま利用していきます。

ビルド実行
$ cd cancer/ 
$ ls 
hello-world  Makefile  README.md  template.yaml 
$ make build 
GOOS=linux GOARCH=amd64 go build -o hello-world/hello-world ./hello-world 
※cannot find packageエラーが発生したら、go getでインストールをしていきましょう。

パッケージインストール
$ go get "github.com/aws/aws-lambda-go/events" 


動作確認

ビルドが完了したら、APIをローカルで実行してみます。

APIのローカル起動
$ sam local start-api 
動作確認してみましょう。

ターミナル画面から「+」ボタンを押し、「New Terminal」を選択してcurlコマンドを実行します。

動作確認
$ curl http://127.0.0.1:3000/hello 
Hello, 54.237.36.52 
ここまでで、通常のGoプロジェクトテンプレートが完成しました。


Layer側のGoプロジェクトを作成

Layersのプロジェクトを作成するために、まずはディレクトリを作成しましょう。

Layerプロジェクトのディレクトリ作成
$ mkdir layers 
$ cd layers 
$ mkdir first-layer 
$ cd first-layer 
$ pwd 
/home/ec2-user/environment/cancer/layers/first-layer 
次に、第一レイヤであるfirst.goを作成していきます。

first.goの作成
$ vi first.go 
first.go
package main 
 
import ( 
  "fmt") 
 
func main() { 
  fmt.Println("Hello, First Layer!") 
} 
layerの実行確認
$ go run first.go 
Hello, First Layer! 
Lambdaにソースコードをアップロードするため、ビルドモジュールをzipに固めます。

zipの作成
$ GOOS=linux GOARCH=amd64 go build -o first 
$ zip first.zip ./first 
$ ls 
first  first.go  first.zip 
その後、S3にzipファイルをアップロードします。今回は「sam-template-store」というバケットを既に作成しているので、こちらにアップロードしていきます。バケットを作成していない場合はコンソールから作成しましょう。

S3にzipファイルをアップロード
$ aws s3 cp ./first.zip s3://sam-template-store/ --acl public-read                           


YAMLでレイヤのデプロイ

template.yamlを使用して、レイヤを作成していきます。

既にアップロードされたS3のzipをContentUriに指定しましょう。

template.yaml
AWSTemplateFormatVersion: '2010-09-09' 
Transform: AWS::Serverless-2016-10-31 
Description: > 
  cancer 
 
  Sample SAM Template for cancer 
 
# More info about Globals: https://github.com/awslabs/serverless-application-model/blob/master/docs/globals.rst 
Globals: 
  Function: 
    Timeout: 5 
 
Resources: 
  FirstLayersFunction: 
    Type: AWS::Serverless::LayerVersion 
    Properties: 
      LayerName: FirstLayer 
      Description: First Layer 
      ContentUri: 's3://sam-template-store/first.zip' 
      CompatibleRuntimes:  
        - go1.x 
 
Outputs: 
  LayerVersionArn: 
    Value: !Ref FirstLayersFunction 
CloudFormationのコマンドでデプロイします。

レイヤのデプロイ
$ pwd 
/home/ec2-user/environment/cancer 
$ aws cloudformation deploy --stack-name first-layer --template-file template.yaml 
Successfullyがターミナルに表示されたら、レイヤのArnを取得するため、以下コマンドを実行します。

レイヤのArn取得
$ aws cloudformation describe-stacks --stack-name first-layer 
... 
        "Description": "cancer\nSample SAM Template for cancer\n",  
            "Tags": [],  
            "Outputs": [ 
                { 
                    "OutputKey": "LayerVersionArn",  
                    "OutputValue": "arn:aws:lambda:us-east-1:xxxxxxxxxxxx:layer:FirstLayer:3" 
                } 
            ] 
... 
OutputValueで表示されたArnを下記で使用していきます。


レイヤをLambdaFunctionに追加

ここで、HelloWorldFunctionを作成し、Layersとして先ほど作成したLambdaを指定します。
template.yamlに以下を追記していきましょう。

template.yaml
AWSTemplateFormatVersion: '2010-09-09' 
Transform: AWS::Serverless-2016-10-31 
Description: > 
  cancer 
 
  Sample SAM Template for cancer 
 
Globals: 
  Function: 
    Timeout: 5 
 
Resources: 
  HelloWorldFunction: 
    Type: AWS::Serverless::Function 
    Properties: 
      CodeUri: hello-world/ 
      Handler: hello-world 
      Runtime: go1.x 
      Tracing: Active 
      Events: 
        CatchAll: 
          Type: Api 
          Properties: 
            Path: /hello 
            Method: GET 
      Layers: 
        - "arn:aws:lambda:us-east-1:xxxxxxxxxxxx:layer:FirstLayer:3" 
  FirstLayersFunction: 
    Type: AWS::Serverless::LayerVersion 
    Properties: 
      LayerName: FirstLayer 
      Description: First Layer 
      ContentUri: 's3://sam-template-store/first.zip' 
      CompatibleRuntimes:  
        - go1.x 
 
Outputs: 
  LayerVersionArn: 
    Value: !Ref FirstLayersFunction 
samコマンドでパッケージングとデプロイを行います。

Makefileに記載すると打ち込むコマンドが少なくなるので便利です。

Makefile
.PHONY: deps clean build 
 
deps: 
    go get -u ./... 
 
clean:  
    rm -rf ./hello-world/hello-world 
 
build: 
    GOOS=linux GOARCH=amd64 go build -o hello-world/hello-world ./hello-world 
 
# 追記     
package: 
    sam package --template-file template.yaml --output-template-file output-template.yaml --s3-bucket sam-template-store  
 
# 追記 
deploy: 
    sam deploy --template-file output-template.yaml --stack-name sam-template-store --capabilities CAPABILITY_IAM 
Makefileでデプロイまで実行してみましょう。

pakageの作成
$ make package 
sam package --template-file template.yaml --output-template-file output-template.yaml --s3-bucket sam-template-store  
Functionのデプロイ
$ make deploy 
sam deploy --template-file output-template.yaml --stack-name sam-template-store --capabilities CAPABILITY_IAM 
最後に、Lambdaのコンソールから状況を確認してみます。
HelloWorldFunctionにLayersとして、先ほど作成したFirstLayerが参照されてことが確認できました。



FireShot Capture 116 - Lambda Management Console_ - https___console.aws.amazon.com_lam.png


コメント

このブログの人気の投稿

投稿時間:2021-06-20 02:06:12 RSSフィード2021-06-20 02:00 分まとめ(3871件)

投稿時間:2021-04-30 23:37:32 RSSフィード2021-04-30 23:00 分まとめ(42件)

投稿時間:2023-02-05 02:09:04 RSSフィード2023-02-05 02:00 分まとめ(9件)