ENGINEER BLOG ENGINEER BLOG
  • 公開日
  • 最終更新日

【SAM】デプロイ環境ごとに設定を分離する

この記事を共有する

はじめに

パーソル&サーバーワークスの嶋田です。

アプリケーションを開発していると、デプロイする環境ごとに設定パラメーターをハンドリングしたいことがありますよね。
何が最適かはプロジェクトによって異なりますが、今回は samconfig.tomlenvironment を使ったアプローチをご紹介します。

手順

公式チュートリアルの手順をベースに作業します ※本ブログの手順のみで作業に支障はありません

sam cliのバージョン

$ sam --version
SAM CLI, version 1.133.0

samプロジェクトの作成

$ 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 - 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 - GraphQLApi Hello World Example
        11 - Full Stack
        12 - Lambda EFS example
        13 - Serverless Connector Hello World Example
        14 - Multi-step workflow with Connectors
        15 - DynamoDB Example
        16 - Machine Learning
Template: 1
Use the most popular runtime and package type? (python3.13 and zip) [y/N]: N
Which runtime would you like to use?
        1 - dotnet8
        2 - dotnet6
        3 - go (provided.al2)
        4 - go (provided.al2023)
        5 - graalvm.java11 (provided.al2)
        6 - graalvm.java17 (provided.al2)
        7 - java21
        8 - java17
        9 - java11
        10 - java8.al2
        11 - nodejs22.x
        12 - nodejs20.x
        13 - nodejs18.x
        14 - python3.9
        15 - python3.8
        16 - python3.13
        17 - python3.12
        18 - python3.11
        19 - python3.10
        20 - ruby3.3
        21 - ruby3.2
        22 - rust (provided.al2)
        23 - rust (provided.al2023)
Runtime: 11
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: 1
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-blog-sample-project
    -----------------------
    Generating application:
    -----------------------
    Name: sam-blog-sample-project
    Runtime: nodejs22.x
    Architectures: x86_64
    Dependency Manager: npm
    Application Template: hello-world
    Output Directory: .
    Configuration file: sam-blog-sample-project/samconfig.toml
    Next steps can be found in the README file at sam-blog-sample-project/README.md
Commands you can use next
=========================
[*] Create pipeline: cd sam-blog-sample-project && sam pipeline init --bootstrap
[*] Validate SAM template: cd sam-blog-sample-project && sam validate
[*] Test Function in the Cloud: cd sam-blog-sample-project && sam sync --stack-name {stack-name} --watch

ディレクトリの移動

$ cd sam-blog-sample-project/

ここまでで、SAMプロジェクトを作成して、プロジェクトのルートディレクトリに移動まで完了しました。
プロジェクトのルートディレクトリ直下にあるsamconfig.tomlファイルが、本ブログの主役です。
catを使って中身をみてみます。

samconfig.toml(samの設定ファイル)の確認

$ cat 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.global.parameters]
stack_name = "sam-blog-sample-project"
[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"

なにやらたくさんの項目がありますね、ですが怖がる必要はありません。
各設定値の説明は割愛しますが、これらの記述を読むにあたって抑えるポイントが3つあるので、順を追って見てみましょう。

[default.global.parameters]

  • default
    • 環境名のことです。samコマンドを実行した際に --config-env オプションで環境名を指定できます。何も指定しない場合は、default扱いとなります。今回の主役です。
  • global
    • どのSAMコマンドに紐づく設定なのか?です。catの結果をみると、build / deploy / validate などのコマンドに紐づく設定であることがうかがえます。global はコマンドではありませんが、samプロジェクトで実行するすべてのsamコマンドに波及する値として設定することを意味します。
  • parameters
    • builddeploy コマンドの実行時に、デフォルトとして用いられる値が記述されています。例えば sam sync コマンドを実行した場合は、 --watch オプションを付与してsyncコマンドを実行したのと同義となります。

SAMを使ったアプリケーションリリースまでのサイクルは、大きく分けて2ステップあります。 builddeploy です。補足ですが、不要になったスタックの削除は delete で行います。 設定ファイルの確認が終わったので、実際に build しましょう。

samプロジェクトのbuild

$ sam build
Starting Build use cache
Manifest is not changed for (HelloWorldFunction), running incremental build
Building codeuri: /home/ec2-user/Developments/sam-blog-sample-project/hello-world runtime: nodejs22.x
architecture: x86_64 functions: HelloWorldFunction
 Running NodejsNpmBuilder:NpmPack
 Running NodejsNpmBuilder:CopyNpmrcAndLockfile
 Running NodejsNpmBuilder:CopySource
 Running NodejsNpmBuilder:CopySource
 Running NodejsNpmBuilder:CleanUpNpmrc
 Running NodejsNpmBuilder:LockfileCleanUp
 Running NodejsNpmBuilder:LockfileCleanUp
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

build が無事完了したので、deployします。

samで構築したアプリケーションをデプロイする

$ sam deploy --no-confirm-changeset
                Managed S3 bucket: aws-sam-cli-managed-default-samclisourcebucket-0jsdlxcilt06
                A different default S3 bucket can be set in samconfig.toml
                Or by specifying --s3-bucket explicitly.
        Uploading to 7ce1f134cb26788817fd18fb91dfdd72  798845 / 798845  (100.00%)
        Deploying with following values
        ===============================
        Stack name                   : sam-blog-sample-project
        Region                       : ap-northeast-1
        Confirm changeset            : False
        Disable rollback             : False
        Deployment s3 bucket         : aws-sam-cli-managed-default-samclisourcebucket-0jsdlxcilt06
        Capabilities                 : ["CAPABILITY_IAM"]
        Parameter overrides          : {}
        Signing Profiles             : {}
Initiating deployment
=====================
        Uploading to a930aac911c0634c31c46de71a6db82d.template  1203 / 1203  (100.00%)
Waiting for changeset to be created..
CloudFormation stack changeset
-----------------------------------------------------------------------------------------------------
Operation                 LogicalResourceId         ResourceType              Replacement
-----------------------------------------------------------------------------------------------------
+ Add                     HelloWorldFunctionHello   AWS::Lambda::Permission   N/A
                          WorldPermissionProd
+ Add                     HelloWorldFunctionRole    AWS::IAM::Role            N/A
+ Add                     HelloWorldFunction        AWS::Lambda::Function     N/A
+ Add                     ServerlessRestApiDeploy   AWS::ApiGateway::Deploy   N/A
                          ment47fc2d5f9d            ment
+ Add                     ServerlessRestApiProdSt   AWS::ApiGateway::Stage    N/A
                          age
+ Add                     ServerlessRestApi         AWS::ApiGateway::RestAp   N/A
                                                    i
-----------------------------------------------------------------------------------------------------
Changeset created successfully. arn:aws:cloudformation:ap-northeast-1:012345678910:changeSet/samcli-deploy1739702703/48c6fee7-e958-4928-bf14-fb5b8ac94740
2025-02-16 10:45:09 - 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::St   sam-blog-sample-project   User Initiated
                          ack
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_IN_PROGRESS -      AWS::Lambda::Function     HelloWorldFunction        Eventual consistency
CONFIGURATION_COMPLETE                                                        check initiated
CREATE_IN_PROGRESS        AWS::ApiGateway::RestAp   ServerlessRestApi         -
                          i
CREATE_IN_PROGRESS        AWS::ApiGateway::RestAp   ServerlessRestApi         Resource creation
                          i                                                   Initiated
CREATE_COMPLETE           AWS::ApiGateway::RestAp   ServerlessRestApi         -
                          i
CREATE_IN_PROGRESS        AWS::ApiGateway::Deploy   ServerlessRestApiDeploy   -
                          ment                      ment47fc2d5f9d
CREATE_IN_PROGRESS        AWS::Lambda::Permission   HelloWorldFunctionHello   -
                                                    WorldPermissionProd
CREATE_IN_PROGRESS        AWS::Lambda::Permission   HelloWorldFunctionHello   Resource creation
                                                    WorldPermissionProd       Initiated
CREATE_IN_PROGRESS        AWS::ApiGateway::Deploy   ServerlessRestApiDeploy   Resource creation
                          ment                      ment47fc2d5f9d            Initiated
CREATE_COMPLETE           AWS::Lambda::Function     HelloWorldFunction        -
CREATE_COMPLETE           AWS::Lambda::Permission   HelloWorldFunctionHello   -
                                                    WorldPermissionProd
CREATE_COMPLETE           AWS::ApiGateway::Deploy   ServerlessRestApiDeploy   -
                          ment                      ment47fc2d5f9d
CREATE_IN_PROGRESS        AWS::ApiGateway::Stage    ServerlessRestApiProdSt   -
                                                    age
CREATE_IN_PROGRESS        AWS::ApiGateway::Stage    ServerlessRestApiProdSt   Resource creation
                                                    age                       Initiated
CREATE_COMPLETE           AWS::ApiGateway::Stage    ServerlessRestApiProdSt   -
                                                    age
CREATE_COMPLETE           AWS::CloudFormation::St   sam-blog-sample-project   -
                          ack
-----------------------------------------------------------------------------------------------------
CloudFormation outputs from deployed stack
--------------------------------------------------------------------------------------------------------
Outputs
--------------------------------------------------------------------------------------------------------
Key                 HelloWorldFunctionIamRole
Description         Implicit IAM Role created for Hello World function
Value               arn:aws:iam::012345678910:role/sam-blog-sample-project-HelloWorldFunctionRole-VJIy2JRWm1ir
Key                 HelloWorldApi
Description         API Gateway endpoint URL for Prod stage for Hello World function
Value               https://od3cp5ase6.execute-api.ap-northeast-1.amazonaws.com/Prod/hello/
Key                 HelloWorldFunction
Description         Hello World Lambda Function ARN
Value               arn:aws:lambda:ap-northeast-1:012345678910:function:sam-blog-sample-project-HelloWorldFunction-vO7pks7sIehY
--------------------------------------------------------------------------------------------------------
Successfully created/updated stack - sam-blog-sample-project in ap-northeast-1

アプリケーションの動作を確認する

API Gatewayがデプロイされているので、curlでGETリクエストを送信してみます。

$ curl https://od3cp5ase6.execute-api.ap-northeast-1.amazonaws.com/Prod/hello/
{"message":"hello world"}

ここまでで、samconfig.tomlファイルに記載していた、default環境のdeployが完了しました。
続けて、開発環境向けのdeployも実施してみましょう。

samconfig.tomlファイルの編集

まず、 samconfig.toml ファイルを編集します。defaultで設定されている箇所を複製して、 dev に置換します。
これからデプロイするスタック名を、元のスタック名の末尾に dev とつけます。

$ cat 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.global.parameters]
stack_name = "sam-blog-sample-project"
[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.global.parameters]
stack_name = "sam-blog-sample-project-dev"
[dev.build.parameters]
cached = true
parallel = true
[dev.validate.parameters]
lint = true
[dev.deploy.parameters]
capabilities = "CAPABILITY_IAM"
confirm_changeset = true
resolve_s3 = true
[dev.package.parameters]
resolve_s3 = true
[dev.sync.parameters]
watch = true
[dev.local_start_api.parameters]
warm_containers = "EAGER"
[dev.local_start_lambda.parameters]
warm_containers = "EAGER"

編集で追加したdev環境のリソースをデプロイする

sam deploy --config-env dev でデプロイします。
samコマンドの実行時に--config-envオプションで環境名を指定することで、どの環境向けのデプロイなのかをハンドリングできます。

$ sam deploy --config-env dev
                Managed S3 bucket: aws-sam-cli-managed-default-samclisourcebucket-0jsdlxcilt06
                A different default S3 bucket can be set in samconfig.toml
                Or by specifying --s3-bucket explicitly.
File with same data already exists at 7ce1f134cb26788817fd18fb91dfdd72, skipping upload
        Deploying with following values
        ===============================
        Stack name                   : sam-blog-sample-project-dev
        Region                       : ap-northeast-1
        Confirm changeset            : True
        Disable rollback             : False
        Deployment s3 bucket         : aws-sam-cli-managed-default-samclisourcebucket-0jsdlxcilt06
        Capabilities                 : ["CAPABILITY_IAM"]
        Parameter overrides          : {}
        Signing Profiles             : {}
Initiating deployment
=====================
File with same data already exists at a930aac911c0634c31c46de71a6db82d.template, skipping upload
Waiting for changeset to be created..
CloudFormation stack changeset
---------------------------------------------------------------------------------------------------------------------------------------------------------
Operation                              LogicalResourceId                      ResourceType                           Replacement
---------------------------------------------------------------------------------------------------------------------------------------------------------
+ Add                                  HelloWorldFunctionHelloWorldPermissi   AWS::Lambda::Permission                N/A
                                       onProd
+ Add                                  HelloWorldFunctionRole                 AWS::IAM::Role                         N/A
+ Add                                  HelloWorldFunction                     AWS::Lambda::Function                  N/A
+ Add                                  ServerlessRestApiDeployment47fc2d5f9   AWS::ApiGateway::Deployment            N/A
                                       d
+ Add                                  ServerlessRestApiProdStage             AWS::ApiGateway::Stage                 N/A
+ Add                                  ServerlessRestApi                      AWS::ApiGateway::RestApi               N/A
---------------------------------------------------------------------------------------------------------------------------------------------------------
Changeset created successfully. arn:aws:cloudformation:ap-northeast-1:012345678910:changeSet/samcli-deploy1739703473/21ac0f0a-6d98-455b-8a61-56ae33c49a9c
Previewing CloudFormation changeset before deployment
======================================================
Deploy this changeset? [y/N]: y
2025-02-16 10:58:14 - 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-blog-sample-project-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_IN_PROGRESS -                   AWS::Lambda::Function                  HelloWorldFunction                     Eventual consistency check initiated
CONFIGURATION_COMPLETE
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            ServerlessRestApiDeployment47fc2d5f9   -
                                                                              d
CREATE_IN_PROGRESS                     AWS::Lambda::Permission                HelloWorldFunctionHelloWorldPermissi   -
                                                                              onProd
CREATE_IN_PROGRESS                     AWS::Lambda::Permission                HelloWorldFunctionHelloWorldPermissi   Resource creation Initiated
                                                                              onProd
CREATE_IN_PROGRESS                     AWS::ApiGateway::Deployment            ServerlessRestApiDeployment47fc2d5f9   Resource creation Initiated
                                                                              d
CREATE_COMPLETE                        AWS::Lambda::Permission                HelloWorldFunctionHelloWorldPermissi   -
                                                                              onProd
CREATE_COMPLETE                        AWS::Lambda::Function                  HelloWorldFunction                     -
CREATE_COMPLETE                        AWS::ApiGateway::Deployment            ServerlessRestApiDeployment47fc2d5f9   -
                                                                              d
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-blog-sample-project-dev            -
---------------------------------------------------------------------------------------------------------------------------------------------------------
CloudFormation outputs from deployed stack
---------------------------------------------------------------------------------------------------------------------------------------------------------
Outputs
---------------------------------------------------------------------------------------------------------------------------------------------------------
Key                 HelloWorldFunctionIamRole
Description         Implicit IAM Role created for Hello World function
Value               arn:aws:iam::012345678910:role/sam-blog-sample-project-dev-HelloWorldFunctionRole-hR4XqXKEIQYn
Key                 HelloWorldApi
Description         API Gateway endpoint URL for Prod stage for Hello World function
Value               https://h51a5l4lel.execute-api.ap-northeast-1.amazonaws.com/Prod/hello/
Key                 HelloWorldFunction
Description         Hello World Lambda Function ARN
Value               arn:aws:lambda:ap-northeast-1:012345678910:function:sam-blog-sample-project-dev-HelloWorldFunction-HnfplOCfU5lo
---------------------------------------------------------------------------------------------------------------------------------------------------------
Successfully created/updated stack - sam-blog-sample-project-dev in ap-northeast-1

これまでデプロイしたスタックリソースを確認する

実際にスタックの一覧を表示してみます。

$ aws cloudformation list-stacks --stack-status-filter CREATE_COMPLETE --query "StackSummaries[*].StackNam
e" --output table
-----------------------------------------------------------------------
|                             ListStacks                              |
+---------------------------------------------------------------------+
|  sam-blog-sample-project-dev                                        |
|  sam-blog-sample-project                                            |
+---------------------------------------------------------------------+

環境ごとのスタック分離に成功しました。
最後に、sam delete コマンドでリソースの後片付けをしましょう。

後片付け

$ sam delete --config-env dev
        Are you sure you want to delete the stack sam-blog-sample-project-dev in the region ap-northeast-1 ? [y/N]: y
        Do you want to delete the template file a930aac911c0634c31c46de71a6db82d.template in S3? [y/N]: y
        - Deleting S3 object with key 7ce1f134cb26788817fd18fb91dfdd72
        - Deleting S3 object with key a930aac911c0634c31c46de71a6db82d.template
        - Deleting Cloudformation stack sam-blog-sample-project-dev
Deleted successfully
$ sam delete
        Are you sure you want to delete the stack sam-blog-sample-project in the region ap-northeast-1 ? [y/N]: y
        Do you want to delete the template file a930aac911c0634c31c46de71a6db82d.template in S3? [y/N]: y
        - Could not find and delete the S3 object with the key 7ce1f134cb26788817fd18fb91dfdd72
        - Could not find and delete the S3 object with the key a930aac911c0634c31c46de71a6db82d.template
        - Deleting Cloudformation stack sam-blog-sample-project
Deleted successfully

Deleted successfullyと出ていますが、念のため確認します。

$ aws cloudformation list-stacks --stack-status-filter DELETE_COMPLETE --query "StackSummaries[*].StackName" --output table
-----------------------------------------------------------------------
|                             ListStacks                              |
+---------------------------------------------------------------------+
|  sam-blog-sample-project-dev                                        |
|  sam-blog-sample-project                                            |
+---------------------------------------------------------------------+

問題なく削除できていますね。忘れずにプロジェクトディレクトリも削除しましょう。

$ cd ../
$ rm -rf ./sam-blog-sample-project

以上です。お疲れさまでした。

この記事は私が書きました

嶋田 龍登

記事一覧

インフラからアプリのことまでなんでもやりたい、フルスタックを目指すエンジニア

嶋田 龍登

この記事を共有する

クラウドのご相談

CONTACT

クラウド導入や運用でお悩みの方は、お気軽にご相談ください。
専門家がサポートします。

サービス資料ダウンロード

DOWNLOAD

ビジネスをクラウドで加速させる準備はできていますか?
今すぐサービス資料をダウンロードして、詳細をご確認ください。