【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)

関連記事

  1. AWS

    【AWS】AWS SAMを使いCLIでDynamoDBやLambda関…

  2. AWS

    【AWS】Lambdaを使ってみる

  3. AWS

    【AWS】DynamoDBのバックアップ、復元、別リージョンへのコピー…

  4. AWS

    【AWS】Amazon DynamoDBを使ってみる(CLI、API)…

  5. AWS

    【AWS】AWS LambdaとAmazon DynamoDBを使って…

  6. AWS

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

最近の記事

  1. PHP
  2. PHP
  3. TypeScript
  4. Docker
  5. AWS
  6. Docker

制作実績一覧

  1. Checkeys