上記、「AWS Hands-on for Beginners Amazon EC2 Auto Scaling スケーリング基礎編」 をAWS CLIでやってみる
ハンズオンから引用
ハンズオンではPython3.7を使用していたが、サポート修了のためPython3.8を使用
1. AWS Lambda ハンズオン① Lambda を単体で使ってみる
関数設定
コマンド
FUNCTION_NAME="translate-function" \
&& echo ${FUNCTION_NAME}
RUNTIME="python3.8" \
&& echo ${RUNTIME}
POLICY_NAME="translate-function-policy" \
&& echo ${POLICY_NAME}
ROLE_NAME="translate-function-role" \
&& echo ${ROLE_NAME}
MEMORY_SIZE=256 \
&& echo ${MEMORY_SIZE}
TIMEOUT=10 \
&& echo ${TIMEOUT}
出力
[cloudshell-user@ip-10-130-40-130 ~]$ FUNCTION_NAME="translate-function" \
> && echo ${FUNCTION_NAME}
translate-function
[cloudshell-user@ip-10-130-40-130 ~]$
[cloudshell-user@ip-10-130-40-130 ~]$ RUNTIME="python3.8" \
> && echo ${RUNTIME}
python3.8
[cloudshell-user@ip-10-130-40-130 ~]$
[cloudshell-user@ip-10-130-40-130 ~]$ POLICY_NAME="translate-function-policy" \
> && echo ${POLICY_NAME}
translate-function-policy
[cloudshell-user@ip-10-130-40-130 ~]$
[cloudshell-user@ip-10-130-40-130 ~]$ ROLE_NAME="translate-function-role" \
> && echo ${ROLE_NAME}
translate-function-role
[cloudshell-user@ip-10-130-40-130 ~]$
[cloudshell-user@ip-10-130-40-130 ~]$ MEMORY_SIZE=256 \
> && echo ${MEMORY_SIZE}
256
[cloudshell-user@ip-10-130-40-130 ~]$
[cloudshell-user@ip-10-130-40-130 ~]$ TIMEOUT=10 \
> && echo ${TIMEOUT}
10
IAMポリシー作成
コマンド
# ポリシードキュメントの作成
POLICY_DOCUMENT_JSON=$(cat << EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "logs:CreateLogGroup",
"Resource": "arn:aws:logs:ap-northeast-1:999999999999:*"
},
{
"Effect": "Allow",
"Action": [
"logs:CreateLogStream",
"logs:PutLogEvents"
],
"Resource": [
"arn:aws:logs:ap-northeast-1:999999999999:log-group:/aws/lambda/translate-function:*"
]
}
]
}
EOF
) \
&& echo ${POLICY_DOCUMENT_JSON}
# ポリシーの作成
aws iam create-policy \
--policy-name ${POLICY_NAME} \
--policy-document "${POLICY_DOCUMENT_JSON}"
# ARN取得
POLICY_ARN=$(
aws iam list-policies \
--query "Policies[?PolicyName=='${POLICY_NAME}'].Arn" \
--output text
) \
&& echo ${POLICY_ARN}
出力
[cloudshell-user@ip-10-130-40-130 ~]$ # ポリシードキュメントの作成
[cloudshell-user@ip-10-130-40-130 ~]$ POLICY_DOCUMENT_JSON=$(cat << EOF
> {
> "Version": "2012-10-17",
> "Statement": [
> {
> "Effect": "Allow",
> "Action": "logs:CreateLogGroup",
> "Resource": "arn:aws:logs:ap-northeast-1:999999999999:*"
> },
> {
> "Effect": "Allow",
> "Action": [
> "logs:CreateLogStream",
> "logs:PutLogEvents"
> ],
> "Resource": [
> "arn:aws:logs:ap-northeast-1:999999999999:log-group:/aws/lambda/translate-function:*"
> ]
> }
> ]
> }
> EOF
> ) \
> && echo ${POLICY_DOCUMENT_JSON}
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": "logs:CreateLogGroup", "Resource": "arn:aws:logs:ap-northeast-1:999999999999:*" }, { "Effect": "Allow", "Action": [ "logs:CreateLogStream", "logs:PutLogEvents" ], "Resource": [ "arn:aws:logs:ap-northeast-1:999999999999:log-group:/aws/lambda/translate-function:*" ] } ] }
[cloudshell-user@ip-10-130-40-130 ~]$
[cloudshell-user@ip-10-130-40-130 ~]$ # ポリシーの作成
[cloudshell-user@ip-10-130-40-130 ~]$ aws iam create-policy \
> --policy-name ${POLICY_NAME} \
> --policy-document "${POLICY_DOCUMENT_JSON}"
{
"Policy": {
"PolicyName": "translate-function-policy",
"PolicyId": "ANPAWFKRCMKOZKEIZQSVJ",
"Arn": "arn:aws:iam::999999999999:policy/translate-function-policy",
"Path": "/",
"DefaultVersionId": "v1",
"AttachmentCount": 0,
"PermissionsBoundaryUsageCount": 0,
"IsAttachable": true,
"CreateDate": "2024-07-13T05:52:57+00:00",
"UpdateDate": "2024-07-13T05:52:57+00:00"
}
}
[cloudshell-user@ip-10-130-40-130 ~]$
[cloudshell-user@ip-10-130-40-130 ~]$ # ARN取得
[cloudshell-user@ip-10-130-40-130 ~]$ POLICY_ARN=$(
> aws iam list-policies \
> --query "Policies[?PolicyName=='${POLICY_NAME}'].Arn" \
> --output text
> ) \
> && echo ${POLICY_ARN}
arn:aws:iam::999999999999:policy/translate-function-policy
IAMロール作成
コマンド
# 信頼関係ポリシードキュメントの作成
ASSUME_ROLE_POLICY_DOCUMENT=$(cat << EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "lambda.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
EOF
) \
&& echo ${ASSUME_ROLE_POLICY_DOCUMENT}
# IAMロールの作成
aws iam create-role \
--role-name ${ROLE_NAME} \
--assume-role-policy-document "${ASSUME_ROLE_POLICY_DOCUMENT}"
# IAMロールにポリシーをアタッチ
aws iam attach-role-policy \
--role-name ${ROLE_NAME} \
--policy-arn ${POLICY_ARN}
# ARN取得
ROLE_ARN=$(
aws iam get-role \
--role-name ${ROLE_NAME} \
--query 'Role.Arn' --output text
) \
&& echo ${ROLE_ARN}
出力
[cloudshell-user@ip-10-130-40-130 ~]$ # 信頼関係ポリシードキュメントの作成
[cloudshell-user@ip-10-130-40-130 ~]$ ASSUME_ROLE_POLICY_DOCUMENT=$(cat << EOF
> {
> "Version": "2012-10-17",
> "Statement": [
> {
> "Effect": "Allow",
> "Principal": {
> "Service": "lambda.amazonaws.com"
> },
> "Action": "sts:AssumeRole"
> }
> ]
> }
> EOF
> ) \
> && echo ${ASSUME_ROLE_POLICY_DOCUMENT}
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Service": "lambda.amazonaws.com" }, "Action": "sts:AssumeRole" } ] }
[cloudshell-user@ip-10-130-40-130 ~]$
[cloudshell-user@ip-10-130-40-130 ~]$ # IAMロールの作成
[cloudshell-user@ip-10-130-40-130 ~]$ aws iam create-role \
> --role-name ${ROLE_NAME} \
> --assume-role-policy-document "${ASSUME_ROLE_POLICY_DOCUMENT}"
{
"Role": {
"Path": "/",
"RoleName": "translate-function-role",
"RoleId": "AROAWFKRCMKOVFJD5Y2OU",
"Arn": "arn:aws:iam::999999999999:role/translate-function-role",
"CreateDate": "2024-07-13T05:54:33+00:00",
"AssumeRolePolicyDocument": {
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "lambda.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
}
}
[cloudshell-user@ip-10-130-40-130 ~]$
[cloudshell-user@ip-10-130-40-130 ~]$ # IAMロールにポリシーをアタッチ
[cloudshell-user@ip-10-130-40-130 ~]$ aws iam attach-role-policy \
> --role-name ${ROLE_NAME} \
> --policy-arn ${POLICY_ARN}
[cloudshell-user@ip-10-130-40-130 ~]$
[cloudshell-user@ip-10-130-40-130 ~]$ # ARN取得
[cloudshell-user@ip-10-130-40-130 ~]$ ROLE_ARN=$(
> aws iam get-role \
> --role-name ${ROLE_NAME} \
> --query 'Role.Arn' --output text
> ) \
> && echo ${ROLE_ARN}
arn:aws:iam::999999999999:role/translate-function-role
Lambda用コードソースの作成
コマンド
cat << EOF > lambda_function.py
import json
def lambda_handler(event, context):
# TODO implement
return {
'statusCode': 200,
'body': json.dumps('Hello from Lambda!')
}
EOF
出力
[cloudshell-user@ip-10-130-40-130 ~]$ cat << EOF > lambda_function.py
> import json
>
> def lambda_handler(event, context):
> # TODO implement
> return {
> 'statusCode': 200,
> 'body': json.dumps('Hello from Lambda!')
> }
> EOF
Lambda用デプロイパッケージの作成
コマンド
zip function.zip lambda_function.py
出力
[cloudshell-user@ip-10-130-40-130 ~]$ zip function.zip lambda_function.py
adding: lambda_function.py (deflated 19%)
Lambda関数の作成
--handlerはPythonファイル名.関数名で指定
コマンド
# Lambda関数の作成
aws lambda create-function \
--function-name ${FUNCTION_NAME} \
--runtime ${RUNTIME} \
--role $ROLE_ARN \
--handler lambda_function.lambda_handler \
--zip-file fileb://function.zip \
--memory-size ${MEMORY_SIZE} \
--timeout ${TIMEOUT}
# ARN取得
FUNCTION_ARN=$(
aws lambda list-functions \
--query "Functions[?FunctionName=='${FUNCTION_NAME}'].FunctionArn" \
--output text
) \
&& echo ${FUNCTION_ARN}
出力
[cloudshell-user@ip-10-130-40-130 ~]$ # Lambda関数の作成
[cloudshell-user@ip-10-130-40-130 ~]$ aws lambda create-function \
> --function-name ${FUNCTION_NAME} \
> --runtime ${RUNTIME} \
> --role $ROLE_ARN \
> --handler lambda_function.lambda_handler \
> --zip-file fileb://function.zip \
> --memory-size ${MEMORY_SIZE} \
> --timeout ${TIMEOUT}
{
"FunctionName": "translate-function",
"FunctionArn": "arn:aws:lambda:ap-northeast-1:999999999999:function:translate-function",
"Runtime": "python3.8",
"Role": "arn:aws:iam::999999999999:role/translate-function-role",
"Handler": "lambda_function.lambda_handler",
"CodeSize": 320,
"Description": "",
"Timeout": 10,
"MemorySize": 256,
"LastModified": "2024-07-13T06:29:36.292+0000",
"CodeSha256": "k2GJUJo8DYDjiUH1MeGyiT4S1t10hWI/GYWEcatHzfo=",
"Version": "$LATEST",
"TracingConfig": {
"Mode": "PassThrough"
},
"RevisionId": "666ba46f-3bd0-45c2-a795-5760ad264c83",
"State": "Pending",
"StateReason": "The function is being created.",
"StateReasonCode": "Creating",
"PackageType": "Zip",
"Architectures": [
"x86_64"
],
"EphemeralStorage": {
"Size": 512
},
"SnapStart": {
"ApplyOn": "None",
"OptimizationStatus": "Off"
},
"RuntimeVersionConfig": {
"RuntimeVersionArn": "arn:aws:lambda:ap-northeast-1::runtime:a768321bd39c88f083afe0a045064adc3615105a319dbbcd583856654db68283"
},
"LoggingConfig": {
"LogFormat": "Text",
"LogGroup": "/aws/lambda/translate-function"
}
}
[cloudshell-user@ip-10-130-40-130 ~]$ # ARN取得
[cloudshell-user@ip-10-130-40-130 ~]$ FUNCTION_ARN=$(
> aws lambda list-functions \
> --query "Functions[?FunctionName=='${FUNCTION_NAME}'].FunctionArn" \
> --output text
> ) \
> && echo ${FUNCTION_ARN}
arn:aws:lambda:ap-northeast-1:999999999999:function:translate-function
Lambda関数のテスト実行
--payloadはbase64形式で指定
コマンド
# イベントの作成
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
出力
[cloudshell-user@ip-10-132-89-176 ~]$ # イベントの作成
[cloudshell-user@ip-10-132-89-176 ~]$ EVENT=$(cat << EOF
> {
> "key1": "value1",
> "key2": "value2",
> "key3": "value3"
> }
> EOF
> ) \
> && echo ${EVENT}
{ "key1": "value1", "key2": "value2", "key3": "value3" }
[cloudshell-user@ip-10-132-89-176 ~]$
[cloudshell-user@ip-10-132-89-176 ~]$ # JSONフォーマットの確認
[cloudshell-user@ip-10-132-89-176 ~]$ echo ${EVENT} | python -m json.tool
{
"key1": "value1",
"key2": "value2",
"key3": "value3"
}
[cloudshell-user@ip-10-132-89-176 ~]$
[cloudshell-user@ip-10-132-89-176 ~]$ # テスト実行
[cloudshell-user@ip-10-132-89-176 ~]$ aws lambda invoke \
> --function-name ${FUNCTION_NAME} \
> --payload `echo ${EVENT} | base64 -w 0` \
> outputfile.txt
{
"StatusCode": 200,
"ExecutedVersion": "$LATEST"
}
[cloudshell-user@ip-10-132-89-176 ~]$ cat outputfile.txt
{"statusCode": 200, "body": "\"Hello from Lambda!\""}
Lambda用ソースコードの更新
コマンド
# ソースコードの更新
cat << EOF > lambda_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
# デプロイパッケージの作成
zip function.zip lambda_function.py
# Lambda関数の更新
aws lambda update-function-code \
--function-name ${FUNCTION_NAME} \
--zip-file fileb://function.zip
出力
[cloudshell-user@ip-10-132-89-176 ~]$ # ソースコードの更新
[cloudshell-user@ip-10-132-89-176 ~]$ cat << EOF > lambda_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
[cloudshell-user@ip-10-132-89-176 ~]$
[cloudshell-user@ip-10-132-89-176 ~]$ # デプロイパッケージの作成
[cloudshell-user@ip-10-132-89-176 ~]$ zip function.zip lambda_function.py
updating: lambda_function.py (deflated 31%)
[cloudshell-user@ip-10-132-89-176 ~]$
[cloudshell-user@ip-10-132-89-176 ~]$ # Lambda関数の更新
[cloudshell-user@ip-10-132-89-176 ~]$ aws lambda update-function-code \
> --function-name ${FUNCTION_NAME} \
> --zip-file fileb://function.zip
{
"FunctionName": "translate-function",
"FunctionArn": "arn:aws:lambda:ap-northeast-1:999999999999:function:translate-function",
"Runtime": "python3.8",
"Role": "arn:aws:iam::999999999999:role/translate-function-role",
"Handler": "lambda_function.lambda_handler",
"CodeSize": 356,
"Description": "",
"Timeout": 10,
"MemorySize": 256,
"LastModified": "2024-07-13T10:09:30.000+0000",
"CodeSha256": "i6TM4nP5Go39fnVJjin2PHlVi6ZCav7Xfqz1ffbmiQI=",
"Version": "$LATEST",
"TracingConfig": {
"Mode": "PassThrough"
},
"RevisionId": "56db0836-ddf9-4d04-a1a9-aa382555d351",
"State": "Active",
"LastUpdateStatus": "InProgress",
"LastUpdateStatusReason": "The function is being created.",
"LastUpdateStatusReasonCode": "Creating",
"PackageType": "Zip",
"Architectures": [
"x86_64"
],
"EphemeralStorage": {
"Size": 512
},
"SnapStart": {
"ApplyOn": "None",
"OptimizationStatus": "Off"
},
"RuntimeVersionConfig": {
"RuntimeVersionArn": "arn:aws:lambda:ap-northeast-1::runtime:a768321bd39c88f083afe0a045064adc3615105a319dbbcd583856654db68283"
},
"LoggingConfig": {
"LogFormat": "Text",
"LogGroup": "/aws/lambda/translate-function"
}
}
Lambda関数のテスト実行
コマンド
# テスト実行
aws lambda invoke \
--function-name ${FUNCTION_NAME} \
--payload `echo ${EVENT} | base64 -w 0` \
outputfile.txt
cat outputfile.txt
出力
[cloudshell-user@ip-10-132-89-176 ~]$ aws lambda invoke \
> --function-name ${FUNCTION_NAME} \
> --payload `echo ${EVENT} | base64 -w 0` \
> outputfile.txt
{
"StatusCode": 200,
"ExecutedVersion": "$LATEST"
}
[cloudshell-user@ip-10-132-89-176 ~]$
[cloudshell-user@ip-10-132-89-176 ~]$ cat outputfile.txt
{"statusCode": 200, "body": "\"Hello Hands on world!\""}
CloudWatchログの確認
コマンド
# 最新のログストリームの取得
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}
出力
[cloudshell-user@ip-10-132-89-176 ~]$ # 最新のログストリームの取得
[cloudshell-user@ip-10-132-89-176 ~]$ 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/07/13/[$LATEST]20430606b82f401e94c39467f8074e5b
[cloudshell-user@ip-10-132-89-176 ~]$
[cloudshell-user@ip-10-132-89-176 ~]$ # ログの確認
[cloudshell-user@ip-10-132-89-176 ~]$ aws logs get-log-events \
> --log-group-name /aws/lambda/${FUNCTION_NAME} \
> --log-stream-name ${LATEST_LOG_STREAM}
{
"events": [
{
"timestamp": 1720865480248,
"message": "INIT_START Runtime Version: python:3.8.v51\tRuntime Version ARN: arn:aws:lambda:ap-northeast-1::runtime:a768321bd39c88f083afe0a045064adc3615105a319dbbd583856654db68283\n",
"ingestionTime": 1720865484129
},
{
"timestamp": 1720865480373,
"message": "START RequestId: 0b810e7a-e8aa-4a1d-88ad-8a8d1d584bdc Version: $LATEST\n",
"ingestionTime": 1720865484129
},
{
"timestamp": 1720865480374,
"message": "[INFO]\t2024-07-13T10:11:20.373Z\t0b810e7a-e8aa-4a1d-88ad-8a8d1d584bdc\t{'key1': 'value1', 'key2': 'value2', 'key3': 'value3'}\n",
"ingestionTime": 1720865484129
},
{
"timestamp": 1720865480375,
"message": "END RequestId: 0b810e7a-e8aa-4a1d-88ad-8a8d1d584bdc\n",
"ingestionTime": 1720865484129
},
{
"timestamp": 1720865480375,
"message": "REPORT RequestId: 0b810e7a-e8aa-4a1d-88ad-8a8d1d584bdc\tDuration: 2.19 ms\tBilled Duration: 3 ms\tMemory Size: 256 MB\tMax Memory Used: 39 MB\tInit Duation: 124.47 ms\t\n",
"ingestionTime": 1720865484129
},
{
"timestamp": 1720865687128,
"message": "START RequestId: a0040360-8c77-47d8-b748-9cc176dea3de Version: $LATEST\n",
"ingestionTime": 1720865696156
},
{
"timestamp": 1720865687128,
"message": "[INFO]\t2024-07-13T10:14:47.128Z\ta0040360-8c77-47d8-b748-9cc176dea3de\t{'key1': 'value1', 'key2': 'value2', 'key3': 'value3'}\n",
"ingestionTime": 1720865696156
},
{
"timestamp": 1720865687131,
"message": "END RequestId: a0040360-8c77-47d8-b748-9cc176dea3de\n",
"ingestionTime": 1720865696156
},
{
"timestamp": 1720865687131,
"message": "REPORT RequestId: a0040360-8c77-47d8-b748-9cc176dea3de\tDuration: 1.24 ms\tBilled Duration: 2 ms\tMemory Size: 256 MB\tMax Memory Used: 40 MB\t\n",
"ingestionTime": 1720865696156
}
],
"nextForwardToken": "f/38376587209602749806084872664013029979155431024260087811/s",
"nextBackwardToken": "b/38376582595957680898473965017354384466886398518340943872/s"
}
2. AWS Lambda ハンズオン② 他のサービスを呼び出してみる
Lambda用ソースコードの更新
コマンド
# ソースコードの更新
cat << EOF > lambda_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
# デプロイパッケージの作成
zip function.zip lambda_function.py
# Lambda関数の更新
aws lambda update-function-code \
--function-name ${FUNCTION_NAME} \
--zip-file fileb://function.zip
出力
[cloudshell-user@ip-10-132-89-176 ~]$ # ソースコードの更新
[cloudshell-user@ip-10-132-89-176 ~]$ cat << EOF > lambda_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
[cloudshell-user@ip-10-132-89-176 ~]$
[cloudshell-user@ip-10-132-89-176 ~]$ # デプロイパッケージの作成
[cloudshell-user@ip-10-132-89-176 ~]$ zip function.zip lambda_function.py
updating: lambda_function.py (deflated 45%)
[cloudshell-user@ip-10-132-89-176 ~]$
[cloudshell-user@ip-10-132-89-176 ~]$ # Lambda関数の更新
[cloudshell-user@ip-10-132-89-176 ~]$ aws lambda update-function-code \
> --function-name ${FUNCTION_NAME} \
> --zip-file fileb://function.zip
{
"FunctionName": "translate-function",
"FunctionArn": "arn:aws:lambda:ap-northeast-1:999999999999:function:translate-function",
"Runtime": "python3.8",
"Role": "arn:aws:iam::999999999999:role/translate-function-role",
"Handler": "lambda_function.lambda_handler",
"CodeSize": 434,
"Description": "",
"Timeout": 10,
"MemorySize": 256,
"LastModified": "2024-07-13T11:31:33.000+0000",
"CodeSha256": "Imcd+SL+u1nQ+JgEeEUcH6aXulz4/3qD7q6RGFMwd2I=",
"Version": "$LATEST",
"TracingConfig": {
"Mode": "PassThrough"
},
"RevisionId": "58a51fb9-3851-4d06-aa68-dc6f72663229",
"State": "Active",
"LastUpdateStatus": "InProgress",
"LastUpdateStatusReason": "The function is being created.",
"LastUpdateStatusReasonCode": "Creating",
"PackageType": "Zip",
"Architectures": [
"x86_64"
],
"EphemeralStorage": {
"Size": 512
},
"SnapStart": {
"ApplyOn": "None",
"OptimizationStatus": "Off"
},
"RuntimeVersionConfig": {
"RuntimeVersionArn": "arn:aws:lambda:ap-northeast-1::runtime:a768321bd39c88f083afe0a045064adc3615105a319dbbcd583856654db68283"
},
"LoggingConfig": {
"LogFormat": "Text",
"LogGroup": "/aws/lambda/translate-function"
}
}
IAMロールを修正
コマンド
ATTACH_POLICY_NAME="TranslateFullAccess" \
&& echo ${ATTACH_POLICY_NAME}
# IAMロールにポリシーをアタッチ
aws iam attach-role-policy \
--role-name ${ROLE_NAME} \
--policy-arn arn:aws:iam::aws:policy/${ATTACH_POLICY_NAME}
出力
[cloudshell-user@ip-10-132-89-176 ~]$ ATTACH_POLICY_NAME="TranslateFullAccess" \
> && echo ${ATTACH_POLICY_NAME}
TranslateFullAccess
[cloudshell-user@ip-10-132-89-176 ~]$
[cloudshell-user@ip-10-132-89-176 ~]$ # IAMロールにポリシーをアタッチ
[cloudshell-user@ip-10-132-89-176 ~]$ aws iam attach-role-policy \
> --role-name ${ROLE_NAME} \
> --policy-arn arn:aws:iam::aws:policy/${ATTACH_POLICY_NAME}
Lambda関数のテスト実行
コマンド
# テスト実行
aws lambda invoke \
--function-name ${FUNCTION_NAME} \
--payload `echo ${EVENT} | base64 -w 0` \
outputfile.txt
cat outputfile.txt
出力
[cloudshell-user@ip-10-132-89-176 ~]$ # テスト実行
[cloudshell-user@ip-10-132-89-176 ~]$ aws lambda invoke \
> --function-name ${FUNCTION_NAME} \
> --payload `echo ${EVENT} | base64 -w 0` \
> outputfile.txt
{
"StatusCode": 200,
"ExecutedVersion": "$LATEST"
}
[cloudshell-user@ip-10-132-89-176 ~]$
[cloudshell-user@ip-10-132-89-176 ~]$ cat outputfile.txt
{"statusCode": 200, "body": "{\"output_text\": \"Good morning\"}"}
Lambda用ソースコードの更新
コマンド
# ソースコードの更新
cat << EOF > lambda_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
# デプロイパッケージの作成
zip function.zip lambda_function.py
# Lambda関数の更新
aws lambda update-function-code \
--function-name ${FUNCTION_NAME} \
--zip-file fileb://function.zip
出力
[cloudshell-user@ip-10-132-89-176 ~]$ # ソースコードの更新
[cloudshell-user@ip-10-132-89-176 ~]$ cat << EOF > lambda_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
[cloudshell-user@ip-10-132-89-176 ~]$
[cloudshell-user@ip-10-132-89-176 ~]$ # デプロイパッケージの作成
[cloudshell-user@ip-10-132-89-176 ~]$ zip function.zip lambda_function.py
updating: lambda_function.py (deflated 44%)
[cloudshell-user@ip-10-132-89-176 ~]$
[cloudshell-user@ip-10-132-89-176 ~]$ # Lambda関数の更新
[cloudshell-user@ip-10-132-89-176 ~]$ aws lambda update-function-code \
> --function-name ${FUNCTION_NAME} \
> --zip-file fileb://function.zip
{
"FunctionName": "translate-function",
"FunctionArn": "arn:aws:lambda:ap-northeast-1:999999999999:function:translate-function",
"Runtime": "python3.8",
"Role": "arn:aws:iam::999999999999:role/translate-function-role",
"Handler": "lambda_function.lambda_handler",
"CodeSize": 435,
"Description": "",
"Timeout": 10,
"MemorySize": 256,
"LastModified": "2024-07-13T11:58:01.000+0000",
"CodeSha256": "IzTNqG84eDihL3zaRBo7+Vcu77ZB/u+ZSAJWC9pdZac=",
"Version": "$LATEST",
"TracingConfig": {
"Mode": "PassThrough"
},
"RevisionId": "f9500e26-d906-486f-88ee-151187e0518c",
"State": "Active",
"LastUpdateStatus": "InProgress",
"LastUpdateStatusReason": "The function is being created.",
"LastUpdateStatusReasonCode": "Creating",
"PackageType": "Zip",
"Architectures": [
"x86_64"
],
"EphemeralStorage": {
"Size": 512
},
"SnapStart": {
"ApplyOn": "None",
"OptimizationStatus": "Off"
},
"RuntimeVersionConfig": {
"RuntimeVersionArn": "arn:aws:lambda:ap-northeast-1::runtime:a768321bd39c88f083afe0a045064adc3615105a319dbbcd583856654db68283"
},
"LoggingConfig": {
"LogFormat": "Text",
"LogGroup": "/aws/lambda/translate-function"
}
}
Lambda関数のテスト実行
コマンド
# テスト実行
aws lambda invoke \
--function-name ${FUNCTION_NAME} \
--payload `echo ${EVENT} | base64 -w 0` \
outputfile.txt
cat outputfile.txt
出力
[cloudshell-user@ip-10-132-89-176 ~]$ # テスト実行
[cloudshell-user@ip-10-132-89-176 ~]$ aws lambda invoke \
> --function-name ${FUNCTION_NAME} \
> --payload `echo ${EVENT} | base64 -w 0` \
> outputfile.txt
{
"StatusCode": 200,
"ExecutedVersion": "$LATEST"
}
[cloudshell-user@ip-10-132-89-176 ~]$
[cloudshell-user@ip-10-132-89-176 ~]$ cat outputfile.txt
{"statusCode": 200, "body": "{\"output_text\": \"Goodnight\"}"}
3. Amazon API Gateway ハンズオン① API Gateway を単体で使ってみる
変数
コマンド
# API名
API_NAME="translate-api" \
&& echo ${API_NAME}
# リソース名
RESOURCE_NAME="sample" \
&& echo ${RESOURCE_NAME}
出力
[cloudshell-user@ip-10-134-14-200 ~]$ # API名
[cloudshell-user@ip-10-134-14-200 ~]$ API_NAME="translate-api" \
> && echo ${API_NAME}
translate-api
[cloudshell-user@ip-10-134-14-200 ~]$
[cloudshell-user@ip-10-134-14-200 ~]$ # リソース名
[cloudshell-user@ip-10-134-14-200 ~]$ RESOURCE_NAME="sample" \
> && echo ${RESOURCE_NAME}
sample
API Gateway APIの作成
コマンド
aws apigateway create-rest-api \
--name ${API_NAME}
出力
[cloudshell-user@ip-10-134-14-200 ~]$ aws apigateway create-rest-api \
> --name ${API_NAME}
{
"id": "jvalq6w8li",
"name": "translate-api",
"createdDate": "2024-07-14T02:47:29+00:00",
"apiKeySource": "HEADER",
"endpointConfiguration": {
"types": [
"EDGE"
]
},
"disableExecuteApiEndpoint": false,
"rootResourceId": "okjuj6zkl4"
}
API Gateway API IDの取得
コマンド
# API IDの取得
RESET_API_ID=$(
aws apigateway get-rest-apis \
--query "items[?name=='${API_NAME}'].id" \
--output text
) \
&& echo ${RESET_API_ID}
出力
[cloudshell-user@ip-10-134-14-200 ~]$ # API IDの取得
[cloudshell-user@ip-10-134-14-200 ~]$ RESET_API_ID=$(
> aws apigateway get-rest-apis \
> --query "items[?name=='${API_NAME}'].id" \
> --output text
> ) \
> && echo ${RESET_API_ID}
jvalq6w8li
API GatewayルートリソースIDの取得
コマンド
# ルートリソースIDの取得
PARENT_ID=$(
aws apigateway get-resources \
--rest-api-id ${RESET_API_ID} \
--query "items[?path=='/'].id" \
--output text
) \
&& echo ${PARENT_ID}
出力
[cloudshell-user@ip-10-134-14-200 ~]$ # ルートリソースIDの取得
[cloudshell-user@ip-10-134-14-200 ~]$ PARENT_ID=$(
> aws apigateway get-resources \
> --rest-api-id ${RESET_API_ID} \
> --query "items[?path=='/'].id" \
> --output text
> ) \
> && echo ${PARENT_ID}
okjuj6zkl4
API Gatewayリソースの作成
コマンド
# リソースの作成
aws apigateway create-resource \
--rest-api-id ${RESET_API_ID} \
--parent-id ${PARENT_ID} \
--path-part ${RESOURCE_NAME}
# リソースIDの取得
RESOURCE_ID=$(
aws apigateway get-resources \
--rest-api-id ${RESET_API_ID} \
--query "items[?path=='/${RESOURCE_NAME}'].id" \
--output text
) \
&& echo ${RESOURCE_ID}
出力
[cloudshell-user@ip-10-134-14-200 ~]$ # リソースの作成
[cloudshell-user@ip-10-134-14-200 ~]$ aws apigateway create-resource \
> --rest-api-id ${RESET_API_ID} \
> --parent-id ${PARENT_ID} \
> --path-part ${RESOURCE_NAME}
{
"id": "5wxri4",
"parentId": "okjuj6zkl4",
"pathPart": "sample",
"path": "/sample"
}
[cloudshell-user@ip-10-134-14-200 ~]$
[cloudshell-user@ip-10-134-14-200 ~]$ # リソースIDの取得
[cloudshell-user@ip-10-134-14-200 ~]$ RESOURCE_ID=$(
> aws apigateway get-resources \
> --rest-api-id ${RESET_API_ID} \
> --query "items[?path=='/${RESOURCE_NAME}'].id" \
> --output text
> ) \
> && echo ${RESOURCE_ID}
5wxri4
API Gateway GETメソッドの作成
コマンド
# GETメソッドの作成
aws apigateway put-method \
--rest-api-id ${RESET_API_ID} \
--resource-id ${RESOURCE_ID} \
--http-method GET \
--authorization-type NONE
出力
[cloudshell-user@ip-10-134-14-200 ~]$ # GETメソッドの作成
[cloudshell-user@ip-10-134-14-200 ~]$ aws apigateway put-method \
> --rest-api-id ${RESET_API_ID} \
> --resource-id ${RESOURCE_ID} \
> --http-method GET \
> --authorization-type NONE
{
"httpMethod": "GET",
"authorizationType": "NONE",
"apiKeyRequired": false
}
API Gateway統合の作成(Mock)
コマンド
# 統合の作成(Mock)
aws apigateway put-integration \
--rest-api-id ${RESET_API_ID} \
--resource-id ${RESOURCE_ID} \
--http-method GET \
--type MOCK \
--request-templates '{"application/json": "{\"statusCode\": 200}"}'
出力
[cloudshell-user@ip-10-134-14-200 ~]$ # 統合の作成(Mock)
[cloudshell-user@ip-10-134-14-200 ~]$ aws apigateway put-integration \
> --rest-api-id ${RESET_API_ID} \
> --resource-id ${RESOURCE_ID} \
> --http-method GET \
> --type MOCK \
> --request-templates '{"application/json": "{\"statusCode\": 200}"}'
{
"type": "MOCK",
"requestTemplates": {
"application/json": "{\"statusCode\": 200}"
},
"passthroughBehavior": "WHEN_NO_MATCH",
"timeoutInMillis": 29000,
"cacheNamespace": "5wxri4",
"cacheKeyParameters": []
}
API Gatewayレスポンスの設定
--response-templates '{"application/json": '"${ESCAPED_JSON}"'}'
${ESCAPED_JSON}のJSONは改行コード、ダブルクォートをエスケープする必要がある
下記にてJSONをエスケープ形式に変換
ESCAPED_JSON=$(echo "${JSON_TEMPLATE}" | jq -Rs .)
コマンド
# メソッドレスポンスの設定
aws apigateway put-method-response \
--rest-api-id ${RESET_API_ID} \
--resource-id ${RESOURCE_ID} \
--http-method GET \
--status-code 200 \
--response-models '{"application/json": "Empty"}'
# テンプレートの作成
JSON_TEMPLATE=$(cat << EOF
{
"statusCode": 200,
"body": [
{
"report_id": 5,
"report_title" : "Hello, world"
},
{
"report_id": 7,
"report_title" : "Good morning!"
}
]
}
EOF
) \
&& echo ${JSON_TEMPLATE}
# JSONフォーマットの確認
echo ${JSON_TEMPLATE} | python -m json.tool
# JSONをエスケープ形式に変換
ESCAPED_JSON=$(echo "${JSON_TEMPLATE}" | jq -Rs .)
# JSONフォーマットの確認
echo ${ESCAPED_JSON} | python -m json.tool
# 統合レスポンスの設定
aws apigateway put-integration-response \
--rest-api-id ${RESET_API_ID} \
--resource-id ${RESOURCE_ID} \
--http-method GET \
--status-code 200 \
--selection-pattern '' \
--response-templates '{"application/json": '"${ESCAPED_JSON}"'}'
出力
[cloudshell-user@ip-10-134-14-200 ~]$ # メソッドレスポンスの設定
[cloudshell-user@ip-10-134-14-200 ~]$ aws apigateway put-method-response \
> --rest-api-id ${RESET_API_ID} \
> --resource-id ${RESOURCE_ID} \
> --http-method GET \
> --status-code 200 \
> --response-models '{"application/json": "Empty"}'
{
"statusCode": "200",
"responseModels": {
"application/json": "Empty"
}
}
[cloudshell-user@ip-10-134-14-200 ~]$
[cloudshell-user@ip-10-134-14-200 ~]$ # テンプレートの作成
[cloudshell-user@ip-10-134-14-200 ~]$ JSON_TEMPLATE=$(cat << EOF
> {
> "statusCode": 200,
> "body": [
> {
> "report_id": 5,
> "report_title" : "Hello, world"
> },
> {
> "report_id": 7,
> "report_title" : "Good morning!"
> }
> ]
> }
> EOF
> ) \
> && echo ${JSON_TEMPLATE}
{ "statusCode": 200, "body": [ { "report_id": 5, "report_title" : "Hello, world" }, { "report_id": 7, "report_title" : "Good morning!" } ] }
[cloudshell-user@ip-10-134-14-200 ~]$
[cloudshell-user@ip-10-134-14-200 ~]$ # JSONフォーマットの確認
[cloudshell-user@ip-10-134-14-200 ~]$ echo ${JSON_TEMPLATE} | python -m json.tool
{
"statusCode": 200,
"body": [
{
"report_id": 5,
"report_title": "Hello, world"
},
{
"report_id": 7,
"report_title": "Good morning!"
}
]
}
[cloudshell-user@ip-10-134-14-200 ~]$
[cloudshell-user@ip-10-134-14-200 ~]$ # JSONをエスケープ形式に変換
[cloudshell-user@ip-10-134-14-200 ~]$ ESCAPED_JSON=$(echo "${JSON_TEMPLATE}" | jq -Rs .)
[cloudshell-user@ip-10-134-14-200 ~]$
[cloudshell-user@ip-10-134-14-200 ~]$ # JSONフォーマットの確認
[cloudshell-user@ip-10-134-14-200 ~]$ echo ${ESCAPED_JSON} | python -m json.tool
"{\n \"statusCode\": 200,\n \"body\": [\n {\n \"report_id\": 5,\n \"report_title\" : \"Hello, world\"\n },\n {\n \"report_id\": 7,\n \"report_title\" : \"Good morning!\"\n }\n ]\n}\n"
[cloudshell-user@ip-10-134-14-200 ~]$
[cloudshell-user@ip-10-134-14-200 ~]$ # 統合レスポンスの設定
[cloudshell-user@ip-10-134-14-200 ~]$ aws apigateway put-integration-response \
> --rest-api-id ${RESET_API_ID} \
> --resource-id ${RESOURCE_ID} \
> --http-method GET \
> --status-code 200 \
> --selection-pattern '' \
> --response-templates '{"application/json": '"${ESCAPED_JSON}"'}'
{
"statusCode": "200",
"selectionPattern": "",
"responseTemplates": {
"application/json": "{\n \"statusCode\": 200,\n \"body\": [\n {\n \"report_id\": 5,\n \"report_title\" : \"Hello, world\"\n },\n {\n \"report_id\": 7,\n \"report_title\" : \"Good morning!\"\n }\n ]\n}\n"
}
}
Lambda関数のテスト実行
コマンド
aws apigateway test-invoke-method \
--rest-api-id ${RESET_API_ID} \
--resource-id ${RESOURCE_ID} \
--http-method GET
出力
[cloudshell-user@ip-10-134-14-200 ~]$ aws apigateway test-invoke-method \
> --rest-api-id ${RESET_API_ID} \
> --resource-id ${RESOURCE_ID} \
> --http-method GET
{
"status": 200,
"body": "{\n \"statusCode\": 200,\n \"body\": [\n {\n \"report_id\": 5,\n \"report_title\" : \"Hello, world\"\n },\n {\n \"report_id\": 7,\n \"report_title\" : \"Good morning!\"\n }\n ]\n}\n",
"headers": {
"Content-Type": "application/json"
},
"multiValueHeaders": {
"Content-Type": [
"application/json"
]
},
"log": "Execution log for request b93368df-81ee-4d2f-b996-2c6fefb8a6e4\nSun Jul 14 02:56:13 UTC 2024 : Starting execution for request: b93368df-81ee-4d2f-b996-2c6fefb8a6e4\nSun Jul 14 02:56:13 UTC 2024 : HTTP Method: GET, Resource Path: /sample\nSun Jul 14 02:56:13 UTC 2024 : Method request path: {}\nSun Jul 14 02:56:13 UTC 2024 : Method request query string: {}\nSun Jul 14 02:56:13 UTC 2024 : Method request headers: {}\nSun Jul 14 02:56:13 UTC 2024 : Method request body before transformations: \nSun Jul 14 02:56:13 UTC 2024 : Method response body after transformations: {\n \"statusCode\": 200,\n \"body\": [\n {\n \"report_id\": 5,\n \"report_title\" : \"Hello, world\"\n },\n {\n \"report_id\": 7,\n \"report_title\" : \"Good morning!\"\n }\n ]\n}\n\nSun Jul 14 02:56:13 UTC 2024 : Method response headers: {Content-Type=application/json}\nSun Jul 14 02:56:13 UTC 2024 : Successfully completed execution\nSun Jul 14 02:56:13 UTC 2024 : Method completed with status: 200\n",
"latency": 11
}
API Gatewayのデプロイ
コマンド
# 変数
STAGE_NAME="dev" \
&& echo ${STAGE_NAME}
# デプロイ
aws apigateway create-deployment \
--rest-api-id ${RESET_API_ID} \
--stage-name ${STAGE_NAME}
出力
[cloudshell-user@ip-10-134-14-200 ~]$ # 変数
[cloudshell-user@ip-10-134-14-200 ~]$ STAGE_NAME="dev" \
> && echo ${STAGE_NAME}
dev
[cloudshell-user@ip-10-134-14-200 ~]$
[cloudshell-user@ip-10-134-14-200 ~]$ # デプロイ
[cloudshell-user@ip-10-134-14-200 ~]$ aws apigateway create-deployment \
> --rest-api-id ${RESET_API_ID} \
> --stage-name ${STAGE_NAME}
{
"id": "frmb2a",
"createdDate": "2024-07-14T03:05:44+00:00"
}
4. Amazon API Gateway ハンズオン② API Gateway と Lambda を組み合わせる
API Gateway sampleリソースの削除
コマンド
# リソースの削除
aws apigateway delete-resource \
--rest-api-id ${RESET_API_ID} \
--resource-id ${RESOURCE_ID}
出力
[cloudshell-user@ip-10-134-14-200 ~]$ aws apigateway delete-resource \
> --rest-api-id ${RESET_API_ID} \
> --resource-id ${RESOURCE_ID}
API Gateway translateリソースの作成
コマンド
# 変数
RESOURCE_NAME="translate" \
&& echo $RESOURCE_NAME{}
# リソースの作成
aws apigateway create-resource \
--rest-api-id ${RESET_API_ID} \
--parent-id ${PARENT_ID} \
--path-part ${RESOURCE_NAME}
# リソースIDの取得
RESOURCE_ID=$(
aws apigateway get-resources \
--rest-api-id ${RESET_API_ID} \
--query "items[?path=='/${RESOURCE_NAME}'].id" \
--output text
) \
&& echo ${RESOURCE_ID}
出力
[cloudshell-user@ip-10-134-14-200 ~]$ # 変数
[cloudshell-user@ip-10-134-14-200 ~]$ RESOURCE_NAME="translate" \
> && echo $RESOURCE_NAME{}
translate{}
[cloudshell-user@ip-10-134-14-200 ~]$
[cloudshell-user@ip-10-134-14-200 ~]$ # リソースの作成
[cloudshell-user@ip-10-134-14-200 ~]$ aws apigateway create-resource \
> --rest-api-id ${RESET_API_ID} \
> --parent-id ${PARENT_ID} \
> --path-part ${RESOURCE_NAME}
{
"id": "yphb9r",
"parentId": "okjuj6zkl4",
"pathPart": "translate",
"path": "/translate"
}
[cloudshell-user@ip-10-134-14-200 ~]$
[cloudshell-user@ip-10-134-14-200 ~]$ # リソースIDの取得
[cloudshell-user@ip-10-134-14-200 ~]$ RESOURCE_ID=$(
> aws apigateway get-resources \
> --rest-api-id ${RESET_API_ID} \
> --query "items[?path=='/${RESOURCE_NAME}'].id" \
> --output text
> ) \
> && echo ${RESOURCE_ID}
yphb9r
API Gateway GETメソッドの作成
コマンド
# GETメソッドの作成
aws apigateway put-method \
--rest-api-id ${RESET_API_ID} \
--resource-id ${RESOURCE_ID} \
--http-method GET \
--authorization-type NONE \
--request-parameters "method.request.querystring.input_text=true"
出力
[cloudshell-user@ip-10-134-14-200 ~]$ # GETメソッドの作成
[cloudshell-user@ip-10-134-14-200 ~]$ aws apigateway put-method \
> --rest-api-id ${RESET_API_ID} \
> --resource-id ${RESOURCE_ID} \
> --http-method GET \
> --authorization-type NONE \
> --request-parameters "method.request.querystring.input_text=true"
{
"httpMethod": "GET",
"authorizationType": "NONE",
"apiKeyRequired": false,
"requestParameters": {
"method.request.querystring.input_text": true
}
}
API Gateway Lambdaプロキシ統合の設定
コマンド
# Lambdaプロキシ統合の設定
aws apigateway put-integration \
--rest-api-id ${RESET_API_ID} \
--resource-id ${RESOURCE_ID} \
--http-method GET \
--type AWS_PROXY \
--integration-http-method POST \
--uri "arn:aws:apigateway:ap-northeast-1:lambda:path/2015-03-31/functions/${FUNCTION_ARN}/invocations" \
--passthrough-behavior WHEN_NO_MATCH \
--content-handling CONVERT_TO_TEXT
出力
[cloudshell-user@ip-10-134-14-200 ~]$ # Lambdaプロキシ統合の設定
[cloudshell-user@ip-10-134-14-200 ~]$ aws apigateway put-integration \
> --rest-api-id ${RESET_API_ID} \
> --resource-id ${RESOURCE_ID} \
> --http-method GET \
> --type AWS_PROXY \
> --integration-http-method POST \
> --uri "arn:aws:apigateway:ap-northeast-1:lambda:path/2015-03-31/functions/${FUNCTION_ARN}/invocations" \
> --passthrough-behavior WHEN_NO_MATCH \
> --content-handling CONVERT_TO_TEXT
{
"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:translate-function/invocations",
"passthroughBehavior": "WHEN_NO_MATCH",
"contentHandling": "CONVERT_TO_TEXT",
"timeoutInMillis": 29000,
"cacheNamespace": "yphb9r",
"cacheKeyParameters": []
}
API Gateway レスポンスの設定
コマンド
# メソッドレスポンスの設定
aws apigateway put-method-response \
--rest-api-id ${RESET_API_ID} \
--resource-id ${RESOURCE_ID} \
--http-method GET \
--status-code 200 \
--response-models '{"application/json": "Empty"}'
# 統合レスポンスの設定
aws apigateway put-integration-response \
--rest-api-id ${RESET_API_ID} \
--resource-id ${RESOURCE_ID} \
--http-method GET \
--status-code 200 \
--selection-pattern '' \
--response-templates '{"application/json": ""}'
出力
[cloudshell-user@ip-10-134-14-200 ~]$ aws apigateway put-method-response \
> --rest-api-id ${RESET_API_ID} \
> --resource-id ${RESOURCE_ID} \
> --http-method GET \
> --status-code 200 \
> --response-models '{"application/json": "Empty"}'
{
"statusCode": "200",
"responseModels": {
"application/json": "Empty"
}
}
[cloudshell-user@ip-10-134-14-200 ~]$
[cloudshell-user@ip-10-134-14-200 ~]$ # 統合レスポンスの設定
[cloudshell-user@ip-10-134-14-200 ~]$ aws apigateway put-integration-response \
> --rest-api-id ${RESET_API_ID} \
> --resource-id ${RESOURCE_ID} \
> --http-method GET \
> --status-code 200 \
> --selection-pattern '' \
> --response-templates '{"application/json": ""}'
{
"statusCode": "200",
"selectionPattern": "",
"responseTemplates": {
"application/json": null
}
}
Lambda用ソースコードの更新
コマンド
# ソースコードの更新
cat << EOF > lambda_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
# デプロイパッケージの作成
zip function.zip lambda_function.py
# Lambda関数の更新
aws lambda update-function-code \
--function-name ${FUNCTION_NAME} \
--zip-file fileb://function.zip
出力
[cloudshell-user@ip-10-134-14-200 ~]$ # ソースコードの更新
[cloudshell-user@ip-10-134-14-200 ~]$ cat << EOF > lambda_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
[cloudshell-user@ip-10-134-14-200 ~]$
[cloudshell-user@ip-10-134-14-200 ~]$ # デプロイパッケージの作成
[cloudshell-user@ip-10-134-14-200 ~]$ zip function.zip lambda_function.py
updating: lambda_function.py (deflated 46%)
[cloudshell-user@ip-10-134-14-200 ~]$
[cloudshell-user@ip-10-134-14-200 ~]$ # Lambda関数の更新
[cloudshell-user@ip-10-134-14-200 ~]$ aws lambda update-function-code \
> --function-name ${FUNCTION_NAME} \
> --zip-file fileb://function.zip
{
"FunctionName": "translate-function",
"FunctionArn": "arn:aws:lambda:ap-northeast-1:999999999999:function:translate-function",
"Runtime": "python3.8",
"Role": "arn:aws:iam::999999999999:role/translate-function-role",
"Handler": "lambda_function.lambda_handler",
"CodeSize": 480,
"Description": "",
"Timeout": 10,
"MemorySize": 256,
"LastModified": "2024-07-14T05:40:01.000+0000",
"CodeSha256": "vobstg6e0kd9a1FLK3FUZd6RIolhXQ+yk9EtzgR9kNU=",
"Version": "$LATEST",
"TracingConfig": {
"Mode": "PassThrough"
},
"RevisionId": "3ff59c3c-fe71-4689-b901-8060cd4ccd02",
"State": "Active",
"LastUpdateStatus": "InProgress",
"LastUpdateStatusReason": "The function is being created.",
"LastUpdateStatusReasonCode": "Creating",
"PackageType": "Zip",
"Architectures": [
"x86_64"
],
"EphemeralStorage": {
"Size": 512
},
"SnapStart": {
"ApplyOn": "None",
"OptimizationStatus": "Off"
},
"RuntimeVersionConfig": {
"RuntimeVersionArn": "arn:aws:lambda:ap-northeast-1::runtime:a768321bd39c88f083afe0a045064adc3615105a319dbbcd583856654db68283"
},
"LoggingConfig": {
"LogFormat": "Text",
"LogGroup": "/aws/lambda/translate-function"
}
}
Lambda関数のテスト実行
コマンド
# イベントの作成
EVENT=$(cat << EOF
{
"body": "eyJ0ZXN0IjoiYm9keSJ9",
"resource": "/{proxy+}",
"path": "/path/to/resource",
"httpMethod": "POST",
"isBase64Encoded": true,
"queryStringParameters": {
"input_text": "こんにちは"
},
"multiValueQueryStringParameters": {
"foo": [
"bar"
]
},
"pathParameters": {
"proxy": "/path/to/resource"
},
"stageVariables": {
"baz": "qux"
},
"headers": {
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8",
"Accept-Encoding": "gzip, deflate, sdch",
"Accept-Language": "en-US,en;q=0.8",
"Cache-Control": "max-age=0",
"CloudFront-Forwarded-Proto": "https",
"CloudFront-Is-Desktop-Viewer": "true",
"CloudFront-Is-Mobile-Viewer": "false",
"CloudFront-Is-SmartTV-Viewer": "false",
"CloudFront-Is-Tablet-Viewer": "false",
"CloudFront-Viewer-Country": "US",
"Host": "1234567890.execute-api.us-east-1.amazonaws.com",
"Upgrade-Insecure-Requests": "1",
"User-Agent": "Custom User Agent String",
"Via": "1.1 08f323deadbeefa7af34d5feb414ce27.cloudfront.net (CloudFront)",
"X-Amz-Cf-Id": "cDehVQoZnx43VYQb9j2-nvCh-9z396Uhbp027Y2JvkCPNLmGJHqlaA==",
"X-Forwarded-For": "127.0.0.1, 127.0.0.2",
"X-Forwarded-Port": "443",
"X-Forwarded-Proto": "https"
},
"multiValueHeaders": {
"Accept": [
"text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8"
],
"Accept-Encoding": [
"gzip, deflate, sdch"
],
"Accept-Language": [
"en-US,en;q=0.8"
],
"Cache-Control": [
"max-age=0"
],
"CloudFront-Forwarded-Proto": [
"https"
],
"CloudFront-Is-Desktop-Viewer": [
"true"
],
"CloudFront-Is-Mobile-Viewer": [
"false"
],
"CloudFront-Is-SmartTV-Viewer": [
"false"
],
"CloudFront-Is-Tablet-Viewer": [
"false"
],
"CloudFront-Viewer-Country": [
"US"
],
"Host": [
"0123456789.execute-api.us-east-1.amazonaws.com"
],
"Upgrade-Insecure-Requests": [
"1"
],
"User-Agent": [
"Custom User Agent String"
],
"Via": [
"1.1 08f323deadbeefa7af34d5feb414ce27.cloudfront.net (CloudFront)"
],
"X-Amz-Cf-Id": [
"cDehVQoZnx43VYQb9j2-nvCh-9z396Uhbp027Y2JvkCPNLmGJHqlaA=="
],
"X-Forwarded-For": [
"127.0.0.1, 127.0.0.2"
],
"X-Forwarded-Port": [
"443"
],
"X-Forwarded-Proto": [
"https"
]
},
"requestContext": {
"accountId": "123456789012",
"resourceId": "123456",
"stage": "prod",
"requestId": "c6af9ac6-7b61-11e6-9a41-93e8deadbeef",
"requestTime": "09/Apr/2015:12:34:56 +0000",
"requestTimeEpoch": 1428582896000,
"identity": {
"cognitoIdentityPoolId": null,
"accountId": null,
"cognitoIdentityId": null,
"caller": null,
"accessKey": null,
"sourceIp": "127.0.0.1",
"cognitoAuthenticationType": null,
"cognitoAuthenticationProvider": null,
"userArn": null,
"userAgent": "Custom User Agent String",
"user": null
},
"path": "/prod/path/to/resource",
"resourcePath": "/{proxy+}",
"httpMethod": "POST",
"apiId": "1234567890",
"protocol": "HTTP/1.1"
}
}
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
出力
[cloudshell-user@ip-10-134-14-200 ~]$ # イベントの作成
[cloudshell-user@ip-10-134-14-200 ~]$ EVENT=$(cat << EOF
> {
> "body": "eyJ0ZXN0IjoiYm9keSJ9",
> "resource": "/{proxy+}",
> "path": "/path/to/resource",
> "httpMethod": "POST",
> "isBase64Encoded": true,
> "queryStringParameters": {
> "input_text": "こんにちは"
> },
> "multiValueQueryStringParameters": {
> "foo": [
> "bar"
> ]
> },
> "pathParameters": {
> "proxy": "/path/to/resource"
> },
> "stageVariables": {
> "baz": "qux"
> },
> "headers": {
> "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8",
> "Accept-Encoding": "gzip, deflate, sdch",
> "Accept-Language": "en-US,en;q=0.8",
> "Cache-Control": "max-age=0",
> "CloudFront-Forwarded-Proto": "https",
> "CloudFront-Is-Desktop-Viewer": "true",
> "CloudFront-Is-Mobile-Viewer": "false",
> "CloudFront-Is-SmartTV-Viewer": "false",
> "CloudFront-Is-Tablet-Viewer": "false",
> "CloudFront-Viewer-Country": "US",
> "Host": "1234567890.execute-api.us-east-1.amazonaws.com",
> "Upgrade-Insecure-Requests": "1",
> "User-Agent": "Custom User Agent String",
> "Via": "1.1 08f323deadbeefa7af34d5feb414ce27.cloudfront.net (CloudFront)",
> "X-Amz-Cf-Id": "cDehVQoZnx43VYQb9j2-nvCh-9z396Uhbp027Y2JvkCPNLmGJHqlaA==",
> "X-Forwarded-For": "127.0.0.1, 127.0.0.2",
> "X-Forwarded-Port": "443",
> "X-Forwarded-Proto": "https"
> },
> "multiValueHeaders": {
> "Accept": [
> "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8"
> ],
> "Accept-Encoding": [
> "gzip, deflate, sdch"
> ],
> "Accept-Language": [
> "en-US,en;q=0.8"
> ],
> "Cache-Control": [
> "max-age=0"
> ],
> "CloudFront-Forwarded-Proto": [
> "https"
> ],
> "CloudFront-Is-Desktop-Viewer": [
> "true"
> ],
> "CloudFront-Is-Mobile-Viewer": [
> "false"
> ],
> "CloudFront-Is-SmartTV-Viewer": [
> "false"
> ],
> "CloudFront-Is-Tablet-Viewer": [
> "false"
> ],
> "CloudFront-Viewer-Country": [
> "US"
> ],
> "Host": [
> "0123456789.execute-api.us-east-1.amazonaws.com"
> ],
> "Upgrade-Insecure-Requests": [
> "1"
> ],
> "User-Agent": [
> "Custom User Agent String"
> ],
> "Via": [
> "1.1 08f323deadbeefa7af34d5feb414ce27.cloudfront.net (CloudFront)"
> ],
> "X-Amz-Cf-Id": [
> "cDehVQoZnx43VYQb9j2-nvCh-9z396Uhbp027Y2JvkCPNLmGJHqlaA=="
> ],
> "X-Forwarded-For": [
> "127.0.0.1, 127.0.0.2"
> ],
> "X-Forwarded-Port": [
> "443"
> ],
> "X-Forwarded-Proto": [
> "https"
> ]
> },
> "requestContext": {
> "accountId": "123456789012",
> "resourceId": "123456",
> "stage": "prod",
> "requestId": "c6af9ac6-7b61-11e6-9a41-93e8deadbeef",
> "requestTime": "09/Apr/2015:12:34:56 +0000",
> "requestTimeEpoch": 1428582896000,
> "identity": {
> "cognitoIdentityPoolId": null,
> "accountId": null,
> "cognitoIdentityId": null,
> "caller": null,
> "accessKey": null,
> "sourceIp": "127.0.0.1",
> "cognitoAuthenticationType": null,
> "cognitoAuthenticationProvider": null,
> "userArn": null,
> "userAgent": "Custom User Agent String",
> "user": null
> },
> "path": "/prod/path/to/resource",
> "resourcePath": "/{proxy+}",
> "httpMethod": "POST",
> "apiId": "1234567890",
> "protocol": "HTTP/1.1"
> }
> }
> EOF
> ) \
> && echo ${EVENT}
{ "body": "eyJ0ZXN0IjoiYm9keSJ9", "resource": "/{proxy+}", "path": "/path/to/resource", "httpMethod": "POST", "isBase64Encoded": true, "queryStringParameters": { "input_text": "こんにちは" }, "multiValueQueryStringParameters": { "foo": [ "bar" ] }, "pathParameters": { "proxy": "/path/to/resource" }, "stageVariables": { "baz": "qux" }, "headers": { "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8", "Accept-Encoding": "gzip, deflate, sdch", "Accept-Language": "en-US,en;q=0.8", "Cache-Control": "max-age=0", "CloudFront-Forwarded-Proto": "https", "CloudFront-Is-Desktop-Viewer": "true", "CloudFront-Is-Mobile-Viewer": "false", "CloudFront-Is-SmartTV-Viewer": "false", "CloudFront-Is-Tablet-Viewer": "false", "CloudFront-Viewer-Country": "US", "Host": "1234567890.execute-api.us-east-1.amazonaws.com", "Upgrade-Insecure-Requests": "1", "User-Agent": "Custom User Agent String", "Via": "1.1 08f323deadbeefa7af34d5feb414ce27.cloudfront.net (CloudFront)", "X-Amz-Cf-Id": "cDehVQoZnx43VYQb9j2-nvCh-9z396Uhbp027Y2JvkCPNLmGJHqlaA==", "X-Forwarded-For": "127.0.0.1, 127.0.0.2", "X-Forwarded-Port": "443", "X-Forwarded-Proto": "https" }, "multiValueHeaders": { "Accept": [ "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8" ], "Accept-Encoding": [ "gzip, deflate, sdch" ], "Accept-Language": [ "en-US,en;q=0.8" ], "Cache-Control": [ "max-age=0" ], "CloudFront-Forwarded-Proto": [ "https" ], "CloudFront-Is-Desktop-Viewer": [ "true" ], "CloudFront-Is-Mobile-Viewer": [ "false" ], "CloudFront-Is-SmartTV-Viewer": [ "false" ], "CloudFront-Is-Tablet-Viewer": [ "false" ], "CloudFront-Viewer-Country": [ "US" ], "Host": [ "0123456789.execute-api.us-east-1.amazonaws.com" ], "Upgrade-Insecure-Requests": [ "1" ], "User-Agent": [ "Custom User Agent String" ], "Via": [ "1.1 08f323deadbeefa7af34d5feb414ce27.cloudfront.net (CloudFront)" ], "X-Amz-Cf-Id": [ "cDehVQoZnx43VYQb9j2-nvCh-9z396Uhbp027Y2JvkCPNLmGJHqlaA==" ], "X-Forwarded-For": [ "127.0.0.1, 127.0.0.2" ], "X-Forwarded-Port": [ "443" ], "X-Forwarded-Proto": [ "https" ] }, "requestContext": { "accountId": "123456789012", "resourceId": "123456", "stage": "prod", "requestId": "c6af9ac6-7b61-11e6-9a41-93e8deadbeef", "requestTime": "09/Apr/2015:12:34:56 +0000", "requestTimeEpoch": 1428582896000, "identity": { "cognitoIdentityPoolId": null, "accountId": null, "cognitoIdentityId": null, "caller": null, "accessKey": null, "sourceIp": "127.0.0.1", "cognitoAuthenticationType": null, "cognitoAuthenticationProvider": null, "userArn": null, "userAgent": "Custom User Agent String", "user": null }, "path": "/prod/path/to/resource", "resourcePath": "/{proxy+}", "httpMethod": "POST", "apiId": "1234567890", "protocol": "HTTP/1.1" } }
[cloudshell-user@ip-10-134-14-200 ~]$
[cloudshell-user@ip-10-134-14-200 ~]$ # JSONフォーマットの確認
[cloudshell-user@ip-10-134-14-200 ~]$ echo ${EVENT} | python -m json.tool
{
"body": "eyJ0ZXN0IjoiYm9keSJ9",
"resource": "/{proxy+}",
"path": "/path/to/resource",
"httpMethod": "POST",
"isBase64Encoded": true,
"queryStringParameters": {
"input_text": "\u3053\u3093\u306b\u3061\u306f"
},
"multiValueQueryStringParameters": {
"foo": [
"bar"
]
},
"pathParameters": {
"proxy": "/path/to/resource"
},
"stageVariables": {
"baz": "qux"
},
"headers": {
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8",
"Accept-Encoding": "gzip, deflate, sdch",
"Accept-Language": "en-US,en;q=0.8",
"Cache-Control": "max-age=0",
"CloudFront-Forwarded-Proto": "https",
"CloudFront-Is-Desktop-Viewer": "true",
"CloudFront-Is-Mobile-Viewer": "false",
"CloudFront-Is-SmartTV-Viewer": "false",
"CloudFront-Is-Tablet-Viewer": "false",
"CloudFront-Viewer-Country": "US",
"Host": "1234567890.execute-api.us-east-1.amazonaws.com",
"Upgrade-Insecure-Requests": "1",
"User-Agent": "Custom User Agent String",
"Via": "1.1 08f323deadbeefa7af34d5feb414ce27.cloudfront.net (CloudFront)",
"X-Amz-Cf-Id": "cDehVQoZnx43VYQb9j2-nvCh-9z396Uhbp027Y2JvkCPNLmGJHqlaA==",
"X-Forwarded-For": "127.0.0.1, 127.0.0.2",
"X-Forwarded-Port": "443",
"X-Forwarded-Proto": "https"
},
"multiValueHeaders": {
"Accept": [
"text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8"
],
"Accept-Encoding": [
"gzip, deflate, sdch"
],
"Accept-Language": [
"en-US,en;q=0.8"
],
"Cache-Control": [
"max-age=0"
],
"CloudFront-Forwarded-Proto": [
"https"
],
"CloudFront-Is-Desktop-Viewer": [
"true"
],
"CloudFront-Is-Mobile-Viewer": [
"false"
],
"CloudFront-Is-SmartTV-Viewer": [
"false"
],
"CloudFront-Is-Tablet-Viewer": [
"false"
],
"CloudFront-Viewer-Country": [
"US"
],
"Host": [
"0123456789.execute-api.us-east-1.amazonaws.com"
],
"Upgrade-Insecure-Requests": [
"1"
],
"User-Agent": [
"Custom User Agent String"
],
"Via": [
"1.1 08f323deadbeefa7af34d5feb414ce27.cloudfront.net (CloudFront)"
],
"X-Amz-Cf-Id": [
"cDehVQoZnx43VYQb9j2-nvCh-9z396Uhbp027Y2JvkCPNLmGJHqlaA=="
],
"X-Forwarded-For": [
"127.0.0.1, 127.0.0.2"
],
"X-Forwarded-Port": [
"443"
],
"X-Forwarded-Proto": [
"https"
]
},
"requestContext": {
"accountId": "123456789012",
"resourceId": "123456",
"stage": "prod",
"requestId": "c6af9ac6-7b61-11e6-9a41-93e8deadbeef",
"requestTime": "09/Apr/2015:12:34:56 +0000",
"requestTimeEpoch": 1428582896000,
"identity": {
"cognitoIdentityPoolId": null,
"accountId": null,
"cognitoIdentityId": null,
"caller": null,
"accessKey": null,
"sourceIp": "127.0.0.1",
"cognitoAuthenticationType": null,
"cognitoAuthenticationProvider": null,
"userArn": null,
"userAgent": "Custom User Agent String",
"user": null
},
"path": "/prod/path/to/resource",
"resourcePath": "/{proxy+}",
"httpMethod": "POST",
"apiId": "1234567890",
"protocol": "HTTP/1.1"
}
}
[cloudshell-user@ip-10-134-14-200 ~]$
[cloudshell-user@ip-10-134-14-200 ~]$ # テスト実行
[cloudshell-user@ip-10-134-14-200 ~]$ aws lambda invoke \
> --function-name ${FUNCTION_NAME} \
> --payload `echo ${EVENT} | base64 -w 0` \
> outputfile.txt
{
"StatusCode": 200,
"ExecutedVersion": "$LATEST"
}
[cloudshell-user@ip-10-134-14-200 ~]$
[cloudshell-user@ip-10-134-14-200 ~]$ cat outputfile.txt
{"statusCode": 200, "body": "{\"output_text\": \"Hi\"}", "isBase64Encoded": false, "headers": {}}
API Gatewayのデプロイ
コマンド
# デプロイ
aws apigateway create-deployment \
--rest-api-id ${RESET_API_ID} \
--stage-name ${STAGE_NAME}
出力
[cloudshell-user@ip-10-134-14-200 ~]$ # デプロイ
[cloudshell-user@ip-10-134-14-200 ~]$ aws apigateway create-deployment \
> --rest-api-id ${RESET_API_ID} \
> --stage-name ${STAGE_NAME}
{
"id": "91sxdk",
"createdDate": "2024-07-14T08:52:50+00:00"
}
5. Amazon DynamoDB ハンズオン① テーブルを作ってみる
Amazon DynamoDBテーブル作成
コマンド
# 変数
TABLE_NAME="translate-history" \
&& echo ${TABLE_NAME}
# プライマリキー名
ATTRIBUTE_NAME="timestamp" \
&& echo ${ATTRIBUTE_NAME}
# 読み込みキャパシティーユニット:1
READCAPACITYUNITS=1
# 書き込みキャパシティーユニット:1
WRITECAPACITYUNITS=1
# テーブル作成
aws dynamodb create-table \
--table-name ${TABLE_NAME} \
--attribute-definitions AttributeName=timestamp,AttributeType=S \
--key-schema AttributeName=${ATTRIBUTE_NAME},KeyType=HASH \
--provisioned-throughput ReadCapacityUnits=${READCAPACITYUNITS},WriteCapacityUnits=${WRITECAPACITYUNITS}
出力
[cloudshell-user@ip-10-134-14-200 ~]$ # 変数
[cloudshell-user@ip-10-134-14-200 ~]$ TABLE_NAME="translate-history" \
> && echo ${TABLE_NAME}
translate-history
[cloudshell-user@ip-10-134-14-200 ~]$
[cloudshell-user@ip-10-134-14-200 ~]$ # プライマリキー名
[cloudshell-user@ip-10-134-14-200 ~]$ ATTRIBUTE_NAME="timestamp" \
> && echo ${ATTRIBUTE_NAME}
timestamp
[cloudshell-user@ip-10-134-14-200 ~]$
[cloudshell-user@ip-10-134-14-200 ~]$ # 読み込みキャパシティーユニット:1
[cloudshell-user@ip-10-134-14-200 ~]$ READCAPACITYUNITS=1
[cloudshell-user@ip-10-134-14-200 ~]$
[cloudshell-user@ip-10-134-14-200 ~]$ # 書き込みキャパシティーユニット:1
[cloudshell-user@ip-10-134-14-200 ~]$ WRITECAPACITYUNITS=1
[cloudshell-user@ip-10-134-14-200 ~]$
[cloudshell-user@ip-10-134-14-200 ~]$ # テーブル作成
[cloudshell-user@ip-10-134-14-200 ~]$ aws dynamodb create-table \
> --table-name ${TABLE_NAME} \
> --attribute-definitions AttributeName=timestamp,AttributeType=S \
> --key-schema AttributeName=${ATTRIBUTE_NAME},KeyType=HASH \
> --provisioned-throughput ReadCapacityUnits=${READCAPACITYUNITS},WriteCapacityUnits=${WRITECAPACITYUNITS}
{
"TableDescription": {
"AttributeDefinitions": [
{
"AttributeName": "timestamp",
"AttributeType": "S"
}
],
"TableName": "translate-history",
"KeySchema": [
{
"AttributeName": "timestamp",
"KeyType": "HASH"
}
],
"TableStatus": "CREATING",
"CreationDateTime": "2024-07-14T09:40:46.901000+00:00",
"ProvisionedThroughput": {
"NumberOfDecreasesToday": 0,
"ReadCapacityUnits": 1,
"WriteCapacityUnits": 1
},
"TableSizeBytes": 0,
"ItemCount": 0,
"TableArn": "arn:aws:dynamodb:ap-northeast-1:999999999999:table/translate-history",
"TableId": "28329b22-e74a-41ee-9e57-584592a726c9",
"DeletionProtectionEnabled": false
}
}
Amazon DynamoDBテーブル内項目の作成
コマンド
# 項目作成
aws dynamodb put-item \
--table-name ${TABLE_NAME} \
--item '{
"timestamp": {"S": "20191024183000"},
"input_text": {"S": "★こんにちは"},
"output_text": {"S": "★Hello"}
}'
出力
[cloudshell-user@ip-10-134-14-200 ~]$ # 項目作成
[cloudshell-user@ip-10-134-14-200 ~]$ aws dynamodb put-item \
> --table-name ${TABLE_NAME} \
> --item '{
> "timestamp": {"S": "20191024183000"},
> "input_text": {"S": "★こんにちは"},
> "output_text": {"S": "★Hello"}
> }'
6. Amazon DynamoDB ハンズオン② API Gateway と Lambda と DynamoDB を組み合わせる
Lamdba用ソースコードの更新
コマンド
# ソースコードの更新
cat << EOF > lambda_function.py
import json
import boto3
import datetime
translate = boto3.client(service_name='translate')
dynamodb_translate_history_tbl = boto3.resource('dynamodb').Table('translate-history')
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_text": input_text,
"output_text": output_text
}
)
return {
'statusCode': 200,
'body': json.dumps({
'output_text': output_text
}),
'isBase64Encoded': False,
'headers': {}
}
EOF
# デプロイパッケージの作成
zip function.zip lambda_function.py
# Lambda関数の更新
aws lambda update-function-code \
--function-name ${FUNCTION_NAME} \
--zip-file fileb://function.zip
出力
[cloudshell-user@ip-10-134-14-200 ~]$ cat << EOF > lambda_function.py
> import json
> import boto3
> import datetime
>
> translate = boto3.client(service_name='translate')
>
> dynamodb_translate_history_tbl = boto3.resource('dynamodb').Table('translate-history')
>
> 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_text": input_text,
> "output_text": output_text
> }
> )
>
> return {
> 'statusCode': 200,
> 'body': json.dumps({
> 'output_text': output_text
> }),
> 'isBase64Encoded': False,
> 'headers': {}
> }
> EOF
[cloudshell-user@ip-10-134-14-200 ~]$
[cloudshell-user@ip-10-134-14-200 ~]$ # デプロイパッケージの作成
[cloudshell-user@ip-10-134-14-200 ~]$ zip function.zip lambda_function.py
updating: lambda_function.py (deflated 53%)
[cloudshell-user@ip-10-134-14-200 ~]$
[cloudshell-user@ip-10-134-14-200 ~]$ # Lambda関数の更新
[cloudshell-user@ip-10-134-14-200 ~]$ aws lambda update-function-code \
> --function-name ${FUNCTION_NAME} \
> --zip-file fileb://function.zip
{
"FunctionName": "translate-function",
"FunctionArn": "arn:aws:lambda:ap-northeast-1:999999999999:function:translate-function",
"Runtime": "python3.8",
"Role": "arn:aws:iam::999999999999:role/translate-function-role",
"Handler": "lambda_function.lambda_handler",
"CodeSize": 595,
"Description": "",
"Timeout": 10,
"MemorySize": 256,
"LastModified": "2024-07-14T10:38:17.000+0000",
"CodeSha256": "MDk/lPJX18SMSIw5HOhSmOzZVNHkuZIjCNTsAtp5KPg=",
"Version": "$LATEST",
"TracingConfig": {
"Mode": "PassThrough"
},
"RevisionId": "8d78d184-ce09-4a0f-bb65-cf47a18b41dd",
"State": "Active",
"LastUpdateStatus": "InProgress",
"LastUpdateStatusReason": "The function is being created.",
"LastUpdateStatusReasonCode": "Creating",
"PackageType": "Zip",
"Architectures": [
"x86_64"
],
"EphemeralStorage": {
"Size": 512
},
"SnapStart": {
"ApplyOn": "None",
"OptimizationStatus": "Off"
},
"RuntimeVersionConfig": {
"RuntimeVersionArn": "arn:aws:lambda:ap-northeast-1::runtime:a768321bd39c88f083afe0a045064adc3615105a319dbbcd583856654db68283"
},
"LoggingConfig": {
"LogFormat": "Text",
"LogGroup": "/aws/lambda/translate-function"
}
}
IAMロールを修正
コマンド
# ポリシー名
ATTACH_POLICY_NAME="AmazonDynamoDBFullAccess" \
&& echo ${ATTACH_POLICY_NAME}
# IAMロールにポリシーをアタッチ
aws iam attach-role-policy \
--role-name ${ROLE_NAME} \
--policy-arn arn:aws:iam::aws:policy/${ATTACH_POLICY_NAME}
出力
[cloudshell-user@ip-10-134-14-200 ~]$ # ポリシー名
[cloudshell-user@ip-10-134-14-200 ~]$ ATTACH_POLICY_NAME="AmazonDynamoDBFullAccess" \
> && echo ${ATTACH_POLICY_NAME}
AmazonDynamoDBFullAccess
[cloudshell-user@ip-10-134-14-200 ~]$
[cloudshell-user@ip-10-134-14-200 ~]$ # IAMロールにポリシーをアタッチ
[cloudshell-user@ip-10-134-14-200 ~]$ aws iam attach-role-policy \
> --role-name ${ROLE_NAME} \
> --policy-arn arn:aws:iam::aws:policy/${ATTACH_POLICY_NAME}
Lambda関数のテスト実行
コマンド
# イベントの作成
EVENT=$(cat << EOF
{
"body": "eyJ0ZXN0IjoiYm9keSJ9",
"resource": "/{proxy+}",
"path": "/path/to/resource",
"httpMethod": "POST",
"isBase64Encoded": true,
"queryStringParameters": {
"input_text": "こんばんは"
},
"multiValueQueryStringParameters": {
"foo": [
"bar"
]
},
"pathParameters": {
"proxy": "/path/to/resource"
},
"stageVariables": {
"baz": "qux"
},
"headers": {
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8",
"Accept-Encoding": "gzip, deflate, sdch",
"Accept-Language": "en-US,en;q=0.8",
"Cache-Control": "max-age=0",
"CloudFront-Forwarded-Proto": "https",
"CloudFront-Is-Desktop-Viewer": "true",
"CloudFront-Is-Mobile-Viewer": "false",
"CloudFront-Is-SmartTV-Viewer": "false",
"CloudFront-Is-Tablet-Viewer": "false",
"CloudFront-Viewer-Country": "US",
"Host": "1234567890.execute-api.us-east-1.amazonaws.com",
"Upgrade-Insecure-Requests": "1",
"User-Agent": "Custom User Agent String",
"Via": "1.1 08f323deadbeefa7af34d5feb414ce27.cloudfront.net (CloudFront)",
"X-Amz-Cf-Id": "cDehVQoZnx43VYQb9j2-nvCh-9z396Uhbp027Y2JvkCPNLmGJHqlaA==",
"X-Forwarded-For": "127.0.0.1, 127.0.0.2",
"X-Forwarded-Port": "443",
"X-Forwarded-Proto": "https"
},
"multiValueHeaders": {
"Accept": [
"text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8"
],
"Accept-Encoding": [
"gzip, deflate, sdch"
],
"Accept-Language": [
"en-US,en;q=0.8"
],
"Cache-Control": [
"max-age=0"
],
"CloudFront-Forwarded-Proto": [
"https"
],
"CloudFront-Is-Desktop-Viewer": [
"true"
],
"CloudFront-Is-Mobile-Viewer": [
"false"
],
"CloudFront-Is-SmartTV-Viewer": [
"false"
],
"CloudFront-Is-Tablet-Viewer": [
"false"
],
"CloudFront-Viewer-Country": [
"US"
],
"Host": [
"0123456789.execute-api.us-east-1.amazonaws.com"
],
"Upgrade-Insecure-Requests": [
"1"
],
"User-Agent": [
"Custom User Agent String"
],
"Via": [
"1.1 08f323deadbeefa7af34d5feb414ce27.cloudfront.net (CloudFront)"
],
"X-Amz-Cf-Id": [
"cDehVQoZnx43VYQb9j2-nvCh-9z396Uhbp027Y2JvkCPNLmGJHqlaA=="
],
"X-Forwarded-For": [
"127.0.0.1, 127.0.0.2"
],
"X-Forwarded-Port": [
"443"
],
"X-Forwarded-Proto": [
"https"
]
},
"requestContext": {
"accountId": "123456789012",
"resourceId": "123456",
"stage": "prod",
"requestId": "c6af9ac6-7b61-11e6-9a41-93e8deadbeef",
"requestTime": "09/Apr/2015:12:34:56 +0000",
"requestTimeEpoch": 1428582896000,
"identity": {
"cognitoIdentityPoolId": null,
"accountId": null,
"cognitoIdentityId": null,
"caller": null,
"accessKey": null,
"sourceIp": "127.0.0.1",
"cognitoAuthenticationType": null,
"cognitoAuthenticationProvider": null,
"userArn": null,
"userAgent": "Custom User Agent String",
"user": null
},
"path": "/prod/path/to/resource",
"resourcePath": "/{proxy+}",
"httpMethod": "POST",
"apiId": "1234567890",
"protocol": "HTTP/1.1"
}
}
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
出力
[cloudshell-user@ip-10-134-14-200 ~]$ # イベントの作成
[cloudshell-user@ip-10-134-14-200 ~]$ EVENT=$(cat << EOF
> {
> "body": "eyJ0ZXN0IjoiYm9keSJ9",
> "resource": "/{proxy+}",
> "path": "/path/to/resource",
> "httpMethod": "POST",
> "isBase64Encoded": true,
> "queryStringParameters": {
> "input_text": "こんばんは"
> },
> "multiValueQueryStringParameters": {
> "foo": [
> "bar"
> ]
> },
> "pathParameters": {
> "proxy": "/path/to/resource"
> },
> "stageVariables": {
> "baz": "qux"
> },
> "headers": {
> "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8",
> "Accept-Encoding": "gzip, deflate, sdch",
> "Accept-Language": "en-US,en;q=0.8",
> "Cache-Control": "max-age=0",
> "CloudFront-Forwarded-Proto": "https",
> "CloudFront-Is-Desktop-Viewer": "true",
> "CloudFront-Is-Mobile-Viewer": "false",
> "CloudFront-Is-SmartTV-Viewer": "false",
> "CloudFront-Is-Tablet-Viewer": "false",
> "CloudFront-Viewer-Country": "US",
> "Host": "1234567890.execute-api.us-east-1.amazonaws.com",
> "Upgrade-Insecure-Requests": "1",
> "User-Agent": "Custom User Agent String",
> "Via": "1.1 08f323deadbeefa7af34d5feb414ce27.cloudfront.net (CloudFront)",
> "X-Amz-Cf-Id": "cDehVQoZnx43VYQb9j2-nvCh-9z396Uhbp027Y2JvkCPNLmGJHqlaA==",
> "X-Forwarded-For": "127.0.0.1, 127.0.0.2",
> "X-Forwarded-Port": "443",
> "X-Forwarded-Proto": "https"
> },
> "multiValueHeaders": {
> "Accept": [
> "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8"
> ],
> "Accept-Encoding": [
> "gzip, deflate, sdch"
> ],
> "Accept-Language": [
> "en-US,en;q=0.8"
> ],
> "Cache-Control": [
> "max-age=0"
> ],
> "CloudFront-Forwarded-Proto": [
> "https"
> ],
> "CloudFront-Is-Desktop-Viewer": [
> "true"
> ],
> "CloudFront-Is-Mobile-Viewer": [
> "false"
> ],
> "CloudFront-Is-SmartTV-Viewer": [
> "false"
> ],
> "CloudFront-Is-Tablet-Viewer": [
> "false"
> ],
> "CloudFront-Viewer-Country": [
> "US"
> ],
> "Host": [
> "0123456789.execute-api.us-east-1.amazonaws.com"
> ],
> "Upgrade-Insecure-Requests": [
> "1"
> ],
> "User-Agent": [
> "Custom User Agent String"
> ],
> "Via": [
> "1.1 08f323deadbeefa7af34d5feb414ce27.cloudfront.net (CloudFront)"
> ],
> "X-Amz-Cf-Id": [
> "cDehVQoZnx43VYQb9j2-nvCh-9z396Uhbp027Y2JvkCPNLmGJHqlaA=="
> ],
> "X-Forwarded-For": [
> "127.0.0.1, 127.0.0.2"
> ],
> "X-Forwarded-Port": [
> "443"
> ],
> "X-Forwarded-Proto": [
> "https"
> ]
> },
> "requestContext": {
> "accountId": "123456789012",
> "resourceId": "123456",
> "stage": "prod",
> "requestId": "c6af9ac6-7b61-11e6-9a41-93e8deadbeef",
> "requestTime": "09/Apr/2015:12:34:56 +0000",
> "requestTimeEpoch": 1428582896000,
> "identity": {
> "cognitoIdentityPoolId": null,
> "accountId": null,
> "cognitoIdentityId": null,
> "caller": null,
> "accessKey": null,
> "sourceIp": "127.0.0.1",
> "cognitoAuthenticationType": null,
> "cognitoAuthenticationProvider": null,
> "userArn": null,
> "userAgent": "Custom User Agent String",
> "user": null
> },
> "path": "/prod/path/to/resource",
> "resourcePath": "/{proxy+}",
> "httpMethod": "POST",
> "apiId": "1234567890",
> "protocol": "HTTP/1.1"
> }
> }
> EOF
> ) \
> && echo ${EVENT}
{ "body": "eyJ0ZXN0IjoiYm9keSJ9", "resource": "/{proxy+}", "path": "/path/to/resource", "httpMethod": "POST", "isBase64Encoded": true, "queryStringParameters": { "input_text": "こんばんは" }, "multiValueQueryStringParameters": { "foo": [ "bar" ] }, "pathParameters": { "proxy": "/path/to/resource" }, "stageVariables": { "baz": "qux" }, "headers": { "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8", "Accept-Encoding": "gzip, deflate, sdch", "Accept-Language": "en-US,en;q=0.8", "Cache-Control": "max-age=0", "CloudFront-Forwarded-Proto": "https", "CloudFront-Is-Desktop-Viewer": "true", "CloudFront-Is-Mobile-Viewer": "false", "CloudFront-Is-SmartTV-Viewer": "false", "CloudFront-Is-Tablet-Viewer": "false", "CloudFront-Viewer-Country": "US", "Host": "1234567890.execute-api.us-east-1.amazonaws.com", "Upgrade-Insecure-Requests": "1", "User-Agent": "Custom User Agent String", "Via": "1.1 08f323deadbeefa7af34d5feb414ce27.cloudfront.net (CloudFront)", "X-Amz-Cf-Id": "cDehVQoZnx43VYQb9j2-nvCh-9z396Uhbp027Y2JvkCPNLmGJHqlaA==", "X-Forwarded-For": "127.0.0.1, 127.0.0.2", "X-Forwarded-Port": "443", "X-Forwarded-Proto": "https" }, "multiValueHeaders": { "Accept": [ "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8" ], "Accept-Encoding": [ "gzip, deflate, sdch" ], "Accept-Language": [ "en-US,en;q=0.8" ], "Cache-Control": [ "max-age=0" ], "CloudFront-Forwarded-Proto": [ "https" ], "CloudFront-Is-Desktop-Viewer": [ "true" ], "CloudFront-Is-Mobile-Viewer": [ "false" ], "CloudFront-Is-SmartTV-Viewer": [ "false" ], "CloudFront-Is-Tablet-Viewer": [ "false" ], "CloudFront-Viewer-Country": [ "US" ], "Host": [ "0123456789.execute-api.us-east-1.amazonaws.com" ], "Upgrade-Insecure-Requests": [ "1" ], "User-Agent": [ "Custom User Agent String" ], "Via": [ "1.1 08f323deadbeefa7af34d5feb414ce27.cloudfront.net (CloudFront)" ], "X-Amz-Cf-Id": [ "cDehVQoZnx43VYQb9j2-nvCh-9z396Uhbp027Y2JvkCPNLmGJHqlaA==" ], "X-Forwarded-For": [ "127.0.0.1, 127.0.0.2" ], "X-Forwarded-Port": [ "443" ], "X-Forwarded-Proto": [ "https" ] }, "requestContext": { "accountId": "123456789012", "resourceId": "123456", "stage": "prod", "requestId": "c6af9ac6-7b61-11e6-9a41-93e8deadbeef", "requestTime": "09/Apr/2015:12:34:56 +0000", "requestTimeEpoch": 1428582896000, "identity": { "cognitoIdentityPoolId": null, "accountId": null, "cognitoIdentityId": null, "caller": null, "accessKey": null, "sourceIp": "127.0.0.1", "cognitoAuthenticationType": null, "cognitoAuthenticationProvider": null, "userArn": null, "userAgent": "Custom User Agent String", "user": null }, "path": "/prod/path/to/resource", "resourcePath": "/{proxy+}", "httpMethod": "POST", "apiId": "1234567890", "protocol": "HTTP/1.1" } }
[cloudshell-user@ip-10-134-14-200 ~]$
[cloudshell-user@ip-10-134-14-200 ~]$ # JSONフォーマットの確認
[cloudshell-user@ip-10-134-14-200 ~]$ echo ${EVENT} | python -m json.tool
{
"body": "eyJ0ZXN0IjoiYm9keSJ9",
"resource": "/{proxy+}",
"path": "/path/to/resource",
"httpMethod": "POST",
"isBase64Encoded": true,
"queryStringParameters": {
"input_text": "\u3053\u3093\u3070\u3093\u306f"
},
"multiValueQueryStringParameters": {
"foo": [
"bar"
]
},
"pathParameters": {
"proxy": "/path/to/resource"
},
"stageVariables": {
"baz": "qux"
},
"headers": {
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8",
"Accept-Encoding": "gzip, deflate, sdch",
"Accept-Language": "en-US,en;q=0.8",
"Cache-Control": "max-age=0",
"CloudFront-Forwarded-Proto": "https",
"CloudFront-Is-Desktop-Viewer": "true",
"CloudFront-Is-Mobile-Viewer": "false",
"CloudFront-Is-SmartTV-Viewer": "false",
"CloudFront-Is-Tablet-Viewer": "false",
"CloudFront-Viewer-Country": "US",
"Host": "1234567890.execute-api.us-east-1.amazonaws.com",
"Upgrade-Insecure-Requests": "1",
"User-Agent": "Custom User Agent String",
"Via": "1.1 08f323deadbeefa7af34d5feb414ce27.cloudfront.net (CloudFront)",
"X-Amz-Cf-Id": "cDehVQoZnx43VYQb9j2-nvCh-9z396Uhbp027Y2JvkCPNLmGJHqlaA==",
"X-Forwarded-For": "127.0.0.1, 127.0.0.2",
"X-Forwarded-Port": "443",
"X-Forwarded-Proto": "https"
},
"multiValueHeaders": {
"Accept": [
"text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8"
],
"Accept-Encoding": [
"gzip, deflate, sdch"
],
"Accept-Language": [
"en-US,en;q=0.8"
],
"Cache-Control": [
"max-age=0"
],
"CloudFront-Forwarded-Proto": [
"https"
],
"CloudFront-Is-Desktop-Viewer": [
"true"
],
"CloudFront-Is-Mobile-Viewer": [
"false"
],
"CloudFront-Is-SmartTV-Viewer": [
"false"
],
"CloudFront-Is-Tablet-Viewer": [
"false"
],
"CloudFront-Viewer-Country": [
"US"
],
"Host": [
"0123456789.execute-api.us-east-1.amazonaws.com"
],
"Upgrade-Insecure-Requests": [
"1"
],
"User-Agent": [
"Custom User Agent String"
],
"Via": [
"1.1 08f323deadbeefa7af34d5feb414ce27.cloudfront.net (CloudFront)"
],
"X-Amz-Cf-Id": [
"cDehVQoZnx43VYQb9j2-nvCh-9z396Uhbp027Y2JvkCPNLmGJHqlaA=="
],
"X-Forwarded-For": [
"127.0.0.1, 127.0.0.2"
],
"X-Forwarded-Port": [
"443"
],
"X-Forwarded-Proto": [
"https"
]
},
"requestContext": {
"accountId": "123456789012",
"resourceId": "123456",
"stage": "prod",
"requestId": "c6af9ac6-7b61-11e6-9a41-93e8deadbeef",
"requestTime": "09/Apr/2015:12:34:56 +0000",
"requestTimeEpoch": 1428582896000,
"identity": {
"cognitoIdentityPoolId": null,
"accountId": null,
"cognitoIdentityId": null,
"caller": null,
"accessKey": null,
"sourceIp": "127.0.0.1",
"cognitoAuthenticationType": null,
"cognitoAuthenticationProvider": null,
"userArn": null,
"userAgent": "Custom User Agent String",
"user": null
},
"path": "/prod/path/to/resource",
"resourcePath": "/{proxy+}",
"httpMethod": "POST",
"apiId": "1234567890",
"protocol": "HTTP/1.1"
}
}
[cloudshell-user@ip-10-134-14-200 ~]$
[cloudshell-user@ip-10-134-14-200 ~]$ # テスト実行
[cloudshell-user@ip-10-134-14-200 ~]$ aws lambda invoke \
> --function-name ${FUNCTION_NAME} \
> --payload `echo ${EVENT} | base64 -w 0` \
> outputfile.txt
{
"StatusCode": 200,
"ExecutedVersion": "$LATEST"
}
[cloudshell-user@ip-10-134-14-200 ~]$
[cloudshell-user@ip-10-134-14-200 ~]$ cat outputfile.txt
{"statusCode": 200, "body": "{\"output_text\": \"Good evening\"}", "isBase64Encoded": false, "headers": {}}
DynamoDBテーブル内の項目の確認
コマンド
aws dynamodb scan \
--table-name translate-history
出力
[cloudshell-user@ip-10-134-14-200 ~]$ aws dynamodb scan \
> --table-name translate-history
{
"Items": [
{
"input_text": {
"S": "★こんにちは"
},
"output_text": {
"S": "★Hello"
},
"timestamp": {
"S": "20191024183000"
}
},
{
"input_text": {
"S": "こんばんは"
},
"output_text": {
"S": "Good evening"
},
"timestamp": {
"S": "20240714104707"
}
}
],
"Count": 2,
"ScannedCount": 2,
"ConsumedCapacity": null
}
DynamoDBテーブル内の項目の削除
コマンド
aws dynamodb delete-item \
--table-name ${TABLE_NAME} \
--key '{"timestamp": {"S": "20191024183000"}}'
出力
[cloudshell-user@ip-10-134-14-200 ~]$ aws dynamodb delete-item \
> --table-name ${TABLE_NAME} \
> --key '{"timestamp": {"S": "20191024183000"}}'
DynamoDBテーブル内の項目の確認
コマンド
aws dynamodb scan \
--table-name translate-history
出力
[cloudshell-user@ip-10-134-14-200 ~]$ aws dynamodb scan \
> --table-name translate-history
{
"Items": [
{
"input_text": {
"S": "ハンズオン完走しました"
},
"output_text": {
"S": "I finished the hands-on race"
},
"timestamp": {
"S": "20240714105931"
}
},
{
"input_text": {
"S": "こんばんは"
},
"output_text": {
"S": "Good evening"
},
"timestamp": {
"S": "20240714104707"
}
}
],
"Count": 2,
"ScannedCount": 2,
"ConsumedCapacity": null
}
7. リソース削除
ハンズオン内ではリソースの削除は含まれていなかったが、ハンズオン後は削除を実施
DnyamoDB削除
コマンド
aws dynamodb delete-table \
--table-name ${TABLE_NAME}
出力
[cloudshell-user@ip-10-134-26-238 ~]$ aws dynamodb delete-table \
> --table-name ${TABLE_NAME}
{
"TableDescription": {
"TableName": "translate-history",
"TableStatus": "DELETING",
"ProvisionedThroughput": {
"NumberOfDecreasesToday": 0,
"ReadCapacityUnits": 1,
"WriteCapacityUnits": 1
},
"TableSizeBytes": 0,
"ItemCount": 0,
"TableArn": "arn:aws:dynamodb:ap-northeast-1:999999999999:table/translate-history",
"TableId": "28329b22-e74a-41ee-9e57-584592a726c9",
"DeletionProtectionEnabled": false
}
}
API Gateway削除
コマンド
aws apigateway delete-rest-api \
--rest-api-id ${RESET_API_ID}
出力
[cloudshell-user@ip-10-134-26-238 ~]$ aws apigateway delete-rest-api \
> --rest-api-id ${RESET_API_ID}
Lambda関数の削除
コマンド
aws lambda delete-function \
--function-name ${FUNCTION_NAME}
出力
[cloudshell-user@ip-10-134-26-238 ~]$ aws lambda delete-function \
> --function-name ${FUNCTION_NAME}
IAMロールの削除
ポリシーのデタッチ
AWS CLIでロールを削除する場合、最初にすべてのポリシーをデタッチする必要がある
コマンド
# ロールにアタッチされているポリシーをリスト
POLICIES=$(
aws iam list-attached-role-policies \
--role-name $ROLE_NAME \
--query 'AttachedPolicies[*].PolicyArn' \
--output text
) \
&& echo ${POLICIES}
# リスト内のポリシーをデタッチする
for POLICY in $POLICIES; do
aws iam detach-role-policy \
--role-name ${ROLE_NAME} \
--policy-arn ${POLICY}
done
出力
[cloudshell-user@ip-10-134-26-238 ~]$ # ロールにアタッチされているポリシーをリスト
[cloudshell-user@ip-10-134-26-238 ~]$ POLICIES=$(
> aws iam list-attached-role-policies \
> --role-name $ROLE_NAME \
> --query 'AttachedPolicies[*].PolicyArn' \
> --output text
> ) \
> && echo ${POLICIES}
arn:aws:iam::999999999999:policy/translate-function-policy arn:aws:iam::aws:policy/TranslateFullAccess arn:aws:iam::aws:policy/AmazonDynamoDBFullAccess
[cloudshell-user@ip-10-134-26-238 ~]$
[cloudshell-user@ip-10-134-26-238 ~]$ # リスト内のポリシーをデタッチする
[cloudshell-user@ip-10-134-26-238 ~]$ for POLICY in $POLICIES; do
> aws iam detach-role-policy \
> --role-name ${ROLE_NAME} \
> --policy-arn ${POLICY}
> done
IAMロールの削除
コマンド
# IAMロールの削除
aws iam delete-role \
--role-name ${ROLE_NAME}
出力
[cloudshell-user@ip-10-134-26-238 ~]$ # IAMロールの削除
[cloudshell-user@ip-10-134-26-238 ~]$ aws iam delete-role \
> --role-name ${ROLE_NAME}
IAMポリシーの削除
コマンド
# IAMポリシーの削除
aws iam delete-policy \
--policy-arn ${POLICY_ARN}
出力
[cloudshell-user@ip-10-134-26-238 ~]$ aws iam delete-policy \
> --policy-arn ${POLICY_ARN}