AWS SAM CLI Hello world (cloudshell利用)

AWS
この記事は約29分で読めます。
記事内に広告が含まれています。

sam cliにHello worldした時の備忘録です。

sam(serverless Application Model)はcloudformationの一部でサーバレスに特化して、cloudformationより簡単に記述しやすくなっています。今回はcloud shellでsam cliを操作してHello worldをAWSにデプロイしたため、簡単にご紹介します。

※cloud shellではコンテナを動かせない為、デプロイ前のローカルテストは出来ません!一般的にはcloud9を利用したほうが幸せです。

では早速!

cloud shellでsam cliの基本操作

cloudshellでもsam cliは動かすことが出来ます。

$sam --version
SAM CLI, version 1.52.0

※cloudshellはdockerが使えないため、dockerを利用する「sam local start-api」等が実施できない制約はありますが、sam cliの雰囲気はつかめます。

sam init

cloudshellにログイン後、samテンプレートを構築します。

  • hello worldテンプレートを利用
    ※api-gateway, lamdaが構築する内容です。
  • python3.7を指定
    ※現時点(2022年8月)のcloudshellのpython3は3.7である。
$ sam init

You can preselect a particular runtime or package type when using the `sam init` experience.
Call `sam init --help` to learn more.

Which template source would you like to use?
        1 - AWS Quick Start Templates
        2 - Custom Template Location
Choice: 1

Choose an AWS Quick Start application template
        1 - Hello World Example
        2 - Multi-step workflow
        3 - Serverless API
        4 - Scheduled task
        5 - Standalone function
        6 - Data processing
        7 - Infrastructure event management
        8 - Machine Learning
Template: 1

Use the most popular runtime and package type? (Python and zip) [y/N]: n

Which runtime would you like to use?
        1 - dotnet6
        2 - dotnet5.0
        3 - dotnetcore3.1
        4 - go1.x
        5 - graalvm.java11 (provided.al2)
        6 - graalvm.java17 (provided.al2)
        7 - java11
        8 - java8.al2
        9 - java8
        10 - nodejs16.x
        11 - nodejs14.x
        12 - nodejs12.x
        13 - python3.9
        14 - python3.8
        15 - python3.7
        16 - python3.6
        17 - ruby2.7
        18 - rust (provided.al2)
Runtime: 15

What package type would you like to use?
        1 - Zip
        2 - Image
Package type: 1

Based on your selections, the only dependency manager available is pip.
We will proceed copying the template using pip.

Would you like to enable X-Ray tracing on the function(s) in your application?  [y/N]: n

Project name [sam-app]: 

Cloning from https://github.com/aws/aws-sam-cli-app-templates (process may take a moment)

    -----------------------
    Generating application:
    -----------------------
    Name: sam-app
    Runtime: python3.7
    Architectures: x86_64
    Dependency Manager: pip
    Application Template: hello-world
    Output Directory: .
    
    Next steps can be found in the README file at ./sam-app/README.md
        

    Commands you can use next
    =========================
    [*] Create pipeline: cd sam-app && sam pipeline init --bootstrap
    [*] Validate SAM template: sam validate
    [*] Test Function in the Cloud: sam sync --stack-name {stack-name} --watch

無事に構築出来たようです。

sam-appフォルダに移動し、以下の中身を確認してみます。

  • samテンプレート(template.yaml)
  • lambda関数(app.py)
$cd sam-app/
$cat template.yaml
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: >
  sam-app

  Sample SAM Template for sam-app

# More info about Globals: https://github.com/awslabs/serverless-application-model/blob/master/docs/globals.rst
Globals:
  Function:
    Timeout: 3

Resources:
  HelloWorldFunction:
    Type: AWS::Serverless::Function # More info about Function Resource: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#awsserverlessfunction
    Properties:
      CodeUri: hello_world/
      Handler: app.lambda_handler
      Runtime: python3.7
      Events:
        HelloWorld:
          Type: Api # More info about API Event Source: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#api
          Properties:
            Path: /hello
            Method: get

Outputs:
  # ServerlessRestApi is an implicit API created out of Events key under Serverless::Function
  # Find out more about other implicit resources you can reference within SAM
  # https://github.com/awslabs/serverless-application-model/blob/master/docs/internals/generated_resources.rst#api
  HelloWorldApi:
    Description: "API Gateway endpoint URL for Prod stage for Hello World function"
    Value: !Sub "https://${ServerlessRestApi}.execute-api.${AWS::Region}.amazonaws.com/Prod/hello/"
  HelloWorldFunction:
    Description: "Hello World Lambda Function ARN"
    Value: !GetAtt HelloWorldFunction.Arn
  HelloWorldFunctionIamRole:
    Description: "Implicit IAM Role created for Hello World function"
    Value: !GetAtt HelloWorldFunctionRole.Arn
$cat hello_world/app.py 
import json

# import requests


def lambda_handler(event, context):
    """Sample pure Lambda function

    Parameters
    ----------
    event: dict, required
        API Gateway Lambda Proxy Input Format

        Event doc: https://docs.aws.amazon.com/apigateway/latest/developerguide/set-up-lambda-proxy-integrations.html#api-gateway-simple-proxy-for-lambda-input-format

    context: object, required
        Lambda Context runtime methods and attributes

        Context doc: https://docs.aws.amazon.com/lambda/latest/dg/python-context-object.html

    Returns
    ------
    API Gateway Lambda Proxy Output Format: dict

        Return doc: https://docs.aws.amazon.com/apigateway/latest/developerguide/set-up-lambda-proxy-integrations.html
    """

    # try:
    #     ip = requests.get("http://checkip.amazonaws.com/")
    # except requests.RequestException as e:
    #     # Send some context about this error to Lambda Logs
    #     print(e)

    #     raise e

    return {
        "statusCode": 200,
        "body": json.dumps({
            "message": "hello world",
            # "location": ip.text.replace("\n", "")
        }),
    }

api-gatewayのurlにアクセスするとlambda関数がコールされ、「hello world」を返してくれるコードとなっています

・・・ざっくりと理解したつもり。

sam build

続いてtemplate.yamlが存在するフォルダ「sam-app」でビルド(デプロイ前の依存関係解決など準備)を行います。

$sam build
Your template contains a resource with logical ID "ServerlessRestApi", which is a reserved logical ID in AWS SAM. It could result in unexpected behaviors and is not recommended.
Building codeuri: /home/cloudshell-user/sam-app/hello_world runtime: python3.7 metadata: {} architecture: x86_64 functions: ['HelloWorldFunction']
Running PythonPipBuilder:ResolveDependencies
Running PythonPipBuilder:CopySource

Build Succeeded

Built Artifacts  : .aws-sam/build
Built Template   : .aws-sam/build/template.yaml

Commands you can use next
=========================
[*] Validate SAM template: sam validate
[*] Invoke Function: sam local invoke
[*] Test Function in the Cloud: sam sync --stack-name {stack-name} --watch
[*] Deploy: sam deploy --guided

無事に成功しました。

もしここでpythonのバージョン不一致など問題があると、ビルドが失敗します。

sam deploy

実際に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]: y
        #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]: y
        #Preserves the state of previously provisioned resources when an operation fails
        Disable rollback [y/N]: n
        HelloWorldFunction may not have authorization defined, Is this okay? [y/N]: y
        Save arguments to configuration file [Y/n]: y
        SAM configuration file [samconfig.toml]: 
        SAM configuration environment [default]: 

        Looking for resources needed for deployment:
         Managed S3 bucket: aws-sam-cli-managed-default-samclisourcebucket-xxxxxxxxx
         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/a749410668d0b70bdxxxxxxx  465116 / 465116  (100.00%)

        Deploying with following values
        ===============================
        Stack name                   : sam-app
        Region                       : ap-northeast-1
        Confirm changeset            : True
        Disable rollback             : False
        Deployment s3 bucket         : aws-sam-cli-managed-default-samclisourcebucket-xxxxxxxxxx
        Capabilities                 : ["CAPABILITY_IAM"]
        Parameter overrides          : {}
        Signing Profiles             : {}

Initiating deployment
=====================
Uploading to sam-app/03ec28a1387579cb1axxxxxxxxx.template  1144 / 1144  (100.00%)

Waiting for changeset to be created..
CloudFormation stack changeset
--------------------------------------------------------------------------------------------------------------------------
Operation      LogicalResourceId                                    ResourceType                         Replacement       
---------------------------------------------------------------------------------------------------------------------------
+ Add          HelloWorldFunctionHelloWorldPermissionProd           AWS::Lambda::Permission              N/A               
+ Add          HelloWorldFunctionRole                               AWS::IAM::Role                       N/A               
+ Add          HelloWorldFunction                                   AWS::Lambda::Function                N/A               
+ Add          ServerlessRestApiDeployment47xxxxxxxx                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:xxxxxxxxxxxx:changeSet/samcli-deploy16xxxx/ee71499b-xxxx-42d4-bfec-xxxxxxx


Previewing CloudFormation changeset before deployment
======================================================
Deploy this changeset? [y/N]: y

2022-08-23 02:23:55 - Waiting for stack create/update to complete

CloudFormation events from stack operations (refresh every 0.5 seconds)
---------------------------------------------------------------------------------------------------------------------------------
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::ApiGateway::Deployment       ServerlessRestApiDeployment47fcxxxxxxxxx       -                          
CREATE_IN_PROGRESS   AWS::Lambda::Permission           HelloWorldFunctionHelloWorldPermissionProd     -                          
CREATE_IN_PROGRESS   AWS::Lambda::Permission           HelloWorldFunctionHelloWorldPermissionProd     Resource creation Initiated
CREATE_IN_PROGRESS   AWS::ApiGateway::Deployment       ServerlessRestApiDeployment47fxxxxxxxx         Resource creation Initiated
CREATE_COMPLETE      AWS::ApiGateway::Deployment       ServerlessRestApiDeployment47fxxxxxxxxx        -                          
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           HelloWorldFunctionHelloWorldPermissionProd     -                          
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::xxxxxxxxxxxxx:role/sam-app-HelloWorldFunctionRole-UMXXXXXXXX     

Key                 HelloWorldApi                                                                 
Description         API Gateway endpoint URL for Prod stage for Hello World function              
Value               https://swxxxxxxx.execute-api.ap-northeast-1.amazonaws.com/Prod/hello/       

Key                 HelloWorldFunction                                                            
Description         Hello World Lambda Function ARN                                               
Value               arn:aws:lambda:ap-northeast-1:xxxxxxxxxxxxxxx:function:sam-app-HelloWorldFunction-jimSNxxxx                                               
------------------------------------------------------------------------------------------------------------------------

Successfully created/updated stack - sam-app in ap-northeast-1

※一部文字はxxxで伏せています。

無事にデプロイが完了したため、ブラウザでapi-gatewayのURLにアクセスすると、無事に以下が返ってきました。Hello-worldのURLは制限がかかっていないため注意しましょう。

\(^_^)/
{
message: "hello world"
}

内容を変更して再度デプロイする場合は、

  • sam build
  • sam deploy
    ※2回目以降は–guidedオプションは不要です。

を実行してあげればOKです。変更分だけアップロードされます。

sam delete

samプロジェクトフォルダ(sam-app)でsam deleteを実行すれば、

  • lambda関数
  • api-gateway
  • role
  • s3

などを全部綺麗に削除してくれます。

$sam delete
        Are you sure you want to delete the stack sam-app in the region ap-northeast-1 ? [y/N]: y
        Are you sure you want to delete the folder sam-app in S3 which contains the artifacts? [y/N]: y
        - Deleting S3 object with key sam-app/599d1e96fc75b648a6bfd472db8f9051
        - Deleting S3 object with key sam-app/03ec28a1387579cb1ab12fee97d73b28.template
        - Deleting S3 object with key sam-app/1d02fc33fa3aeb45f5a86f73e8e83b33.template
        - Deleting S3 object with key sam-app/a749410668d0b70bd0c12c169aec16b3
        - Deleting Cloudformation stack sam-app

Deleted successfully

まとめ

今回はaws資格のDAVに備えて色々と勉強する中で、sam cliにcloudshellで少しだけ触れました。

sam cliで記述することで、デプロイは確実に行え、簡単にサーバレスアプリケーションを構築することが出来ます。ただ、サーバレスアプリケーションの構成要素であるLambda、API Gateway、及びその連携をある程度理解しないと、sam cliのtemplate内容の理解はドキュメントを見ても難しいかなって思います。ある程度理解した後に、サーバレステンプレートの雛形として開発メンバに配ったりすると開発が加速出来そうです。

(メイン記事では触れていませんが)cloud9にはdockerが入っているため、ローカルテストも簡単に行うことが出来ます。ただし、dynamoDB等の他サービスとローカルで連携するにはdynamoDBのdockerを自前で準備したりするなど、まだ使いにくいと感じます。

コメント

Top
タイトルとURLをコピーしました