前回は、ローカルからリモート実行の記事を書きました。
今回は、よくあるAPI Gateway + AWS Lambdaの開発をVSCodeを使ってやる方法です。
AWS SAM を使いローカルからクラウドへdeploy、クラウド側での実行、ローカルでの実行を行ってみます。
sam build
, sam deploy
によるエラーに遭遇します、エラーが出ると理解が深まります。
VSCode + Remote Containerでの環境構築ができず、Windows PCのローカル環境使っています。
※エラーの回避方法ないか模索中(systemctlコマンドは通るが service docker start ができない)
ローカル環境に、sam cli や python は入れたくない、複数バージョン管理が手間だったり、他に依存したりで・・・。
環境準備
- Windows10, 64bitとして進める
前提
- Docker Desktop for Windows,VSCode がインストールされていること
- インストールしていない場合は https://docs.docker.com/docker-for-windows/install/
- AWS公式みると、古いWindows ではdocker toolbox 使う。(https://docs.docker.com/toolbox/)
- AWS公式で、'If you're using Windows 10 in Hyper-V mode, see' https://docs.docker.com/docker-for-windows/#file-sharing
- Windows10に入れたVSCodeに拡張機能 AWS Toolkit をインストール
Windows10に Python, SAM CLIのインストール
- Pythonをインストール
- Python3.8の3.8.11インストーラーが見つからない、https://www.python.org/downloads/windows/
- Python3.8.10 を使うことにする。ダウンロード(https://www.python.org/ftp/python/3.8.10/python-3.8.10-amd64.exe)
- AWS SAM CLI をインストール
- ※ 他への依存性があるのと、複数バージョンは混在できないと思う。
C:\Program Files\Amazon\AWSSAMCLI
にインストールされる。 - https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-sam-cli-install.html
- Windows向け ダウンロード(https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-sam-cli-install-windows.html)
- AWS_SAM_CLI_64_PY3.msi がインストーラー
- ※ 他への依存性があるのと、複数バージョンは混在できないと思う。
インストール後の確認
sam --version
- PATH パスが通らない時:OS再起動しないとPATHには設定されない。OS再起動しないで続行する場合は、自前でPATH設定して対応
PS > $ENV:Path
PS > $ENV:Path+=";C:\Program Files\Amazon\AWSSAMCLI\bin"
- 以下にコマンドプロンプトの場合を載せておくが、VSCode内のターミナルではpowershell(PS)がデフォルトになる
cmd $ echo %path%
cmd $ set PATH=%PATH%;"C:\Program Files\Amazon\AWSSAMCLI\bin"
AWS credentials
- ここ多くの人はスキップ(既にやってる)
-
C:\Users\アカウント\.aws
ディレクトリに、credentialsファイルは既にあるのでスキップ
ここから本編、Hello World のアプリケーションを作成
公式のサンプル
やっていく順序は以下のStepの順序
#Step 1 - Download a sample application
PS> sam init
#Step 2 - Build your application
PS> cd sam-app
PS> sam build
#Step 3 - Deploy your application
PS> sam deploy --guided
それぞれのStepでの例
sam init の実行例
C:\usr\iot\local-windows-sam>sam init
SAM CLI now collects telemetry to better understand customer needs.
You can OPT OUT and disable telemetry collection by setting the
environment variable SAM_CLI_TELEMETRY=0 in your shell.
Thanks for your help!
Learn More: https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-sam-telemetry.html
Which template source would you like to use?
1 - AWS Quick Start Templates
2 - Custom Template Location
Choice: 1
What package type would you like to use?
1 - Zip (artifact is a zip uploaded to S3)
2 - Image (artifact is an image uploaded to an ECR image repository)
Package type: 1
Which runtime would you like to use?
1 - nodejs14.x
2 - python3.8
3 - ruby2.7
4 - go1.x
5 - java11
6 - dotnetcore3.1
7 - nodejs12.x
8 - nodejs10.x
9 - python3.7
10 - python3.6
11 - python2.7
12 - ruby2.5
13 - java8.al2
14 - java8
15 - dotnetcore2.1
Runtime: 2
Project name [sam-app]: sam-app
Cloning from https://github.com/aws/aws-sam-cli-app-templates
AWS quick start application templates:
1 - Hello World Example
2 - EventBridge Hello World
3 - EventBridge App from scratch (100+ Event Schemas)
4 - Step Functions Sample App (Stock Trader)
5 - Elastic File System Sample App
Template selection: 1
-----------------------
Generating application:
-----------------------
Name: sam-app
Runtime: python3.8
Dependency Manager: pip
Application Template: hello-world
Output Directory: .
Next steps can be found in the README file at ./sam-app/README.md
sam build の実行例
PS > sam build
Building codeuri: C:\usr\iot\local-windows-sam\sam-app\hello_world runtime: python3.8 metadata: {} 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
=========================
[*] Invoke Function: sam local invoke
[*] Deploy: sam deploy --guided
sam deploy --guided の実行例
PS > sam deploy --guided --profile sam-cli-workshop-user-ssugimoto --region us-west-2
Configuring SAM deploy
======================
Looking for config file [samconfig.toml] : Found
Reading default arguments : Success
Setting default arguments for 'sam deploy'
=========================================
Stack Name [sam-app]:
AWS Region [us-west-2]:
#Shows you resources changes to be deployed and require a 'Y' to initiate deploy
Confirm changes before deploy [Y/n]:
#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]:
HelloWorldFunction may not have authorization defined, Is this okay? [y/N]: y
Save arguments to configuration file [Y/n]:
SAM configuration file [samconfig.toml]:
SAM configuration environment [default]:
Looking for resources needed for deployment: Found!
Managed S3 bucket: aws-sam-cli-managed-default-samclisourcebucket-1r2lcvc8co1oz
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/8e58a457d00a2ca022ac1dd4e0854ce9 443076 / 443076 (100.00%)
Deploying with following values
===============================
Stack name : sam-app
Region : us-west-2
Confirm changeset : True
Deployment s3 bucket : aws-sam-cli-managed-default-samclisourcebucket-1r2lcvc8co1oz
Capabilities : ["CAPABILITY_IAM"]
Parameter overrides : {}
Signing Profiles : {}
Initiating deployment
=====================
Uploading to sam-app/eb49a69d21ad708d76b312beecbaba31.template 1130 / 1130 (100.00%)
Waiting for changeset to be created..
CloudFormation stack changeset
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Operation LogicalResourceId ResourceType Replacement
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
* Modify HelloWorldFunction AWS::Lambda::Function False
* Modify ServerlessRestApi AWS::ApiGateway::RestApi False
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Changeset created successfully. arn:aws:cloudformation:us-west-2:479448073833:changeSet/samcli-deploy1628696755/25217138-8763-4c8d-b095-d250a2205bd4
Previewing CloudFormation changeset before deployment
======================================================
Deploy this changeset? [y/N]: y
2021-08-12 00:46:12 - Waiting for stack create/update to complete
CloudFormation events from changeset
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
ResourceStatus ResourceType LogicalResourceId ResourceStatusReason
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
UPDATE_IN_PROGRESS AWS::Lambda::Function HelloWorldFunction -
UPDATE_COMPLETE AWS::Lambda::Function HelloWorldFunction -
UPDATE_COMPLETE AWS::CloudFormation::Stack sam-app -
UPDATE_COMPLETE_CLEANUP_IN_PROGRESS 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::479448073833:role/sam-app-HelloWorldFunctionRole-2549BPE01P17
Key HelloWorldApi
Description API Gateway endpoint URL for Prod stage for Hello World function
Value https://h0ju25ugt2.execute-api.us-west-2.amazonaws.com/Prod/hello/
Key HelloWorldFunction
Description Hello World Lambda Function ARN
Value arn:aws:lambda:us-west-2:479448073833:function:sam-app-HelloWorldFunction-Gks4AwHw1UQ6
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Successfully created/updated stack - sam-app in us-west-2
sam コマンドでのエラー時の対応例
エラー① PythonのPATHが通らない、sam build
で発生
- Pythonインストール時にPATHへの追加を設定しなかった場合に発生
- Pythonが複数バージョンインストールされていてPATHの記載順の優先で別バージョンになっている場合
PS >cd sam-app
PS >sam build
Building codeuri: C:\usr\iot\local-windows-sam\sam-app\hello_world runtime: python3.8 metadata: {} functions: ['HelloWorldFunction']
Traceback (most recent call last):
File "runpy.py", line 194, in _run_module_as_main
File "runpy.py", line 87, in _run_code
File "C:\Program Files\Amazon\AWSSAMCLI\runtime\lib\site-packages\samcli\__main__.py", line 12, in <module>
cli(prog_name="sam")
File "C:\Program Files\Amazon\AWSSAMCLI\runtime\lib\site-packages\click\core.py", line 829, in __call__
return self.main(*args, **kwargs)
File "C:\Program Files\Amazon\AWSSAMCLI\runtime\lib\site-packages\click\core.py", line 782, in main
rv = self.invoke(ctx)
File "C:\Program Files\Amazon\AWSSAMCLI\runtime\lib\site-packages\click\core.py", line 1259, in invoke
return _process_result(sub_ctx.command.invoke(sub_ctx))
File "C:\Program Files\Amazon\AWSSAMCLI\runtime\lib\site-packages\click\core.py", line 1066, in invoke
return ctx.invoke(self.callback, **ctx.params)
File "C:\Program Files\Amazon\AWSSAMCLI\runtime\lib\site-packages\click\core.py", line 610, in invoke
return callback(*args, **kwargs)
File "C:\Program Files\Amazon\AWSSAMCLI\runtime\lib\site-packages\click\decorators.py", line 73, in new_func
return ctx.invoke(f, obj, *args, **kwargs)
File "C:\Program Files\Amazon\AWSSAMCLI\runtime\lib\site-packages\click\core.py", line 610, in invoke
return callback(*args, **kwargs)
File "C:\Program Files\Amazon\AWSSAMCLI\runtime\lib\site-packages\samcli\lib\telemetry\metric.py", line 153, in wrapped
raise exception # pylint: disable=raising-bad-type
File "C:\Program Files\Amazon\AWSSAMCLI\runtime\lib\site-packages\samcli\lib\telemetry\metric.py", line 122, in wrapped
return_value = func(*args, **kwargs)
File "C:\Program Files\Amazon\AWSSAMCLI\runtime\lib\site-packages\samcli\lib\utils\version_checker.py", line 42, in wrapped
actual_result = func(*args, **kwargs)
File "C:\Program Files\Amazon\AWSSAMCLI\runtime\lib\site-packages\samcli\cli\main.py", line 90, in wrapper
return func(*args, **kwargs)
File "C:\Program Files\Amazon\AWSSAMCLI\runtime\lib\site-packages\samcli\commands\build\command.py", line 210, in cli
do_cli(
File "C:\Program Files\Amazon\AWSSAMCLI\runtime\lib\site-packages\samcli\commands\build\command.py", line 318, in do_cli
artifacts = builder.build()
File "C:\Program Files\Amazon\AWSSAMCLI\runtime\lib\site-packages\samcli\lib\build\app_builder.py", line 169, in build
return build_strategy.build()
File "C:\Program Files\Amazon\AWSSAMCLI\runtime\lib\site-packages\samcli\lib\build\build_strategy.py", line 42, in build
result.update(self._build_functions(self._build_graph))
File "C:\Program Files\Amazon\AWSSAMCLI\runtime\lib\site-packages\samcli\lib\build\build_strategy.py", line 53, in _build_functions
function_build_results.update(self.build_single_function_definition(build_definition))
File "C:\Program Files\Amazon\AWSSAMCLI\runtime\lib\site-packages\samcli\lib\build\build_strategy.py", line 123, in build_single_function_definition
result = self._build_function(
File "C:\Program Files\Amazon\AWSSAMCLI\runtime\lib\site-packages\samcli\lib\build\app_builder.py", line 541, in _build_function
return self._build_function_in_process(
File "C:\Program Files\Amazon\AWSSAMCLI\runtime\lib\site-packages\samcli\lib\build\app_builder.py", line 592, in _build_function_in_process
builder.build(
File "C:\Program Files\Amazon\AWSSAMCLI\runtime\lib\site-packages\aws_lambda_builders\builder.py", line 125, in build
return workflow.run()
File "C:\Program Files\Amazon\AWSSAMCLI\runtime\lib\site-packages\aws_lambda_builders\workflow.py", line 58, in wrapper
valid_path = binary_checker.validator.validate(executable_path)
File "C:\Program Files\Amazon\AWSSAMCLI\runtime\lib\site-packages\aws_lambda_builders\workflows\python_pip\validator.py", line 43, in validate
p = subprocess.Popen(
File "subprocess.py", line 858, in __init__
File "subprocess.py", line 1311, in _execute_child
OSError: [WinError 15612] アプリケーションを開始できません。問題を解決するには、アプリケーションを再インストールしてください。
対応、python3へのPATH設定がないのでエラーになっている
PS > $ENV:Path+=";C:\Users\アカウント\AppData\Local\Programs\Python\Python38"
PS > python -version
Python
エラー② InvalidClientTokenId
がエラーに出る。sam deploy
で発生
sam --deploy
...
..
Creating the required resources...
Error: Failed to create managed resources: An error occurred (InvalidClientTokenId) when calling the CreateChangeSet operation: The security token included in the request is invalid.
のように、InvalidClientTokenId
が表示されるときは、awsのクレデンシャル(credentials)の[default]
が使われ、意図したAWS認証プロファイルが使われていない可能性がある。
対応、sam コマンドの引数にプロファイルとリージョン指定を追加する
対応例)クレデンシャルファイルが以下のような場合に、AWS認証プロファイル「sam-cli-workshop-user-ssugimoto」を使いたい場合
[default]
aws_access_key_id =xxxx
aws_secret_access_key=yyyy
[sam-cli-workshop-user-ssugimoto]
aws_access_key_id=xxx2
aws_secret_access_key=yyy2
- 実行するコマンド
PS > sam deploy --guided --profile sam-cli-workshop-user-ssugimoto --region us-west-2
エラー③ PythonPipBuilder:Validation - Binary validation failed for python
PythonのPATHがない
PS > sam build
Building codeuri: C:\usr\iot\local-windows-sam\sam-app\hello_world runtime: python3.8 metadata: {} functions: ['HelloWorldFunction']
Build Failed
Error: PythonPipBuilder:Validation - Binary validation failed for python, searched for python in following locations : ['C:\\Users\\アカウント\\AppData\\Local\\Microsoft\\WindowsApps\\python.EXE'] which did not satisfy constraints for runtime: python3.8. Do you have python for
runtime: python3.8 on your PATH?
対応、PATH設定をする
一時的、暫定対処
PS > $ENV:Path+=";C:\Users\アカウント\AppData\Local\Programs\Python\Python38"
PS > sam build
Building codeuri: C:\usr\iot\local-windows-sam\sam-app\hello_world runtime: python3.8 metadata: {} 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
=========================
[*] Invoke Function: sam local invoke
[*] Deploy: sam deploy --guided
VSCodeへの設定(推奨)
- 下記の設定ではVSCode内のターミナル用のため、Windows の Powershellやcmdを別で起動する場合は、.batや .ps1 で環境変数をセットすることが必要。
- PATHの行がWindows向けのPython3.8へのVSCode内のターミナルを開いた時の設定例、python.exe,python38.dllのファイルがあるディレクトリを指定する
└─.vscode
├── settings.json
└── launch.json
{
"files.eol": "\n",
"terminal.integrated.env.windows": {
"PATH":"${env:USERPROFILE}\\AppData\\Local\\Programs\\Python\\Python38;${env:PATH}",
},
"terminal.integrated.env.osx": {
"PATH": "${workspaceRoot}/node_modules/.bin:${env:PATH}"
}
}
AWSクラウド側にdeployされたものの確認
関数
cloudformation stack
APIの実行
-
URLでGETリクエスト
ブラウザのアドレスに入力 https://xxxxx.execute-api.us-west-2.amazonaws.com/Prod/hello/
ローカル windows10での実行
-
sam local start-api
コマンドでローカルにAPIサーバ機能が起動します - このコマンドでは、Dockerが必須です。
- APIサーバにリクエストがくると、Lambdaが動くコンテナが起動してリクエストを処理します
- リクエストのたびにLambdaコンテナが起動するため、さくさく動かすにはCPUスペックが必要なのと、コンテナ初期化が速い言語(Pyhonやnode)でないともっさり動きます
作成したスタックの削除
PS > aws cloudformation delete-stack --stack-name sam-app --profile sam-cli-workshop-user-ssugimoto --region us-west-2
-
./sam-app/samconfig.toml
にstack_name, region, prodile, s3_bucket の記載がされています