上記、「AWS Hands-on for Beginners Serverless #2 AWS SAM を使ってテンプレートからサーバーレスな環境を構築する」 をAWS CLIでやってみる
Cloud9は新規利用できなくなりました。
今まで利用したことがあるアカウントはまだ利用できるようです。
03 Cloud9 のセットアップ + [Option] Cloud9 で簡単な Lambda 関数を作成する
変数
コマンド
# Cloud9環境名
CLOUD9_ENVIRONMENT_NAME="aws-hands-on-for-beginners-serverless-2" \
&& echo ${CLOUD9_ENVIRONMENT_NAME}
# Cloud9説明
CLOUD9_ENVIRONMENT_DESC="aws-hands-on-for-beginners-serverless-2" \
&& echo ${CLOUD9_ENVIRONMENT_DESC}
# インスタンスタイプ
CLOUD9_INSTANCE_TYPE="t2.micro" \
&& echo ${CLOUD9_INSTANCE_TYPE}
# プラットフォーム
CLOUD9_IMAGE_ID="resolve:ssm:/aws/service/cloud9/amis/amazonlinux-2-x86_64" \
&& echo ${CLOUD9_IMAGE_ID}
出力
[cloudshell-user@ip-10-132-75-96 ~]$ # Cloud9環境名
[cloudshell-user@ip-10-132-75-96 ~]$ CLOUD9_ENVIRONMENT_NAME="aws-hands-on-for-beginners-serverless-2" \
> && echo ${CLOUD9_ENVIRONMENT_NAME}
aws-hands-on-for-beginners-serverless-2
[cloudshell-user@ip-10-132-75-96 ~]$
[cloudshell-user@ip-10-132-75-96 ~]$ # Cloud9説明
[cloudshell-user@ip-10-132-75-96 ~]$ CLOUD9_ENVIRONMENT_DESC="aws-hands-on-for-beginners-serverless-2" \
> && echo ${CLOUD9_ENVIRONMENT_DESC}
aws-hands-on-for-beginners-serverless-2
[cloudshell-user@ip-10-132-75-96 ~]$
[cloudshell-user@ip-10-132-75-96 ~]$ # インスタンスタイプ
[cloudshell-user@ip-10-132-75-96 ~]$ CLOUD9_INSTANCE_TYPE="t2.micro" \
> && echo ${CLOUD9_INSTANCE_TYPE}
t2.micro
[cloudshell-user@ip-10-132-75-96 ~]$
[cloudshell-user@ip-10-132-75-96 ~]$ # プラットフォーム
[cloudshell-user@ip-10-132-75-96 ~]$ CLOUD9_IMAGE_ID="resolve:ssm:/aws/service/cloud9/amis/amazonlinux-2-x86_64" \
> && echo ${CLOUD9_IMAGE_ID}
resolve:ssm:/aws/service/cloud9/amis/amazonlinux-2-x86_64
作成
コマンド
# Cloud9環境作成
CLOUD9_ENVIRONMENT_ID=$(
aws cloud9 create-environment-ec2 \
--name ${CLOUD9_ENVIRONMENT_NAME} \
--instance-type ${CLOUD9_INSTANCE_TYPE} \
--image-id ${CLOUD9_IMAGE_ID} \
--connection-type CONNECT_SSM \
--automatic-stop-time-minutes 30 \
--query environmentId \
--output text
) \
&& echo ${CLOUD9_ENVIRONMENT_ID}
出力
[cloudshell-user@ip-10-132-75-96 ~]$ # Cloud9環境作成 (サブネット指定なし)
[cloudshell-user@ip-10-132-75-96 ~]$ CLOUD9_ENVIRONMENT_ID=$(
> aws cloud9 create-environment-ec2 \
> --name ${CLOUD9_ENVIRONMENT_NAME} \
> --instance-type ${CLOUD9_INSTANCE_TYPE} \
> --image-id ${CLOUD9_IMAGE_ID} \
> --connection-type CONNECT_SSM \
> --automatic-stop-time-minutes 30 \
> --query environmentId \
> --output text
> ) \
> && echo ${CLOUD9_ENVIRONMENT_ID}
9386580986704311a816739ecbfad97d
04 SAM で Lambda 関数を作成する ①
以降、Cloud9で実施
コマンド
date_var=$(date +%Y%m%d) \
&& echo ${date_var}
S3_BUCKET_NAME="hands-on-serverless-${date_var}" \
&& echo ${S3_BUCKET_NAME}
出力
admin:~/environment $ date_var=$(date +%Y%m%d) \
> && echo ${date_var}
20240921
admin:~/environment $ S3_BUCKET_NAME="hands-on-serverless-${date_var}" \
> && echo ${S3_BUCKET_NAME}
hands-on-serverless-20240921
S3バケット作成
コマンド
# 作成
aws s3 mb s3://${S3_BUCKET_NAME}
出力
admin:~/environment $ # 作成
admin:~/environment $ aws s3 mb s3://${S3_BUCKET_NAME}
make_bucket: hands-on-serverless-20240921
ディレクトリ作成
コマンド
mkdir hands-on-serverless-2
cd hands-on-serverless-2
mkdir translate-function
出力
admin:~/environment $ mkdir hands-on-serverless-2
admin:~/environment $ cd hands-on-serverless-2
admin:~/environment/hands-on-serverless-2 $ mkdir translate-function
translate-function.py作成
コマンド
cat << EOF > translate-function/translate-function.py
import json
import logging
logger = logging.getLogger()
logger.setLevel(logging.INFO)
def lambda_handler(event, context):
logger.info(event)
return {
'statusCode': 200,
'body': json.dumps('Hello Hands on world!')
}
EOF
出力
admin:~/environment/hands-on-serverless-2 $ cat << EOF > translate-function/translate-function.py
> import json
> import logging
>
> logger = logging.getLogger()
> logger.setLevel(logging.INFO)
>
> def lambda_handler(event, context):
>
> logger.info(event)
>
> return {
> 'statusCode': 200,
> 'body': json.dumps('Hello Hands on world!')
> }
> EOF
template.yaml作成
ハンズオンな内容からpythonのバージョンを3.8に変更
コマンド
cat << EOF > template.yaml
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: AWS Hands-on for Beginners - Serverless 2
Resources:
TranslateLambda:
Type: AWS::Serverless::Function
Properties:
FunctionName: translate-function-2
CodeUri: ./translate-function
Handler: translate-function.lambda_handler
Runtime: python3.8
Timeout: 5
MemorySize: 256
EOF
出力
admin:~/environment/hands-on-serverless-2 $ cat << EOF > template.yaml
> AWSTemplateFormatVersion: '2010-09-09'
> Transform: AWS::Serverless-2016-10-31
> Description: AWS Hands-on for Beginners - Serverless 2
> Resources:
> TranslateLambda:
> Type: AWS::Serverless::Function
> Properties:
> FunctionName: translate-function-2
> CodeUri: ./translate-function
> Handler: translate-function.lambda_handler
> Runtime: python3.8
> Timeout: 5
> MemorySize: 256
> EOF
パッケージング
コマンド
# パッケージング
aws cloudformation package \
--template-file template.yaml \
--s3-bucket ${S3_BUCKET_NAME} \
--output-template-file packaged-template.yaml
出力
admin:~/environment/hands-on-serverless-2 $ # パッケージング
admin:~/environment/hands-on-serverless-2 $ aws cloudformation package \
> --template-file template.yaml \
> --s3-bucket ${S3_BUCKET_NAME} \
> --output-template-file packaged-template.yaml
Uploading to f802e187101b61229f32ab9c1db914b5 310 / 310.0 (100.00%)
Successfully packaged artifacts and wrote output template to file packaged-template.yaml.
Execute the following command to deploy the packaged template
aws cloudformation deploy --template-file /home/ec2-user/environment/hands-on-serverless-2/packaged-template.yaml --stack-name <YOUR STACK NAME>
デプロイ
コマンド
# スタック名
STACK_NAME="hands-on-serverless-2" \
&& echo ${STACK_NAME}
# デプロイ
aws cloudformation deploy \
--template-file ./packaged-template.yaml \
--stack-name ${STACK_NAME} \
--capabilities CAPABILITY_IAM
出力
admin:~/environment/hands-on-serverless-2 $ # スタック名
admin:~/environment/hands-on-serverless-2 $ STACK_NAME="hands-on-serverless-2" \
> && echo ${STACK_NAME}
hands-on-serverless-2
admin:~/environment/hands-on-serverless-2 $
admin:~/environment/hands-on-serverless-2 $ # デプロイ
admin:~/environment/hands-on-serverless-2 $ aws cloudformation deploy \
> --template-file ./packaged-template.yaml \
> --stack-name ${STACK_NAME} \
> --capabilities CAPABILITY_IAM
Waiting for changeset to be created..
Waiting for stack create/update to complete
Successfully created/updated stack - hands-on-serverless-2
リソース一覧確認
コマンド
aws cloudformation describe-stack-resources \
--stack-name ${STACK_NAME} \
--no-cli-pager
出力
admin:~/environment/hands-on-serverless-2 $ aws cloudformation describe-stack-resources \
> --stack-name ${STACK_NAME} \
> --no-cli-pager
{
"StackResources": [
{
"StackName": "hands-on-serverless-2",
"StackId": "arn:aws:cloudformation:ap-northeast-1:999999999999:stack/hands-on-serverless-2/4fe2cc10-77c9-11ef-b579-06c2182e3129",
"LogicalResourceId": "TranslateLambda",
"PhysicalResourceId": "translate-function-2",
"ResourceType": "AWS::Lambda::Function",
"Timestamp": "2024-09-21T03:27:13.956000+00:00",
"ResourceStatus": "CREATE_COMPLETE",
"DriftInformation": {
"StackResourceDriftStatus": "NOT_CHECKED"
}
},
{
"StackName": "hands-on-serverless-2",
"StackId": "arn:aws:cloudformation:ap-northeast-1:999999999999:stack/hands-on-serverless-2/4fe2cc10-77c9-11ef-b579-06c2182e3129",
"LogicalResourceId": "TranslateLambdaRole",
"PhysicalResourceId": "hands-on-serverless-2-TranslateLambdaRole-42Dlsxf0UdTm",
"ResourceType": "AWS::IAM::Role",
"Timestamp": "2024-09-21T03:27:03.522000+00:00",
"ResourceStatus": "CREATE_COMPLETE",
"DriftInformation": {
"StackResourceDriftStatus": "NOT_CHECKED"
}
}
]
}
Lambda関数のテスト
実行
コマンド
FUNCTION_NAME="translate-function-2" \
&& echo ${FUNCTION_NAME}
# イベントの作成
EVENT=$(cat << EOF
{
"key1": "value1",
"key2": "value2",
"key3": "value3"
}
EOF
) \
&& echo ${EVENT}
# JSONフォーマットの確認
echo ${EVENT} | python -m json.tool
# テスト実行
aws lambda invoke \
--function-name ${FUNCTION_NAME} \
--payload `echo ${EVENT} | base64 -w 0` \
outputfile.txt
cat outputfile.txt
出力
admin:~/environment/hands-on-serverless-2 $ FUNCTION_NAME="translate-function-2" \
> && echo ${FUNCTION_NAME}
translate-function-2
admin:~/environment/hands-on-serverless-2 $
admin:~/environment/hands-on-serverless-2 $ # イベントの作成
admin:~/environment/hands-on-serverless-2 $ EVENT=$(cat << EOF
> {
> "key1": "value1",
> "key2": "value2",
> "key3": "value3"
> }
> EOF
> ) \
> && echo ${EVENT}
{ "key1": "value1", "key2": "value2", "key3": "value3" }
admin:~/environment/hands-on-serverless-2 $
admin:~/environment/hands-on-serverless-2 $ # JSONフォーマットの確認
admin:~/environment/hands-on-serverless-2 $ echo ${EVENT} | python -m json.tool
{
"key1": "value1",
"key2": "value2",
"key3": "value3"
}
admin:~/environment/hands-on-serverless-2 $
admin:~/environment/hands-on-serverless-2 $ # テスト実行
admin:~/environment/hands-on-serverless-2 $ aws lambda invoke \
> --function-name ${FUNCTION_NAME} \
> --payload `echo ${EVENT} | base64 -w 0` \
> outputfile.txt
{
"StatusCode": 200,
"ExecutedVersion": "$LATEST"
}
admin:~/environment/hands-on-serverless-2 $
admin:~/environment/hands-on-serverless-2 $ cat outputfile.txt
{"statusCode": 200, "body": "\"Hello Hands on world!\""}
ログの確認
コマンド
# 最新のログストリームを取得
LATEST_LOG_STREAM=$(
aws logs describe-log-streams \
--log-group-name /aws/lambda/${FUNCTION_NAME} \
--order-by LastEventTime \
--descending \
--limit 1 \
--query 'logStreams[0].logStreamName' \
--output text
) \
&& echo ${LATEST_LOG_STREAM}
# ログの確認
aws logs get-log-events \
--log-group-name /aws/lambda/${FUNCTION_NAME} \
--log-stream-name ${LATEST_LOG_STREAM} \
--no-cli-pager
出力
admin:~/environment/hands-on-serverless-2 $ # 最新のログストリームを取得
admin:~/environment/hands-on-serverless-2 $ LATEST_LOG_STREAM=$(
> aws logs describe-log-streams \
> --log-group-name /aws/lambda/${FUNCTION_NAME} \
> --order-by LastEventTime \
> --descending \
> --limit 1 \
> --query 'logStreams[0].logStreamName' \
> --output text
> ) \
> && echo ${LATEST_LOG_STREAM}
2024/09/21/[$LATEST]2d58743780da4bdeb6b0f54309591ba5
admin:~/environment/hands-on-serverless-2 $
admin:~/environment/hands-on-serverless-2 $ # ログの確認
admin:~/environment/hands-on-serverless-2 $ aws logs get-log-events \
> --log-group-name /aws/lambda/${FUNCTION_NAME} \
> --log-stream-name ${LATEST_LOG_STREAM} \
> --no-cli-pager
{
"events": [
{
"timestamp": 1726889412091,
"message": "INIT_START Runtime Version: python:3.8.v53\tRuntime Version ARN: arn:aws:lambda:ap-northeast-1::runtime:124ac49f727c31fa5ba440a749eef8274ca2beb4a0a8f107a0d8c69632c715a7\n",
"ingestionTime": 1726889420747
},
{
"timestamp": 1726889412230,
"message": "START RequestId: d83323b8-6503-465c-a490-5794cd7bb5ab Version: $LATEST\n",
"ingestionTime": 1726889420747
},
{
"timestamp": 1726889412231,
"message": "[INFO]\t2024-09-21T03:30:12.231Z\td83323b8-6503-465c-a490-5794cd7bb5ab\t{'key1': 'value1', 'key2': 'value2', 'key3': 'value3'}\n",
"ingestionTime": 1726889420747
},
{
"timestamp": 1726889412232,
"message": "END RequestId: d83323b8-6503-465c-a490-5794cd7bb5ab\n",
"ingestionTime": 1726889420747
},
{
"timestamp": 1726889412232,
"message": "REPORT RequestId: d83323b8-6503-465c-a490-5794cd7bb5ab\tDuration: 1.97 ms\tBilled Duration: 2 ms\tMemory Size: 256 MB\tMax Memory Used: 39 MB\tInit Duration: 139.04 ms\t\n",
"ingestionTime": 1726889420747
}
],
"nextForwardToken": "f/38510920768226143949026995082048256680616396673389297668/s",
"nextBackwardToken": "b/38510920765081738876034177219091720404172977701046059008/s"
}
05 SAM で Lambda 関数を作成する ②
translate-function.py修正
コマンド
cat << EOF > translate-function/translate-function.py
import json
import boto3
translate = boto3.client('translate')
def lambda_handler(event, context):
input_text = "こんにちは"
response = translate.translate_text(
Text=input_text,
SourceLanguageCode='ja',
TargetLanguageCode='en'
)
output_text = response.get('TranslatedText')
return {
'statusCode': 200,
'body': json.dumps({
'output_text': output_text
})
}
EOF
出力
admin:~/environment/hands-on-serverless-2 $ cat << EOF > translate-function/translate-function.py
> import json
> import boto3
>
> translate = boto3.client('translate')
>
> def lambda_handler(event, context):
>
> input_text = "こんにちは"
>
> response = translate.translate_text(
> Text=input_text,
> SourceLanguageCode='ja',
> TargetLanguageCode='en'
> )
>
> output_text = response.get('TranslatedText')
>
> return {
> 'statusCode': 200,
> 'body': json.dumps({
> 'output_text': output_text
> })
> }
> EOF
template.yaml修正
コマンド
cat << EOF > template.yaml
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: AWS Hands-on for Beginners - Serverless 2
Resources:
TranslateLambda:
Type: AWS::Serverless::Function
Properties:
FunctionName: translate-function-2
CodeUri: ./translate-function
Handler: translate-function.lambda_handler
Runtime: python3.8
Timeout: 5
MemorySize: 256
Policies:
- TranslateFullAccess
EOF
出力
admin:~/environment/hands-on-serverless-2 $ cat << EOF > template.yaml
> AWSTemplateFormatVersion: '2010-09-09'
> Transform: AWS::Serverless-2016-10-31
> Description: AWS Hands-on for Beginners - Serverless 2
> Resources:
> TranslateLambda:
> Type: AWS::Serverless::Function
> Properties:
> FunctionName: translate-function-2
> CodeUri: ./translate-function
> Handler: translate-function.lambda_handler
> Runtime: python3.8
> Timeout: 5
> MemorySize: 256
> Policies:
> - TranslateFullAccess
> EOF
パッケージング
コマンド
# パッケージング
aws cloudformation package \
--template-file template.yaml \
--s3-bucket ${S3_BUCKET_NAME} \
--output-template-file packaged-template.yaml
出力
admin:~/environment/hands-on-serverless-2 $ # パッケージング
admin:~/environment/hands-on-serverless-2 $ aws cloudformation package \
> --template-file template.yaml \
> --s3-bucket ${S3_BUCKET_NAME} \
> --output-template-file packaged-template.yaml
Uploading to 44a6c97b5e9e64448acb91573299c6ba 392 / 392.0 (100.00%)
Successfully packaged artifacts and wrote output template to file packaged-template.yaml.
Execute the following command to deploy the packaged template
aws cloudformation deploy --template-file /home/ec2-user/environment/hands-on-serverless-2/packaged-template.yaml --stack-name <YOUR STACK NAME>
デプロイ
コマンド
# デプロイ
aws cloudformation deploy \
--template-file ./packaged-template.yaml \
--stack-name ${STACK_NAME} \
--capabilities CAPABILITY_IAM
出力
admin:~/environment/hands-on-serverless-2 $ # デプロイ
admin:~/environment/hands-on-serverless-2 $ aws cloudformation deploy \
> --template-file ./packaged-template.yaml \
> --stack-name ${STACK_NAME} \
> --capabilities CAPABILITY_IAM
Waiting for changeset to be created..
Waiting for stack create/update to complete
Successfully created/updated stack - hands-on-serverless-2
リソース一覧確認
コマンド
aws cloudformation describe-stack-resources \
--stack-name ${STACK_NAME} \
--no-cli-pager
出力
admin:~/environment/hands-on-serverless-2 $ aws cloudformation describe-stack-resources \
> --stack-name ${STACK_NAME} \
> --no-cli-pager
{
"StackResources": [
{
"StackName": "hands-on-serverless-2",
"StackId": "arn:aws:cloudformation:ap-northeast-1:999999999999:stack/hands-on-serverless-2/4fe2cc10-77c9-11ef-b579-06c2182e3129",
"LogicalResourceId": "TranslateLambda",
"PhysicalResourceId": "translate-function-2",
"ResourceType": "AWS::Lambda::Function",
"Timestamp": "2024-09-21T03:36:02.138000+00:00",
"ResourceStatus": "UPDATE_COMPLETE",
"DriftInformation": {
"StackResourceDriftStatus": "NOT_CHECKED"
}
},
{
"StackName": "hands-on-serverless-2",
"StackId": "arn:aws:cloudformation:ap-northeast-1:999999999999:stack/hands-on-serverless-2/4fe2cc10-77c9-11ef-b579-06c2182e3129",
"LogicalResourceId": "TranslateLambdaRole",
"PhysicalResourceId": "hands-on-serverless-2-TranslateLambdaRole-42Dlsxf0UdTm",
"ResourceType": "AWS::IAM::Role",
"Timestamp": "2024-09-21T03:35:53.950000+00:00",
"ResourceStatus": "UPDATE_COMPLETE",
"DriftInformation": {
"StackResourceDriftStatus": "NOT_CHECKED"
}
}
]
}
Lambda関数確認
コマンド
aws lambda get-function \
--function-name ${FUNCTION_NAME} \
--no-cli-pager
出力
admin:~/environment/hands-on-serverless-2 $ aws lambda get-function \
> --function-name ${FUNCTION_NAME} \
> --no-cli-pager
{
"Configuration": {
"FunctionName": "translate-function-2",
"FunctionArn": "arn:aws:lambda:ap-northeast-1:999999999999:function:translate-function-2",
"Runtime": "python3.8",
"Role": "arn:aws:iam::999999999999:role/hands-on-serverless-2-TranslateLambdaRole-42Dlsxf0UdTm",
"Handler": "translate-function.lambda_handler",
"CodeSize": 392,
"Description": "",
"Timeout": 5,
"MemorySize": 256,
"LastModified": "2024-09-21T03:35:56.000+0000",
"CodeSha256": "WLi5VOJXE3DVBonupV/4oeRivAA8CP8Hg6VziUwFGT0=",
"Version": "$LATEST",
"TracingConfig": {
"Mode": "PassThrough"
},
"RevisionId": "859cc5bd-fda8-48f1-8e2b-88f66b058646",
"State": "Active",
"LastUpdateStatus": "Successful",
"PackageType": "Zip",
"Architectures": [
"x86_64"
],
"EphemeralStorage": {
"Size": 512
},
"SnapStart": {
"ApplyOn": "None",
"OptimizationStatus": "Off"
},
"RuntimeVersionConfig": {
"RuntimeVersionArn": "arn:aws:lambda:ap-northeast-1::runtime:124ac49f727c31fa5ba440a749eef8274ca2beb4a0a8f107a0d8c69632c715a7"
},
"LoggingConfig": {
"LogFormat": "Text",
"LogGroup": "/aws/lambda/translate-function-2"
}
},
"Code": {
"RepositoryType": "S3",
"Location": "https://awslambda-ap-ne-1-tasks.s3.ap-northeast-1.amazonaws.com/snapshots/999999999999/translate-function-2-baa841b6-43d7-4973-9e29-98116b67031e?versionId=wI3s6o8C1fXpwBfTdBJcfkyKv_KKyMh4&X-Amz-Security-Token=IQoJb3JpZ2luX2VjEEsaDmFwLW5vcnRoZWFzdC0xIkgwRgIhAKgozOj84fBl1hId8aD2wG2GPpJauZJwA%2Bod5dccKpC9AiEA9xCI7uNIZ7%2FA9D1PyTDjQL8lyYRQSKdbWqibpcEPB2oqyAUIhP%2F%2F%2F%2F%2F%2F%2F%2F%2F%2FARAEGgw5MTk5ODA5MjUxMzkiDCqRZXTQbJip5qf79CqcBXui8v516NtXFzdXu9e1DGifhWlmNd7arJ85Qqe%2Bk2X6CbP09X%2B6sY99XzSxpvHXnJf6yXsdsQsDLUgPqzdqSxZpE2kYCONPYqmkFfSzev%2Bu%2FSJYfU29W0jKsVa1Lo2354MDft0JphFhEhbH4Ll2CB5jvhP178zS3YDP%2FMwhi9jP2JeFAYan2XltSHawUgPCsvF1ZZKQVJxZ7Mc3%2F2VhYD29g4UKhHo62YLLv%2FPd2NmjD1t3E8rNQxhNq94S7w33Arex9RyUTiMF1nKGMO5E%2F2ffwfNqkFZxJ9NuO3IcNPzl0ktW32kRfvtnmVn2EUkYBf7abbzbMyIXzuJW8XWhLRhlUqGslwbO0r2UvlpoQcdpzaTh%2BYZQUQIdZ8fE%2F8Y%2B6bAz7FkRxAAId3cljGMnMYCbpaPuzIUb5HAwxvbnR%2Bz8OUV0%2F3hXEBrMQPNBiHUvaoIzcJBDeqLiqlbuiVztD9OUtNnTLTXwl536NRsW1TImA9Zor0GkMsSoYC5OBoHgLqqcTwCKWFMZ0wEBV7gbBHxlHndJKHYgVtvnQzppoJj8qbZCYmbw1wyjZGDVugfOMGg%2F06C%2BBnV%2B6%2FotGHhrBoeeAk4eyP4GpeVFQYpea5LEKbnOTXlC9EJAtNZIhvfKjF5QaeTCumIBbyLI9lAxmnbk4UleC9yUjIxqdd4BmIi0KVM3bEUW0pe7WWqD4wZxlppjHVN1McS5XlCAIEbPwrfmwRtYMIpH%2B3tjnygYwvTvCd6LKk1w91PJu%2BMCe4H5DwqDJmwzvdS3dIxMa9aPwC3sn4VnxP5QDsEknyWpQme9gYlHOOKslQHJRTjcO6nHsZzNZWDLDsdN0oG2sWLBteC7ZaaDIpBC7y6nAtBR%2B4wO7vfv5N3Qek2P4VHgMMLsuLcGOrABEu9O7Xi6m8iTJUaoNdTcmWNEsd76%2Bm55zp1fszoyd52t25kKCyp6vZO5Zy%2F6MtpzUsfwqbSZKzjiaQSWgOPsaIeYX5lCNR95JB87XrkgTcOw67PkSTpTZMJsQcTNNdcee%2B4QEoMZ3ciFOb32YRI5J5lA6bKQv5W9CmnEd97N6AvCm%2FGft6EANzMm2h3LfhAAzy2xasyTpzjyPJRPMI6YbjbT5VNHjr6aXSyeVi6vw20%3D&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Date=20240921T034042Z&X-Amz-SignedHeaders=host&X-Amz-Expires=600&X-Amz-Credential=ASIA5MMZC4DJSHAE474X%2F20240921%2Fap-northeast-1%2Fs3%2Faws4_request&X-Amz-Signature=4c7d3b4d90f9a47041f2eab2f2364a3c8c0bf444ad97bffd469cc433597bf83d"
},
"Tags": {
"aws:cloudformation:stack-name": "hands-on-serverless-2",
"lambda:createdBy": "SAM",
"aws:cloudformation:stack-id": "arn:aws:cloudformation:ap-northeast-1:999999999999:stack/hands-on-serverless-2/4fe2cc10-77c9-11ef-b579-06c2182e3129",
"aws:cloudformation:logical-id": "TranslateLambda"
}
}
Lambda関数のテスト
実行
コマンド
FUNCTION_NAME="translate-function-2" \
&& echo ${FUNCTION_NAME}
# イベントの作成
EVENT=$(cat << EOF
{
"key1": "value1",
"key2": "value2",
"key3": "value3"
}
EOF
) \
&& echo ${EVENT}
# JSONフォーマットの確認
echo ${EVENT} | python -m json.tool
# テスト実行
aws lambda invoke \
--function-name ${FUNCTION_NAME} \
--payload `echo ${EVENT} | base64 -w 0` \
outputfile.txt
cat outputfile.txt
出力
admin:~/environment/hands-on-serverless-2 $ FUNCTION_NAME="translate-function-2" \
> && echo ${FUNCTION_NAME}
translate-function-2
admin:~/environment/hands-on-serverless-2 $
admin:~/environment/hands-on-serverless-2 $ # イベントの作成
admin:~/environment/hands-on-serverless-2 $ EVENT=$(cat << EOF
> {
> "key1": "value1",
> "key2": "value2",
> "key3": "value3"
> }
> EOF
> ) \
> && echo ${EVENT}
{ "key1": "value1", "key2": "value2", "key3": "value3" }
admin:~/environment/hands-on-serverless-2 $
admin:~/environment/hands-on-serverless-2 $ # JSONフォーマットの確認
admin:~/environment/hands-on-serverless-2 $ echo ${EVENT} | python -m json.tool
{
"key1": "value1",
"key2": "value2",
"key3": "value3"
}
admin:~/environment/hands-on-serverless-2 $
admin:~/environment/hands-on-serverless-2 $ # テスト実行
admin:~/environment/hands-on-serverless-2 $ aws lambda invoke \
> --function-name ${FUNCTION_NAME} \
> --payload `echo ${EVENT} | base64 -w 0` \
> outputfile.txt
{
"StatusCode": 200,
"ExecutedVersion": "$LATEST"
}
admin:~/environment/hands-on-serverless-2 $
admin:~/environment/hands-on-serverless-2 $ cat outputfile.txt
{"statusCode": 200, "body": "{\"output_text\": \"Hi\"}"}
ログの確認
コマンド
# 最新のログストリームを取得
LATEST_LOG_STREAM=$(
aws logs describe-log-streams \
--log-group-name /aws/lambda/${FUNCTION_NAME} \
--order-by LastEventTime \
--descending \
--limit 1 \
--query 'logStreams[0].logStreamName' \
--output text
) \
&& echo ${LATEST_LOG_STREAM}
# ログの確認
aws logs get-log-events \
--log-group-name /aws/lambda/${FUNCTION_NAME} \
--log-stream-name ${LATEST_LOG_STREAM} \
--no-cli-pager
出力
admin:~/environment/hands-on-serverless-2 $ # 最新のログストリームを取得
admin:~/environment/hands-on-serverless-2 $ LATEST_LOG_STREAM=$(
> aws logs describe-log-streams \
> --log-group-name /aws/lambda/${FUNCTION_NAME} \
> --order-by LastEventTime \
> --descending \
> --limit 1 \
> --query 'logStreams[0].logStreamName' \
> --output text
> ) \
> && echo ${LATEST_LOG_STREAM}
2024/09/21/[$LATEST]fc81690f661a46189f7cef561d26b48e
admin:~/environment/hands-on-serverless-2 $
admin:~/environment/hands-on-serverless-2 $ # ログの確認
admin:~/environment/hands-on-serverless-2 $ aws logs get-log-events \
> --log-group-name /aws/lambda/${FUNCTION_NAME} \
> --log-stream-name ${LATEST_LOG_STREAM} \
> --no-cli-pager
{
"events": [
{
"timestamp": 1726890098322,
"message": "INIT_START Runtime Version: python:3.8.v53\tRuntime Version ARN: arn:aws:lambda:ap-northeast-1::runtime:124ac49f727c31fa5ba440a749eef8274ca2beb4a0a8f107a0d8c69632c715a7\n",
"ingestionTime": 1726890106652
},
{
"timestamp": 1726890098738,
"message": "START RequestId: b3b0658a-cab8-47ad-8297-17b5ec4a7e46 Version: $LATEST\n",
"ingestionTime": 1726890106652
},
{
"timestamp": 1726890098911,
"message": "END RequestId: b3b0658a-cab8-47ad-8297-17b5ec4a7e46\n",
"ingestionTime": 1726890106652
},
{
"timestamp": 1726890098911,
"message": "REPORT RequestId: b3b0658a-cab8-47ad-8297-17b5ec4a7e46\tDuration: 172.36 ms\tBilled Duration: 173 ms\tMemory Size: 256 MB\tMax Memory Used: 70 MB\tInit Duration: 415.36 ms\t\n",
"ingestionTime": 1726890106652
}
],
"nextForwardToken": "f/38510936081679556130836764117862224016226608771726835715/s",
"nextBackwardToken": "b/38510936068544417208902227087497685953636723844704370688/s"
}
06 SAM で API Gateway のリソースを作成し、Lambda 関数と連携させる
translate-function.py修正
コマンド
cat << EOF > translate-function/translate-function.py
import json
import boto3
translate = boto3.client(service_name='translate')
def lambda_handler(event, context):
input_text = event['queryStringParameters']['input_text']
response = translate.translate_text(
Text=input_text,
SourceLanguageCode="ja",
TargetLanguageCode="en"
)
output_text = response.get('TranslatedText')
return {
'statusCode': 200,
'body': json.dumps({
'output_text': output_text
}),
'isBase64Encoded': False,
'headers': {}
}
EOF
出力
admin:~/environment/hands-on-serverless-2 $ cat << EOF > translate-function/translate-function.py
> import json
> import boto3
>
> translate = boto3.client(service_name='translate')
>
> def lambda_handler(event, context):
>
> input_text = event['queryStringParameters']['input_text']
>
> response = translate.translate_text(
> Text=input_text,
> SourceLanguageCode="ja",
> TargetLanguageCode="en"
> )
>
> output_text = response.get('TranslatedText')
>
> return {
> 'statusCode': 200,
> 'body': json.dumps({
> 'output_text': output_text
> }),
> 'isBase64Encoded': False,
> 'headers': {}
> }
> EOF
template.yaml修正
コマンド
cat << EOF > template.yaml
Transform: AWS::Serverless-2016-10-31
Description: AWS Hands-on for Beginners - Serverless 2
Resources:
TranslateLambda:
Type: AWS::Serverless::Function
Properties:
FunctionName: translate-function-2
CodeUri: ./translate-function
Handler: translate-function.lambda_handler
Runtime: python3.8
Timeout: 5
MemorySize: 256
Policies:
- TranslateFullAccess
Events:
GetApi:
Type: Api
Properties:
Path: /translate
Method: get
RestApiId: !Ref TranslateAPI
TranslateAPI:
Type: AWS::Serverless::Api
Properties:
Name: translate-api-2
StageName: dev
EndpointConfiguration: REGIONAL
EOF
出力
admin:~/environment/hands-on-serverless-2 $ cat << EOF > template.yaml
> Transform: AWS::Serverless-2016-10-31
> Description: AWS Hands-on for Beginners - Serverless 2
> Resources:
> TranslateLambda:
> Type: AWS::Serverless::Function
> Properties:
> FunctionName: translate-function-2
> CodeUri: ./translate-function
> Handler: translate-function.lambda_handler
> Runtime: python3.8
> Timeout: 5
> MemorySize: 256
> Policies:
> - TranslateFullAccess
> Events:
> GetApi:
> Type: Api
> Properties:
> Path: /translate
> Method: get
> RestApiId: !Ref TranslateAPI
> TranslateAPI:
> Type: AWS::Serverless::Api
> Properties:
> Name: translate-api-2
> StageName: dev
> EndpointConfiguration: REGIONAL
> EOF
パッケージング
コマンド
# パッケージング
aws cloudformation package \
--template-file template.yaml \
--s3-bucket ${S3_BUCKET_NAME} \
--output-template-file packaged-template.yaml
出力
admin:~/environment/hands-on-serverless-2 $ # パッケージング
admin:~/environment/hands-on-serverless-2 $ aws cloudformation package \
> --template-file template.yaml \
> --s3-bucket ${S3_BUCKET_NAME} \
> --output-template-file packaged-template.yaml
Uploading to 5e32642d09e1b88190f79969845b9d2b 434 / 434.0 (100.00%)
Successfully packaged artifacts and wrote output template to file packaged-template.yaml.
Execute the following command to deploy the packaged template
aws cloudformation deploy --template-file /home/ec2-user/environment/hands-on-serverless-2/packaged-template.yaml --stack-name <YOUR STACK NAME>
デプロイ
コマンド
# デプロイ
aws cloudformation deploy \
--template-file ./packaged-template.yaml \
--stack-name ${STACK_NAME} \
--capabilities CAPABILITY_IAM
出力
admin:~/environment/hands-on-serverless-2 $ # デプロイ
admin:~/environment/hands-on-serverless-2 $ aws cloudformation deploy \
> --template-file ./packaged-template.yaml \
> --stack-name ${STACK_NAME} \
> --capabilities CAPABILITY_IAM
Waiting for changeset to be created..
Waiting for stack create/update to complete
Successfully created/updated stack - hands-on-serverless-2
リソース一覧確認
コマンド
aws cloudformation describe-stack-resources \
--stack-name ${STACK_NAME} \
--no-cli-pager
出力
admin:~/environment/hands-on-serverless-2 $ aws cloudformation describe-stack-resources \
> --stack-name ${STACK_NAME} \
> --no-cli-pager
{
"StackResources": [
{
"StackName": "hands-on-serverless-2",
"StackId": "arn:aws:cloudformation:ap-northeast-1:999999999999:stack/hands-on-serverless-2/4fe2cc10-77c9-11ef-b579-06c2182e3129",
"LogicalResourceId": "TranslateAPI",
"PhysicalResourceId": "cmk4jfofx5",
"ResourceType": "AWS::ApiGateway::RestApi",
"Timestamp": "2024-09-21T03:47:14.753000+00:00",
"ResourceStatus": "CREATE_COMPLETE",
"DriftInformation": {
"StackResourceDriftStatus": "NOT_CHECKED"
}
},
{
"StackName": "hands-on-serverless-2",
"StackId": "arn:aws:cloudformation:ap-northeast-1:999999999999:stack/hands-on-serverless-2/4fe2cc10-77c9-11ef-b579-06c2182e3129",
"LogicalResourceId": "TranslateAPIDeployment6ac74e42c4",
"PhysicalResourceId": "4v4vpc",
"ResourceType": "AWS::ApiGateway::Deployment",
"Timestamp": "2024-09-21T03:47:17.179000+00:00",
"ResourceStatus": "CREATE_COMPLETE",
"DriftInformation": {
"StackResourceDriftStatus": "NOT_CHECKED"
}
},
{
"StackName": "hands-on-serverless-2",
"StackId": "arn:aws:cloudformation:ap-northeast-1:999999999999:stack/hands-on-serverless-2/4fe2cc10-77c9-11ef-b579-06c2182e3129",
"LogicalResourceId": "TranslateAPIdevStage",
"PhysicalResourceId": "dev",
"ResourceType": "AWS::ApiGateway::Stage",
"Timestamp": "2024-09-21T03:47:20.768000+00:00",
"ResourceStatus": "CREATE_COMPLETE",
"DriftInformation": {
"StackResourceDriftStatus": "NOT_CHECKED"
}
},
{
"StackName": "hands-on-serverless-2",
"StackId": "arn:aws:cloudformation:ap-northeast-1:999999999999:stack/hands-on-serverless-2/4fe2cc10-77c9-11ef-b579-06c2182e3129",
"LogicalResourceId": "TranslateLambda",
"PhysicalResourceId": "translate-function-2",
"ResourceType": "AWS::Lambda::Function",
"Timestamp": "2024-09-21T03:47:16.241000+00:00",
"ResourceStatus": "UPDATE_COMPLETE",
"DriftInformation": {
"StackResourceDriftStatus": "NOT_CHECKED"
}
},
{
"StackName": "hands-on-serverless-2",
"StackId": "arn:aws:cloudformation:ap-northeast-1:999999999999:stack/hands-on-serverless-2/4fe2cc10-77c9-11ef-b579-06c2182e3129",
"LogicalResourceId": "TranslateLambdaGetApiPermissiondev",
"PhysicalResourceId": "hands-on-serverless-2-TranslateLambdaGetApiPermissiondev-lsmB541cYjAI",
"ResourceType": "AWS::Lambda::Permission",
"Timestamp": "2024-09-21T03:47:16.630000+00:00",
"ResourceStatus": "CREATE_COMPLETE",
"DriftInformation": {
"StackResourceDriftStatus": "NOT_CHECKED"
}
},
{
"StackName": "hands-on-serverless-2",
"StackId": "arn:aws:cloudformation:ap-northeast-1:999999999999:stack/hands-on-serverless-2/4fe2cc10-77c9-11ef-b579-06c2182e3129",
"LogicalResourceId": "TranslateLambdaRole",
"PhysicalResourceId": "hands-on-serverless-2-TranslateLambdaRole-42Dlsxf0UdTm",
"ResourceType": "AWS::IAM::Role",
"Timestamp": "2024-09-21T03:35:53.950000+00:00",
"ResourceStatus": "UPDATE_COMPLETE",
"DriftInformation": {
"StackResourceDriftStatus": "NOT_CHECKED"
}
}
]
}
アクセス確認
コマンド
# API GatewayのREST API ID
LOGICAL_RESOURCE_ID="TranslateAPI" \
&& echo ${LOGICAL_RESOURCE_ID}
RESTAPI_ID=$(
aws cloudformation describe-stack-resources \
--stack-name ${STACK_NAME} \
--logical-resource-id ${LOGICAL_RESOURCE_ID} \
--query "StackResources[*].PhysicalResourceId" \
--output text
) \
&& echo ${RESTAPI_ID}
# リージョン
REGION="ap-northeast-1" \
&& echo ${REGION}
# ステージ
STAGE="dev" \
&& echo ${STAGE}
# API PATH指定
API_PATH="translate" \
&& echo ${API_PATH}
# URLエンコード
encoded_query=$(python3 -c 'import urllib.parse; print(urllib.parse.quote("こんにちは"))') \
&& echo ${encoded_query}
# アクセス確認
curl https://${RESTAPI_ID}.execute-api.${REGION}.amazonaws.com/${STAGE}/${API_PATH}?input_text=${encoded_query}
出力
admin:~/environment/hands-on-serverless-2 $ # API GatewayのREST API ID
admin:~/environment/hands-on-serverless-2 $ LOGICAL_RESOURCE_ID="TranslateAPI" \
> && echo ${LOGICAL_RESOURCE_ID}
TranslateAPI
admin:~/environment/hands-on-serverless-2 $
admin:~/environment/hands-on-serverless-2 $ RESTAPI_ID=$(
> aws cloudformation describe-stack-resources \
> --stack-name ${STACK_NAME} \
> --logical-resource-id ${LOGICAL_RESOURCE_ID} \
> --query "StackResources[*].PhysicalResourceId" \
> --output text
> ) \
> && echo ${RESTAPI_ID}
cmk4jfofx5
admin:~/environment/hands-on-serverless-2 $
admin:~/environment/hands-on-serverless-2 $ # リージョン
admin:~/environment/hands-on-serverless-2 $ REGION="ap-northeast-1" \
> && echo ${REGION}
ap-northeast-1
admin:~/environment/hands-on-serverless-2 $
admin:~/environment/hands-on-serverless-2 $ # ステージ
admin:~/environment/hands-on-serverless-2 $ STAGE="dev" \
> && echo ${STAGE}
dev
admin:~/environment/hands-on-serverless-2 $
admin:~/environment/hands-on-serverless-2 $ # API PATH指定
admin:~/environment/hands-on-serverless-2 $ API_PATH="translate" \
> && echo ${API_PATH}
translate
admin:~/environment/hands-on-serverless-2 $
admin:~/environment/hands-on-serverless-2 $ # URLエンコード
admin:~/environment/hands-on-serverless-2 $ encoded_query=$(python3 -c 'import urllib.parse; print(urllib.parse.quote(" こんにちは"))') \
> && echo ${encoded_query}
%E3%81%93%E3%82%93%E3%81%AB%E3%81%A1%E3%81%AF
admin:~/environment/hands-on-serverless-2 $
admin:~/environment/hands-on-serverless-2 $ # アクセス確認
admin:~/environment/hands-on-serverless-2 $ curl https://${RESTAPI_ID}.execute-api.${REGION}.amazonaws.com/${STAGE}/${API_PATH}?input_text=${encoded_query}
{"output_text": "Hi"}
07 SAM で DynamoDB TBL を作成し、Lambda 関数を連携させる
translate-function.py修正
コマンド
cat << EOF > translate-function/translate-function.py
import json
import boto3
import datetime
translate = boto3.client(service_name='translate')
dynamodb_translate_history_tbl = boto3.resource('dynamodb').Table('translate-history-2')
def lambda_handler(event, context):
input_text = event['queryStringParameters']['input_text']
response = translate.translate_text(
Text=input_text,
SourceLanguageCode="ja",
TargetLanguageCode="en"
)
output_text = response.get('TranslatedText')
dynamodb_translate_history_tbl.put_item(
Item = {
"timestamp": datetime.datetime.now().strftime("%Y%m%d%H%M%S"),
"input": input_text,
"output": output_text
}
)
return {
'statusCode': 200,
'body': json.dumps({
'output_text': output_text
}),
'isBase64Encoded': False,
'headers': {}
}
EOF
出力
admin:~/environment/hands-on-serverless-2 $ cat << EOF > translate-function/translate-function.py
> import json
> import boto3
> import datetime
>
> translate = boto3.client(service_name='translate')
>
> dynamodb_translate_history_tbl = boto3.resource('dynamodb').Table('translate-history-2')
>
> def lambda_handler(event, context):
>
> input_text = event['queryStringParameters']['input_text']
>
> response = translate.translate_text(
> Text=input_text,
> SourceLanguageCode="ja",
> TargetLanguageCode="en"
> )
>
> output_text = response.get('TranslatedText')
>
> dynamodb_translate_history_tbl.put_item(
> Item = {
> "timestamp": datetime.datetime.now().strftime("%Y%m%d%H%M%S"),
> "input": input_text,
> "output": output_text
> }
> )
>
> return {
> 'statusCode': 200,
> 'body': json.dumps({
> 'output_text': output_text
> }),
> 'isBase64Encoded': False,
> 'headers': {}
> }
> EOF
template.yaml修正
コマンド
cat << EOF > template.yaml
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: AWS Hands-on for Beginners - Serverless 2
Resources:
TranslateLambda:
Type: AWS::Serverless::Function
Properties:
FunctionName: translate-function-2
CodeUri: ./translate-function
Handler: translate-function.lambda_handler
Runtime: python3.8
Timeout: 5
MemorySize: 256
Policies:
- TranslateFullAccess
- AmazonDynamoDBFullAccess
Events:
GetApi:
Type: Api
Properties:
Path: /translate
Method: get
RestApiId: !Ref TranslateAPI
TranslateAPI:
Type: AWS::Serverless::Api
Properties:
Name: translate-api-2
StageName: dev
EndpointConfiguration: REGIONAL
TranslateDynamoDbTbl:
Type: AWS::Serverless::SimpleTable
Properties:
TableName: translate-history-2
PrimaryKey:
Name: timestamp
Type: String
ProvisionedThroughput:
ReadCapacityUnits: 1
WriteCapacityUnits: 1
EOF
出力
admin:~/environment/hands-on-serverless-2 $ cat << EOF > template.yaml
> AWSTemplateFormatVersion: '2010-09-09'
> Transform: AWS::Serverless-2016-10-31
> Description: AWS Hands-on for Beginners - Serverless 2
> Resources:
> TranslateLambda:
> Type: AWS::Serverless::Function
> Properties:
> FunctionName: translate-function-2
> CodeUri: ./translate-function
> Handler: translate-function.lambda_handler
> Runtime: python3.8
> Timeout: 5
> MemorySize: 256
> Policies:
> - TranslateFullAccess
> - AmazonDynamoDBFullAccess
> Events:
> GetApi:
> Type: Api
> Properties:
> Path: /translate
> Method: get
> RestApiId: !Ref TranslateAPI
> TranslateAPI:
> Type: AWS::Serverless::Api
> Properties:
> Name: translate-api-2
> StageName: dev
> EndpointConfiguration: REGIONAL
> TranslateDynamoDbTbl:
> Type: AWS::Serverless::SimpleTable
> Properties:
> TableName: translate-history-2
> PrimaryKey:
> Name: timestamp
> Type: String
> ProvisionedThroughput:
> ReadCapacityUnits: 1
> WriteCapacityUnits: 1
> EOF
パッケージング
コマンド
# パッケージング
aws cloudformation package \
--template-file template.yaml \
--s3-bucket ${S3_BUCKET_NAME} \
--output-template-file packaged-template.yaml
出力
admin:~/environment/hands-on-serverless-2 $ # パッケージング
admin:~/environment/hands-on-serverless-2 $ aws cloudformation package \
> --template-file template.yaml \
> --s3-bucket ${S3_BUCKET_NAME} \
> --output-template-file packaged-template.yaml
Uploading to 390d10c0b490f110117d9155f60cf0b0 552 / 552.0 (100.00%)
Successfully packaged artifacts and wrote output template to file packaged-template.yaml.
Execute the following command to deploy the packaged template
aws cloudformation deploy --template-file /home/ec2-user/environment/hands-on-serverless-2/packaged-template.yaml --stack-name <YOUR STACK NAME>
デプロイ
コマンド
# デプロイ
aws cloudformation deploy \
--template-file ./packaged-template.yaml \
--stack-name ${STACK_NAME} \
--capabilities CAPABILITY_IAM
出力
admin:~/environment/hands-on-serverless-2 $ # デプロイ
admin:~/environment/hands-on-serverless-2 $ aws cloudformation deploy \
> --template-file ./packaged-template.yaml \
> --stack-name ${STACK_NAME} \
> --capabilities CAPABILITY_IAM
Waiting for changeset to be created..
Waiting for stack create/update to complete
Successfully created/updated stack - hands-on-serverless-2
リソース一覧確認
コマンド
aws cloudformation describe-stack-resources \
--stack-name ${STACK_NAME} \
--no-cli-pager
出力
admin:~/environment/hands-on-serverless-2 $ aws cloudformation describe-stack-resources \
> --stack-name ${STACK_NAME} \
> --no-cli-pager
{
"StackResources": [
{
"StackName": "hands-on-serverless-2",
"StackId": "arn:aws:cloudformation:ap-northeast-1:999999999999:stack/hands-on-serverless-2/4fe2cc10-77c9-11ef-b579-06c2182e3129",
"LogicalResourceId": "TranslateAPI",
"PhysicalResourceId": "cmk4jfofx5",
"ResourceType": "AWS::ApiGateway::RestApi",
"Timestamp": "2024-09-21T03:47:14.753000+00:00",
"ResourceStatus": "CREATE_COMPLETE",
"DriftInformation": {
"StackResourceDriftStatus": "NOT_CHECKED"
}
},
{
"StackName": "hands-on-serverless-2",
"StackId": "arn:aws:cloudformation:ap-northeast-1:999999999999:stack/hands-on-serverless-2/4fe2cc10-77c9-11ef-b579-06c2182e3129",
"LogicalResourceId": "TranslateAPIDeployment6ac74e42c4",
"PhysicalResourceId": "4v4vpc",
"ResourceType": "AWS::ApiGateway::Deployment",
"Timestamp": "2024-09-21T03:47:17.179000+00:00",
"ResourceStatus": "CREATE_COMPLETE",
"DriftInformation": {
"StackResourceDriftStatus": "NOT_CHECKED"
}
},
{
"StackName": "hands-on-serverless-2",
"StackId": "arn:aws:cloudformation:ap-northeast-1:999999999999:stack/hands-on-serverless-2/4fe2cc10-77c9-11ef-b579-06c2182e3129",
"LogicalResourceId": "TranslateAPIdevStage",
"PhysicalResourceId": "dev",
"ResourceType": "AWS::ApiGateway::Stage",
"Timestamp": "2024-09-21T03:47:20.768000+00:00",
"ResourceStatus": "CREATE_COMPLETE",
"DriftInformation": {
"StackResourceDriftStatus": "NOT_CHECKED"
}
},
{
"StackName": "hands-on-serverless-2",
"StackId": "arn:aws:cloudformation:ap-northeast-1:999999999999:stack/hands-on-serverless-2/4fe2cc10-77c9-11ef-b579-06c2182e3129",
"LogicalResourceId": "TranslateDynamoDbTbl",
"PhysicalResourceId": "translate-history-2",
"ResourceType": "AWS::DynamoDB::Table",
"Timestamp": "2024-09-21T03:53:32.031000+00:00",
"ResourceStatus": "CREATE_COMPLETE",
"DriftInformation": {
"StackResourceDriftStatus": "NOT_CHECKED"
}
},
{
"StackName": "hands-on-serverless-2",
"StackId": "arn:aws:cloudformation:ap-northeast-1:999999999999:stack/hands-on-serverless-2/4fe2cc10-77c9-11ef-b579-06c2182e3129",
"LogicalResourceId": "TranslateLambda",
"PhysicalResourceId": "translate-function-2",
"ResourceType": "AWS::Lambda::Function",
"Timestamp": "2024-09-21T03:53:44.516000+00:00",
"ResourceStatus": "UPDATE_COMPLETE",
"DriftInformation": {
"StackResourceDriftStatus": "NOT_CHECKED"
}
},
{
"StackName": "hands-on-serverless-2",
"StackId": "arn:aws:cloudformation:ap-northeast-1:999999999999:stack/hands-on-serverless-2/4fe2cc10-77c9-11ef-b579-06c2182e3129",
"LogicalResourceId": "TranslateLambdaGetApiPermissiondev",
"PhysicalResourceId": "hands-on-serverless-2-TranslateLambdaGetApiPermissiondev-lsmB541cYjAI",
"ResourceType": "AWS::Lambda::Permission",
"Timestamp": "2024-09-21T03:47:16.630000+00:00",
"ResourceStatus": "CREATE_COMPLETE",
"DriftInformation": {
"StackResourceDriftStatus": "NOT_CHECKED"
}
},
{
"StackName": "hands-on-serverless-2",
"StackId": "arn:aws:cloudformation:ap-northeast-1:999999999999:stack/hands-on-serverless-2/4fe2cc10-77c9-11ef-b579-06c2182e3129",
"LogicalResourceId": "TranslateLambdaRole",
"PhysicalResourceId": "hands-on-serverless-2-TranslateLambdaRole-42Dlsxf0UdTm",
"ResourceType": "AWS::IAM::Role",
"Timestamp": "2024-09-21T03:53:36.371000+00:00",
"ResourceStatus": "UPDATE_COMPLETE",
"DriftInformation": {
"StackResourceDriftStatus": "NOT_CHECKED"
}
}
]
}
アクセス確認
コマンド
# API GatewayのREST API ID
LOGICAL_RESOURCE_ID="TranslateAPI" \
&& echo ${LOGICAL_RESOURCE_ID}
RESTAPI_ID=$(
aws cloudformation describe-stack-resources \
--stack-name ${STACK_NAME} \
--logical-resource-id ${LOGICAL_RESOURCE_ID} \
--query "StackResources[*].PhysicalResourceId" \
--output text
) \
&& echo ${RESTAPI_ID}
# リージョン
REGION="ap-northeast-1" \
&& echo ${REGION}
# ステージ
STAGE="dev" \
&& echo ${STAGE}
# API PATH指定
API_PATH="translate" \
&& echo ${API_PATH}
# URLエンコード
encoded_query=$(python3 -c 'import urllib.parse; print(urllib.parse.quote("ハンズオン完走しました!"))') \
&& echo ${encoded_query}
# アクセス確認
curl https://${RESTAPI_ID}.execute-api.${REGION}.amazonaws.com/${STAGE}/${API_PATH}?input_text=${encoded_query}
出力
admin:~/environment/hands-on-serverless-2 $ # API GatewayのREST API ID
admin:~/environment/hands-on-serverless-2 $ LOGICAL_RESOURCE_ID="TranslateAPI" \
> && echo ${LOGICAL_RESOURCE_ID}
TranslateAPI
admin:~/environment/hands-on-serverless-2 $
admin:~/environment/hands-on-serverless-2 $ RESTAPI_ID=$(
> aws cloudformation describe-stack-resources \
> --stack-name ${STACK_NAME} \
> --logical-resource-id ${LOGICAL_RESOURCE_ID} \
> --query "StackResources[*].PhysicalResourceId" \
> --output text
> ) \
> && echo ${RESTAPI_ID}
cmk4jfofx5
admin:~/environment/hands-on-serverless-2 $
admin:~/environment/hands-on-serverless-2 $ # リージョン
admin:~/environment/hands-on-serverless-2 $ REGION="ap-northeast-1" \
> && echo ${REGION}
ap-northeast-1
admin:~/environment/hands-on-serverless-2 $
admin:~/environment/hands-on-serverless-2 $ # ステージ
admin:~/environment/hands-on-serverless-2 $ STAGE="dev" \
> && echo ${STAGE}
dev
admin:~/environment/hands-on-serverless-2 $
admin:~/environment/hands-on-serverless-2 $ # API PATH指定
admin:~/environment/hands-on-serverless-2 $ API_PATH="translate" \
> && echo ${API_PATH}
translate
admin:~/environment/hands-on-serverless-2 $
admin:~/environment/hands-on-serverless-2 $ # URLエンコード
admin:~/environment/hands-on-serverless-2 $ encoded_query=$(python3 -c 'import urllib.parse; print(urllib.parse.quote(" ハンズオン完走しました!"))') \
> && echo ${encoded_query}
%E3%83%8F%E3%83%B3%E3%82%BA%E3%82%AA%E3%83%B3%E5%AE%8C%E8%B5%B0%E3%81%97%E3%81%BE%E3%81%97%E3%81%9F%21
admin:~/environment/hands-on-serverless-2 $
admin:~/environment/hands-on-serverless-2 $ # アクセス確認
admin:~/environment/hands-on-serverless-2 $ curl https://${RESTAPI_ID}.execute-api.${REGION}.amazonaws.com/${STAGE}/${API_PATH}?input_text=${encoded_query}
{"output_text": "I finished the hands-on race!"}
DynamoDB項目確認
コマンド
TABLE_NAME="translate-history-2" \
&& echo ${TABLE_NAME}
aws dynamodb scan \
--table-name ${TABLE_NAME} \
--no-cli-pager
出力
admin:~/environment/hands-on-serverless-2 $ TABLE_NAME="translate-history-2" \
> && echo ${TABLE_NAME}
translate-history-2
admin:~/environment/hands-on-serverless-2 $
admin:~/environment/hands-on-serverless-2 $ aws dynamodb scan \
> --table-name ${TABLE_NAME} \
> --no-cli-pager
{
"Items": [
{
"output": {
"S": "I finished the hands-on race!"
},
"input": {
"S": "ハンズオン完走しました!"
},
"timestamp": {
"S": "20240921035541"
}
}
],
"Count": 1,
"ScannedCount": 1,
"ConsumedCapacity": null
}
08 [Option] SAM CLI を使ってみる ①
SAM CLIインストール
SAM CLIはCloud9上にインストール済みだったため省略
バージョン確認
コマンド
sam --version
出力
admin:~/environment/hands-on-serverless-2 $ sam --version
SAM CLI, version 1.112.0
初期化
コマンド
sam init
出力
admin:~/environment/hands-on-serverless-2 $ 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.
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 - GraphQLApi Hello World Example
13 - Full Stack
14 - Lambda EFS example
15 - Hello World Example With Powertools for AWS Lambda
16 - DynamoDB Example
17 - Machine Learning
Template: 1
Use the most popular runtime and package type? (Python and zip) [y/N]:
Which runtime would you like to use?
1 - aot.dotnet7 (provided.al2)
2 - dotnet8
3 - dotnet6
4 - go1.x
5 - go (provided.al2)
6 - go (provided.al2023)
7 - graalvm.java11 (provided.al2)
8 - graalvm.java17 (provided.al2)
9 - java21
10 - java17
11 - java11
12 - java8.al2
13 - nodejs20.x
14 - nodejs18.x
15 - nodejs16.x
16 - python3.9
17 - python3.8
18 - python3.12
19 - python3.11
20 - python3.10
21 - ruby3.2
22 - rust (provided.al2)
23 - rust (provided.al2023)
Runtime: 17
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]:
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]:
Cloning from https://github.com/aws/aws-sam-cli-app-templates (process may take a moment)
-----------------------
Generating application:
-----------------------
Name: sam-app
Runtime: python3.8
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 CLI update available (1.124.0); (1.112.0 installed)
To download: https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-sam-cli-install.html
SAMテンプレートの事前検証
コマンド
cd sam-app
sam validate
出力
admin:~/environment/hands-on-serverless-2 $ cd sam-app
admin:~/environment/hands-on-serverless-2/sam-app $ sam validate
/home/ec2-user/environment/hands-on-serverless-2/sam-app/template.yaml is a valid SAM Template
ビルド
コマンド
sam build
出力
admin:~/environment/hands-on-serverless-2/sam-app $ sam build
Starting Build use cache
Manifest file is changed (new hash: 3298f13049d19cffaa37ca931dd4d421) or dependency folder
(.aws-sam/deps/32f89f1c-9246-4a7e-b63e-d52456c0382f) is missing for (HelloWorldFunction), downloading dependencies and
copying/building source
Building codeuri: /home/ec2-user/environment/hands-on-serverless-2/sam-app/hello_world runtime: python3.8 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
09 [Option] SAM CLI を使ってみる ②
AWS環境へデプロイ
AWS環境へデプロイ
コマンド
sam deploy --guided
出力
admin:~/environment/hands-on-serverless-2/sam-app $ 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 [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 has no authentication. 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:
Creating the required resources...
Successfully created!
Managed S3 bucket: aws-sam-cli-managed-default-samclisourcebucket-ktfpyr4rinwv
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/ec2-user/environment/hands-on-serverless-2/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
Uploading to sam-app/45916096b7662dd4d586fe710b60ddc6 570354 / 570354 (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-ktfpyr4rinwv
Capabilities : ["CAPABILITY_IAM"]
Parameter overrides : {}
Signing Profiles : {}
Initiating deployment
=====================
Uploading to sam-app/d3a404bc8c7a981f5668a316182fb5ca.template 1199 / 1199 (100.00%)
Waiting for changeset to be created..
CloudFormation stack changeset
---------------------------------------------------------------------------------------------------------------------
Operation LogicalResourceId ResourceType Replacement
---------------------------------------------------------------------------------------------------------------------
+ Add HelloWorldFunctionHelloWorl AWS::Lambda::Permission N/A
dPermissionProd
+ Add HelloWorldFunctionRole AWS::IAM::Role N/A
+ Add HelloWorldFunction AWS::Lambda::Function N/A
+ Add ServerlessRestApiDeployment AWS::ApiGateway::Deployment N/A
47fc2d5f9d
+ Add ServerlessRestApiProdStage AWS::ApiGateway::Stage N/A
+ Add ServerlessRestApi AWS::ApiGateway::RestApi N/A
---------------------------------------------------------------------------------------------------------------------
Changeset created successfully. arn:aws:cloudformation:ap-northeast-1:999999999999:changeSet/samcli-deploy1726892456/69844e11-1503-4ab7-a24d-32025917bb53
Previewing CloudFormation changeset before deployment
======================================================
Deploy this changeset? [y/N]: y
2024-09-21 04:21:51 - 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-app 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
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 ServerlessRestApiDeployment -
47fc2d5f9d
CREATE_IN_PROGRESS AWS::Lambda::Permission HelloWorldFunctionHelloWorl -
dPermissionProd
CREATE_COMPLETE AWS::Lambda::Function HelloWorldFunction -
CREATE_IN_PROGRESS AWS::Lambda::Permission HelloWorldFunctionHelloWorl Resource creation Initiated
dPermissionProd
CREATE_IN_PROGRESS AWS::ApiGateway::Deployment ServerlessRestApiDeployment Resource creation Initiated
47fc2d5f9d
CREATE_COMPLETE AWS::Lambda::Permission HelloWorldFunctionHelloWorl -
dPermissionProd
CREATE_COMPLETE AWS::ApiGateway::Deployment ServerlessRestApiDeployment -
47fc2d5f9d
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-app -
---------------------------------------------------------------------------------------------------------------------
CloudFormation outputs from deployed stack
---------------------------------------------------------------------------------------------------------------------
Outputs
---------------------------------------------------------------------------------------------------------------------
Key HelloWorldFunctionIamRole
Description Implicit IAM Role created for Hello World function
Value arn:aws:iam::999999999999:role/sam-app-HelloWorldFunctionRole-xOpzgzYhRboR
Key HelloWorldApi
Description API Gateway endpoint URL for Prod stage for Hello World function
Value https://utldn1vmd5.execute-api.ap-northeast-1.amazonaws.com/Prod/hello/
Key HelloWorldFunction
Description Hello World Lambda Function ARN
Value arn:aws:lambda:ap-northeast-1:999999999999:function:sam-app-HelloWorldFunction-QPWF3lu5WH5D
---------------------------------------------------------------------------------------------------------------------
Successfully created/updated stack - sam-app in ap-northeast-1
リソース一覧確認
コマンド
# 変数
SAM_STACK_NAME="sam-app" \
&& echo ${SAM_STACK_NAME}
aws cloudformation describe-stack-resources \
--stack-name ${SAM_STACK_NAME} \
--no-cli-pager
出力
admin:~/environment/hands-on-serverless-2/sam-app $ # 変数
admin:~/environment/hands-on-serverless-2/sam-app $ SAM_STACK_NAME="sam-app" \
> && echo ${SAM_STACK_NAME}
sam-app
admin:~/environment/hands-on-serverless-2/sam-app $
admin:~/environment/hands-on-serverless-2/sam-app $ aws cloudformation describe-stack-resources \
> --stack-name ${SAM_STACK_NAME} \
> --no-cli-pager
{
"StackResources": [
{
"StackName": "sam-app",
"StackId": "arn:aws:cloudformation:ap-northeast-1:999999999999:stack/sam-app/e63d61a0-77d0-11ef-a3d7-0e6278aaa549",
"LogicalResourceId": "HelloWorldFunction",
"PhysicalResourceId": "sam-app-HelloWorldFunction-QPWF3lu5WH5D",
"ResourceType": "AWS::Lambda::Function",
"Timestamp": "2024-09-21T04:22:20.846000+00:00",
"ResourceStatus": "CREATE_COMPLETE",
"DriftInformation": {
"StackResourceDriftStatus": "NOT_CHECKED"
}
},
{
"StackName": "sam-app",
"StackId": "arn:aws:cloudformation:ap-northeast-1:999999999999:stack/sam-app/e63d61a0-77d0-11ef-a3d7-0e6278aaa549",
"LogicalResourceId": "HelloWorldFunctionHelloWorldPermissionProd",
"PhysicalResourceId": "sam-app-HelloWorldFunctionHelloWorldPermissionProd-27VjLwUTX2y5",
"ResourceType": "AWS::Lambda::Permission",
"Timestamp": "2024-09-21T04:22:21.255000+00:00",
"ResourceStatus": "CREATE_COMPLETE",
"DriftInformation": {
"StackResourceDriftStatus": "NOT_CHECKED"
}
},
{
"StackName": "sam-app",
"StackId": "arn:aws:cloudformation:ap-northeast-1:999999999999:stack/sam-app/e63d61a0-77d0-11ef-a3d7-0e6278aaa549",
"LogicalResourceId": "HelloWorldFunctionRole",
"PhysicalResourceId": "sam-app-HelloWorldFunctionRole-xOpzgzYhRboR",
"ResourceType": "AWS::IAM::Role",
"Timestamp": "2024-09-21T04:22:11.921000+00:00",
"ResourceStatus": "CREATE_COMPLETE",
"DriftInformation": {
"StackResourceDriftStatus": "NOT_CHECKED"
}
},
{
"StackName": "sam-app",
"StackId": "arn:aws:cloudformation:ap-northeast-1:999999999999:stack/sam-app/e63d61a0-77d0-11ef-a3d7-0e6278aaa549",
"LogicalResourceId": "ServerlessRestApi",
"PhysicalResourceId": "utldn1vmd5",
"ResourceType": "AWS::ApiGateway::RestApi",
"Timestamp": "2024-09-21T04:22:19.351000+00:00",
"ResourceStatus": "CREATE_COMPLETE",
"DriftInformation": {
"StackResourceDriftStatus": "NOT_CHECKED"
}
},
{
"StackName": "sam-app",
"StackId": "arn:aws:cloudformation:ap-northeast-1:999999999999:stack/sam-app/e63d61a0-77d0-11ef-a3d7-0e6278aaa549",
"LogicalResourceId": "ServerlessRestApiDeployment47fc2d5f9d",
"PhysicalResourceId": "ivdeh7",
"ResourceType": "AWS::ApiGateway::Deployment",
"Timestamp": "2024-09-21T04:22:21.546000+00:00",
"ResourceStatus": "CREATE_COMPLETE",
"DriftInformation": {
"StackResourceDriftStatus": "NOT_CHECKED"
}
},
{
"StackName": "sam-app",
"StackId": "arn:aws:cloudformation:ap-northeast-1:999999999999:stack/sam-app/e63d61a0-77d0-11ef-a3d7-0e6278aaa549",
"LogicalResourceId": "ServerlessRestApiProdStage",
"PhysicalResourceId": "Prod",
"ResourceType": "AWS::ApiGateway::Stage",
"Timestamp": "2024-09-21T04:22:24.918000+00:00",
"ResourceStatus": "CREATE_COMPLETE",
"DriftInformation": {
"StackResourceDriftStatus": "NOT_CHECKED"
}
}
]
}
Lambda関数確認
コマンド
LOGICAL_RESOURCE_ID="HelloWorldFunction" \
&& echo ${LOGICAL_RESOURCE_ID}
FUNCTION_NAME=$(
aws cloudformation describe-stack-resources \
--stack-name ${SAM_STACK_NAME} \
--logical-resource-id ${LOGICAL_RESOURCE_ID} \
--query "StackResources[*].PhysicalResourceId" \
--output text
) \
&& echo ${FUNCTION_NAME}
aws lambda get-function \
--function-name ${FUNCTION_NAME} \
--no-cli-pager
出力
admin:~/environment/hands-on-serverless-2/sam-app $ LOGICAL_RESOURCE_ID="HelloWorldFunction" \
> && echo ${LOGICAL_RESOURCE_ID}
HelloWorldFunction
admin:~/environment/hands-on-serverless-2/sam-app $
admin:~/environment/hands-on-serverless-2/sam-app $ FUNCTION_NAME=$(
> aws cloudformation describe-stack-resources \
> --stack-name ${SAM_STACK_NAME} \
> --logical-resource-id ${LOGICAL_RESOURCE_ID} \
> --query "StackResources[*].PhysicalResourceId" \
> --output text
> ) \
> && echo ${FUNCTION_NAME}
sam-app-HelloWorldFunction-QPWF3lu5WH5D
admin:~/environment/hands-on-serverless-2/sam-app $
admin:~/environment/hands-on-serverless-2/sam-app $ aws lambda get-function \
> --function-name ${FUNCTION_NAME} \
> --no-cli-pager
{
"Configuration": {
"FunctionName": "sam-app-HelloWorldFunction-QPWF3lu5WH5D",
"FunctionArn": "arn:aws:lambda:ap-northeast-1:999999999999:function:sam-app-HelloWorldFunction-QPWF3lu5WH5D",
"Runtime": "python3.8",
"Role": "arn:aws:iam::999999999999:role/sam-app-HelloWorldFunctionRole-xOpzgzYhRboR",
"Handler": "app.lambda_handler",
"CodeSize": 570354,
"Description": "",
"Timeout": 3,
"MemorySize": 128,
"LastModified": "2024-09-21T04:22:14.441+0000",
"CodeSha256": "pNM7IcLQTYIufw6aqcdNld2OlKqp3nHICGnvwFabSWs=",
"Version": "$LATEST",
"TracingConfig": {
"Mode": "PassThrough"
},
"RevisionId": "ecde4344-6162-45a3-bde2-35fed2663246",
"State": "Active",
"LastUpdateStatus": "Successful",
"PackageType": "Zip",
"Architectures": [
"x86_64"
],
"EphemeralStorage": {
"Size": 512
},
"SnapStart": {
"ApplyOn": "None",
"OptimizationStatus": "Off"
},
"RuntimeVersionConfig": {
"RuntimeVersionArn": "arn:aws:lambda:ap-northeast-1::runtime:124ac49f727c31fa5ba440a749eef8274ca2beb4a0a8f107a0d8c69632c715a7"
},
"LoggingConfig": {
"LogFormat": "Text",
"LogGroup": "/aws/lambda/sam-app-HelloWorldFunction-QPWF3lu5WH5D"
}
},
"Code": {
"RepositoryType": "S3",
"Location": "https://awslambda-ap-ne-1-tasks.s3.ap-northeast-1.amazonaws.com/snapshots/999999999999/sam-app-HelloWorldFunction-QPWF3lu5WH5D-4cafe2d9-bfa0-4c6e-ace5-85f911d4f1ef?versionId=AGlFg4bdX_55gF7.2sT1lAhgMhrWAGsH&X-Amz-Security-Token=IQoJb3JpZ2luX2VjEEwaDmFwLW5vcnRoZWFzdC0xIkgwRgIhAMoMdKTWxnLDNx4NJjO4YCL9lm7m6wSZYmC40NFuCi4jAiEAr5znnrclUvuMamBBI0g4ALoTMXnejgPx0F46nQVa9gkqyQUIhv%2F%2F%2F%2F%2F%2F%2F%2F%2F%2FARAEGgw5MTk5ODA5MjUxMzkiDFUBOddgElEh5YMYnyqdBSU6eAlk%2FyFhxYp9Y94%2B%2FRKjrS7SKIXqte4F%2F357WL8qIqEDUry1oFtgj%2BMewyzrDed6plST8MiNal1yKJRHjEB7kqZBgFDE0lC3AGHQPHdoNzD%2F5sHv4A9ieL1BihdhSsR1Xzhl7eeA0fm%2FVg74YiQ%2F1NLSPsfcYC91VcmHFU8LulKi8IW%2FLzkyAu1dzuXYAg%2BXpJL0%2FP9EEPx7%2BmRWDvJw2w7iNg%2B3r5PZbV2Xsf6hY298I5SlyGkheL9U420q9kWyzjVRHzdT4ZB0BrIy9aG3u18HfzP2T726lsYsxjX6vHZWP3IpX%2BicMs7GwltRAQb9lmuW8RD0s2Wzvis7vSfv2domuyHsZYqPCD7EarkkFfzciVnbxB9rsknpH849A4NkFSI1lkp2bfYYBjawDVSv4QZQBdqVFdveAOSnZd18H07SwAR3ke5TS7TKEDY04GGcqE5gOROwZyGLt%2BoXJQ4rJXN97E%2FDl8vEnKDSwZ59cx3Y2fiscA0cptralwxXclmLlYbbKHrKx6Gze3xAwOZ8yk4EEHjW99%2FMvwmYLegjXlPf9h2i7X8rpPDvd%2Bpnvma4EbpxkjoYkKEp1vXzIEU1rJDsA8jydMXXN5s2h%2B3QE2SPstKaWPPjAP6f%2FKmB%2FnLNzMYDD5WPVkw4chWuDx5xhlf6Xs4gF554CE6thIvM72%2FyeREKjsQMf0YzptHABJFyrbY9lGG2uspHp6D0yhWdA57dGiAEeoRzbsBel6xrhXOW7qMQWD8mBNBKcSqiTO4F%2Brp6sXs8XLMDjbZkSPVqYz0HRp40G3SKn3x%2F9GPTBGRySqq1AFmz3vvxtglzxn1iLFtLEcvHbwDTIIQQDL%2BXfQ%2F2txpUX2%2F%2BFbWiGFB4V4hm2rEsJoA%2F6SSewjD5lbm3BjqwAXlNdi1xqFIUhtokULxnHet8spsTm5EwOuvQEkwRQORKNja%2F9h37HVyIXbH72SEilUPCaO9JwX9e904lkp6gE2kVrzMzkfC1FKng5Mif6ZpwlzW67LUBK4LOB1FTCiFV2L2infzo0EHTWrfwCSAHRKvqO7QSm1bvbX05BStzWOg7ceZimwFcY%2Bw4q9CIJ5sufAfdx4OKFNf2jhOmrC3OmOXCZAdd6%2BrIGXftXBd%2FK2lM&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Date=20240921T043717Z&X-Amz-SignedHeaders=host&X-Amz-Expires=600&X-Amz-Credential=ASIA5MMZC4DJ6TXSYHCW%2F20240921%2Fap-northeast-1%2Fs3%2Faws4_request&X-Amz-Signature=7cdfc1caa15064ddb507f020ae3fcdeab0579682f75325bb7030e2b6153f15a1"
},
"Tags": {
"aws:cloudformation:stack-name": "sam-app",
"lambda:createdBy": "SAM",
"aws:cloudformation:stack-id": "arn:aws:cloudformation:ap-northeast-1:999999999999:stack/sam-app/e63d61a0-77d0-11ef-a3d7-0e6278aaa549",
"aws:cloudformation:logical-id": "HelloWorldFunction"
}
}
API Gatewayの確認
コマンド
LOGICAL_RESOURCE_ID="ServerlessRestApi" \
&& echo ${LOGICAL_RESOURCE_ID}
RESOURCE_PATH="/hello" \
&& echo ${RESOURCE_PATH}
RESET_API_ID=$(
aws cloudformation describe-stack-resources \
--stack-name ${SAM_STACK_NAME} \
--logical-resource-id ${LOGICAL_RESOURCE_ID} \
--query "StackResources[*].PhysicalResourceId" \
--output text
) \
&& echo ${RESET_API_ID}
RESOURCE_ID=$(
aws apigateway get-resources \
--rest-api-id ${RESET_API_ID} \
--query "items[?path=='${RESOURCE_PATH}'].id" \
--output text
) \
&& echo ${RESOURCE_ID}
# GETメソッドの詳細確認
aws apigateway get-method \
--rest-api-id ${RESET_API_ID} \
--resource-id ${RESOURCE_ID} \
--http-method GET
出力
admin:~/environment/hands-on-serverless-2/sam-app $ LOGICAL_RESOURCE_ID="ServerlessRestApi" \
> && echo ${LOGICAL_RESOURCE_ID}
ServerlessRestApi
admin:~/environment/hands-on-serverless-2/sam-app $
admin:~/environment/hands-on-serverless-2/sam-app $ RESOURCE_PATH="/hello" \
> && echo ${RESOURCE_PATH}
/hello
admin:~/environment/hands-on-serverless-2/sam-app $
admin:~/environment/hands-on-serverless-2/sam-app $ RESET_API_ID=$(
> aws cloudformation describe-stack-resources \
> --stack-name ${SAM_STACK_NAME} \
> --logical-resource-id ${LOGICAL_RESOURCE_ID} \
> --query "StackResources[*].PhysicalResourceId" \
> --output text
> ) \
> && echo ${RESET_API_ID}
utldn1vmd5
admin:~/environment/hands-on-serverless-2/sam-app $
admin:~/environment/hands-on-serverless-2/sam-app $ RESOURCE_ID=$(
> aws apigateway get-resources \
> --rest-api-id ${RESET_API_ID} \
> --query "items[?path=='${RESOURCE_PATH}'].id" \
> --output text
> ) \
> && echo ${RESOURCE_ID}
j5qo59
admin:~/environment/hands-on-serverless-2/sam-app $
admin:~/environment/hands-on-serverless-2/sam-app $ # GETメソッドの詳細確認
admin:~/environment/hands-on-serverless-2/sam-app $ aws apigateway get-method \
> --rest-api-id ${RESET_API_ID} \
> --resource-id ${RESOURCE_ID} \
> --http-method GET
{
"httpMethod": "GET",
"authorizationType": "NONE",
"apiKeyRequired": false,
"methodIntegration": {
"type": "AWS_PROXY",
"httpMethod": "POST",
"uri": "arn:aws:apigateway:ap-northeast-1:lambda:path/2015-03-31/functions/arn:aws:lambda:ap-northeast-1:999999999999:function:sam-app-HelloWorldFunction-QPWF3lu5WH5D/invocations",
"passthroughBehavior": "WHEN_NO_MATCH",
"timeoutInMillis": 29000,
"cacheNamespace": "j5qo59",
"cacheKeyParameters": []
}
}
ローカルエンドポイント作成 (sam local start-lambda)
ローカルエンドポイント作成
コマンド
sam local start-lambda
出力
admin:~/environment/hands-on-serverless-2/sam-app $ sam local start-lambda
Initializing the lambda functions containers.
Local image was not found.
Removing rapid images for repo public.ecr.aws/sam/emulation-python3.8
Building image........................................................................................................................................................
Using local image: public.ecr.aws/lambda/python:3.8-rapid-x86_64.
Mounting /home/ec2-user/environment/hands-on-serverless-2/sam-app/.aws-sam/build/HelloWorldFunction as
/var/task:ro,delegated, inside runtime container
Containers Initialization is done.
Starting the Local Lambda Service. You can now invoke your Lambda Functions defined in your template through the
endpoint.
2024-09-21 05:13:37 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:3001
2024-09-21 05:13:37 Press CTRL+C to quit
Cloud9 2個目のターミナルで実施
コマンド
aws lambda invoke \
--function-name "HelloWorldFunction" \
--endpoint-url "http://127.0.0.1:3001" \
--no-verify-ssl out.txt
出力 (Cloud9 ターミナル2)
admin:~/environment $ aws lambda invoke \
> --function-name "HelloWorldFunction" \
> --endpoint-url "http://127.0.0.1:3001" \
> --no-verify-ssl out.txt
{
"StatusCode": 200
}
出力 (Cloud9 ターミナル1)
admin:~/environment/hands-on-serverless-2/sam-app $ sam local start-lambda
Initializing the lambda functions containers.
Local image was not found.
Removing rapid images for repo public.ecr.aws/sam/emulation-python3.8
Building image........................................................................................................................................................
Using local image: public.ecr.aws/lambda/python:3.8-rapid-x86_64.
Mounting /home/ec2-user/environment/hands-on-serverless-2/sam-app/.aws-sam/build/HelloWorldFunction as
/var/task:ro,delegated, inside runtime container
Containers Initialization is done.
Starting the Local Lambda Service. You can now invoke your Lambda Functions defined in your template through the
endpoint.
2024-09-21 05:13:37 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:3001
2024-09-21 05:13:37 Press CTRL+C to quit
Invoking app.lambda_handler (python3.8)
Reuse the created warm container for Lambda function 'HelloWorldFunction'
Lambda function 'HelloWorldFunction' is already running
START RequestId: 49a80c64-a51c-4f66-9fcf-a9ffd864f6eb Version: $LATEST
END RequestId: 55d76972-58bd-43a5-926a-5d78725ba187
REPORT RequestId: 55d76972-58bd-43a5-926a-5d78725ba187 Init Duration: 0.02 ms Duration: 299.86 ms Billed Duration: 300 ms Memory Size: 128 MB Max Memory Used: 128 MB
2024-09-21 05:31:22 127.0.0.1 - - [21/Sep/2024 05:31:22] "POST /2015-03-31/functions/HelloWorldFunction/invocations HTTP/1.1" 200 -
^C
Commands you can use next
=========================
[*] Validate SAM template: sam validate
[*] Test Function in the Cloud: sam sync --stack-name {{stack-name}} --watch
[*] Deploy: sam deploy --guided
Cloud9 1個目のターミナルはCtrl + cでプログラムを終了
出力確認
コマンド (Cloud9 ターミナル2)
cat out.txt
出力 (Cloud9 ターミナル2)
admin:~/environment $ cat out.txt
{"statusCode": 200, "body": "{\"message\": \"hello world\"}"}
ローカルエンドポイント作成 (sam local start-api)
ローカルエンドポイント作成
コマンド (Cloud9 ターミナル1)
sam local start-api
出力 (Cloud9 ターミナル1)
admin:~/environment/hands-on-serverless-2/sam-app $ sam local start-api
Initializing the lambda functions containers.
Local image is up-to-date
Using local image: public.ecr.aws/lambda/python:3.8-rapid-x86_64.
Mounting /home/ec2-user/environment/hands-on-serverless-2/sam-app/.aws-sam/build/HelloWorldFunction as
/var/task:ro,delegated, inside runtime container
Containers Initialization is done.
Mounting HelloWorldFunction at http://127.0.0.1:3000/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
2024-09-21 05:42:24 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:3000
2024-09-21 05:42:24 Press CTRL+C to quit
アクセス確認
コマンド (Cloud9 ターミナル2)
curl http://127.0.0.1:3000/hello
出力 (Cloud9 ターミナル2)
admin:~/environment $ curl http://127.0.0.1:3000/hello
{"message": "hello world"}
出力 (Cloud9 ターミナル1)
admin:~/environment/hands-on-serverless-2/sam-app $ sam local start-api
Initializing the lambda functions containers.
Local image is up-to-date
Using local image: public.ecr.aws/lambda/python:3.8-rapid-x86_64.
Mounting /home/ec2-user/environment/hands-on-serverless-2/sam-app/.aws-sam/build/HelloWorldFunction as
/var/task:ro,delegated, inside runtime container
Containers Initialization is done.
Mounting HelloWorldFunction at http://127.0.0.1:3000/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
2024-09-21 05:42:24 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:3000
2024-09-21 05:42:24 Press CTRL+C to quit
Invoking app.lambda_handler (python3.8)
Reuse the created warm container for Lambda function 'HelloWorldFunction'
Lambda function 'HelloWorldFunction' is already running
END RequestId: 2b933c1a-8f28-47fa-85d6-97c33441f055
REPORT RequestId: 2b933c1a-8f28-47fa-85d6-97c33441f055 Init Duration: 0.02 ms Duration: 93.39 ms Billed Duration: 94 ms Memory Size: 128 MB Max Memory Used: 128 MB
No Content-Type given. Defaulting to 'application/json'.
2024-09-21 05:44:42 127.0.0.1 - - [21/Sep/2024 05:44:42] "GET /hello HTTP/1.1" 200 -
^C
Commands you can use next
=========================
[*] Validate SAM template: sam validate
[*] Test Function in the Cloud: sam sync --stack-name {{stack-name}} --watch
[*] Deploy: sam deploy --guided
Cloud9 1個目のターミナルはCtrl + cでプログラムを終了
app.py更新
コマンド (Cloud9 ターミナル1)
cat << EOF > hands-on-serverless-2/sam-app/hello_world/app.py
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 - SAM CLI",
# "location": ip.text.replace("\n", "")
}),
}
EOF
出力 (Cloud9 ターミナル1)
admin:~/environment/hands-on-serverless-2/sam-app $ cat << EOF > hello_world/app.py
> 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 - SAM CLI",
> # "location": ip.text.replace("\n", "")
> }),
> }
> EOF
ビルド
コマンド (Cloud9 ターミナル1)
sam build
出力 (Cloud9 ターミナル1)
admin:~/environment/hands-on-serverless-2/sam-app $ sam build
Starting Build use cache
Manifest is not changed for (HelloWorldFunction), running incremental build
Building codeuri: /home/ec2-user/environment/hands-on-serverless-2/sam-app/hello_world runtime: python3.8 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
ローカルエンドポイント作成
コマンド (Cloud9 ターミナル1)
sam local start-api
出力 (Cloud9 ターミナル1)
admin:~/environment/hands-on-serverless-2/sam-app $ sam local start-api
Initializing the lambda functions containers.
Local image is up-to-date
Using local image: public.ecr.aws/lambda/python:3.8-rapid-x86_64.
Mounting /home/ec2-user/environment/hands-on-serverless-2/sam-app/.aws-sam/build/HelloWorldFunction as
/var/task:ro,delegated, inside runtime container
Containers Initialization is done.
Mounting HelloWorldFunction at http://127.0.0.1:3000/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
2024-09-21 05:57:30 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:3000
2024-09-21 05:57:30 Press CTRL+C to quit
コマンド (Cloud9 ターミナル2)
curl http://127.0.0.1:3000/hello
出力 (Cloud9 ターミナル2)
admin:~/environment $ curl http://127.0.0.1:3000/hello
{"message": "hello world - SAM CLI"}
出力 (Cloud9 ターミナル1)
admin:~/environment/hands-on-serverless-2/sam-app $ sam local start-api
Initializing the lambda functions containers.
Local image is up-to-date
Using local image: public.ecr.aws/lambda/python:3.8-rapid-x86_64.
Mounting /home/ec2-user/environment/hands-on-serverless-2/sam-app/.aws-sam/build/HelloWorldFunction as
/var/task:ro,delegated, inside runtime container
Containers Initialization is done.
Mounting HelloWorldFunction at http://127.0.0.1:3000/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
2024-09-21 05:57:30 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:3000
2024-09-21 05:57:30 Press CTRL+C to quit
Invoking app.lambda_handler (python3.8)
Reuse the created warm container for Lambda function 'HelloWorldFunction'
Lambda function 'HelloWorldFunction' is already running
END RequestId: 972d3a22-8d03-4953-862b-bc2b535d757b
REPORT RequestId: 972d3a22-8d03-4953-862b-bc2b535d757b Init Duration: 0.02 ms Duration: 114.26 ms Billed Duration: 115 ms Memory Size: 128 MB Max Memory Used: 128 MB
No Content-Type given. Defaulting to 'application/json'.
2024-09-21 05:58:29 127.0.0.1 - - [21/Sep/2024 05:58:29] "GET /hello HTTP/1.1" 200 -
^C
Commands you can use next
=========================
[*] Validate SAM template: sam validate
[*] Test Function in the Cloud: sam sync --stack-name {{stack-name}} --watch
[*] Deploy: sam deploy --guided
10 クリーンアップ & 落ち穂拾い & まとめ
以降、CloudShellで実施
Cloud9
コマンド
aws cloud9 delete-environment \
--environment-id ${CLOUD9_ENVIRONMENT_ID}
出力
[cloudshell-user@ip-10-132-75-96 ~]$ aws cloud9 delete-environment \
> --environment-id ${CLOUD9_ENVIRONMENT_ID}
S3
コマンド
# パッケージ用バケット
S3_BUCKET_NAME="hands-on-serverless-20240921" \
&& echo ${S3_BUCKET_NAME}
# オブジェクト一覧取得
OBJECT_LIST=$(
aws s3api list-object-versions \
--bucket ${S3_BUCKET_NAME} \
--query='{Objects: Versions[].{Key:Key,VersionId:VersionId}}'
) \
&& echo ${OBJECT_LIST}
# JSONフォーマットの確認
echo ${OBJECT_LIST} | python -m json.tool
# バケットを空にする
aws s3api delete-objects \
--bucket ${S3_BUCKET_NAME} \
--delete "${OBJECT_LIST}"
# S3バケットを削除
aws s3api delete-bucket \
--bucket ${S3_BUCKET_NAME}
# Managed Stack for AWS SAM CLIバケット
SAM_CLI_MNG_STACK="aws-sam-cli-managed-default" \
&& echo ${SAM_CLI_MNG_STACK}
LOGICAL_RESOURCE_ID="SamCliSourceBucket" \
&& echo ${LOGICAL_RESOURCE_ID}
S3_SAM_CLI_MNG_BUCKET_NAME=$(
aws cloudformation describe-stack-resources \
--stack-name ${SAM_CLI_MNG_STACK} \
--logical-resource-id ${LOGICAL_RESOURCE_ID} \
--query "StackResources[*].PhysicalResourceId" \
--output text
) \
&& echo ${S3_SAM_CLI_MNG_BUCKET_NAME}
# オブジェクト一覧取得
OBJECT_LIST=$(
aws s3api list-object-versions \
--bucket ${S3_SAM_CLI_MNG_BUCKET_NAME} \
--query='{Objects: Versions[].{Key:Key,VersionId:VersionId}}'
) \
&& echo ${OBJECT_LIST}
# JSONフォーマットの確認
echo ${OBJECT_LIST} | python -m json.tool
# バケットを空にする
aws s3api delete-objects \
--bucket ${S3_SAM_CLI_MNG_BUCKET_NAME} \
--delete "${OBJECT_LIST}"
# S3バケットを削除
aws s3api delete-bucket \
--bucket ${S3_SAM_CLI_MNG_BUCKET_NAME}
出力
[cloudshell-user@ip-10-132-75-96 ~]$ # パッケージ用バケット
[cloudshell-user@ip-10-132-75-96 ~]$ S3_BUCKET_NAME="hands-on-serverless-20240921" \
> && echo ${S3_BUCKET_NAME}
hands-on-serverless-20240921
[cloudshell-user@ip-10-132-75-96 ~]$
[cloudshell-user@ip-10-132-75-96 ~]$ # オブジェクト一覧取得
[cloudshell-user@ip-10-132-75-96 ~]$ OBJECT_LIST=$(
> aws s3api list-object-versions \
> --bucket ${S3_BUCKET_NAME} \
> --query='{Objects: Versions[].{Key:Key,VersionId:VersionId}}'
> ) \
> && echo ${OBJECT_LIST}
{ "Objects": [ { "Key": "390d10c0b490f110117d9155f60cf0b0", "VersionId": "null" }, { "Key": "44a6c97b5e9e64448acb91573299c6ba", "VersionId": "null" }, { "Key": "5e32642d09e1b88190f79969845b9d2b", "VersionId": "null" }, { "Key": "f802e187101b61229f32ab9c1db914b5", "VersionId": "null" } ] }
[cloudshell-user@ip-10-132-75-96 ~]$
[cloudshell-user@ip-10-132-75-96 ~]$ # JSONフォーマットの確認
[cloudshell-user@ip-10-132-75-96 ~]$ echo ${OBJECT_LIST} | python -m json.tool
{
"Objects": [
{
"Key": "390d10c0b490f110117d9155f60cf0b0",
"VersionId": "null"
},
{
"Key": "44a6c97b5e9e64448acb91573299c6ba",
"VersionId": "null"
},
{
"Key": "5e32642d09e1b88190f79969845b9d2b",
"VersionId": "null"
},
{
"Key": "f802e187101b61229f32ab9c1db914b5",
"VersionId": "null"
}
]
}
[cloudshell-user@ip-10-132-75-96 ~]$
[cloudshell-user@ip-10-132-75-96 ~]$ # バケットを空にする
[cloudshell-user@ip-10-132-75-96 ~]$ aws s3api delete-objects \
> --bucket ${S3_BUCKET_NAME} \
> --delete "${OBJECT_LIST}"
{
"Deleted": [
{
"Key": "390d10c0b490f110117d9155f60cf0b0",
"VersionId": "null"
},
{
"Key": "5e32642d09e1b88190f79969845b9d2b",
"VersionId": "null"
},
{
"Key": "f802e187101b61229f32ab9c1db914b5",
"VersionId": "null"
},
{
"Key": "44a6c97b5e9e64448acb91573299c6ba",
"VersionId": "null"
}
]
}
[cloudshell-user@ip-10-132-75-96 ~]$
[cloudshell-user@ip-10-132-75-96 ~]$ # S3バケットを削除
[cloudshell-user@ip-10-132-75-96 ~]$ aws s3api delete-bucket \
> --bucket ${S3_BUCKET_NAME}
[cloudshell-user@ip-10-132-75-96 ~]$
[cloudshell-user@ip-10-132-75-96 ~]$ # Managed Stack for AWS SAM CLIバケット
[cloudshell-user@ip-10-132-75-96 ~]$ SAM_CLI_MNG_STACK="aws-sam-cli-managed-default" \
> && echo ${SAM_CLI_MNG_STACK}
aws-sam-cli-managed-default
[cloudshell-user@ip-10-132-75-96 ~]$
[cloudshell-user@ip-10-132-75-96 ~]$ LOGICAL_RESOURCE_ID="SamCliSourceBucket" \
> && echo ${LOGICAL_RESOURCE_ID}
SamCliSourceBucket
[cloudshell-user@ip-10-132-75-96 ~]$
[cloudshell-user@ip-10-132-75-96 ~]$ S3_SAM_CLI_MNG_BUCKET_NAME=$(
> aws cloudformation describe-stack-resources \
> --stack-name ${SAM_CLI_MNG_STACK} \
> --logical-resource-id ${LOGICAL_RESOURCE_ID} \
> --query "StackResources[*].PhysicalResourceId" \
> --output text
> ) \
> && echo ${S3_SAM_CLI_MNG_BUCKET_NAME}
aws-sam-cli-managed-default-samclisourcebucket-ktfpyr4rinwv
[cloudshell-user@ip-10-132-75-96 ~]$
[cloudshell-user@ip-10-132-75-96 ~]$ # オブジェクト一覧取得
[cloudshell-user@ip-10-132-75-96 ~]$ OBJECT_LIST=$(
> aws s3api list-object-versions \
> --bucket ${S3_SAM_CLI_MNG_BUCKET_NAME} \
> --query='{Objects: Versions[].{Key:Key,VersionId:VersionId}}'
> ) \
> && echo ${OBJECT_LIST}
{ "Objects": [ { "Key": "sam-app/45916096b7662dd4d586fe710b60ddc6", "VersionId": "xUa0Ov7KulLQToXuwsro4kcPaGZTMIsN" }, { "Key": "sam-app/d3a404bc8c7a981f5668a316182fb5ca.template", "VersionId": "HXRokj97Q9MAGulZQTLmt7lnJpHa6cRu" } ] }
[cloudshell-user@ip-10-132-75-96 ~]$
[cloudshell-user@ip-10-132-75-96 ~]$ # JSONフォーマットの確認
[cloudshell-user@ip-10-132-75-96 ~]$ echo ${OBJECT_LIST} | python -m json.tool
{
"Objects": [
{
"Key": "sam-app/45916096b7662dd4d586fe710b60ddc6",
"VersionId": "xUa0Ov7KulLQToXuwsro4kcPaGZTMIsN"
},
{
"Key": "sam-app/d3a404bc8c7a981f5668a316182fb5ca.template",
"VersionId": "HXRokj97Q9MAGulZQTLmt7lnJpHa6cRu"
}
]
}
[cloudshell-user@ip-10-132-75-96 ~]$
[cloudshell-user@ip-10-132-75-96 ~]$ # バケットを空にする
[cloudshell-user@ip-10-132-75-96 ~]$ aws s3api delete-objects \
> --bucket ${S3_SAM_CLI_MNG_BUCKET_NAME} \
> --delete "${OBJECT_LIST}"
{
"Deleted": [
{
"Key": "sam-app/45916096b7662dd4d586fe710b60ddc6",
"VersionId": "xUa0Ov7KulLQToXuwsro4kcPaGZTMIsN"
},
{
"Key": "sam-app/d3a404bc8c7a981f5668a316182fb5ca.template",
"VersionId": "HXRokj97Q9MAGulZQTLmt7lnJpHa6cRu"
}
]
}
[cloudshell-user@ip-10-132-75-96 ~]$
[cloudshell-user@ip-10-132-75-96 ~]$ # S3バケットを削除
[cloudshell-user@ip-10-132-75-96 ~]$ aws s3api delete-bucket \
> --bucket ${S3_SAM_CLI_MNG_BUCKET_NAME}
CloudFormation
コマンド
# パッケージ用スタック名
STACK_NAME="hands-on-serverless-2" \
&& echo ${STACK_NAME}
aws cloudformation delete-stack \
--stack-name ${STACK_NAME}
# Managed Stack for AWS SAM CLIスタック名
SAM_CLI_MNG_STACK="aws-sam-cli-managed-default" \
&& echo ${SAM_CLI_MNG_STACK}
aws cloudformation delete-stack \
--stack-name ${SAM_CLI_MNG_STACK}
# Managed Stack for AWS SAM CLIスタック名
SAM_STACK_NAME="sam-app" \
&& echo ${SAM_STACK_NAME}
aws cloudformation delete-stack \
--stack-name ${SAM_STACK_NAME}
出力
[cloudshell-user@ip-10-132-75-96 ~]$ # パッケージ用スタック名
[cloudshell-user@ip-10-132-75-96 ~]$ STACK_NAME="hands-on-serverless-2" \
[cloudshell-user@ip-10-132-75-96 ~]$ && echo ${STACK_NAME}
[cloudshell-user@ip-10-132-75-96 ~]$
[cloudshell-user@ip-10-132-75-96 ~]$ aws cloudformation delete-stack \
[cloudshell-user@ip-10-132-75-96 ~]$ --stack-name ${STACK_NAME}
[cloudshell-user@ip-10-132-75-96 ~]$
[cloudshell-user@ip-10-132-75-96 ~]$ # Managed Stack for AWS SAM CLIスタック名
[cloudshell-user@ip-10-132-75-96 ~]$ SAM_CLI_MNG_STACK="aws-sam-cli-managed-default" \
[cloudshell-user@ip-10-132-75-96 ~]$ && echo ${SAM_CLI_MNG_STACK}
[cloudshell-user@ip-10-132-75-96 ~]$
[cloudshell-user@ip-10-132-75-96 ~]$ aws cloudformation delete-stack \
[cloudshell-user@ip-10-132-75-96 ~]$ --stack-name ${SAM_CLI_MNG_STACK}
[cloudshell-user@ip-10-132-75-96 ~]$
[cloudshell-user@ip-10-132-75-96 ~]$ # Managed Stack for AWS SAM CLIスタック名
[cloudshell-user@ip-10-132-75-96 ~]$ SAM_STACK_NAME="sam-app" \
[cloudshell-user@ip-10-132-75-96 ~]$ && echo ${SAM_STACK_NAME}
[cloudshell-user@ip-10-132-75-96 ~]$
[cloudshell-user@ip-10-132-75-96 ~]$ aws cloudformation delete-stack \
[cloudshell-user@ip-10-132-75-96 ~]$ --stack-name ${SAM_STACK_NAME}