- 公開日
- 最終更新日
【SAM】デプロイ環境ごとに設定を分離する
この記事を共有する
はじめに
パーソル&サーバーワークスの嶋田です。
アプリケーションを開発していると、デプロイする環境ごとに設定パラメーターをハンドリングしたいことがありますよね。
何が最適かはプロジェクトによって異なりますが、今回は samconfig.toml の environment を使ったアプローチをご紹介します。
手順
公式チュートリアルの手順をベースに作業します ※本ブログの手順のみで作業に支障はありません
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
- build や deploy コマンドの実行時に、デフォルトとして用いられる値が記述されています。例えば sam sync コマンドを実行した場合は、 --watch オプションを付与してsyncコマンドを実行したのと同義となります。
SAMを使ったアプリケーションリリースまでのサイクルは、大きく分けて2ステップあります。 build と deploy です。補足ですが、不要になったスタックの削除は 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
以上です。お疲れさまでした。
この記事は私が書きました
嶋田 龍登
記事一覧インフラからアプリのことまでなんでもやりたい、フルスタックを目指すエンジニア