【AWS】AWS SAMを使いsamconfig.tomlでデプロイ先ごとに管理(Typescript)

AWS

1. 概要

前回は「AWS SAM CLI」を使いLambda関数とDynamoDBをつないで作成したAPIをデプロイする内容でした。今回は「AWS SAM CLI」を使いsamconfig.tomlでデプロイ先ごとに管理する内容となります。

  • 開発環境
    • dev
  • 検証環境
    • stg
  • 本番環境
    • prd

2. AWSアカウントにサインアップ

2-1. 前提条件

3. AWSアクセスキーの取得

3-1. AWSアクセスキーの取得

4. AWS CLI のインストール

4-1. インストール

5. AWS SAM CLIのインストール

5-1. インストール

6. アプリケーションを初期化

6-1. init

sam init
  • プロジェクト名
    • sam-env-sample
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 - Data processing
        3 - Hello World Example with Powertools for AWS Lambda
        4 - Multi-step workflow
        5 - Scheduled task
        6 - Standalone function
        7 - Serverless API
        8 - Infrastructure event management
        9 - Lambda Response Streaming
        10 - Serverless Connector Hello World Example
        11 - Multi-step workflow with Connectors
        12 - GraphQLApi Hello World Example
        13 - Full Stack
        14 - Lambda EFS example
        15 - DynamoDB Example
        16 - Machine Learning
Template: 1

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

Which runtime would you like to use?
        1 - aot.dotnet7 (provided.al2)
        2 - dotnet8
        3 - dotnet6
        4 - go (provided.al2)
        5 - go (provided.al2023)
        6 - graalvm.java11 (provided.al2)
        7 - graalvm.java17 (provided.al2)
        8 - java21
        9 - java17
        10 - java11
        11 - java8.al2
        12 - nodejs20.x
        13 - nodejs18.x
        14 - nodejs16.x
        15 - python3.9
        16 - python3.8
        17 - python3.12
        18 - python3.11
        19 - python3.10
        20 - ruby3.3
        21 - ruby3.2
        22 - rust (provided.al2)
        23 - rust (provided.al2023)
Runtime: 12

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 npm.
We will proceed copying the template using npm.

Select your starter template
        1 - Hello World Example
        2 - Hello World Example TypeScript
Template: 2

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

Would you like to enable monitoring using CloudWatch Application Insights?
For more info, please view https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/cloudwatch-application-insights.html [y/N]:

Would you like to set Structured Logging in JSON format on your Lambda functions?  [y/N]:

Project name [sam-app]: sam-env-sample

    -----------------------
    Generating application:
    -----------------------
    Name: sam-env-sample
    Runtime: nodejs20.x
    Architectures: x86_64
    Dependency Manager: npm
    Application Template: hello-world-typescript
    Output Directory: .
    Configuration file: sam-env-sample/samconfig.toml

    Next steps can be found in the README file at sam-env-sample/README.md


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

6-2. ディレクトリ構造

cd sam-env-sample
.
├── README.md
├── events
│   └── event.json
├── hello-world
│   ├── app.ts
│   ├── jest.config.ts
│   ├── package.json
│   ├── tests
│   │   └── unit
│   │       └── test-handler.test.ts
│   └── tsconfig.json
├── samconfig.toml
└── template.yaml

4 directories, 9 files

6-3. ライブラリのインストール

cd hello-world
npm install
cd ..

6-4. ソースコードを修正

code .

6-4-1. samconfig.toml

# More information about the configuration file can be found here:
# https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-sam-cli-config.html
version = 0.1

[default]
[default.global.parameters]
stack_name = "sam-env-sample"

[default.build.parameters]
cached = true
parallel = true

[default.validate.parameters]
lint = true

[default.deploy.parameters]
capabilities = "CAPABILITY_IAM"
confirm_changeset = true
resolve_s3 = true

[default.package.parameters]
resolve_s3 = true

[default.sync.parameters]
watch = true

[default.local_start_api.parameters]
warm_containers = "EAGER"

[default.local_start_lambda.parameters]
warm_containers = "EAGER"

[dev.deploy.parameters]
stack_name = "sam-env-sample-dev"
s3_prefix = "sam-env-sample-dev"
region = "ap-northeast-1"
capabilities = "CAPABILITY_IAM"
confirm_changeset = true
resolve_s3 = true
disable_rollback = false
parameter_overrides = [
    "StageName=dev",
    "YourName=Development",
    "MyName=Sondon",
]

[stg.deploy.parameters]
stack_name = "sam-env-sample-stg"
s3_prefix = "sam-env-sample-stg"
region = "ap-northeast-1"
capabilities = "CAPABILITY_IAM"
confirm_changeset = true
resolve_s3 = true
disable_rollback = false
parameter_overrides = [
    "StageName=stg",
    "YourName=Staging",
    "MyName=Sondon",
]

[prd.deploy.parameters]
stack_name = "sam-env-sample-prd"
s3_prefix = "sam-env-sample-prd"
region = "ap-northeast-1"
capabilities = "CAPABILITY_IAM"
confirm_changeset = true
resolve_s3 = true
disable_rollback = false
parameter_overrides = [
    "StageName=prd",
    "YourName=Production",
    "MyName=Sondon",
]
  • 下記3つのブロックを追加
    • dev.deploy.parameters
    • stg.deploy.parameters
    • prd.deploy.parameters

6-4-2. template.yaml

AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: >
  sam-env-sample

  Sample SAM Template for sam-env-sample
  
# More info about Globals: https://github.com/awslabs/serverless-application-model/blob/master/docs/globals.rst
Globals:
  Function:
    Timeout: 3

Parameters:
  MyName:
    Type: String
  StageName:
    Type: String
  YourName:
    Type: String

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.lambdaHandler
      Runtime: nodejs20.x
      Architectures:
        - x86_64
      FunctionName: !Sub "sam-env-sample-${StageName}"
      Environment:
        Variables:
          MY_NAME: !Ref MyName
          STAGE_NAME: !Ref StageName
          YOUR_NAME: !Ref YourName
      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
    Metadata: # Manage esbuild properties
      BuildMethod: esbuild
      BuildProperties:
        Minify: true
        Target: "es2020"
        Sourcemap: true
        EntryPoints: 
        - app.ts

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
  • 下記を追記
    • Parameters
    • FunctionName
    • Environment

6-4-3. hello-world/app.ts

import { APIGatewayProxyEvent, APIGatewayProxyResult } from 'aws-lambda';

/**
 *
 * Event doc: https://docs.aws.amazon.com/apigateway/latest/developerguide/set-up-lambda-proxy-integrations.html#api-gateway-simple-proxy-for-lambda-input-format
 * @param {Object} event - API Gateway Lambda Proxy Input Format
 *
 * Return doc: https://docs.aws.amazon.com/apigateway/latest/developerguide/set-up-lambda-proxy-integrations.html
 * @returns {Object} object - API Gateway Lambda Proxy Output Format
 *
 */

const myName: string | undefined = process.env.MY_NAME;
const stageName: string | undefined = process.env.STAGE_NAME;
const yourName: string | undefined = process.env.YOUR_NAME;

export const lambdaHandler = async (event: APIGatewayProxyEvent): Promise<APIGatewayProxyResult> => {
    try {
        return {
            statusCode: 200,
            body: JSON.stringify({
                message: `hello world : myName=${myName}, stageName=${stageName}, yourName=${yourName}`,
            }),
        };
    } catch (err) {
        console.log(err);
        return {
            statusCode: 500,
            body: JSON.stringify({
                message: 'some error happened',
            }),
        };
    }
};
  • 「process.env」を追加

7. アプリケーションを構築

7-1. build

sam build
Starting Build use cache                                                                                                                   
Manifest file is changed (new hash: 3a55b648027d1145164f225fad481127) or dependency folder                                                 
(.aws-sam/deps/0e8e5caf-23a2-4744-9bef-123456789012) is missing for (HelloWorldFunction), downloading dependencies and copying/building    
source                                                                                                                                     
Building codeuri: /home/sondon/dev/aws/apps/sam-env-sample/hello-world runtime: nodejs20.x metadata: {'BuildMethod': 'esbuild',            
'BuildProperties': {'Minify': True, 'Target': 'es2020', 'Sourcemap': True, 'EntryPoints': ['app.ts']}} architecture: x86_64 functions:     
HelloWorldFunction                                                                                                                         
 Running NodejsNpmEsbuildBuilder:CopySource                                                                                                
 Running NodejsNpmEsbuildBuilder:NpmInstall                                                                                                
 Running NodejsNpmEsbuildBuilder:EsbuildBundle                                                                                             
 Running NodejsNpmEsbuildBuilder:CleanUp                                                                                                   
 Running NodejsNpmEsbuildBuilder:MoveDependencies                                                                                          
                                                                                                                                           
Sourcemap set without --enable-source-maps, adding --enable-source-maps to function HelloWorldFunction NODE_OPTIONS                        
                                                                                                                                           
You are using source maps, note that this comes with a performance hit! Set Sourcemap to false and remove NODE_OPTIONS:                    
--enable-source-maps to disable source maps.                                                                                               
                                                                                                                                           

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

7-2. ディレクトリ構造

tree .aws-sam -I "deps|cache" -L 3
.aws-sam
├── build
│   ├── HelloWorldFunction
│   │   ├── app.js
│   │   └── app.js.map
│   └── template.yaml
└── build.toml

2 directories, 4 files

8. アプリケーションをAWS クラウドにデプロイ

8-1. デプロイ先ごとにdeploy

※必要なポリシーを追加

★「dev」をデプロイ

sam deploy --config-env dev
                Managed S3 bucket: aws-sam-cli-managed-default-samclisourcebucket-123456789012
                A different default S3 bucket can be set in samconfig.toml
                Or by specifying --s3-bucket explicitly.
        Uploading to sam-env-sample-dev/12345678901234567890123456789012  1500 / 1500  (100.00%)

        Deploying with following values
        ===============================
        Stack name                   : sam-env-sample-dev
        Region                       : ap-northeast-1
        Confirm changeset            : True
        Disable rollback             : False
        Deployment s3 bucket         : aws-sam-cli-managed-default-samclisourcebucket-123456789012
        Capabilities                 : ["CAPABILITY_IAM"]
        Parameter overrides          : {"StageName": "dev", "YourName": "Development", "MyName": "Sondon"}
        Signing Profiles             : {}

Initiating deployment
=====================

        Uploading to sam-env-sample-dev/12345678901234567890123456789012.template  1748 / 1748  (100.00%)


Waiting for changeset to be created..

CloudFormation stack changeset
-------------------------------------------------------------------------------------------------------------------------------------
Operation                         LogicalResourceId                 ResourceType                      Replacement                     
-------------------------------------------------------------------------------------------------------------------------------------
+ Add                             HelloWorldFunctionHelloWorldPer   AWS::Lambda::Permission           N/A                             
                                  missionProd                                                                                         
+ Add                             HelloWorldFunctionRole            AWS::IAM::Role                    N/A                             
+ Add                             HelloWorldFunction                AWS::Lambda::Function             N/A                             
+ Add                             ServerlessRestApiDeploymentac65   AWS::ApiGateway::Deployment       N/A                             
                                  9f343a                                                                                              
+ Add                             ServerlessRestApiProdStage        AWS::ApiGateway::Stage            N/A                             
+ Add                             ServerlessRestApi                 AWS::ApiGateway::RestApi          N/A                             
-------------------------------------------------------------------------------------------------------------------------------------


Changeset created successfully. arn:aws:cloudformation:ap-northeast-1:123456789012:changeSet/samcli-deploy1717311064/94527002-5635-4af8-91f9-123456789012


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

2024-06-02 15:51:18 - Waiting for stack create/update to complete

CloudFormation events from stack operations (refresh every 5.0 seconds)
-------------------------------------------------------------------------------------------------------------------------------------
ResourceStatus                    ResourceType                      LogicalResourceId                 ResourceStatusReason            
-------------------------------------------------------------------------------------------------------------------------------------
CREATE_IN_PROGRESS                AWS::CloudFormation::Stack        sam-env-sample-dev                User Initiated                  
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       ServerlessRestApiDeploymentac65   -                               
                                                                    9f343a                                                            
CREATE_IN_PROGRESS                AWS::Lambda::Permission           HelloWorldFunctionHelloWorldPer   -                               
                                                                    missionProd                                                       
CREATE_IN_PROGRESS                AWS::Lambda::Permission           HelloWorldFunctionHelloWorldPer   Resource creation Initiated     
                                                                    missionProd                                                       
CREATE_IN_PROGRESS                AWS::ApiGateway::Deployment       ServerlessRestApiDeploymentac65   Resource creation Initiated     
                                                                    9f343a                                                            
CREATE_COMPLETE                   AWS::Lambda::Permission           HelloWorldFunctionHelloWorldPer   -                               
                                                                    missionProd                                                       
CREATE_COMPLETE                   AWS::ApiGateway::Deployment       ServerlessRestApiDeploymentac65   -                               
                                                                    9f343a                                                            
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::CloudFormation::Stack        sam-env-sample-dev                -                               
-------------------------------------------------------------------------------------------------------------------------------------

CloudFormation outputs from deployed stack
----------------------------------------------------------------------------------------------------------------------------------------
Outputs                                                                                                                                
----------------------------------------------------------------------------------------------------------------------------------------
Key                 HelloWorldFunctionIamRole                                                                                          
Description         Implicit IAM Role created for Hello World function                                                                 
Value               arn:aws:iam::123456789012:role/sam-env-sample-dev-HelloWorldFunctionRole-123456789012                              

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

Key                 HelloWorldFunction                                                                                                 
Description         Hello World Lambda Function ARN                                                                                    
Value               arn:aws:lambda:ap-northeast-1:123456789012:function:sam-env-sample-dev                                             
----------------------------------------------------------------------------------------------------------------------------------------


Successfully created/updated stack - sam-env-sample-dev in ap-northeast-1

★「stg」や「prd」もデプロイ

sam deploy --config-env stg
sam deploy --config-env prd

9. アプリケーションを実行

9-1. APIエンドポイントの値を取得

  • 上記8-1ログより「Outputs」を探す
    • Key
      • HelloWorldApi
    • Value
      • https://1234567890.execute-api.ap-northeast-1.amazonaws.com/Prod/hello/
      • これが対象のAPIエンドポイント

9-2. APIの呼び出し(dev)

curl https://1234567890.execute-api.ap-northeast-1.amazonaws.com/Prod/hello/

{“message”:”hello world : myName=Sondon, stageName=dev, yourName=Development”}

9-3. APIの呼び出し(stg)

curl https://4567890123.execute-api.ap-northeast-1.amazonaws.com/Prod/hello/

{“message”:”hello world : myName=Sondon, stageName=stg, yourName=Staging”}

9-4. APIの呼び出し(prd)

curl https://7890123456.execute-api.ap-northeast-1.amazonaws.com/Prod/hello/

{“message”:”hello world : myName=Sondon, stageName=prd, yourName=Production”}

10. Management Consoleで確認

10-1. 画面で確認

11. AWSクラウドからアプリケーションを削除

※必要に応じ削除

sam delete --stack-name sam-env-sample-dev
sam delete --stack-name sam-env-sample-stg
sam delete --stack-name sam-env-sample-prd

12. 備考

「AWS SAM CLI」を使いsamconfig.tomlでデプロイ先ごとに管理する内容でした。

13. 参考

  1. AWS Serverless Application Model (AWS SAM) とは何ですか? – AWS Serverless Application Model (amazon.com)
  2. Lambda 環境変数の使用 – AWS Lambda (amazon.com)

投稿者プロフィール

Sondon
開発好きなシステムエンジニアです。
卓球にハマってます。

関連記事

  1. AWS

    【AWS】API Gateway + Lambda + SESで汎用メ…

  2. AWS

    【AWS】Deploy Serverless NextJS app w…

  3. 【新米エンジニア学習記録③】Next.jsのデプロイ

  4. AWS

    【API Gateway】Lambda Web AdapterからWe…

  5. AWS

    【AWS】AWS Step Functionsを触ってみる

  6. AWS

    【AWS】Redash on EC2 が突然 502 Bad Gate…

最近の記事

  1. AWS
  2. AWS

制作実績一覧

  1. Checkeys