Ubuntu ServerにAWS SAMをインストールした時のメモ

概要

Ubuntu ServerへAWS SAMを使いたくてインストールしたので、その時のメモ。

UbuntuへのAWS SAM CLIのインストール

参考にしたサイトは下記です。

AWS SAM CLI のインストール

AWS SAM CLIのダウンロード

下記のようにzipファイルを任意のディレクトリへダウンロードします

1
$ wget https://github.com/aws/aws-sam-cli/releases/latest/download/aws-sam-cli-linux-x86_64.zip

Unzipしてインストールしていきます

1
2
$ unzip aws-sam-cli-linux-x86_64.zip -d sam-installation
$ sudo ./sam-installation/install

インストールが完了したらバージョンを確認します。

1
2
$ sam --version
SAM CLI, version 1.76.0

AWS SAM でサンプルアプリ作成

SAMでサンプルでアプリを構築してみます。
参考にしたサイトは下記です。

The Complete AWS SAM Workshop

Hello World プロジェクトの作成

まずはSAMのプロジェクトを作成します。
適当な作業用ディレクトリへ移動して下記のコマンドを実行します。

1
$ sam init

ウィザードに従って選択していきます。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
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 - Multi-step workflow
3 - Serverless API
4 - Scheduled task
5 - Standalone function
6 - Data processing
7 - Hello World Example With Powertools
8 - Infrastructure event management
9 - Serverless Connector Hello World Example
10 - Multi-step workflow with Connectors
11 - Lambda EFS example
12 - DynamoDB Example
13 - Machine Learning
Template: 1

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

希望するランタイムとバージョンを選択します、今回は “16 - Python3.9” にしました

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
Which runtime would you like to use?
1 - aot.dotnet7 (provided.al2)
2 - dotnet6
3 - dotnet5.0
4 - dotnetcore3.1
5 - go1.x
6 - go (provided.al2)
7 - graalvm.java11 (provided.al2)
8 - graalvm.java17 (provided.al2)
9 - java11
10 - java8.al2
11 - java8
12 - nodejs18.x
13 - nodejs16.x
14 - nodejs14.x
15 - nodejs12.x
16 - python3.9
17 - python3.8
18 - python3.7
19 - ruby2.7
20 - rust (provided.al2)
Runtime: 16

zipパッケージを選択し、Project nameはsam-appのままにしました。
途中X-RayやApplication Insgihtsを有効化するか聞かれますが、Noを選択しています。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
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 pip.
We will proceed copying the template using pip.

Would you like to enable X-Ray tracing on the function(s) in your application? [y/N]: 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]: n

Project name [sam-app]:

以下の表に表示されて、初期化が完了します

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
Cloning from https://github.com/aws/aws-sam-cli-app-templates (process may take a moment)

-----------------------
Generating application:
-----------------------
Name: sam-app
Runtime: python3.9
Architectures: x86_64
Dependency Manager: pip
Application Template: hello-world
Output Directory: .
Configuration file: sam-app/samconfig.toml

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


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

sam-appのフォルダが作成されました。

1
2
$ ls
sam-app

Hello World の内容

API Gateway, Lambda, IAM Roleで構成されるアプリケーションのテンプレートが作成されました。

アーキテクチャや、実際のLambdaのコードの内容はAWSのサイトを参照してください。
Project Architecture

Hello World のローカル実行

変更をリポジトリへプッシュする前に、動作確認やデバッグをするために、
AWS SAM CLI を使用してローカルで実行を行います。

まずは、依存関係のライブラリをインストールします。

ちなみに、今回の環境は以下のPythonおよびpipのバージョンです。

1
2
3
4
$ python --version
Python 3.9.16
$ pip --version
pip 22.0.4 from /home/user/.pyenv/versions/3.9.16/envs/develop-3.9.16/lib/python3.9/site-packages/pip (python 3.9)

“sam init”を実行したディレクトリからhello_worldディレクトリへ移動し、pipでインストールを行います。

1
2
$ cd sam-app/hello_world
$ pip install -r requirements.txt

依存ライブラリのインストールが完了しました

1
2
Installing collected packages: charset-normalizer, urllib3, idna, certifi, requests
Successfully installed certifi-2022.12.7 charset-normalizer-3.0.1 idna-3.4 requests-2.28.2 urllib3-1.26.14

sam-appフォルダへ戻り、Lambdaをローカル実行してみます。
statusCodeと、bodyが出力されたら成功です。

1
2
3
4
5
6
7
8
9
10
11
$ cd ~/environment/sam-app
$ sam local invoke --event events/event.json
Invoking app.lambda_handler (python3.9)
Local image was not found.
Removing rapid images for repo public.ecr.aws/sam/emulation-python3.9
Building image.............
Using local image: public.ecr.aws/lambda/python:3.9-rapid-x86_64.

Mounting /home/user/environment/sam-app/hello_world as /var/task:ro,delegated inside runtime container
{"statusCode": 200, "body": "{\"message\": \"hello world\"}"}END RequestId: 6e1309d6-4f7f-4d7d-bac6-0c0e6b102a49
REPORT RequestId: 6e1309d6-4f7f-4d7d-bac6-0c0e6b102a49 Init Duration: 0.31 ms Duration: 181.50 ms Billed Duration: 182 ms Memory Size: 128 MB Max Memory Used: 128 MB

次に、API Gateway をシミュレートするローカル HTTP サーバーを実行します

1
2
3
4
5
6
7
8
9
10
11
12
13
$ cd ~/environment/sam-app
$ sam local start-api --port 8080
Initializing the lambda functions containers.
Local image is up-to-date
Using local image: public.ecr.aws/lambda/python:3.9-rapid-x86_64.

Mounting /home/user/environment/sam-app/hello_world as /var/task:ro,delegated inside runtime container
Containers Initialization is done.
Mounting HelloWorldFunction at http://127.0.0.1:8080/hello [GET]
You can now browse to the above endpoints to invoke your functions. You do not need to restart/reload SAM CLI while working on your functions, changes will be reflected instantly/automatically. If you used sam build before running local commands, you will need to re-run sam build for the changes to be picked up. You only need to restart SAM CLI if you update your AWS SAM template
2023-03-04 22:05:33 WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead.
* Running on http://127.0.0.1:8080
2023-03-04 22:05:33 Press CTRL+C to quit

そして、実際にローカルのAPI Gatewayへリクエストを投げてみます。
別のターミナルを開いてcurlコマンドを実行します。

1
2
$ curl http://localhost:8080/hello
{"message": "hello world"}

Hello World のコード変更と反映

Lambdaのコードを変更し応答メッセージを変更すると、プロセスを再起動しなくても、アプリケーションの応答が変更されます。

~/environment/sam-app/hello_world/app.py

1
2
3
4
5
6
7
8
return {
"statusCode": 200,
"body": json.dumps({
- "message": "hello world",
+ "message": "hello my friend",
# "location": ip.text.replace("\n", "")
}),
}
1
2
$ curl http://localhost:8080/hello
{"message": "hello my friend"}

Hello World の単体テスト

次のコマンドを実行して単体テストを実行します。

1
2
3
$ cd ~/environment/sam-app
$ pip install pytest pytest-mock
$ python -m pytest tests/unit

“hello world”を”hello my friend”に変更していたので、結果はエラーになります。

1
2
3
E       AssertionError: assert 'hello my friend' == 'hello world'
E - hello world
E + hello my friend

テストコードを修正します。
tests/unit/test_handler.py

1
2
3
4
5
6
7
8
9
def test_lambda_handler(apigw_event):

ret = app.lambda_handler(apigw_event, "")
data = json.loads(ret["body"])

assert ret["statusCode"] == 200
assert "message" in ret["body"]
- assert data["message"] == "hello world"
+ assert data["message"] == "hello my friend"

今回はエラーが出ません

1
2
3
$ python -m pytest tests/unit
tests/unit/test_handler.py . [100%]
=========== 1 passed in 0.01s ===========

Hello World のビルドとデプロイ

sam buildコマンドを実行してプロジェクトをビルドします。
この処理の中で依存関係を確認してデプロイアーティファクトを生成します。

1
2
3
4
5
6
$ cd ~/environment/sam-app
$ sam build
Build Succeeded

Built Artifacts : .aws-sam/build
Built Template : .aws-sam/build/template.yaml

sam deployコマンドを実行してプロジェクトをデプロイします。
–guidedパラメータを指定し、ガイド付きモードで進めます。

1
2
3
4
$ cd ~/environment/sam-app
$ sam deploy --guided

Error: Unable to locate credentials

エラーが出てしまいました、どうやらAWS CLIのconfigureの問題のようです。
–profileオプションを普段使っており、デフォルトの認証情報が無いためデプロイ時に認証エラーになっていました。
sam deploy コマンドにも–profileオプションがあるので、それを追加したら成功しました。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
$ sam deploy --guided --profile user

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-east-1]: ap-northeast-1
#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]:
#Preserves the state of previously provisioned resources when an operation fails
Disable rollback [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:

(中略)

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

デプロイが成功すると下記のような出力がされます。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
CloudFormation outputs from deployed stack
-----------------------------------------------------------------------------------------------------------------------------------------
Outputs
-----------------------------------------------------------------------------------------------------------------------------------------
Key HelloWorldFunctionIamRole
Description Implicit IAM Role created for Hello World function
Value arn:aws:iam::123456789123:role/sam-app-HelloWorldFunctionRole-1QWE9DKNCP6V3
Key HelloWorldApi
Description API Gateway endpoint URL for Prod stage for Hello World function
Value https://tkgp1hj1zk.execute-api.ap-northeast-1.amazonaws.com/Prod/hello/

Key HelloWorldFunction
Description Hello World Lambda Function ARN
Value arn:aws:lambda:ap-northeast-1:123456789123:function:sam-app-HelloWorldFunction-5RxoDCiBWUPV
-----------------------------------------------------------------------------------------------------------------------------------------

Successfully created/updated stack - sam-app in ap-northeast-1

表示されたAPIに対してcurlでリクエストを投げると、テストした時と同じ結果が返ることが確認できます。

1
2
curl -s https://tkgp1hj1zk.execute-api.ap-northeast-1.amazonaws.com/Prod/hello/ 
{"message": "hello my friend"}

ガイド付きデプロイを実行したときの入力値はsamconfig.tomlに保存され、次回から入力の手間が省略できます。
~/environment/sam-app/samconfig.toml

1
2
3
4
5
6
7
8
9
10
[default.deploy]
[default.deploy.parameters]
capabilities = "CAPABILITY_IAM"
confirm_changeset = true
resolve_s3 = true
s3_bucket = "aws-sam-cli-managed-default-samclisourcebucket-3uw8p3xikut"
s3_prefix = "sam-app"
region = "ap-northeast-1"
profile = "user"
image_repositories = []

ガイド付きデプロイとsamconfig.tomlについて、下記も参考にするよう記載があったのでリンクしておきます。

A simpler deployment experience with AWS SAM CLI

Hello World のリソース削除

デプロイしたリソースを削除します。

1
2
3
4
5
6
$ cd ~/environment/sam-app
$ sam delete
Are you sure you want to delete the stack sam-app in the region ap-northeast-1 ? [y/N]: y
Are you sure you want to delete the folder sam-app in S3 which contains the artifacts? [y/N]: y

Deleted successfully