投稿の経緯
・AWS GameDay Serverlessに参加決定するも、筆者は開発ド素人(マズい)
→(2023/8/2追記)GameDayの参戦レポートを本記事掲載後に会社ブログに投稿しました。GameDay楽しかったので、気になる方は是非ともご覧ください!
・下記書籍を参考に勉強し、備忘をまとめた
本記事の内容
・とりあえず試しにSAMを触りたい方向け
・実際にAWS SAMを用いて、サーバレスシステムを構築しているところを記載。
※SAMの説明は古いが、下記AWS公式のBlackbeltや公式ドキュメントを参照。
前提
・環境にdockerはインストール済であること
・筆者はAWS上のEC2インスタンス(Ubuntu)でコードを実行
・EC2インスタンスにアタッチしたロールにはCloudFormation、API Gateway、Lambdaの作成権限を付与
手順
AWS SAM CLIのインストール
以下のコマンドを入力。
$ mkdir serverless-tutorial
$ cd serverless-tutorial/
$ sudo wget https://github.com/aws/aws-sam-cli/releases/latest/download/aws-sam-cli-linux-x86_64.zip
$ unzip aws-sam-cli-linux-x86_64.zip -d sam-installation
$ sudo ./sam-installation/install
You can now run: /usr/local/bin/sam --version
$ sam --version
SAM CLI, version 1.89.0
参考URLは以下の通り。
sam init
Lambdaへデプロイするコードや、単体テストのコード等をデプロイするための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
You can preselect a particular runtime or package type when using the `sam init` experience.
Call `sam init --help` to learn more.
# 使用したいテンプレートソースを選択(1を選択)
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 - Full Stack
13 - Lambda EFS example
14 - DynamoDB Example
15 - Machine Learning
Template: 1
# Pythonのバージョン等を細かく指定したいのでNを入力
Use the most popular runtime and package type? (Python and zip) [y/N]: N
# 利用したいランタイムを選択。(今回はpython3.10を選択)
Which runtime would you like to use?
1 - aot.dotnet7 (provided.al2)
2 - dotnet6
3 - go1.x
4 - go (provided.al2)
5 - graalvm.java11 (provided.al2)
6 - graalvm.java17 (provided.al2)
7 - java17
8 - java11
9 - java8.al2
10 - java8
11 - nodejs18.x
12 - nodejs16.x
13 - nodejs14.x
14 - nodejs12.x
15 - python3.9
16 - python3.8
17 - python3.7
18 - python3.10
19 - ruby3.2
20 - ruby2.7
21 - rust (provided.al2)
Runtime: 18
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
# 何も入力しないと、[]内のsam-appというプロジェクトが作成される
Project name [sam-app]:
-----------------------
Generating application:
-----------------------
Name: sam-app
Runtime: python3.10
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ディレクトリが作成される。
ここから、テンプレートから作成したプロジェクトをビルドする。
$ ls -a
total 73404
drwxr-xr-x 4 ubuntu docker 4096 Jul 2 11:27 ./
drwxr-x--- 11 ubuntu docker 4096 Jul 2 11:27 ../
-rw-r--r-- 1 root root 75146042 Jun 26 21:40 aws-sam-cli-linux-x86_64.zip
drwxr-xr-x 6 ubuntu docker 4096 Jul 2 11:28 sam-app/ # sam initで作成された
drwxr-xr-x 4 ubuntu docker 4096 Jul 2 11:22 sam-installation/
$ cd sam-app
$ sam build
# 実行結果
Starting Build use cache
Manifest file is changed (new hash: 3298f13049d19cffaa37ca931dd4d421) or dependency folder (.aws-sam/deps/e9a851e2-d6a5-4e10-98b3-3cdb8c662e80) is missing for (HelloWorldFunction),
downloading dependencies and copying/building source
Building codeuri: /home/ubuntu/serverless-tutorial/sam-app/hello_world runtime: python3.10 metadata: {} architecture: x86_64 functions: HelloWorldFunction
Running PythonPipBuilder:CleanUp
Running PythonPipBuilder:ResolveDependencies
Running PythonPipBuilder:CopySource
Running PythonPipBuilder:CopySource
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
sam local invoke
ビルドが完了したので、ローカルでサーバレスアプリケーションをテストする。
sam local invoke
はAWS Lambda関数の1回限りの呼び出しをローカルで呼び出す。
今回はLambda関数の実行結果としてhello world
と帰ってくる。
$ sam local invoke
# 実行結果
Invoking app.lambda_handler (python3.10)
Local image was not found.
Removing rapid images for repo public.ecr.aws/sam/emulation-python3.10
Building image...........................................................................................................................
Using local image: public.ecr.aws/lambda/python:3.10-rapid-x86_64.
Mounting /home/ubuntu/serverless-tutorial/sam-app/.aws-sam/build/HelloWorldFunction as /var/task:ro,delegated, inside runtime container
START RequestId: f1f4376b-5ff7-4c52-ac88-987c70f57260 Version: $LATEST
# hello worldと出力されている
{"statusCode": 200, "body": "{\"message\": \"hello world\"}"}END RequestId: f1f4376b-5ff7-4c52-ac88-987c70f57260
REPORT RequestId: f1f4376b-5ff7-4c52-ac88-987c70f57260 Init Duration: 0.04 ms Duration: 45.54 ms Billed Duration: 46 ms Memory Size: 128 MB Max Memory Used: 128 MB
ここでhello_world/app.py
のコードの"message"
部分を編集する。
下記のようにreturn
の内部を編集する。
import json
# import requests
def lambda_handler(event, context):
"""Sample pure Lambda function
Parameters
----------
event: dict, required
API Gateway Lambda Proxy Input Format
Event doc: https://docs.aws.amazon.com/apigateway/latest/developerguide/set-up-lambda-proxy-integrations.html#api-gateway-simple-proxy-for-lambda-input-format
context: object, required
Lambda Context runtime methods and attributes
Context doc: https://docs.aws.amazon.com/lambda/latest/dg/python-context-object.html
Returns
------
API Gateway Lambda Proxy Output Format: dict
Return doc: https://docs.aws.amazon.com/apigateway/latest/developerguide/set-up-lambda-proxy-integrations.html
"""
# try:
# ip = requests.get("http://checkip.amazonaws.com/")
# except requests.RequestException as e:
# # Send some context about this error to Lambda Logs
# print(e)
# raise e
return {
"statusCode": 200,
"body": json.dumps({
## 編集前
## "message": "hello world",
## 編集後
"message": "hello hello!",
# "location": ip.text.replace("\n", "")
}),
}
sam build
更新内容を反映するために、sam build
を行う。
$ sam build
# 実行結果
Starting Build use cache
Manifest is not changed for (HelloWorldFunction), running incremental build
Building codeuri: /home/ubuntu/serverless-tutorial/sam-app/hello_world runtime: python3.10 metadata: {} architecture: x86_64 functions: HelloWorldFunction
Running PythonPipBuilder:CopySource
Running PythonPipBuilder:CopySource
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
再度sam local
でサーバレスアプリケーションをローカルでテストすると、編集後の値が返ってくる。hello hello!
と返ってきている。
$ sam local invoke
Invoking app.lambda_handler (python3.10)
Local image is up-to-date
Using local image: public.ecr.aws/lambda/python:3.10-rapid-x86_64.
Mounting /home/ubuntu/serverless-tutorial/sam-app/.aws-sam/build/HelloWorldFunction as /var/task:ro,delegated, inside runtime container START RequestId: c33ed473-c100-47cc-acb2-7658a061b4de Version: $LATEST
START RequestId: c33ed473-c100-47cc-acb2-7658a061b4de Version: $LATEST
# 先ほど編集した内容(hello hello!)が出力に反映されている。
{"statusCode": 200, "body": "{\"message\": \"hello hello!\"}"}END RequestId: c33ed473-c100-47cc-acb2-7658a061b4de
REPORT RequestId: c33ed473-c100-47cc-acb2-7658a061b4de Init Duration: 0.05 ms Duration: 45.94 ms Billed Duration: 46 ms Memory Size: 128 MB Max Memory Used: 128 MB
sam deploy --guided
ここまでは全てローカルで実行していたが、サーバレスアプリケーションをAWS環境に構築する。実行コマンドはsam deploy --guided
。--guided
はsam deploy
を行うための設定ファイルsamconfig.toml
を同時に作成するためにつけたオプション。今回はCloudFormation、API Gateway、Lambdaがリソースとして作成される。
$ sam deploy --guided
# 以下出力結果
# 一部出力内容を変更
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]: y
#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]: y
#Preserves the state of previously provisioned resources when an operation fails
Disable rollback [y/N]: n
HelloWorldFunction has no authentication. Is this okay? [y/N]: y
Save arguments to configuration file [Y/n]: y
SAM configuration file [samconfig.toml]:
SAM configuration environment [default]:
Looking for resources needed for deployment:
Managed S3 bucket: aws-sam-cli-managed-default-samclisourcebucket-8uhdtd6bd37
A different default S3 bucket can be set in samconfig.toml and auto resolution of buckets turned off by setting resolve_s3=False
Parameter "stack_name=sam-app" in [default.deploy.parameters] is defined as a global parameter [default.global.parameters].
This parameter will be only saved under [default.global.parameters] in /home/ubuntu/serverless-tutorial/sam-app/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
File with same data already exists at sam-app/3e6e92efda1e69daf7bd8183e6781c3e, skipping upload
Deploying with following values
===============================
Stack name : sam-app
Region : ap-northeast-1
Confirm changeset : True
Disable rollback : False
Deployment s3 bucket : aws-sam-cli-managed-default-samclisourcebucket-8uhdtd6bd37
Capabilities : ["CAPABILITY_IAM"]
Parameter overrides : {}
Signing Profiles : {}
Initiating deployment
=====================
File with same data already exists at sam-app/b3330d37c9281d8f7153abbc4cae4b3c.template, skipping upload
Waiting for changeset to be created..
CloudFormation stack changeset
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Operation LogicalResourceId ResourceType Replacement
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+ Add HelloWorldFunctionHelloWorldPermissionProd AWS::Lambda::Permission N/A
+ Add HelloWorldFunctionRole AWS::IAM::Role N/A
+ Add HelloWorldFunction AWS::Lambda::Function N/A
+ Add ServerlessRestApiDeployment47fc2d5f9d AWS::ApiGateway::Deployment N/A
+ Add ServerlessRestApiProdStage AWS::ApiGateway::Stage N/A
+ Add ServerlessRestApi AWS::ApiGateway::RestApi N/A
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Changeset created successfully. arn:aws:cloudformation:ap-northeast-1:XXXXXXXXXXXX:changeSet/samcli-deploy1688300214/6f0eaeed-ead2-49c7-8885-014e9ae8e549
Previewing CloudFormation changeset before deployment
======================================================
Deploy this changeset? [y/N]: y
2023-07-02 12:17:02 - 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::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::Lambda::Permission HelloWorldFunctionHelloWorldPermissionProd -
CREATE_IN_PROGRESS AWS::ApiGateway::Deployment ServerlessRestApiDeployment47fc2d5f9d -
CREATE_IN_PROGRESS AWS::Lambda::Permission HelloWorldFunctionHelloWorldPermissionProd Resource creation Initiated
CREATE_IN_PROGRESS AWS::ApiGateway::Deployment ServerlessRestApiDeployment47fc2d5f9d Resource creation Initiated
CREATE_COMPLETE AWS::ApiGateway::Deployment ServerlessRestApiDeployment47fc2d5f9d -
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::Lambda::Permission HelloWorldFunctionHelloWorldPermissionProd -
CREATE_COMPLETE 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::XXXXXXXXXXXX:role/sam-app-HelloWorldFunctionRole-1KAO6TL6MXH5O
Key HelloWorldApi
Description API Gateway endpoint URL for Prod stage for Hello World function
# 後ほどcurlコマンドを打つ部分↓
Value https://8bvmn8uqtf.execute-api.ap-northeast-1.amazonaws.com/Prod/hello/
Key HelloWorldFunction
Description Hello World Lambda Function ARN
Value arn:aws:lambda:ap-northeast-1:XXXXXXXXXXXX:function:sam-app-HelloWorldFunction-U6bskXd54TP9
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Successfully created/updated stack - sam-app in ap-northeast-1
これでAWS環境にサーバレスアプリケーションが構築できた。
自分のAWS環境のCloudFormationのスタックを見ると、二つのスタックが構築されている。
sam-app
のスタックではLambda、Lambda用のIAMロール、API Gatewayが、aws-sam-cli-managed-default
のスタックではS3バケットが作成される。なお、S3バケットにはCloudFormation用のテンプレートファイルが格納される。
上記コードのOutputs
のValue
にcurlコマンドをうち、実際にLambda関数の実行結果が返ってくることを確認する。
$ curl https://8bvmn8uqtf.execute-api.ap-northeast-1.amazonaws.com/Prod/hello/
# 出力結果
{"message": "hello hello HELLOOOOOOOO!"}
再度コードを編集し、sam deploy
AWS環境にデプロイした後も、出力結果は編集できるので試してみる。
再度hello_world/app.py
のコードの"message"
部分を編集する。
import json
# import requests
def lambda_handler(event, context):
"""Sample pure Lambda function
Parameters
----------
event: dict, required
API Gateway Lambda Proxy Input Format
Event doc: https://docs.aws.amazon.com/apigateway/latest/developerguide/set-up-lambda-proxy-integrations.html#api-gateway-simple-proxy-for-lambda-input-format
context: object, required
Lambda Context runtime methods and attributes
Context doc: https://docs.aws.amazon.com/lambda/latest/dg/python-context-object.html
Returns
------
API Gateway Lambda Proxy Output Format: dict
Return doc: https://docs.aws.amazon.com/apigateway/latest/developerguide/set-up-lambda-proxy-integrations.html
"""
# try:
# ip = requests.get("http://checkip.amazonaws.com/")
# except requests.RequestException as e:
# # Send some context about this error to Lambda Logs
# print(e)
# raise e
return {
"statusCode": 200,
"body": json.dumps({
## 編集前
## "message": "hello world",
## 編集前
## "message": "hello hello!",
"message": "hellooooo!",
# "location": ip.text.replace("\n", "")
}),
}
コード変更を反映させるために、sam build
でビルドを実行する。
その後sam local invoke
でローカルで出力結果を確認する。
$ sam build
$ sam local invoke
# 実行結果
Invoking app.lambda_handler (python3.10)
Local image is up-to-date
Using local image: public.ecr.aws/lambda/python:3.10-rapid-x86_64.
Mounting /home/ubuntu/serverless-tutorial-2/sam-app/.aws-sam/build/HelloWorldFunction as /var/task:ro,delegated, inside runtime container
START RequestId: 457c04db-df34-48c8-8fd2-e326dbcdafc8 Version: $LATEST
END RequestId: 457c04db-df34-48c8-8fd2-e326dbcdafc8
REPORT RequestId: 457c04db-df34-48c8-8fd2-e326dbcdafc8 Init Duration: 0.13 ms Duration: 47.16 ms Billed Duration: 48 ms Memory Size: 128 MB Max Memory Used: 128 MB
# 編集内容が反映されている↓
{"statusCode": 200, "body": "{\"message\": \"hellooooo!\"}"}
クラウド環境にも変更を反映させる。samconfig.toml
は既にあるので、今回はsam deploy
を実行する。
$ sam deploy
# 実行結果
Managed S3 bucket: aws-sam-cli-managed-default-samclisourcebucket-cox95u4evrdc
A different default S3 bucket can be set in samconfig.toml
Or by specifying --s3-bucket explicitly.
Uploading to sam-app/2c2adc7df0ab7db15ccc4be7982a9065 606617 / 606617 (100.00%)
Deploying with following values
===============================
Stack name : sam-app
Region : ap-northeast-1
Confirm changeset : True
Disable rollback : False
Deployment s3 bucket : aws-sam-cli-managed-default-samclisourcebucket-cox95u4evrdc
Capabilities : ["CAPABILITY_IAM"]
Parameter overrides : {}
Signing Profiles : {}
Initiating deployment
=====================
Uploading to sam-app/1cdaf37219efaabf73feba5d967cafe9.template 1180 / 1180 (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:ap-northeast-1:XXXXXXXXXXXX:changeSet/samcli-deploy1688779060/99f4ae9e-48a2-4de7-8584-8ee701cf096c
Previewing CloudFormation changeset before deployment
======================================================
Deploy this changeset? [y/N]: y
2023-07-08 01:17:54 - Waiting for stack create/update to complete
CloudFormation events from stack operations (refresh every 5.0 seconds)
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
ResourceStatus ResourceType LogicalResourceId ResourceStatusReason
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
UPDATE_IN_PROGRESS AWS::Lambda::Function HelloWorldFunction -
UPDATE_COMPLETE AWS::Lambda::Function HelloWorldFunction -
UPDATE_COMPLETE_CLEANUP_IN_PROGRESS AWS::CloudFormation::Stack sam-app -
UPDATE_COMPLETE 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::XXXXXXXXXXXX:role/sam-app-HelloWorldFunctionRole-V21FRKZGFOM1
Key HelloWorldApi
Description API Gateway endpoint URL for Prod stage for Hello World function
Value https://433fgvkj53.execute-api.ap-northeast-1.amazonaws.com/Prod/hello/
Key HelloWorldFunction
Description Hello World Lambda Function ARN
Value arn:aws:lambda:ap-northeast-1:XXXXXXXXXXXX:function:sam-app-HelloWorldFunction-iaFnHVLawxjs
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Successfully created/updated stack - sam-app in ap-northeast-1
もう一度curl
コマンドで変更内容が更新されているか試す。
$ curl https://433fgvkj53.execute-api.ap-northeast-1.amazonaws.com/Prod/hello/
# 出力結果
{"message": "hellooooo!"}
確かに再度編集内容が反映されたことを確認できた。
後片付け
作成された2つのAWS CloudFormationのスタックを削除。
最後に
今回はAWS Gamedayの予習がてら、AWS SAMを触った。テンプレートに手を加えていく形で開発ができれば素早くシステムが構築できそう。Gameday頑張るぞ!