上記、「AWS Hands-on for Beginners Serverless #3 AWS Lambda と AWS AI Services を組み合わせて作る音声文字起こし & 感情分析パイプライン」 をAWS CLIでやってみる
03 S3 トリガーで Lambda ファンクションを起動する
S3バケット作成
変数
コマンド
# バケット名
date_var=$(date +%Y%m%d) \
&& echo ${date_var}
S3_BUCKET_NAME="h4b-serverless-3-input-${date_var}" \
&& echo ${S3_BUCKET_NAME}
出力
[cloudshell-user@ip-10-132-73-220 ~]$ # バケット名
[cloudshell-user@ip-10-132-73-220 ~]$ date_var=$(date +%Y%m%d) \
> && echo ${date_var}
20240929
[cloudshell-user@ip-10-132-73-220 ~]$ S3_BUCKET_NAME="h4b-serverless-3-input-${date_var}" \
> && echo ${S3_BUCKET_NAME}
h4b-serverless-3-input-20240929
S3バケット作成
コマンド
# S3バケット作成
aws s3 mb s3://${S3_BUCKET_NAME}
出力
[cloudshell-user@ip-10-132-73-220 ~]$ # S3バケット作成
[cloudshell-user@ip-10-132-73-220 ~]$ aws s3 mb s3://${S3_BUCKET_NAME}
make_bucket: h4b-serverless-3-input-20240929
Lambda関数作成
変数
コマンド
# 関数名
LAMBDA_FUNCTION_NAME="transcribe-function" \
&& echo ${LAMBDA_FUNCTION_NAME}
# IAMポリシー名1
IAM_POLICY_NAME_1="AWSLambdaBasicExecutionRole-${LAMBDA_FUNCTION_NAME}" \
&& echo ${IAM_POLICY_NAME_1}
# IAMポリシー名2
IAM_POLICY_NAME_2="AWSLambdaS3ExecutionRole-${LAMBDA_FUNCTION_NAME}" \
&& echo ${IAM_POLICY_NAME_2}
# IAMロール名
IAM_ROLE_NAME="${LAMBDA_FUNCTION_NAME}-role" \
&& echo ${IAM_ROLE_NAME}
# ランタイム
LAMBDA_RUNTIME="python3.10" \
&& echo ${LAMBDA_RUNTIME}
# アカウントID
ACCOUNT_ID="999999999999" \
&& echo ${ACCOUNT_ID}
出力
[cloudshell-user@ip-10-132-73-220 ~]$ # 関数名
[cloudshell-user@ip-10-132-73-220 ~]$ LAMBDA_FUNCTION_NAME="transcribe-function" \
> && echo ${LAMBDA_FUNCTION_NAME}
transcribe-function
[cloudshell-user@ip-10-132-73-220 ~]$
[cloudshell-user@ip-10-132-73-220 ~]$ # IAMポリシー名1
[cloudshell-user@ip-10-132-73-220 ~]$ IAM_POLICY_NAME_1="AWSLambdaBasicExecutionRole-${LAMBDA_FUNCTION_NAME}" \
> && echo ${IAM_POLICY_NAME_1}
AWSLambdaBasicExecutionRole-transcribe-function
[cloudshell-user@ip-10-132-73-220 ~]$
[cloudshell-user@ip-10-132-73-220 ~]$ # IAMポリシー名2
[cloudshell-user@ip-10-132-73-220 ~]$ IAM_POLICY_NAME_2="AWSLambdaS3ExecutionRole-${LAMBDA_FUNCTION_NAME}" \
> && echo ${IAM_POLICY_NAME_2}
AWSLambdaS3ExecutionRole-transcribe-function
[cloudshell-user@ip-10-132-73-220 ~]$
[cloudshell-user@ip-10-132-73-220 ~]$ # IAMロール名
[cloudshell-user@ip-10-132-73-220 ~]$ IAM_ROLE_NAME="${LAMBDA_FUNCTION_NAME}-role" \
> && echo ${IAM_ROLE_NAME}
transcribe-function-role
[cloudshell-user@ip-10-132-73-220 ~]$
[cloudshell-user@ip-10-132-73-220 ~]$ # ランタイム
[cloudshell-user@ip-10-132-73-220 ~]$ LAMBDA_RUNTIME="python3.10" \
> && echo ${LAMBDA_RUNTIME}
python3.10
[cloudshell-user@ip-10-132-73-220 ~]$
[cloudshell-user@ip-10-132-73-220 ~]$ # アカウントID
[cloudshell-user@ip-10-132-73-220 ~]$ ACCOUNT_ID="999999999999" \
> && echo ${ACCOUNT_ID}
999999999999
IAMポリシー作成
AWSLambdaBasicExecutionRole
コマンド
# AWSLambdaBasicExecutionRole
# ポリシードキュメントの作成
POLICY_DOCUMENT_JSON=$(cat << EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "logs:CreateLogGroup",
"Resource": "arn:aws:logs:ap-northeast-1:${ACCOUNT_ID}:*"
},
{
"Effect": "Allow",
"Action": [
"logs:CreateLogStream",
"logs:PutLogEvents"
],
"Resource": [
"arn:aws:logs:ap-northeast-1:${ACCOUNT_ID}:log-group:/aws/lambda/${LAMBDA_FUNCTION_NAME}:*"
]
}
]
}
EOF
) \
&& echo ${POLICY_DOCUMENT_JSON}
# JSONフォーマットの確認
echo ${POLICY_DOCUMENT_JSON} | python -m json.tool
# ポリシーの作成
aws iam create-policy \
--policy-name ${IAM_POLICY_NAME_1} \
--policy-document "${POLICY_DOCUMENT_JSON}"
# ARN取得
IAM_POLICY_ARN_1=$(
aws iam list-policies \
--query "Policies[?PolicyName=='${IAM_POLICY_NAME_1}'].Arn" \
--output text
) \
&& echo ${IAM_POLICY_ARN_1}
出力
[cloudshell-user@ip-10-132-73-220 ~]$ # AWSLambdaBasicExecutionRole
[cloudshell-user@ip-10-132-73-220 ~]$ # ポリシードキュメントの作成
[cloudshell-user@ip-10-132-73-220 ~]$ POLICY_DOCUMENT_JSON=$(cat << EOF
> {
> "Version": "2012-10-17",
> "Statement": [
> {
> "Effect": "Allow",
> "Action": "logs:CreateLogGroup",
> "Resource": "arn:aws:logs:ap-northeast-1:${ACCOUNT_ID}:*"
> },
> {
> "Effect": "Allow",
> "Action": [
> "logs:CreateLogStream",
> "logs:PutLogEvents"
> ],
> "Resource": [
> "arn:aws:logs:ap-northeast-1:${ACCOUNT_ID}:log-group:/aws/lambda/${LAMBDA_FUNCTION_NAME}:*"
> ]
> }
> ]
> }
> 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/transcribe-function:*" ] } ] }
[cloudshell-user@ip-10-132-73-220 ~]$
[cloudshell-user@ip-10-132-73-220 ~]$ # JSONフォーマットの確認
[cloudshell-user@ip-10-132-73-220 ~]$ echo ${POLICY_DOCUMENT_JSON} | python -m json.tool
{
"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/transcribe-function:*"
]
}
]
}
[cloudshell-user@ip-10-132-73-220 ~]$
[cloudshell-user@ip-10-132-73-220 ~]$ # ポリシーの作成
[cloudshell-user@ip-10-132-73-220 ~]$ aws iam create-policy \
> --policy-name ${IAM_POLICY_NAME_1} \
> --policy-document "${POLICY_DOCUMENT_JSON}"
{
"Policy": {
"PolicyName": "AWSLambdaBasicExecutionRole-transcribe-function",
"PolicyId": "ANPAWFKRCMKOVTQGI5MZX",
"Arn": "arn:aws:iam::999999999999:policy/AWSLambdaBasicExecutionRole-transcribe-function",
"Path": "/",
"DefaultVersionId": "v1",
"AttachmentCount": 0,
"PermissionsBoundaryUsageCount": 0,
"IsAttachable": true,
"CreateDate": "2024-09-29T07:39:15+00:00",
"UpdateDate": "2024-09-29T07:39:15+00:00"
}
}
[cloudshell-user@ip-10-132-73-220 ~]$
[cloudshell-user@ip-10-132-73-220 ~]$ # ARN取得
[cloudshell-user@ip-10-132-73-220 ~]$ IAM_POLICY_ARN_1=$(
> aws iam list-policies \
> --query "Policies[?PolicyName=='${IAM_POLICY_NAME_1}'].Arn" \
> --output text
> ) \
> && echo ${IAM_POLICY_ARN_1}
arn:aws:iam::999999999999:policy/AWSLambdaBasicExecutionRole-transcribe-function
AWSLambdaS3ExecutionRole
コマンド
# AWSLambdaS3ExecutionRole
# ポリシードキュメントの作成
POLICY_DOCUMENT_JSON=$(cat << EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:GetObject"
],
"Resource": "arn:aws:s3:::*"
}
]
}
EOF
) \
&& echo ${POLICY_DOCUMENT_JSON}
# JSONフォーマットの確認
echo ${POLICY_DOCUMENT_JSON} | python -m json.tool
# ポリシーの作成
aws iam create-policy \
--policy-name ${IAM_POLICY_NAME_2} \
--policy-document "${POLICY_DOCUMENT_JSON}"
# ARN取得
IAM_POLICY_ARN_2=$(
aws iam list-policies \
--query "Policies[?PolicyName=='${IAM_POLICY_NAME_2}'].Arn" \
--output text
) \
&& echo ${IAM_POLICY_ARN_2}
出力
[cloudshell-user@ip-10-132-73-220 ~]$ # AWSLambdaS3ExecutionRole
[cloudshell-user@ip-10-132-73-220 ~]$ # ポリシードキュメントの作成
[cloudshell-user@ip-10-132-73-220 ~]$ POLICY_DOCUMENT_JSON=$(cat << EOF
> {
> "Version": "2012-10-17",
> "Statement": [
> {
> "Effect": "Allow",
> "Action": [
> "s3:GetObject"
> ],
> "Resource": "arn:aws:s3:::*"
> }
> ]
> }
> EOF
> ) \
> && echo ${POLICY_DOCUMENT_JSON}
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "s3:GetObject" ], "Resource": "arn:aws:s3:::*" } ] }
[cloudshell-user@ip-10-132-73-220 ~]$
[cloudshell-user@ip-10-132-73-220 ~]$ # JSONフォーマットの確認
[cloudshell-user@ip-10-132-73-220 ~]$ echo ${POLICY_DOCUMENT_JSON} | python -m json.tool
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:GetObject"
],
"Resource": "arn:aws:s3:::*"
}
]
}
[cloudshell-user@ip-10-132-73-220 ~]$
[cloudshell-user@ip-10-132-73-220 ~]$ # ポリシーの作成
[cloudshell-user@ip-10-132-73-220 ~]$ aws iam create-policy \
> --policy-name ${IAM_POLICY_NAME_2} \
> --policy-document "${POLICY_DOCUMENT_JSON}"
{
"Policy": {
"PolicyName": "AWSLambdaS3ExecutionRole-transcribe-function",
"PolicyId": "ANPAWFKRCMKO4VOZM3AAK",
"Arn": "arn:aws:iam::999999999999:policy/AWSLambdaS3ExecutionRole-transcribe-function",
"Path": "/",
"DefaultVersionId": "v1",
"AttachmentCount": 0,
"PermissionsBoundaryUsageCount": 0,
"IsAttachable": true,
"CreateDate": "2024-09-29T07:39:46+00:00",
"UpdateDate": "2024-09-29T07:39:46+00:00"
}
}
[cloudshell-user@ip-10-132-73-220 ~]$
[cloudshell-user@ip-10-132-73-220 ~]$ # ARN取得
[cloudshell-user@ip-10-132-73-220 ~]$ IAM_POLICY_ARN_2=$(
> aws iam list-policies \
> --query "Policies[?PolicyName=='${IAM_POLICY_NAME_2}'].Arn" \
> --output text
> ) \
> && echo ${IAM_POLICY_ARN_2}
arn:aws:iam::999999999999:policy/AWSLambdaS3ExecutionRole-transcribe-function
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}
# JSONフォーマットの確認
echo ${ASSUME_ROLE_POLICY_DOCUMENT} | python -m json.tool
# IAMロールの作成
aws iam create-role \
--role-name ${IAM_ROLE_NAME} \
--assume-role-policy-document "${ASSUME_ROLE_POLICY_DOCUMENT}"
# ARN取得
IAM_ROLE_ARN=$(
aws iam get-role \
--role-name ${IAM_ROLE_NAME} \
--query 'Role.Arn' --output text
) \
&& echo ${IAM_ROLE_ARN}
# IAMロールにポリシーをアタッチ
aws iam attach-role-policy \
--role-name ${IAM_ROLE_NAME} \
--policy-arn ${IAM_POLICY_ARN_1}
aws iam attach-role-policy \
--role-name ${IAM_ROLE_NAME} \
--policy-arn ${IAM_POLICY_ARN_2}
出力
[cloudshell-user@ip-10-132-73-220 ~]$ # 信頼関係ポリシードキュメントの作成
[cloudshell-user@ip-10-132-73-220 ~]$ 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-132-73-220 ~]$
[cloudshell-user@ip-10-132-73-220 ~]$ # JSONフォーマットの確認
[cloudshell-user@ip-10-132-73-220 ~]$ echo ${ASSUME_ROLE_POLICY_DOCUMENT} | python -m json.tool
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "lambda.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
[cloudshell-user@ip-10-132-73-220 ~]$
[cloudshell-user@ip-10-132-73-220 ~]$ # IAMロールの作成
[cloudshell-user@ip-10-132-73-220 ~]$ aws iam create-role \
> --role-name ${IAM_ROLE_NAME} \
> --assume-role-policy-document "${ASSUME_ROLE_POLICY_DOCUMENT}"
{
"Role": {
"Path": "/",
"RoleName": "transcribe-function-role",
"RoleId": "AROAWFKRCMKOUX4DN3SXQ",
"Arn": "arn:aws:iam::999999999999:role/transcribe-function-role",
"CreateDate": "2024-09-29T07:40:18+00:00",
"AssumeRolePolicyDocument": {
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "lambda.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
}
}
[cloudshell-user@ip-10-132-73-220 ~]$
[cloudshell-user@ip-10-132-73-220 ~]$ # ARN取得
[cloudshell-user@ip-10-132-73-220 ~]$ IAM_ROLE_ARN=$(
> aws iam get-role \
> --role-name ${IAM_ROLE_NAME} \
> --query 'Role.Arn' --output text
> ) \
> && echo ${IAM_ROLE_ARN}
arn:aws:iam::999999999999:role/transcribe-function-role
[cloudshell-user@ip-10-132-73-220 ~]$
[cloudshell-user@ip-10-132-73-220 ~]$ # IAMロールにポリシーをアタッチ
[cloudshell-user@ip-10-132-73-220 ~]$ aws iam attach-role-policy \
> --role-name ${IAM_ROLE_NAME} \
> --policy-arn ${IAM_POLICY_ARN_1}
[cloudshell-user@ip-10-132-73-220 ~]$
[cloudshell-user@ip-10-132-73-220 ~]$ aws iam attach-role-policy \
> --role-name ${IAM_ROLE_NAME} \
> --policy-arn ${IAM_POLICY_ARN_2}
Lambdaソースコード
コマンド
cat << EOF > lambda_function.py
import json
import urllib.parse
import boto3
print('Loading function')
s3 = boto3.client('s3')
def lambda_handler(event, context):
#print("Received event: " + json.dumps(event, indent=2))
# Get the object from the event and show its content type
bucket = event['Records'][0]['s3']['bucket']['name']
key = urllib.parse.unquote_plus(event['Records'][0]['s3']['object']['key'], encoding='utf-8')
try:
response = s3.get_object(Bucket=bucket, Key=key)
print("CONTENT TYPE: " + response['ContentType'])
return response['ContentType']
except Exception as e:
print(e)
print('Error getting object {} from bucket {}. Make sure they exist and your bucket is in the same region as this function.'.format(key, bucket))
raise e
EOF
出力
[cloudshell-user@ip-10-132-73-220 ~]$ cat << EOF > lambda_function.py
> import json
> import urllib.parse
> import boto3
>
> print('Loading function')
>
> s3 = boto3.client('s3')
>
>
> def lambda_handler(event, context):
> #print("Received event: " + json.dumps(event, indent=2))
>
> # Get the object from the event and show its content type
> bucket = event['Records'][0]['s3']['bucket']['name']
> key = urllib.parse.unquote_plus(event['Records'][0]['s3']['object']['key'], encoding='utf-8')
> try:
> response = s3.get_object(Bucket=bucket, Key=key)
> print("CONTENT TYPE: " + response['ContentType'])
> return response['ContentType']
> except Exception as e:
> print(e)
> print('Error getting object {} from bucket {}. Make sure they exist and your bucket is in the same region as this function.'.format(key, bucket))
> raise e
> EOF
デプロイパッケージの作成
コマンド
zip function.zip lambda_function.py
出力
[cloudshell-user@ip-10-132-73-220 ~]$ zip function.zip lambda_function.py
adding: lambda_function.py (deflated 45%)
Lambda関数の作成
コマンド
# Lambda関数の作成
aws lambda create-function \
--function-name ${LAMBDA_FUNCTION_NAME} \
--role ${IAM_ROLE_ARN} \
--zip-file fileb://function.zip \
--runtime ${LAMBDA_RUNTIME} \
--handler lambda_function.lambda_handler \
# ARNの取得
LAMBDA_FUNCTION_ARN=$(
aws lambda list-functions \
--query "Functions[?FunctionName=='${LAMBDA_FUNCTION_NAME}'].FunctionArn" \
--output text
) \
&& echo ${LAMBDA_FUNCTION_ARN}
出力
[cloudshell-user@ip-10-132-73-220 ~]$ # Lambda関数の作成
[cloudshell-user@ip-10-132-73-220 ~]$ aws lambda create-function \
> --function-name ${LAMBDA_FUNCTION_NAME} \
> --role ${IAM_ROLE_ARN} \
> --zip-file fileb://function.zip \
> --runtime ${LAMBDA_RUNTIME} \
> --handler lambda_function.lambda_handler \
>
{
"FunctionName": "transcribe-function",
"FunctionArn": "arn:aws:lambda:ap-northeast-1:999999999999:function:transcribe-function",
"Runtime": "python3.10",
"Role": "arn:aws:iam::999999999999:role/transcribe-function-role",
"Handler": "lambda_function.lambda_handler",
"CodeSize": 618,
"Description": "",
"Timeout": 3,
"MemorySize": 128,
"LastModified": "2024-09-29T07:41:42.633+0000",
"CodeSha256": "NBLXCaelqN6abvXytUmpDVs/XdWxOBY5b6yZTUgmMuE=",
"Version": "$LATEST",
"TracingConfig": {
"Mode": "PassThrough"
},
"RevisionId": "33913ed1-07cd-4240-bea8-caa0d0f8ca87",
"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:cd5b19747c6f456b465655915abd7ec32c616f52b3421c0b532d90cf258e0086"
},
"LoggingConfig": {
"LogFormat": "Text",
"LogGroup": "/aws/lambda/transcribe-function"
}
}
[cloudshell-user@ip-10-132-73-220 ~]$ # ARNの取得
[cloudshell-user@ip-10-132-73-220 ~]$ LAMBDA_FUNCTION_ARN=$(
> aws lambda list-functions \
> --query "Functions[?FunctionName=='${LAMBDA_FUNCTION_NAME}'].FunctionArn" \
> --output text
> ) \
> && echo ${LAMBDA_FUNCTION_ARN}
arn:aws:lambda:ap-northeast-1:999999999999:function:transcribe-function
リソースベースのポリシーステートメント追加
コマンド
# リソースベースのポリシーステートメント追加
aws lambda add-permission \
--function-name ${LAMBDA_FUNCTION_NAME} \
--principal s3.amazonaws.com \
--statement-id S3InvokePermission \
--action "lambda:InvokeFunction" \
--source-arn arn:aws:s3:::${S3_BUCKET_NAME} \
--source-account ${ACCOUNT_ID}
出力
[cloudshell-user@ip-10-132-73-220 ~]$ # リソースベースのポリシーステートメント追加
[cloudshell-user@ip-10-132-73-220 ~]$ aws lambda add-permission \
> --function-name ${LAMBDA_FUNCTION_NAME} \
> --principal s3.amazonaws.com \
> --statement-id S3InvokePermission \
> --action "lambda:InvokeFunction" \
> --source-arn arn:aws:s3:::${S3_BUCKET_NAME} \
> --source-account ${ACCOUNT_ID}
{
"Statement": "{\"Sid\":\"S3InvokePermission\",\"Effect\":\"Allow\",\"Principal\":{\"Service\":\"s3.amazonaws.com\"},\"Action\":\"lambda:InvokeFunction\",\"Resource\":\"arn:aws:lambda:ap-northeast-1:999999999999:function:transcribe-function\",\"Condition\":{\"StringEquals\":{\"AWS:SourceAccount\":\"999999999999\"},\"ArnLike\":{\"AWS:SourceArn\":\"arn:aws:s3:::h4b-serverless-3-input-20240929\"}}}"
}
イベント通知設定用JSON
コマンド
# イベント通知設定用JSON
S3_NOTIFICATION_CONFIGURATION=$(cat << EOF
{
"LambdaFunctionConfigurations": [
{
"LambdaFunctionArn": "${LAMBDA_FUNCTION_ARN}",
"Events": ["s3:ObjectCreated:*"]
}
]
}
EOF
) \
&& echo ${S3_NOTIFICATION_CONFIGURATION}
# JSONフォーマットの確認
echo ${S3_NOTIFICATION_CONFIGURATION} | python -m json.tool
出力
[cloudshell-user@ip-10-132-73-220 ~]$ # イベント通知設定用JSON
[cloudshell-user@ip-10-132-73-220 ~]$ S3_NOTIFICATION_CONFIGURATION=$(cat << EOF
> {
> "LambdaFunctionConfigurations": [
> {
> "LambdaFunctionArn": "${LAMBDA_FUNCTION_ARN}",
> "Events": ["s3:ObjectCreated:*"]
> }
> ]
> }
> EOF
> ) \
> && echo ${S3_NOTIFICATION_CONFIGURATION}
{ "LambdaFunctionConfigurations": [ { "LambdaFunctionArn": "arn:aws:lambda:ap-northeast-1:999999999999:function:transcribe-function", "Events": ["s3:ObjectCreated:*"] } ] }
[cloudshell-user@ip-10-132-73-220 ~]$
[cloudshell-user@ip-10-132-73-220 ~]$ # JSONフォーマットの確認
[cloudshell-user@ip-10-132-73-220 ~]$ echo ${S3_NOTIFICATION_CONFIGURATION} | python -m json.tool
{
"LambdaFunctionConfigurations": [
{
"LambdaFunctionArn": "arn:aws:lambda:ap-northeast-1:999999999999:function:transcribe-function",
"Events": [
"s3:ObjectCreated:*"
]
}
]
}
S3 バケットにイベント通知を設定して Lambda をトリガー
コマンド
aws s3api put-bucket-notification-configuration \
--bucket ${S3_BUCKET_NAME} \
--notification-configuration "${S3_NOTIFICATION_CONFIGURATION}"
出力
[cloudshell-user@ip-10-132-73-220 ~]$ aws s3api put-bucket-notification-configuration \
> --bucket ${S3_BUCKET_NAME} \
> --notification-configuration "${S3_NOTIFICATION_CONFIGURATION}"
S3にファイルをアップロード
コマンド
# アップロードファイル名
UPLOAD_FILENAME="h4b-serverless-3.mp3" \
&& echo ${UPLOAD_FILENAME}
# アップロード
aws s3 cp ${UPLOAD_FILENAME} s3://${S3_BUCKET_NAME}/
出力
[cloudshell-user@ip-10-132-73-220 ~]$ # アップロードファイル名
[cloudshell-user@ip-10-132-73-220 ~]$ UPLOAD_FILENAME="h4b-serverless-3.mp3" \
> && echo ${UPLOAD_FILENAME}
h4b-serverless-3.mp3
[cloudshell-user@ip-10-132-73-220 ~]$
[cloudshell-user@ip-10-132-73-220 ~]$ # アップロード
[cloudshell-user@ip-10-132-73-220 ~]$ aws s3 cp ${UPLOAD_FILENAME} s3://${S3_BUCKET_NAME}/
upload: ./h4b-serverless-3.mp3 to s3://h4b-serverless-3-input-20240929/h4b-serverless-3.mp3
CloudWatchロググループ確認
コマンド
# 最新のログストリームを取得
LATEST_LOG_STREAM=$(
aws logs describe-log-streams \
--log-group-name /aws/lambda/${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/${LAMBDA_FUNCTION_NAME} \
--log-stream-name ${LATEST_LOG_STREAM} \
--no-cli-pager
出力
[cloudshell-user@ip-10-132-73-220 ~]$ # 最新のログストリームを取得
[cloudshell-user@ip-10-132-73-220 ~]$ LATEST_LOG_STREAM=$(
> aws logs describe-log-streams \
> --log-group-name /aws/lambda/${LAMBDA_FUNCTION_NAME} \
> --order-by LastEventTime \
> --descending \
> --limit 1 \
> --query 'logStreams[0].logStreamName' \
> --output text
> ) \
> && echo ${LATEST_LOG_STREAM}
2024/09/29/[$LATEST]74551e5835134c22a39d83ea543656c0
[cloudshell-user@ip-10-132-73-220 ~]$
[cloudshell-user@ip-10-132-73-220 ~]$ # ログの確認
[cloudshell-user@ip-10-132-73-220 ~]$ aws logs get-log-events \
> --log-group-name /aws/lambda/${LAMBDA_FUNCTION_NAME} \
> --log-stream-name ${LATEST_LOG_STREAM} \
> --no-cli-pager
{
"events": [
{
"timestamp": 1727596189995,
"message": "INIT_START Runtime Version: python:3.10.v38\tRuntime Version ARN: arn:aws:lambda:ap-northeast-1::runtime:cd5b19747c6f456b465655915abd7ec32c616f52b3421c0b532d90cf258e0086\n",
"ingestionTime": 1727596195784
},
{
"timestamp": 1727596190274,
"message": "Loading function\n",
"ingestionTime": 1727596195784
},
{
"timestamp": 1727596190474,
"message": "START RequestId: 241f7b6e-8c03-4bcc-835f-ad6048ebb83c Version: $LATEST\n",
"ingestionTime": 1727596195784
},
{
"timestamp": 1727596190736,
"message": "CONTENT TYPE: audio/mpeg\n",
"ingestionTime": 1727596195784
},
{
"timestamp": 1727596190739,
"message": "END RequestId: 241f7b6e-8c03-4bcc-835f-ad6048ebb83c\n",
"ingestionTime": 1727596195784
},
{
"timestamp": 1727596190739,
"message": "REPORT RequestId: 241f7b6e-8c03-4bcc-835f-ad6048ebb83c\tDuration: 264.96 ms\tBilled Duration: 265 ms\tMemory Size: 128 MB\tMax Memory Used: 78 MB\tInit Duration: 478.05 ms\t\n",
"ingestionTime": 1727596195784
}
],
"nextForwardToken": "f/38526682455622548841445603785287162832960337203410239493/s",
"nextBackwardToken": "b/38526682439030794413738820167984588438109956242960809984/s"
}
Lambda関数更新
ソースコード更新
コマンド
cat << EOF > lambda_function.py
import json
import urllib.parse
import boto3
print('Loading function')
s3 = boto3.client('s3')
def lambda_handler(event, context):
print("Received event: " + json.dumps(event, indent=2))
# Get the object from the event and show its content type
bucket = event['Records'][0]['s3']['bucket']['name']
key = urllib.parse.unquote_plus(event['Records'][0]['s3']['object']['key'], encoding='utf-8')
try:
response = s3.get_object(Bucket=bucket, Key=key)
print("CONTENT TYPE: " + response['ContentType'])
return response['ContentType']
except Exception as e:
print(e)
print('Error getting object {} from bucket {}. Make sure they exist and your bucket is in the same region as this function.'.format(key, bucket))
raise e
EOF
出力
[cloudshell-user@ip-10-132-73-220 ~]$ cat << EOF > lambda_function.py
> import json
> import urllib.parse
> import boto3
>
> print('Loading function')
>
> s3 = boto3.client('s3')
>
>
> def lambda_handler(event, context):
> print("Received event: " + json.dumps(event, indent=2))
>
> # Get the object from the event and show its content type
> bucket = event['Records'][0]['s3']['bucket']['name']
> key = urllib.parse.unquote_plus(event['Records'][0]['s3']['object']['key'], encoding='utf-8')
> try:
> response = s3.get_object(Bucket=bucket, Key=key)
> print("CONTENT TYPE: " + response['ContentType'])
> return response['ContentType']
> except Exception as e:
> print(e)
> print('Error getting object {} from bucket {}. Make sure they exist and your bucket is in the same region as this function.'.format(key, bucket))
> raise e
> EOF
デプロイパッケージの作成
コマンド
zip function.zip lambda_function.py
出力
[cloudshell-user@ip-10-132-73-220 ~]$ zip function.zip lambda_function.py
updating: lambda_function.py (deflated 45%)
Lambda関数の更新
コマンド
aws lambda update-function-code \
--function-name ${LAMBDA_FUNCTION_NAME} \
--zip-file fileb://function.zip
出力
[cloudshell-user@ip-10-132-73-220 ~]$ aws lambda update-function-code \
> --function-name ${LAMBDA_FUNCTION_NAME} \
> --zip-file fileb://function.zip
{
"FunctionName": "transcribe-function",
"FunctionArn": "arn:aws:lambda:ap-northeast-1:999999999999:function:transcribe-function",
"Runtime": "python3.10",
"Role": "arn:aws:iam::999999999999:role/transcribe-function-role",
"Handler": "lambda_function.lambda_handler",
"CodeSize": 618,
"Description": "",
"Timeout": 3,
"MemorySize": 128,
"LastModified": "2024-09-29T07:52:18.000+0000",
"CodeSha256": "3CtjLOpsg1IZuO8J3ogj+Zz0rZ1ucVpqPsK0mRt9FJE=",
"Version": "$LATEST",
"TracingConfig": {
"Mode": "PassThrough"
},
"RevisionId": "ad218fa8-6fbe-4fef-8ca7-a006fb2cf68b",
"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:cd5b19747c6f456b465655915abd7ec32c616f52b3421c0b532d90cf258e0086"
},
"LoggingConfig": {
"LogFormat": "Text",
"LogGroup": "/aws/lambda/transcribe-function"
}
}
S3にファイルをアップロード
コマンド
# アップロードファイル名
UPLOAD_FILENAME="h4b-serverless-3.mp3" \
&& echo ${UPLOAD_FILENAME}
# アップロード
aws s3 cp ${UPLOAD_FILENAME} s3://${S3_BUCKET_NAME}/
出力
[cloudshell-user@ip-10-132-73-220 ~]$ # アップロードファイル名
[cloudshell-user@ip-10-132-73-220 ~]$ UPLOAD_FILENAME="h4b-serverless-3.mp3" \
> && echo ${UPLOAD_FILENAME}
h4b-serverless-3.mp3
[cloudshell-user@ip-10-132-73-220 ~]$
[cloudshell-user@ip-10-132-73-220 ~]$ # アップロード
[cloudshell-user@ip-10-132-73-220 ~]$ aws s3 cp ${UPLOAD_FILENAME} s3://${S3_BUCKET_NAME}/
upload: ./h4b-serverless-3.mp3 to s3://h4b-serverless-3-input-20240929/h4b-serverless-3.mp3
CloudWatchロググループ確認
コマンド
# 最新のログストリームを取得
LATEST_LOG_STREAM=$(
aws logs describe-log-streams \
--log-group-name /aws/lambda/${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/${LAMBDA_FUNCTION_NAME} \
--log-stream-name ${LATEST_LOG_STREAM} \
--no-cli-pager
出力
[cloudshell-user@ip-10-132-73-220 ~]$ # 最新のログストリームを取得
[cloudshell-user@ip-10-132-73-220 ~]$ LATEST_LOG_STREAM=$(
> aws logs describe-log-streams \
> --log-group-name /aws/lambda/${LAMBDA_FUNCTION_NAME} \
> --order-by LastEventTime \
> --descending \
> --limit 1 \
> --query 'logStreams[0].logStreamName' \
> --output text
> ) \
> && echo ${LATEST_LOG_STREAM}
2024/09/29/[$LATEST]ee2126f3b66541cea630ee1bded27bfe
[cloudshell-user@ip-10-132-73-220 ~]$
[cloudshell-user@ip-10-132-73-220 ~]$ # ログの確認
[cloudshell-user@ip-10-132-73-220 ~]$ aws logs get-log-events \
> --log-group-name /aws/lambda/${LAMBDA_FUNCTION_NAME} \
> --log-stream-name ${LATEST_LOG_STREAM} \
> --no-cli-pager
{
"events": [
{
"timestamp": 1727596368082,
"message": "INIT_START Runtime Version: python:3.10.v38\tRuntime Version ARN: arn:aws:lambda:ap-northeast-1::runtime:cd5b19747c6f456b465655915abd7ec32c616f52b3421c0b532d90cf258e0086\n",
"ingestionTime": 1727596376326
},
{
"timestamp": 1727596368333,
"message": "Loading function\n",
"ingestionTime": 1727596376326
},
{
"timestamp": 1727596368497,
"message": "START RequestId: 50a0a849-744a-4a7b-8c34-bc5eaf5b5e09 Version: $LATEST\n",
"ingestionTime": 1727596376326
},
{
"timestamp": 1727596368498,
"message": "Received event: {\n",
"ingestionTime": 1727596376326
},
{
"timestamp": 1727596368498,
"message": "\"Records\": [\n",
"ingestionTime": 1727596376326
},
{
"timestamp": 1727596368498,
"message": "{\n",
"ingestionTime": 1727596376326
},
{
"timestamp": 1727596368498,
"message": "\"eventVersion\": \"2.1\",\n",
"ingestionTime": 1727596376326
},
{
"timestamp": 1727596368498,
"message": "\"eventSource\": \"aws:s3\",\n",
"ingestionTime": 1727596376326
},
{
"timestamp": 1727596368498,
"message": "\"awsRegion\": \"ap-northeast-1\",\n",
"ingestionTime": 1727596376326
},
{
"timestamp": 1727596368498,
"message": "\"eventTime\": \"2024-09-29T07:52:46.894Z\",\n",
"ingestionTime": 1727596376326
},
{
"timestamp": 1727596368498,
"message": "\"eventName\": \"ObjectCreated:Put\",\n",
"ingestionTime": 1727596376326
},
{
"timestamp": 1727596368498,
"message": "\"userIdentity\": {\n",
"ingestionTime": 1727596376326
},
{
"timestamp": 1727596368498,
"message": "\"principalId\": \"AWS:AIDAWFKRCMKOXV327GJV2\"\n",
"ingestionTime": 1727596376326
},
{
"timestamp": 1727596368498,
"message": "},\n",
"ingestionTime": 1727596376326
},
{
"timestamp": 1727596368498,
"message": "\"requestParameters\": {\n",
"ingestionTime": 1727596376326
},
{
"timestamp": 1727596368498,
"message": "\"sourceIPAddress\": \"35.75.18.236\"\n",
"ingestionTime": 1727596376326
},
{
"timestamp": 1727596368498,
"message": "},\n",
"ingestionTime": 1727596376326
},
{
"timestamp": 1727596368498,
"message": "\"responseElements\": {\n",
"ingestionTime": 1727596376326
},
{
"timestamp": 1727596368498,
"message": "\"x-amz-request-id\": \"74HCBPRQ5FWG2GKR\",\n",
"ingestionTime": 1727596376326
},
{
"timestamp": 1727596368498,
"message": "\"x-amz-id-2\": \"OmoMH73cInpv11HWqelmwdDUVMDnaqdxLldow+WiDu6pKaXIH1IcjPNPP/MysZlJ2PRk++qeile6Su9ZIRjMqYp06kgk2R6T\"\n",
"ingestionTime": 1727596376326
},
{
"timestamp": 1727596368498,
"message": "},\n",
"ingestionTime": 1727596376326
},
{
"timestamp": 1727596368498,
"message": "\"s3\": {\n",
"ingestionTime": 1727596376326
},
{
"timestamp": 1727596368498,
"message": "\"s3SchemaVersion\": \"1.0\",\n",
"ingestionTime": 1727596376326
},
{
"timestamp": 1727596368498,
"message": "\"configurationId\": \"ZTVkNGE5MzItYmI4MS00ZWRjLWIyMmMtMzQzOTVhZjc5ODBh\",\n",
"ingestionTime": 1727596376326
},
{
"timestamp": 1727596368498,
"message": "\"bucket\": {\n",
"ingestionTime": 1727596376326
},
{
"timestamp": 1727596368498,
"message": "\"name\": \"h4b-serverless-3-input-20240929\",\n",
"ingestionTime": 1727596376326
},
{
"timestamp": 1727596368498,
"message": "\"ownerIdentity\": {\n",
"ingestionTime": 1727596376326
},
{
"timestamp": 1727596368498,
"message": "\"principalId\": \"A1N79N9DXMUVCN\"\n",
"ingestionTime": 1727596376326
},
{
"timestamp": 1727596368498,
"message": "},\n",
"ingestionTime": 1727596376326
},
{
"timestamp": 1727596368498,
"message": "\"arn\": \"arn:aws:s3:::h4b-serverless-3-input-20240929\"\n",
"ingestionTime": 1727596376326
},
{
"timestamp": 1727596368498,
"message": "},\n",
"ingestionTime": 1727596376326
},
{
"timestamp": 1727596368498,
"message": "\"object\": {\n",
"ingestionTime": 1727596376326
},
{
"timestamp": 1727596368498,
"message": "\"key\": \"h4b-serverless-3.mp3\",\n",
"ingestionTime": 1727596376326
},
{
"timestamp": 1727596368498,
"message": "\"size\": 27944,\n",
"ingestionTime": 1727596376326
},
{
"timestamp": 1727596368498,
"message": "\"eTag\": \"18fc7f0024c99b45f741d528d0411086\",\n",
"ingestionTime": 1727596376326
},
{
"timestamp": 1727596368498,
"message": "\"sequencer\": \"0066F9074ED6A76D3E\"\n",
"ingestionTime": 1727596376326
},
{
"timestamp": 1727596368498,
"message": "}\n",
"ingestionTime": 1727596376326
},
{
"timestamp": 1727596368498,
"message": "}\n",
"ingestionTime": 1727596376326
},
{
"timestamp": 1727596368498,
"message": "}\n",
"ingestionTime": 1727596376326
},
{
"timestamp": 1727596368498,
"message": "]\n",
"ingestionTime": 1727596376326
},
{
"timestamp": 1727596368498,
"message": "}\n",
"ingestionTime": 1727596376326
},
{
"timestamp": 1727596368775,
"message": "CONTENT TYPE: audio/mpeg\n",
"ingestionTime": 1727596376326
},
{
"timestamp": 1727596368796,
"message": "END RequestId: 50a0a849-744a-4a7b-8c34-bc5eaf5b5e09\n",
"ingestionTime": 1727596376326
},
{
"timestamp": 1727596368797,
"message": "REPORT RequestId: 50a0a849-744a-4a7b-8c34-bc5eaf5b5e09\tDuration: 299.35 ms\tBilled Duration: 300 ms\tMemory Size: 128 MB\tMax Memory Used: 78 MB\tInit Duration: 414.32 ms\t\n",
"ingestionTime": 1727596376326
}
],
"nextForwardToken": "f/38526686426448637401411299339116193659073992568340414507/s",
"nextBackwardToken": "b/38526686410503604584461903792918155094130414091564417024/s"
}
04 Amazon Transcribe を使って文字起こしを試してみる
S3バケット作成
変数
コマンド
# バケット名
date_var=$(date +%Y%m%d) \
&& echo ${date_var}
S3_BUCKET_NAME_2="h4b-serverless-3-output-${date_var}" \
&& echo ${S3_BUCKET_NAME_2}
出力
[cloudshell-user@ip-10-132-73-220 ~]$ # バケット名
[cloudshell-user@ip-10-132-73-220 ~]$ date_var=$(date +%Y%m%d) \
> && echo ${date_var}
20240929
[cloudshell-user@ip-10-132-73-220 ~]$ S3_BUCKET_NAME_2="h4b-serverless-3-output-${date_var}" \
> && echo ${S3_BUCKET_NAME_2}
h4b-serverless-3-output-20240929
S3バケット作成
コマンド
# S3バケット作成
aws s3 mb s3://${S3_BUCKET_NAME_2}
出力
[cloudshell-user@ip-10-132-73-220 ~]$ # S3バケット作成
[cloudshell-user@ip-10-132-73-220 ~]$ aws s3 mb s3://${S3_BUCKET_NAME_2}
make_bucket: h4b-serverless-3-output-20240929
トランスクリプションジョブ作成
変数
コマンド
TRANSCRIPTION_JOB_NAME="Test-Job" \
&& echo ${TRANSCRIPTION_JOB_NAME}
TRANSCRIPTION_LANG_CODE="ja-JP" \
&& echo ${TRANSCRIPTION_LANG_CODE}
出力
[cloudshell-user@ip-10-132-73-220 ~]$ TRANSCRIPTION_JOB_NAME="Test-Job" \
> && echo ${TRANSCRIPTION_JOB_NAME}
Test-Job
[cloudshell-user@ip-10-132-73-220 ~]$
[cloudshell-user@ip-10-132-73-220 ~]$ TRANSCRIPTION_LANG_CODE="ja-JP" \
> && echo ${TRANSCRIPTION_LANG_CODE}
ja-JP
トランスクリプションジョブ作成
コマンド
# トランスクリプションジョブ作成
aws transcribe start-transcription-job \
--transcription-job-name "${TRANSCRIPTION_JOB_NAME}" \
--language-code "${TRANSCRIPTION_LANG_CODE}" \
--media MediaFileUri=s3://${S3_BUCKET_NAME}/${UPLOAD_FILENAME} \
--output-bucket-name "${S3_BUCKET_NAME_2}"
出力
[cloudshell-user@ip-10-132-73-220 ~]$ # トランスクリプションジョブ作成
[cloudshell-user@ip-10-132-73-220 ~]$ aws transcribe start-transcription-job \
> --transcription-job-name "${TRANSCRIPTION_JOB_NAME}" \
> --language-code "${TRANSCRIPTION_LANG_CODE}" \
> --media MediaFileUri=s3://${S3_BUCKET_NAME}/${UPLOAD_FILENAME} \
> --output-bucket-name "${S3_BUCKET_NAME_2}"
{
"TranscriptionJob": {
"TranscriptionJobName": "Test-Job",
"TranscriptionJobStatus": "IN_PROGRESS",
"LanguageCode": "ja-JP",
"Media": {
"MediaFileUri": "s3://h4b-serverless-3-input-20240929/h4b-serverless-3.mp3"
},
"StartTime": "2024-09-29T16:55:31.505000+09:00",
"CreationTime": "2024-09-29T16:55:31.482000+09:00"
}
}
確認
コマンド
# 確認
aws transcribe get-transcription-job \
--transcription-job-name "${TRANSCRIPTION_JOB_NAME}"
出力
[cloudshell-user@ip-10-132-73-220 ~]$ # 確認
[cloudshell-user@ip-10-132-73-220 ~]$ aws transcribe get-transcription-job \
> --transcription-job-name "${TRANSCRIPTION_JOB_NAME}"
{
"TranscriptionJob": {
"TranscriptionJobName": "Test-Job",
"TranscriptionJobStatus": "COMPLETED",
"LanguageCode": "ja-JP",
"MediaSampleRateHertz": 22050,
"MediaFormat": "mp3",
"Media": {
"MediaFileUri": "s3://h4b-serverless-3-input-20240929/h4b-serverless-3.mp3"
},
"Transcript": {
"TranscriptFileUri": "https://s3.ap-northeast-1.amazonaws.com/h4b-serverless-3-output-20240929/Test-Job.json"
},
"StartTime": "2024-09-29T16:55:31.505000+09:00",
"CreationTime": "2024-09-29T16:55:31.482000+09:00",
"CompletionTime": "2024-09-29T16:55:42.879000+09:00",
"Settings": {
"ChannelIdentification": false,
"ShowAlternatives": false
}
}
}
S3バケット内のオブジェクトを確認
コマンド
aws s3api list-object-versions \
--bucket ${S3_BUCKET_NAME_2}
出力
[cloudshell-user@ip-10-132-73-220 ~]$ aws s3api list-object-versions \
> --bucket ${S3_BUCKET_NAME_2}
{
"Versions": [
{
"ETag": "\"d751713988987e9331980363e24189ce\"",
"Size": 2,
"StorageClass": "STANDARD",
"Key": ".write_access_check_file.temp",
"VersionId": "null",
"IsLatest": true,
"LastModified": "2024-09-29T07:55:32+00:00",
"Owner": {
"DisplayName": "user01",
"ID": "974cd83317461904fcbad632a42045ad8cd85cb24065c65f2ca62b7e35d84078"
}
},
{
"ETag": "\"40033c4f71ea9b9cc33b3201afd6c613\"",
"Size": 1991,
"StorageClass": "STANDARD",
"Key": "Test-Job.json",
"VersionId": "null",
"IsLatest": true,
"LastModified": "2024-09-29T07:55:43+00:00",
"Owner": {
"DisplayName": "user01",
"ID": "974cd83317461904fcbad632a42045ad8cd85cb24065c65f2ca62b7e35d84078"
}
}
],
"RequestCharged": null
}
S3からファイルをダウンロード
コマンド
# ダウンロードファイル名
DOWNLOAD_FILENAME="Test-Job.json" \
&& echo ${DOWNLOAD_FILENAME}
# ダウンロード
aws s3 cp s3://${S3_BUCKET_NAME_2}/${DOWNLOAD_FILENAME} ./
出力
[cloudshell-user@ip-10-132-73-220 ~]$ # ダウンロードファイル名
[cloudshell-user@ip-10-132-73-220 ~]$ DOWNLOAD_FILENAME="Test-Job.json" \
> && echo ${DOWNLOAD_FILENAME}
Test-Job.json
[cloudshell-user@ip-10-132-73-220 ~]$
[cloudshell-user@ip-10-132-73-220 ~]$ # ダウンロード
[cloudshell-user@ip-10-132-73-220 ~]$ aws s3 cp s3://${S3_BUCKET_NAME_2}/${DOWNLOAD_FILENAME} ./
download: s3://h4b-serverless-3-output-20240929/Test-Job.json to ./Test-Job.json
ダウンロードしたファイルを確認
コマンド
cat ${DOWNLOAD_FILENAME}
出力
[cloudshell-user@ip-10-132-73-220 ~]$ cat ${DOWNLOAD_FILENAME}
{"jobName":"Test-Job","accountId":"999999999999","status":"COMPLETED","results":{"transcripts":[{"transcript":"半音順調ですか?手を動かすの楽しいですよ"}],"items":[{"id":0,"type":"pronunciation","alternatives":[{"confidence":"0.996","content":"半"}],"start_time":"0.1","end_time":"0.4"},{"id":1,"type":"pronunciation","alternatives":[{"confidence":"0.611","content":"音"}],"start_time":"0.409","end_time":"0.74"},{"id":2,"type":"pronunciation","alternatives":[{"confidence":"0.997","content":"順調"}],"start_time":"0.75","end_time":"1.179"},{"id":3,"type":"pronunciation","alternatives":[{"confidence":"0.999","content":"です"}],"start_time":"1.19","end_time":"1.5"},{"id":4,"type":"pronunciation","alternatives":[{"confidence":"0.999","content":"か"}],"start_time":"1.509","end_time":"1.73"},{"id":5,"type":"punctuation","alternatives":[{"confidence":"0.0","content":"?"}]},{"id":6,"type":"pronunciation","alternatives":[{"confidence":"0.999","content":"手"}],"start_time":"2.19","end_time":"2.339"},{"id":7,"type":"pronunciation","alternatives":[{"confidence":"0.999","content":"を"}],"start_time":"2.349","end_time":"2.5"},{"id":8,"type":"pronunciation","alternatives":[{"confidence":"0.999","content":"動かす"}],"start_time":"2.509","end_time":"3.059"},{"id":9,"type":"pronunciation","alternatives":[{"confidence":"0.999","content":"の"}],"start_time":"3.069","end_time":"3.21"},{"id":10,"type":"pronunciation","alternatives":[{"confidence":"0.999","content":"楽しい"}],"start_time":"3.4","end_time":"3.92"},{"id":11,"type":"pronunciation","alternatives":[{"confidence":"0.999","content":"です"}],"start_time":"3.93","end_time":"4.219"},{"id":12,"type":"pronunciation","alternatives":[{"confidence":"0.999","content":"よ"}],"start_time":"4.23","end_time":"4.519"}],"audio_segments":[{"id":0,"transcript":"半音順調ですか?手を動かすの楽しいですよ","start_time":"0.0","end_time":"4.63","items":[0,1,2,3,4,5,6,7,8,9,10,11,12]}]}}
ハンズオンが半音になってしまう
05 S3 への音声ファイルアップロードをトリガに Lambda を起動し Transcribe するパイプラインを作る
IAM修正
コマンド
# AWS管理ポリシー
AWS_MGMT_POLICY_NAME="AmazonTranscribeFullAccess" \
&& echo ${AWS_MGMT_POLICY_NAME}
# IAMロールにポリシーをアタッチ
aws iam attach-role-policy \
--role-name ${IAM_ROLE_NAME} \
--policy-arn arn:aws:iam::aws:policy/${AWS_MGMT_POLICY_NAME}
# AWS管理ポリシー
AWS_MGMT_POLICY_NAME="AmazonS3FullAccess" \
&& echo ${AWS_MGMT_POLICY_NAME}
# IAMロールにポリシーをアタッチ
aws iam attach-role-policy \
--role-name ${IAM_ROLE_NAME} \
--policy-arn arn:aws:iam::aws:policy/${AWS_MGMT_POLICY_NAME}
出力
[cloudshell-user@ip-10-132-73-220 ~]$ # AWS管理ポリシー
[cloudshell-user@ip-10-132-73-220 ~]$ AWS_MGMT_POLICY_NAME="AmazonTranscribeFullAccess" \
> && echo ${AWS_MGMT_POLICY_NAME}
AmazonTranscribeFullAccess
[cloudshell-user@ip-10-132-73-220 ~]$
[cloudshell-user@ip-10-132-73-220 ~]$ # IAMロールにポリシーをアタッチ
[cloudshell-user@ip-10-132-73-220 ~]$ aws iam attach-role-policy \
> --role-name ${IAM_ROLE_NAME} \
> --policy-arn arn:aws:iam::aws:policy/${AWS_MGMT_POLICY_NAME}
[cloudshell-user@ip-10-132-73-220 ~]$
[cloudshell-user@ip-10-132-73-220 ~]$ # AWS管理ポリシー
[cloudshell-user@ip-10-132-73-220 ~]$ AWS_MGMT_POLICY_NAME="AmazonS3FullAccess" \
> && echo ${AWS_MGMT_POLICY_NAME}
AmazonS3FullAccess
[cloudshell-user@ip-10-132-73-220 ~]$
[cloudshell-user@ip-10-132-73-220 ~]$ # IAMロールにポリシーをアタッチ
[cloudshell-user@ip-10-132-73-220 ~]$ aws iam attach-role-policy \
> --role-name ${IAM_ROLE_NAME} \
> --policy-arn arn:aws:iam::aws:policy/${AWS_MGMT_POLICY_NAME}
Lambda関数更新
ソースコード更新
コマンド
cat << EOF > lambda_function.py
import json
import urllib.parse
import boto3
import datetime
s3 = boto3.client('s3')
transcribe = boto3.client('transcribe')
def lambda_handler(event, context):
bucket = event['Records'][0]['s3']['bucket']['name']
key = urllib.parse.unquote_plus(event['Records'][0]['s3']['object']['key'], encoding='utf-8')
try:
transcribe.start_transcription_job(
TranscriptionJobName= datetime.datetime.now().strftime("%Y%m%d%H%M%S") + '_Transcription',
LanguageCode='ja-JP',
Media={
'MediaFileUri': 'https://s3.ap-northeast-1.amazonaws.com/' + bucket + '/' + key
},
OutputBucketName="${S3_BUCKET_NAME_2}"
)
except Exception as e:
print(e)
print('Error getting object {} from bucket {}. Make sure they exist and your bucket is in the same region as this function.'.format(key, bucket))
raise e
EOF
出力
[cloudshell-user@ip-10-132-73-220 ~]$ cat << EOF > lambda_function.py
> import json
> import urllib.parse
> import boto3
> import datetime
>
> s3 = boto3.client('s3')
> transcribe = boto3.client('transcribe')
>
> def lambda_handler(event, context):
> bucket = event['Records'][0]['s3']['bucket']['name']
> key = urllib.parse.unquote_plus(event['Records'][0]['s3']['object']['key'], encoding='utf-8')
> try:
> transcribe.start_transcription_job(
> TranscriptionJobName= datetime.datetime.now().strftime("%Y%m%d%H%M%S") + '_Transcription',
> LanguageCode='ja-JP',
> Media={
> 'MediaFileUri': 'https://s3.ap-northeast-1.amazonaws.com/' + bucket + '/' + key
> },
> OutputBucketName="${S3_BUCKET_NAME_2}"
> )
> except Exception as e:
> print(e)
> print('Error getting object {} from bucket {}. Make sure they exist and your bucket is in the same region as this function.'.format(key, bucket))
> raise e
> EOF
デプロイパッケージの作成
コマンド
zip function.zip lambda_function.py
出力
[cloudshell-user@ip-10-132-73-220 ~]$ zip function.zip lambda_function.py
updating: lambda_function.py (deflated 46%)
Lambda関数の更新
コマンド
# Lambda関数の更新
aws lambda update-function-code \
--function-name ${LAMBDA_FUNCTION_NAME} \
--zip-file fileb://function.zip
出力
[cloudshell-user@ip-10-132-73-220 ~]$ # Lambda関数の更新
[cloudshell-user@ip-10-132-73-220 ~]$ aws lambda update-function-code \
> --function-name ${LAMBDA_FUNCTION_NAME} \
> --zip-file fileb://function.zip
{
"FunctionName": "transcribe-function",
"FunctionArn": "arn:aws:lambda:ap-northeast-1:999999999999:function:transcribe-function",
"Runtime": "python3.10",
"Role": "arn:aws:iam::999999999999:role/transcribe-function-role",
"Handler": "lambda_function.lambda_handler",
"CodeSize": 691,
"Description": "",
"Timeout": 3,
"MemorySize": 128,
"LastModified": "2024-09-29T08:08:46.000+0000",
"CodeSha256": "f//PUiA9FQQ+LsS2kgcyUO4tHEsJJlaakfL/lCebukU=",
"Version": "$LATEST",
"TracingConfig": {
"Mode": "PassThrough"
},
"RevisionId": "459b1b9e-eed2-48a9-ab4f-6a2efd3d20a3",
"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:cd5b19747c6f456b465655915abd7ec32c616f52b3421c0b532d90cf258e0086"
},
"LoggingConfig": {
"LogFormat": "Text",
"LogGroup": "/aws/lambda/transcribe-function"
}
}
S3にファイルをアップロード
コマンド
# アップロードファイル名
UPLOAD_FILENAME="h4b-serverless-3.mp3" \
&& echo ${UPLOAD_FILENAME}
# アップロード
aws s3 cp ${UPLOAD_FILENAME} s3://${S3_BUCKET_NAME}/
出力
[cloudshell-user@ip-10-132-73-220 ~]$ # アップロードファイル名
[cloudshell-user@ip-10-132-73-220 ~]$ UPLOAD_FILENAME="h4b-serverless-3.mp3" \
> && echo ${UPLOAD_FILENAME}
h4b-serverless-3.mp3
[cloudshell-user@ip-10-132-73-220 ~]$
[cloudshell-user@ip-10-132-73-220 ~]$ # アップロード
[cloudshell-user@ip-10-132-73-220 ~]$ aws s3 cp ${UPLOAD_FILENAME} s3://${S3_BUCKET_NAME}/
upload: ./h4b-serverless-3.mp3 to s3://h4b-serverless-3-input-20240929/h4b-serverless-3.mp3
トランスクリプションジョブ一覧確認
コマンド
# トランスクリプションジョブ一覧確認
aws transcribe list-transcription-jobs
出力
[cloudshell-user@ip-10-132-73-220 ~]$ # トランスクリプションジョブ一覧確認
[cloudshell-user@ip-10-132-73-220 ~]$ aws transcribe list-transcription-jobs
{
"TranscriptionJobSummaries": [
{
"TranscriptionJobName": "20240929081822_Transcription",
"CreationTime": "2024-09-29T17:18:22.780000+09:00",
"StartTime": "2024-09-29T17:18:22.802000+09:00",
"CompletionTime": "2024-09-29T17:18:35.444000+09:00",
"LanguageCode": "ja-JP",
"TranscriptionJobStatus": "COMPLETED",
"OutputLocationType": "CUSTOMER_BUCKET"
},
{
"TranscriptionJobName": "Test-Job",
"CreationTime": "2024-09-29T16:55:31.482000+09:00",
"StartTime": "2024-09-29T16:55:31.505000+09:00",
"CompletionTime": "2024-09-29T16:55:42.879000+09:00",
"LanguageCode": "ja-JP",
"TranscriptionJobStatus": "COMPLETED",
"OutputLocationType": "CUSTOMER_BUCKET"
}
]
}
S3バケット内のオブジェクトを確認
コマンド
# S3バケット内のオブジェクトを確認
aws s3api list-object-versions \
--bucket ${S3_BUCKET_NAME_2}
出力
[cloudshell-user@ip-10-132-73-220 ~]$ # S3バケット内のオブジェクトを確認
[cloudshell-user@ip-10-132-73-220 ~]$ aws s3api list-object-versions \
> --bucket ${S3_BUCKET_NAME_2}
{
"Versions": [
{
"ETag": "\"d751713988987e9331980363e24189ce\"",
"Size": 2,
"StorageClass": "STANDARD",
"Key": ".write_access_check_file.temp",
"VersionId": "null",
"IsLatest": true,
"LastModified": "2024-09-29T08:18:23+00:00",
"Owner": {
"DisplayName": "user01",
"ID": "974cd83317461904fcbad632a42045ad8cd85cb24065c65f2ca62b7e35d84078"
}
},
{
"ETag": "\"1f6856b6b731605a5c910682046378be\"",
"Size": 2011,
"StorageClass": "STANDARD",
"Key": "20240929081822_Transcription.json",
"VersionId": "null",
"IsLatest": true,
"LastModified": "2024-09-29T08:18:36+00:00",
"Owner": {
"DisplayName": "user01",
"ID": "974cd83317461904fcbad632a42045ad8cd85cb24065c65f2ca62b7e35d84078"
}
},
{
"ETag": "\"40033c4f71ea9b9cc33b3201afd6c613\"",
"Size": 1991,
"StorageClass": "STANDARD",
"Key": "Test-Job.json",
"VersionId": "null",
"IsLatest": true,
"LastModified": "2024-09-29T07:55:43+00:00",
"Owner": {
"DisplayName": "user01",
"ID": "974cd83317461904fcbad632a42045ad8cd85cb24065c65f2ca62b7e35d84078"
}
}
],
"RequestCharged": null
}
S3からファイルをダウンロード
コマンド
# ダウンロードファイル名
DOWNLOAD_FILENAME="20240929081822_Transcription.json" \
&& echo ${DOWNLOAD_FILENAME}
# ダウンロード
aws s3 cp s3://${S3_BUCKET_NAME_2}/${DOWNLOAD_FILENAME} ./
出力
[cloudshell-user@ip-10-132-73-220 ~]$ # ダウンロードファイル名
[cloudshell-user@ip-10-132-73-220 ~]$ DOWNLOAD_FILENAME="20240929081822_Transcription.json" \
> && echo ${DOWNLOAD_FILENAME}
20240929081822_Transcription.json
[cloudshell-user@ip-10-132-73-220 ~]$
[cloudshell-user@ip-10-132-73-220 ~]$ # ダウンロード
[cloudshell-user@ip-10-132-73-220 ~]$ aws s3 cp s3://${S3_BUCKET_NAME_2}/${DOWNLOAD_FILENAME} ./
download: s3://h4b-serverless-3-output-20240929/20240929081822_Transcription.json to ./20240929081822_Transcription.json
ダウンロードしたファイルを確認
コマンド
cat ${DOWNLOAD_FILENAME}
出力
[cloudshell-user@ip-10-132-73-220 ~]$ cat ${DOWNLOAD_FILENAME}
{"jobName":"20240929081822_Transcription","accountId":"999999999999","status":"COMPLETED","results":{"transcripts":[{"transcript":"半音順調ですか?手を動かすの楽しいですよ"}],"items":[{"id":0,"type":"pronunciation","alternatives":[{"confidence":"0.996","content":"半"}],"start_time":"0.1","end_time":"0.4"},{"id":1,"type":"pronunciation","alternatives":[{"confidence":"0.611","content":"音"}],"start_time":"0.409","end_time":"0.74"},{"id":2,"type":"pronunciation","alternatives":[{"confidence":"0.997","content":"順調"}],"start_time":"0.75","end_time":"1.179"},{"id":3,"type":"pronunciation","alternatives":[{"confidence":"0.999","content":"です"}],"start_time":"1.19","end_time":"1.5"},{"id":4,"type":"pronunciation","alternatives":[{"confidence":"0.999","content":"か"}],"start_time":"1.509","end_time":"1.73"},{"id":5,"type":"punctuation","alternatives":[{"confidence":"0.0","content":"?"}]},{"id":6,"type":"pronunciation","alternatives":[{"confidence":"0.999","content":"手"}],"start_time":"2.19","end_time":"2.339"},{"id":7,"type":"pronunciation","alternatives":[{"confidence":"0.999","content":"を"}],"start_time":"2.349","end_time":"2.5"},{"id":8,"type":"pronunciation","alternatives":[{"confidence":"0.999","content":"動かす"}],"start_time":"2.509","end_time":"3.059"},{"id":9,"type":"pronunciation","alternatives":[{"confidence":"0.999","content":"の"}],"start_time":"3.069","end_time":"3.21"},{"id":10,"type":"pronunciation","alternatives":[{"confidence":"0.999","content":"楽しい"}],"start_time":"3.4","end_time":"3.92"},{"id":11,"type":"pronunciation","alternatives":[{"confidence":"0.999","content":"です"}],"start_time":"3.93","end_time":"4.219"},{"id":12,"type":"pronunciation","alternatives":[{"confidence":"0.999","content":"よ"}],"start_time":"4.23","end_time":"4.519"}],"audio_segments":[{"id":0,"transcript":"半音順調ですか?手を動かすの楽しいですよ","start_time":"0.0","end_time":"4.63","items":[0,1,2,3,4,5,6,7,8,9,10,11,12]}]}}
ハンズオンが半音になってしまう
06 パイプラインで文字起こししたテキストを Comprehend で感情分析する
Comprehend作成
テスト1
コマンド
ARTICLE="ハンズオン楽しいです!" \
&& echo ${ARTICLE}
aws comprehend detect-sentiment --language-code "ja" --text "${ARTICLE}"
出力
[cloudshell-user@ip-10-132-73-220 ~]$ ARTICLE="ハンズオン楽しいです!" \
> && echo ${ARTICLE}
ハンズオン楽しいです!
[cloudshell-user@ip-10-132-73-220 ~]$
[cloudshell-user@ip-10-132-73-220 ~]$ aws comprehend detect-sentiment --language-code "ja" --text "${ARTICLE}"
{
"Sentiment": "POSITIVE",
"SentimentScore": {
"Positive": 0.9994205236434937,
"Negative": 5.861550016561523e-05,
"Neutral": 0.0005112771177664399,
"Mixed": 9.625600796425715e-06
}
}
テスト2
コマンド
ARTICLE="ハンズオン難しいです!" \
&& echo ${ARTICLE}
aws comprehend detect-sentiment --language-code "ja" --text "${ARTICLE}"
出力
[cloudshell-user@ip-10-132-73-220 ~]$ ARTICLE="ハンズオン難しいです!" \
> && echo ${ARTICLE}
ハンズオン難しいです!
[cloudshell-user@ip-10-132-73-220 ~]$
[cloudshell-user@ip-10-132-73-220 ~]$ aws comprehend detect-sentiment --language-code "ja" --text "${ARTICLE}"
{
"Sentiment": "NEGATIVE",
"SentimentScore": {
"Positive": 0.008654012344777584,
"Negative": 0.9865438342094421,
"Neutral": 0.004730266984552145,
"Mixed": 7.191118493210524e-05
}
}
Lambda関数作成
変数
コマンド
LAMBDA_FUNCTION_NAME_2="comprehend-function" \
&& echo ${LAMBDA_FUNCTION_NAME_2}
# IAMポリシー名1
IAM_POLICY_NAME_3="AWSLambdaBasicExecutionRole-${LAMBDA_FUNCTION_NAME_2}" \
&& echo ${IAM_POLICY_NAME_3}
# IAMポリシー名2
IAM_POLICY_NAME_4="AWSLambdaS3ExecutionRole-${LAMBDA_FUNCTION_NAME_2}" \
&& echo ${IAM_POLICY_NAME_4}
# IAMロール名
IAM_ROLE_NAME_2="${LAMBDA_FUNCTION_NAME_2}-role" \
&& echo ${IAM_ROLE_NAME_2}
# ランタイム
LAMBDA_RUNTIME="python3.10" \
&& echo ${LAMBDA_RUNTIME}
# アカウントID
ACCOUNT_ID="999999999999" \
&& echo ${ACCOUNT_ID}
出力
[cloudshell-user@ip-10-132-73-220 ~]$ LAMBDA_FUNCTION_NAME_2="comprehend-function" \
> && echo ${LAMBDA_FUNCTION_NAME_2}
comprehend-function
[cloudshell-user@ip-10-132-73-220 ~]$
[cloudshell-user@ip-10-132-73-220 ~]$ # IAMポリシー名1
[cloudshell-user@ip-10-132-73-220 ~]$ IAM_POLICY_NAME_3="AWSLambdaBasicExecutionRole-${LAMBDA_FUNCTION_NAME_2}" \
> && echo ${IAM_POLICY_NAME_3}
AWSLambdaBasicExecutionRole-comprehend-function
[cloudshell-user@ip-10-132-73-220 ~]$
[cloudshell-user@ip-10-132-73-220 ~]$ # IAMポリシー名2
[cloudshell-user@ip-10-132-73-220 ~]$ IAM_POLICY_NAME_4="AWSLambdaS3ExecutionRole-${LAMBDA_FUNCTION_NAME_2}" \
> && echo ${IAM_POLICY_NAME_4}
AWSLambdaS3ExecutionRole-comprehend-function
[cloudshell-user@ip-10-132-73-220 ~]$
[cloudshell-user@ip-10-132-73-220 ~]$ # IAMロール名
[cloudshell-user@ip-10-132-73-220 ~]$ IAM_ROLE_NAME_2="${LAMBDA_FUNCTION_NAME_2}-role" \
> && echo ${IAM_ROLE_NAME_2}
comprehend-function-role
[cloudshell-user@ip-10-132-73-220 ~]$
[cloudshell-user@ip-10-132-73-220 ~]$ # ランタイム
[cloudshell-user@ip-10-132-73-220 ~]$ LAMBDA_RUNTIME="python3.10" \
> && echo ${LAMBDA_RUNTIME}
python3.10
[cloudshell-user@ip-10-132-73-220 ~]$
[cloudshell-user@ip-10-132-73-220 ~]$ # アカウントID
[cloudshell-user@ip-10-132-73-220 ~]$ ACCOUNT_ID="999999999999" \
> && echo ${ACCOUNT_ID}
999999999999
IAMポリシー作成
AWSLambdaBasicExecutionRole
コマンド
# AWSLambdaBasicExecutionRole
# ポリシードキュメントの作成
POLICY_DOCUMENT_JSON=$(cat << EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "logs:CreateLogGroup",
"Resource": "arn:aws:logs:ap-northeast-1:${ACCOUNT_ID}:*"
},
{
"Effect": "Allow",
"Action": [
"logs:CreateLogStream",
"logs:PutLogEvents"
],
"Resource": [
"arn:aws:logs:ap-northeast-1:${ACCOUNT_ID}:log-group:/aws/lambda/${LAMBDA_FUNCTION_NAME_2}:*"
]
}
]
}
EOF
) \
&& echo ${POLICY_DOCUMENT_JSON}
# JSONフォーマットの確認
echo ${POLICY_DOCUMENT_JSON} | python -m json.tool
# ポリシーの作成
aws iam create-policy \
--policy-name ${IAM_POLICY_NAME_3} \
--policy-document "${POLICY_DOCUMENT_JSON}"
# ARN取得
IAM_POLICY_ARN_3=$(
aws iam list-policies \
--query "Policies[?PolicyName=='${IAM_POLICY_NAME_3}'].Arn" \
--output text
) \
&& echo ${IAM_POLICY_ARN_3}
出力
[cloudshell-user@ip-10-132-73-220 ~]$ # AWSLambdaBasicExecutionRole
[cloudshell-user@ip-10-132-73-220 ~]$ # ポリシードキュメントの作成
[cloudshell-user@ip-10-132-73-220 ~]$ POLICY_DOCUMENT_JSON=$(cat << EOF
> {
> "Version": "2012-10-17",
> "Statement": [
> {
> "Effect": "Allow",
> "Action": "logs:CreateLogGroup",
> "Resource": "arn:aws:logs:ap-northeast-1:${ACCOUNT_ID}:*"
> },
> {
> "Effect": "Allow",
> "Action": [
> "logs:CreateLogStream",
> "logs:PutLogEvents"
> ],
> "Resource": [
> "arn:aws:logs:ap-northeast-1:${ACCOUNT_ID}:log-group:/aws/lambda/${LAMBDA_FUNCTION_NAME_2}:*"
> ]
> }
> ]
> }
> 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/comprehend-function:*" ] } ] }
[cloudshell-user@ip-10-132-73-220 ~]$
[cloudshell-user@ip-10-132-73-220 ~]$ # JSONフォーマットの確認
[cloudshell-user@ip-10-132-73-220 ~]$ echo ${POLICY_DOCUMENT_JSON} | python -m json.tool
{
"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/comprehend-function:*"
]
}
]
}
[cloudshell-user@ip-10-132-73-220 ~]$
[cloudshell-user@ip-10-132-73-220 ~]$ # ポリシーの作成
[cloudshell-user@ip-10-132-73-220 ~]$ aws iam create-policy \
> --policy-name ${IAM_POLICY_NAME_3} \
> --policy-document "${POLICY_DOCUMENT_JSON}"
{
"Policy": {
"PolicyName": "AWSLambdaBasicExecutionRole-comprehend-function",
"PolicyId": "ANPAWFKRCMKOQW5QIFRXV",
"Arn": "arn:aws:iam::999999999999:policy/AWSLambdaBasicExecutionRole-comprehend-function",
"Path": "/",
"DefaultVersionId": "v1",
"AttachmentCount": 0,
"PermissionsBoundaryUsageCount": 0,
"IsAttachable": true,
"CreateDate": "2024-09-29T08:31:06+00:00",
"UpdateDate": "2024-09-29T08:31:06+00:00"
}
}
[cloudshell-user@ip-10-132-73-220 ~]$
[cloudshell-user@ip-10-132-73-220 ~]$ # ARN取得
[cloudshell-user@ip-10-132-73-220 ~]$ IAM_POLICY_ARN_3=$(
> aws iam list-policies \
> --query "Policies[?PolicyName=='${IAM_POLICY_NAME_3}'].Arn" \
> --output text
> ) \
> && echo ${IAM_POLICY_ARN_3}
arn:aws:iam::999999999999:policy/AWSLambdaBasicExecutionRole-comprehend-function
AWSLambdaS3ExecutionRole
コマンド
# AWSLambdaS3ExecutionRole
# ポリシードキュメントの作成
POLICY_DOCUMENT_JSON=$(cat << EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:GetObject"
],
"Resource": "arn:aws:s3:::*"
}
]
}
EOF
) \
&& echo ${POLICY_DOCUMENT_JSON}
# JSONフォーマットの確認
echo ${POLICY_DOCUMENT_JSON} | python -m json.tool
# ポリシーの作成
aws iam create-policy \
--policy-name ${IAM_POLICY_NAME_4} \
--policy-document "${POLICY_DOCUMENT_JSON}"
# ARN取得
IAM_POLICY_ARN_4=$(
aws iam list-policies \
--query "Policies[?PolicyName=='${IAM_POLICY_NAME_4}'].Arn" \
--output text
) \
&& echo ${IAM_POLICY_ARN_4}
出力
[cloudshell-user@ip-10-132-73-220 ~]$ # AWSLambdaS3ExecutionRole
[cloudshell-user@ip-10-132-73-220 ~]$ # ポリシードキュメントの作成
[cloudshell-user@ip-10-132-73-220 ~]$ POLICY_DOCUMENT_JSON=$(cat << EOF
> {
> "Version": "2012-10-17",
> "Statement": [
> {
> "Effect": "Allow",
> "Action": [
> "s3:GetObject"
> ],
> "Resource": "arn:aws:s3:::*"
> }
> ]
> }
> EOF
> ) \
> && echo ${POLICY_DOCUMENT_JSON}
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "s3:GetObject" ], "Resource": "arn:aws:s3:::*" } ] }
[cloudshell-user@ip-10-132-73-220 ~]$
[cloudshell-user@ip-10-132-73-220 ~]$ # JSONフォーマットの確認
[cloudshell-user@ip-10-132-73-220 ~]$ echo ${POLICY_DOCUMENT_JSON} | python -m json.tool
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:GetObject"
],
"Resource": "arn:aws:s3:::*"
}
]
}
[cloudshell-user@ip-10-132-73-220 ~]$
[cloudshell-user@ip-10-132-73-220 ~]$ # ポリシーの作成
[cloudshell-user@ip-10-132-73-220 ~]$ aws iam create-policy \
> --policy-name ${IAM_POLICY_NAME_4} \
> --policy-document "${POLICY_DOCUMENT_JSON}"
{
"Policy": {
"PolicyName": "AWSLambdaS3ExecutionRole-comprehend-function",
"PolicyId": "ANPAWFKRCMKOWZ7TFX5RM",
"Arn": "arn:aws:iam::999999999999:policy/AWSLambdaS3ExecutionRole-comprehend-function",
"Path": "/",
"DefaultVersionId": "v1",
"AttachmentCount": 0,
"PermissionsBoundaryUsageCount": 0,
"IsAttachable": true,
"CreateDate": "2024-09-29T08:31:53+00:00",
"UpdateDate": "2024-09-29T08:31:53+00:00"
}
}
[cloudshell-user@ip-10-132-73-220 ~]$
[cloudshell-user@ip-10-132-73-220 ~]$ # ARN取得
[cloudshell-user@ip-10-132-73-220 ~]$ IAM_POLICY_ARN_4=$(
> aws iam list-policies \
> --query "Policies[?PolicyName=='${IAM_POLICY_NAME_4}'].Arn" \
> --output text
> ) \
> && echo ${IAM_POLICY_ARN_4}
arn:aws:iam::999999999999:policy/AWSLambdaS3ExecutionRole-comprehend-function
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}
# JSONフォーマットの確認
echo ${ASSUME_ROLE_POLICY_DOCUMENT} | python -m json.tool
# IAMロールの作成
aws iam create-role \
--role-name ${IAM_ROLE_NAME_2} \
--assume-role-policy-document "${ASSUME_ROLE_POLICY_DOCUMENT}"
# ARN取得
IAM_ROLE_ARN_2=$(
aws iam get-role \
--role-name ${IAM_ROLE_NAME_2} \
--query 'Role.Arn' --output text
) \
&& echo ${IAM_ROLE_ARN_2}
# IAMロールにポリシーをアタッチ
aws iam attach-role-policy \
--role-name ${IAM_ROLE_NAME_2} \
--policy-arn ${IAM_POLICY_ARN_3}
aws iam attach-role-policy \
--role-name ${IAM_ROLE_NAME_2} \
--policy-arn ${IAM_POLICY_ARN_4}
# AWS管理ポリシー
AWS_MGMT_POLICY_NAME="AmazonS3FullAccess" \
&& echo ${AWS_MGMT_POLICY_NAME}
# IAMロールにポリシーをアタッチ
aws iam attach-role-policy \
--role-name ${IAM_ROLE_NAME_2} \
--policy-arn arn:aws:iam::aws:policy/${AWS_MGMT_POLICY_NAME}
# AWS管理ポリシー
AWS_MGMT_POLICY_NAME="ComprehendFullAccess" \
&& echo ${AWS_MGMT_POLICY_NAME}
# IAMロールにポリシーをアタッチ
aws iam attach-role-policy \
--role-name ${IAM_ROLE_NAME_2} \
--policy-arn arn:aws:iam::aws:policy/${AWS_MGMT_POLICY_NAME}
出力
[cloudshell-user@ip-10-132-73-220 ~]$ # 信頼関係ポリシードキュメントの作成
[cloudshell-user@ip-10-132-73-220 ~]$ 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-132-73-220 ~]$
[cloudshell-user@ip-10-132-73-220 ~]$ # JSONフォーマットの確認
[cloudshell-user@ip-10-132-73-220 ~]$ echo ${ASSUME_ROLE_POLICY_DOCUMENT} | python -m json.tool
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "lambda.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
[cloudshell-user@ip-10-132-73-220 ~]$
[cloudshell-user@ip-10-132-73-220 ~]$ # IAMロールの作成
[cloudshell-user@ip-10-132-73-220 ~]$ aws iam create-role \
> --role-name ${IAM_ROLE_NAME_2} \
> --assume-role-policy-document "${ASSUME_ROLE_POLICY_DOCUMENT}"
{
"Role": {
"Path": "/",
"RoleName": "comprehend-function-role",
"RoleId": "AROAWFKRCMKOV5PYZUZWU",
"Arn": "arn:aws:iam::999999999999:role/comprehend-function-role",
"CreateDate": "2024-09-29T08:32:38+00:00",
"AssumeRolePolicyDocument": {
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "lambda.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
}
}
[cloudshell-user@ip-10-132-73-220 ~]$
[cloudshell-user@ip-10-132-73-220 ~]$ # ARN取得
[cloudshell-user@ip-10-132-73-220 ~]$ IAM_ROLE_ARN_2=$(
> aws iam get-role \
> --role-name ${IAM_ROLE_NAME_2} \
> --query 'Role.Arn' --output text
> ) \
> && echo ${IAM_ROLE_ARN_2}
arn:aws:iam::999999999999:role/comprehend-function-role
[cloudshell-user@ip-10-132-73-220 ~]$
[cloudshell-user@ip-10-132-73-220 ~]$ # IAMロールにポリシーをアタッチ
[cloudshell-user@ip-10-132-73-220 ~]$ aws iam attach-role-policy \
> --role-name ${IAM_ROLE_NAME_2} \
> --policy-arn ${IAM_POLICY_ARN_3}
[cloudshell-user@ip-10-132-73-220 ~]$
[cloudshell-user@ip-10-132-73-220 ~]$ aws iam attach-role-policy \
> --role-name ${IAM_ROLE_NAME_2} \
> --policy-arn ${IAM_POLICY_ARN_4}
[cloudshell-user@ip-10-132-73-220 ~]$
[cloudshell-user@ip-10-132-73-220 ~]$ # AWS管理ポリシー
[cloudshell-user@ip-10-132-73-220 ~]$ AWS_MGMT_POLICY_NAME="AmazonS3FullAccess" \
> && echo ${AWS_MGMT_POLICY_NAME}
AmazonS3FullAccess
[cloudshell-user@ip-10-132-73-220 ~]$
[cloudshell-user@ip-10-132-73-220 ~]$ # IAMロールにポリシーをアタッチ
[cloudshell-user@ip-10-132-73-220 ~]$ aws iam attach-role-policy \
> --role-name ${IAM_ROLE_NAME_2} \
> --policy-arn arn:aws:iam::aws:policy/${AWS_MGMT_POLICY_NAME}
[cloudshell-user@ip-10-132-73-220 ~]$
[cloudshell-user@ip-10-132-73-220 ~]$ # AWS管理ポリシー
[cloudshell-user@ip-10-132-73-220 ~]$ AWS_MGMT_POLICY_NAME="ComprehendFullAccess" \
> && echo ${AWS_MGMT_POLICY_NAME}
ComprehendFullAccess
[cloudshell-user@ip-10-132-73-220 ~]$
[cloudshell-user@ip-10-132-73-220 ~]$ # IAMロールにポリシーをアタッチ
[cloudshell-user@ip-10-132-73-220 ~]$ aws iam attach-role-policy \
> --role-name ${IAM_ROLE_NAME_2} \
> --policy-arn arn:aws:iam::aws:policy/${AWS_MGMT_POLICY_NAME}
Lambdaソースコード
コマンド
cat << EOF > lambda_function.py
import json
import urllib.parse
import boto3
s3 = boto3.client('s3')
comprehend = boto3.client('comprehend')
def lambda_handler(event, context):
bucket = event['Records'][0]['s3']['bucket']['name']
key = urllib.parse.unquote_plus(event['Records'][0]['s3']['object']['key'], encoding='utf-8')
try:
response = s3.get_object(Bucket=bucket, Key=key)
body = json.load(response['Body'])
transcript = body['results']['transcripts'][0]['transcript']
sentiment_response = comprehend.detect_sentiment(
Text=transcript,
LanguageCode='ja'
)
sentiment_score = sentiment_response.get('SentimentScore')
print(sentiment_score)
except Exception as e:
print(e)
print('Error getting object {} from bucket {}. Make sure they exist and your bucket is in the same region as this function.'.format(key, bucket))
raise e
EOF
出力
[cloudshell-user@ip-10-132-73-220 ~]$ cat << EOF > lambda_function.py
> import json
> import urllib.parse
> import boto3
>
> s3 = boto3.client('s3')
> comprehend = boto3.client('comprehend')
>
> def lambda_handler(event, context):
> bucket = event['Records'][0]['s3']['bucket']['name']
> key = urllib.parse.unquote_plus(event['Records'][0]['s3']['object']['key'], encoding='utf-8')
> try:
> response = s3.get_object(Bucket=bucket, Key=key)
>
> body = json.load(response['Body'])
> transcript = body['results']['transcripts'][0]['transcript']
>
> sentiment_response = comprehend.detect_sentiment(
> Text=transcript,
> LanguageCode='ja'
> )
>
> sentiment_score = sentiment_response.get('SentimentScore')
> print(sentiment_score)
> except Exception as e:
> print(e)
> print('Error getting object {} from bucket {}. Make sure they exist and your bucket is in the same region as this function.'.format(key, bucket))
> raise e
> EOF
デプロイパッケージの作成
コマンド
zip function.zip lambda_function.py
出力
[cloudshell-user@ip-10-132-73-220 ~]$ zip function.zip lambda_function.py
updating: lambda_function.py (deflated 51%)
Lambda関数の作成
コマンド
# Lambda関数の作成
aws lambda create-function \
--function-name ${LAMBDA_FUNCTION_NAME_2} \
--role ${IAM_ROLE_ARN_2} \
--zip-file fileb://function.zip \
--runtime ${LAMBDA_RUNTIME} \
--handler lambda_function.lambda_handler \
# ARNの取得
LAMBDA_FUNCTION_ARN_2=$(
aws lambda list-functions \
--query "Functions[?FunctionName=='${LAMBDA_FUNCTION_NAME_2}'].FunctionArn" \
--output text
) \
&& echo ${LAMBDA_FUNCTION_ARN_2}
出力
[cloudshell-user@ip-10-132-73-220 ~]$ # Lambda関数の作成
[cloudshell-user@ip-10-132-73-220 ~]$ aws lambda create-function \
> --function-name ${LAMBDA_FUNCTION_NAME_2} \
> --role ${IAM_ROLE_ARN_2} \
> --zip-file fileb://function.zip \
> --runtime ${LAMBDA_RUNTIME} \
> --handler lambda_function.lambda_handler \
>
{
"FunctionName": "comprehend-function",
"FunctionArn": "arn:aws:lambda:ap-northeast-1:999999999999:function:comprehend-function",
"Runtime": "python3.10",
"Role": "arn:aws:iam::999999999999:role/comprehend-function-role",
"Handler": "lambda_function.lambda_handler",
"CodeSize": 638,
"Description": "",
"Timeout": 3,
"MemorySize": 128,
"LastModified": "2024-09-29T08:34:29.004+0000",
"CodeSha256": "CudSXtQVY769LoeB/6hrAdUE2J3QTb+3er3ZvuTe4Wk=",
"Version": "$LATEST",
"TracingConfig": {
"Mode": "PassThrough"
},
"RevisionId": "3a24f919-ad39-4b1b-9f22-863df931adba",
"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:cd5b19747c6f456b465655915abd7ec32c616f52b3421c0b532d90cf258e0086"
},
"LoggingConfig": {
"LogFormat": "Text",
"LogGroup": "/aws/lambda/comprehend-function"
}
}
[cloudshell-user@ip-10-132-73-220 ~]$ # ARNの取得
[cloudshell-user@ip-10-132-73-220 ~]$ LAMBDA_FUNCTION_ARN_2=$(
> aws lambda list-functions \
> --query "Functions[?FunctionName=='${LAMBDA_FUNCTION_NAME_2}'].FunctionArn" \
> --output text
> ) \
> && echo ${LAMBDA_FUNCTION_ARN_2}
arn:aws:lambda:ap-northeast-1:999999999999:function:comprehend-function
リソースベースのポリシーステートメント追加
コマンド
# リソースベースのポリシーステートメント追加
aws lambda add-permission \
--function-name ${LAMBDA_FUNCTION_NAME_2} \
--principal s3.amazonaws.com \
--statement-id S3InvokePermission \
--action "lambda:InvokeFunction" \
--source-arn arn:aws:s3:::${S3_BUCKET_NAME_2} \
--source-account ${ACCOUNT_ID}
出力
[cloudshell-user@ip-10-132-73-220 ~]$ # リソースベースのポリシーステートメント追加
[cloudshell-user@ip-10-132-73-220 ~]$ aws lambda add-permission \
> --function-name ${LAMBDA_FUNCTION_NAME_2} \
> --principal s3.amazonaws.com \
> --statement-id S3InvokePermission \
> --action "lambda:InvokeFunction" \
> --source-arn arn:aws:s3:::${S3_BUCKET_NAME_2} \
> --source-account ${ACCOUNT_ID}
{
"Statement": "{\"Sid\":\"S3InvokePermission\",\"Effect\":\"Allow\",\"Principal\":{\"Service\":\"s3.amazonaws.com\"},\"Action\":\"lambda:InvokeFunction\",\"Resource\":\"arn:aws:lambda:ap-northeast-1:999999999999:function:comprehend-function\",\"Condition\":{\"StringEquals\":{\"AWS:SourceAccount\":\"999999999999\"},\"ArnLike\":{\"AWS:SourceArn\":\"arn:aws:s3:::h4b-serverless-3-output-20240929\"}}}"
}
イベント通知設定用JSON
コマンド
# イベント通知設定用JSON
S3_NOTIFICATION_CONFIGURATION=$(cat << EOF
{
"LambdaFunctionConfigurations": [
{
"LambdaFunctionArn": "${LAMBDA_FUNCTION_ARN_2}",
"Events": ["s3:ObjectCreated:*"],
"Filter": {
"Key": {
"FilterRules": [
{
"Name": "Suffix",
"Value": ".json"
}
]
}
}
}
]
}
EOF
) \
&& echo ${S3_NOTIFICATION_CONFIGURATION}
# JSONフォーマットの確認
echo ${S3_NOTIFICATION_CONFIGURATION} | python -m json.tool
出力
[cloudshell-user@ip-10-132-73-220 ~]$ # イベント通知設定用JSON
[cloudshell-user@ip-10-132-73-220 ~]$ S3_NOTIFICATION_CONFIGURATION=$(cat << EOF
> {
> "LambdaFunctionConfigurations": [
> {
> "LambdaFunctionArn": "${LAMBDA_FUNCTION_ARN_2}",
> "Events": ["s3:ObjectCreated:*"],
> "Filter": {
> "Key": {
> "FilterRules": [
> {
> "Name": "Suffix",
> "Value": ".json"
> }
> ]
> }
> }
> }
> ]
> }
> EOF
> ) \
> && echo ${S3_NOTIFICATION_CONFIGURATION}
{ "LambdaFunctionConfigurations": [ { "LambdaFunctionArn": "arn:aws:lambda:ap-northeast-1:999999999999:function:comprehend-function", "Events": ["s3:ObjectCreated:*"], "Filter": { "Key": { "FilterRules": [ { "Name": "Suffix", "Value": ".json" } ] } } } ] }
[cloudshell-user@ip-10-132-73-220 ~]$
[cloudshell-user@ip-10-132-73-220 ~]$ # JSONフォーマットの確認
[cloudshell-user@ip-10-132-73-220 ~]$ echo ${S3_NOTIFICATION_CONFIGURATION} | python -m json.tool
{
"LambdaFunctionConfigurations": [
{
"LambdaFunctionArn": "arn:aws:lambda:ap-northeast-1:999999999999:function:comprehend-function",
"Events": [
"s3:ObjectCreated:*"
],
"Filter": {
"Key": {
"FilterRules": [
{
"Name": "Suffix",
"Value": ".json"
}
]
}
}
}
]
}
S3 バケットにイベント通知を設定して Lambda をトリガー
コマンド
aws s3api put-bucket-notification-configuration \
--bucket ${S3_BUCKET_NAME_2} \
--notification-configuration "${S3_NOTIFICATION_CONFIGURATION}"
出力
[cloudshell-user@ip-10-132-73-220 ~]$ aws s3api put-bucket-notification-configuration \
> --bucket ${S3_BUCKET_NAME_2} \
> --notification-configuration "${S3_NOTIFICATION_CONFIGURATION}"
S3にファイルをアップロード
コマンド
# アップロードファイル名
UPLOAD_FILENAME="h4b-serverless-3.mp3" \
&& echo ${UPLOAD_FILENAME}
# アップロード
aws s3 cp ${UPLOAD_FILENAME} s3://${S3_BUCKET_NAME}/
出力
[cloudshell-user@ip-10-132-73-220 ~]$ # アップロードファイル名
[cloudshell-user@ip-10-132-73-220 ~]$ UPLOAD_FILENAME="h4b-serverless-3.mp3" \
> && echo ${UPLOAD_FILENAME}
h4b-serverless-3.mp3
[cloudshell-user@ip-10-132-73-220 ~]$
[cloudshell-user@ip-10-132-73-220 ~]$ # アップロード
[cloudshell-user@ip-10-132-73-220 ~]$ aws s3 cp ${UPLOAD_FILENAME} s3://${S3_BUCKET_NAME}/
upload: ./h4b-serverless-3.mp3 to s3://h4b-serverless-3-input-20240929/h4b-serverless-3.mp3
トランスクリプションジョブ一覧確認
コマンド
# トランスクリプションジョブ一覧確認
aws transcribe list-transcription-jobs
出力
[cloudshell-user@ip-10-132-73-220 ~]$ # トランスクリプションジョブ一覧確認
[cloudshell-user@ip-10-132-73-220 ~]$ aws transcribe list-transcription-jobs
{
"TranscriptionJobSummaries": [
{
"TranscriptionJobName": "20240929083905_Transcription",
"CreationTime": "2024-09-29T17:39:06.165000+09:00",
"StartTime": "2024-09-29T17:39:06.191000+09:00",
"CompletionTime": "2024-09-29T17:39:13.852000+09:00",
"LanguageCode": "ja-JP",
"TranscriptionJobStatus": "COMPLETED",
"OutputLocationType": "CUSTOMER_BUCKET"
},
{
"TranscriptionJobName": "20240929081822_Transcription",
"CreationTime": "2024-09-29T17:18:22.780000+09:00",
"StartTime": "2024-09-29T17:18:22.802000+09:00",
"CompletionTime": "2024-09-29T17:18:35.444000+09:00",
"LanguageCode": "ja-JP",
"TranscriptionJobStatus": "COMPLETED",
"OutputLocationType": "CUSTOMER_BUCKET"
},
{
"TranscriptionJobName": "Test-Job",
"CreationTime": "2024-09-29T16:55:31.482000+09:00",
"StartTime": "2024-09-29T16:55:31.505000+09:00",
"CompletionTime": "2024-09-29T16:55:42.879000+09:00",
"LanguageCode": "ja-JP",
"TranscriptionJobStatus": "COMPLETED",
"OutputLocationType": "CUSTOMER_BUCKET"
}
]
}
S3バケット内のオブジェクトを確認
コマンド
# S3バケット内のオブジェクトを確認
aws s3api list-object-versions \
--bucket ${S3_BUCKET_NAME_2}
出力
[cloudshell-user@ip-10-132-73-220 ~]$ # S3バケット内のオブジェクトを確認
[cloudshell-user@ip-10-132-73-220 ~]$ aws s3api list-object-versions \
> --bucket ${S3_BUCKET_NAME_2}
{
"Versions": [
{
"ETag": "\"d751713988987e9331980363e24189ce\"",
"Size": 2,
"StorageClass": "STANDARD",
"Key": ".write_access_check_file.temp",
"VersionId": "null",
"IsLatest": true,
"LastModified": "2024-09-29T08:39:07+00:00",
"Owner": {
"DisplayName": "user01",
"ID": "974cd83317461904fcbad632a42045ad8cd85cb24065c65f2ca62b7e35d84078"
}
},
{
"ETag": "\"1f6856b6b731605a5c910682046378be\"",
"Size": 2011,
"StorageClass": "STANDARD",
"Key": "20240929081822_Transcription.json",
"VersionId": "null",
"IsLatest": true,
"LastModified": "2024-09-29T08:18:36+00:00",
"Owner": {
"DisplayName": "user01",
"ID": "974cd83317461904fcbad632a42045ad8cd85cb24065c65f2ca62b7e35d84078"
}
},
{
"ETag": "\"c594426cf1af4afee49d6890daad09de\"",
"Size": 2011,
"StorageClass": "STANDARD",
"Key": "20240929083905_Transcription.json",
"VersionId": "null",
"IsLatest": true,
"LastModified": "2024-09-29T08:39:14+00:00",
"Owner": {
"DisplayName": "user01",
"ID": "974cd83317461904fcbad632a42045ad8cd85cb24065c65f2ca62b7e35d84078"
}
},
{
"ETag": "\"40033c4f71ea9b9cc33b3201afd6c613\"",
"Size": 1991,
"StorageClass": "STANDARD",
"Key": "Test-Job.json",
"VersionId": "null",
"IsLatest": true,
"LastModified": "2024-09-29T07:55:43+00:00",
"Owner": {
"DisplayName": "user01",
"ID": "974cd83317461904fcbad632a42045ad8cd85cb24065c65f2ca62b7e35d84078"
}
}
],
"RequestCharged": null
}
CloudWatchロググループ確認
コマンド
# 最新のログストリームを取得
LATEST_LOG_STREAM=$(
aws logs describe-log-streams \
--log-group-name /aws/lambda/${LAMBDA_FUNCTION_NAME_2} \
--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/${LAMBDA_FUNCTION_NAME_2} \
--log-stream-name ${LATEST_LOG_STREAM} \
--no-cli-pager
出力
[cloudshell-user@ip-10-132-73-220 ~]$ # 最新のログストリームを取得
[cloudshell-user@ip-10-132-73-220 ~]$ LATEST_LOG_STREAM=$(
> aws logs describe-log-streams \
> --log-group-name /aws/lambda/${LAMBDA_FUNCTION_NAME_2} \
> --order-by LastEventTime \
> --descending \
> --limit 1 \
> --query 'logStreams[0].logStreamName' \
> --output text
> ) \
> && echo ${LATEST_LOG_STREAM}
2024/09/29/[$LATEST]a225bbabb4ce4e5b9aba78d06a1d30a0
[cloudshell-user@ip-10-132-73-220 ~]$
[cloudshell-user@ip-10-132-73-220 ~]$ # ログの確認
[cloudshell-user@ip-10-132-73-220 ~]$ aws logs get-log-events \
> --log-group-name /aws/lambda/${LAMBDA_FUNCTION_NAME_2} \
> --log-stream-name ${LATEST_LOG_STREAM} \
> --no-cli-pager
{
"events": [
{
"timestamp": 1727599154655,
"message": "INIT_START Runtime Version: python:3.10.v38\tRuntime Version ARN: arn:aws:lambda:ap-northeast-1::runtime:cd5b19747c6f456b465655915abd7ec32c616f52b3421c0b532d90cf258e0086\n",
"ingestionTime": 1727599155543
},
{
"timestamp": 1727599155089,
"message": "START RequestId: b2a46ec3-34ba-43d1-91eb-8aecaad12218 Version: $LATEST\n",
"ingestionTime": 1727599155543
},
{
"timestamp": 1727599155978,
"message": "{'Positive': 0.9275622963905334, 'Negative': 0.0006652617012150586, 'Neutral': 0.07174542546272278, 'Mixed': 2.7032214347855188e-05}\n",
"ingestionTime": 1727599165029
},
{
"timestamp": 1727599155992,
"message": "END RequestId: b2a46ec3-34ba-43d1-91eb-8aecaad12218\n",
"ingestionTime": 1727599165029
},
{
"timestamp": 1727599155992,
"message": "REPORT RequestId: b2a46ec3-34ba-43d1-91eb-8aecaad12218\tDuration: 902.98 ms\tBilled Duration: 903 ms\tMemory Size: 128 MB\tMax Memory Used: 81 MB\tInit Duration: 433.03 ms\t\n",
"ingestionTime": 1727599165029
}
],
"nextForwardToken": "f/38526748582974151019971469683097397755737395250988187650/s",
"nextBackwardToken": "b/38526748553158054689536026531396345019833403355502411776/s"
}
07 [Option] Amazon Polly で作成した音声ファイルをパイプラインに投入する
SSMLテスト
コマンド
ARTICLE='<speak>こんにちは、金澤です。<amazon:effect name="whispered">囁いたり、</amazon:effect><prosody volume="x-loud">声の大きさを変えたりできますよ !</prosody></speak>' \
&& echo ${ARTICLE}
aws polly synthesize-speech \
--output-format mp3 \
--text-type ssml \
--text "${ARTICLE}" \
--voice-id Takumi \
output.mp3
出力
[cloudshell-user@ip-10-132-73-220 ~]$ ARTICLE='<speak>こんにちは、金澤です。<amazon:effect name="whispered">囁いたり、</amazon:effect><prosody volume="x-loud">声の大きさを変えたりできますよ !</prosody></speak>' \
> && echo ${ARTICLE}
<speak>こんにちは、金澤です。<amazon:effect name="whispered">囁いたり、</amazon:effect><prosody volume="x-loud">声の大きさを変えたりでき ますよ !</prosody></speak>
[cloudshell-user@ip-10-132-73-220 ~]$
[cloudshell-user@ip-10-132-73-220 ~]$ aws polly synthesize-speech \
> --output-format mp3 \
> --text-type ssml \
> --text "${ARTICLE}" \
> --voice-id Takumi \
> output.mp3
{
"ContentType": "audio/mpeg",
"RequestCharacters": "35"
}
プレーンテキストテスト
コマンド
ARTICLE="ハンズオン動画を作るのも楽しいですよ" \
&& echo ${ARTICLE}
aws polly synthesize-speech \
--output-format mp3 \
--text "${ARTICLE}" \
--voice-id Takumi \
output.mp3
出力
[cloudshell-user@ip-10-132-73-220 ~]$ ARTICLE="ハンズオン動画を作るのも楽しいですよ" \
> && echo ${ARTICLE}
ハンズオン動画を作るのも楽しいですよ
[cloudshell-user@ip-10-132-73-220 ~]$
[cloudshell-user@ip-10-132-73-220 ~]$ aws polly synthesize-speech \
> --output-format mp3 \
> --text "${ARTICLE}" \
> --voice-id Takumi \
> output.mp3
{
"ContentType": "audio/mpeg",
"RequestCharacters": "18"
}
S3にファイルをアップロード
コマンド
# アップロードファイル名
UPLOAD_FILENAME="output.mp3" \
&& echo ${UPLOAD_FILENAME}
# アップロード
aws s3 cp ${UPLOAD_FILENAME} s3://${S3_BUCKET_NAME}/
出力
[cloudshell-user@ip-10-132-73-220 ~]$ # アップロードファイル名
[cloudshell-user@ip-10-132-73-220 ~]$ UPLOAD_FILENAME="output.mp3" \
> && echo ${UPLOAD_FILENAME}
output.mp3
[cloudshell-user@ip-10-132-73-220 ~]$
[cloudshell-user@ip-10-132-73-220 ~]$ # アップロード
[cloudshell-user@ip-10-132-73-220 ~]$ aws s3 cp ${UPLOAD_FILENAME} s3://${S3_BUCKET_NAME}/
upload: ./output.mp3 to s3://h4b-serverless-3-input-20240929/output.mp3
トランスクリプションジョブ一覧確認
コマンド
# トランスクリプションジョブ一覧確認
aws transcribe list-transcription-jobs
出力
[cloudshell-user@ip-10-132-73-220 ~]$ # トランスクリプションジョブ一覧確認
[cloudshell-user@ip-10-132-73-220 ~]$ aws transcribe list-transcription-jobs
{
"TranscriptionJobSummaries": [
{
"TranscriptionJobName": "20240929085301_Transcription",
"CreationTime": "2024-09-29T17:53:01.861000+09:00",
"StartTime": "2024-09-29T17:53:01.889000+09:00",
"CompletionTime": "2024-09-29T17:53:09.548000+09:00",
"LanguageCode": "ja-JP",
"TranscriptionJobStatus": "COMPLETED",
"OutputLocationType": "CUSTOMER_BUCKET"
},
{
"TranscriptionJobName": "20240929083905_Transcription",
"CreationTime": "2024-09-29T17:39:06.165000+09:00",
"StartTime": "2024-09-29T17:39:06.191000+09:00",
"CompletionTime": "2024-09-29T17:39:13.852000+09:00",
"LanguageCode": "ja-JP",
"TranscriptionJobStatus": "COMPLETED",
"OutputLocationType": "CUSTOMER_BUCKET"
},
{
"TranscriptionJobName": "20240929081822_Transcription",
"CreationTime": "2024-09-29T17:18:22.780000+09:00",
"StartTime": "2024-09-29T17:18:22.802000+09:00",
"CompletionTime": "2024-09-29T17:18:35.444000+09:00",
"LanguageCode": "ja-JP",
"TranscriptionJobStatus": "COMPLETED",
"OutputLocationType": "CUSTOMER_BUCKET"
},
{
"TranscriptionJobName": "Test-Job",
"CreationTime": "2024-09-29T16:55:31.482000+09:00",
"StartTime": "2024-09-29T16:55:31.505000+09:00",
"CompletionTime": "2024-09-29T16:55:42.879000+09:00",
"LanguageCode": "ja-JP",
"TranscriptionJobStatus": "COMPLETED",
"OutputLocationType": "CUSTOMER_BUCKET"
}
]
}
S3バケット内のオブジェクトを確認
コマンド
# S3バケット内のオブジェクトを確認
aws s3api list-object-versions \
--bucket ${S3_BUCKET_NAME_2}
出力
[cloudshell-user@ip-10-132-73-220 ~]$ # S3バケット内のオブジェクトを確認
[cloudshell-user@ip-10-132-73-220 ~]$ aws s3api list-object-versions \
> --bucket ${S3_BUCKET_NAME_2}
{
"Versions": [
{
"ETag": "\"d751713988987e9331980363e24189ce\"",
"Size": 2,
"StorageClass": "STANDARD",
"Key": ".write_access_check_file.temp",
"VersionId": "null",
"IsLatest": true,
"LastModified": "2024-09-29T08:53:02+00:00",
"Owner": {
"DisplayName": "user01",
"ID": "974cd83317461904fcbad632a42045ad8cd85cb24065c65f2ca62b7e35d84078"
}
},
{
"ETag": "\"1f6856b6b731605a5c910682046378be\"",
"Size": 2011,
"StorageClass": "STANDARD",
"Key": "20240929081822_Transcription.json",
"VersionId": "null",
"IsLatest": true,
"LastModified": "2024-09-29T08:18:36+00:00",
"Owner": {
"DisplayName": "user01",
"ID": "974cd83317461904fcbad632a42045ad8cd85cb24065c65f2ca62b7e35d84078"
}
},
{
"ETag": "\"c594426cf1af4afee49d6890daad09de\"",
"Size": 2011,
"StorageClass": "STANDARD",
"Key": "20240929083905_Transcription.json",
"VersionId": "null",
"IsLatest": true,
"LastModified": "2024-09-29T08:39:14+00:00",
"Owner": {
"DisplayName": "user01",
"ID": "974cd83317461904fcbad632a42045ad8cd85cb24065c65f2ca62b7e35d84078"
}
},
{
"ETag": "\"0bc67d6f1d0fbacccddf3b62bd667dd4\"",
"Size": 1467,
"StorageClass": "STANDARD",
"Key": "20240929085301_Transcription.json",
"VersionId": "null",
"IsLatest": true,
"LastModified": "2024-09-29T08:53:10+00:00",
"Owner": {
"DisplayName": "user01",
"ID": "974cd83317461904fcbad632a42045ad8cd85cb24065c65f2ca62b7e35d84078"
}
},
{
"ETag": "\"40033c4f71ea9b9cc33b3201afd6c613\"",
"Size": 1991,
"StorageClass": "STANDARD",
"Key": "Test-Job.json",
"VersionId": "null",
"IsLatest": true,
"LastModified": "2024-09-29T07:55:43+00:00",
"Owner": {
"DisplayName": "user01",
"ID": "974cd83317461904fcbad632a42045ad8cd85cb24065c65f2ca62b7e35d84078"
}
}
],
"RequestCharged": null
}
S3からファイルをダウンロード
コマンド
# ダウンロードファイル名
DOWNLOAD_FILENAME="20240929085301_Transcription.json" \
&& echo ${DOWNLOAD_FILENAME}
# ダウンロード
aws s3 cp s3://${S3_BUCKET_NAME_2}/${DOWNLOAD_FILENAME} ./
出力
[cloudshell-user@ip-10-132-73-220 ~]$ # ダウンロードファイル名
[cloudshell-user@ip-10-132-73-220 ~]$ DOWNLOAD_FILENAME="20240929085301_Transcription.json" \
> && echo ${DOWNLOAD_FILENAME}
20240929085301_Transcription.json
[cloudshell-user@ip-10-132-73-220 ~]$
[cloudshell-user@ip-10-132-73-220 ~]$ # ダウンロード
[cloudshell-user@ip-10-132-73-220 ~]$ aws s3 cp s3://${S3_BUCKET_NAME_2}/${DOWNLOAD_FILENAME} ./
download: s3://h4b-serverless-3-output-20240929/20240929085301_Transcription.json to ./20240929085301_Transcription.json
ダウンロードしたファイルを確認
コマンド
cat ${DOWNLOAD_FILENAME}
出力
[cloudshell-user@ip-10-132-73-220 ~]$ cat ${DOWNLOAD_FILENAME}
{"jobName":"20240929085301_Transcription","accountId":"999999999999","status":"COMPLETED","results":{"transcripts":[{"transcript":"半蔵動画を作るのも楽しいです。"}],"items":[{"id":0,"type":"pronunciation","alternatives":[{"confidence":"0.475","content":"半蔵"}],"start_time":"0.07","end_time":"0.68"},{"id":1,"type":"pronunciation","alternatives":[{"confidence":"0.999","content":"動画"}],"start_time":"0.689","end_time":"1.019"},{"id":2,"type":"pronunciation","alternatives":[{"confidence":"0.999","content":"を"}],"start_time":"1.029","end_time":"1.139"},{"id":3,"type":"pronunciation","alternatives":[{"confidence":"0.98","content":"作る"}],"start_time":"1.149","end_time":"1.539"},{"id":4,"type":"pronunciation","alternatives":[{"confidence":"0.999","content":"の"}],"start_time":"1.549","end_time":"1.779"},{"id":5,"type":"pronunciation","alternatives":[{"confidence":"0.999","content":"も"}],"start_time":"1.789","end_time":"1.85"},{"id":6,"type":"pronunciation","alternatives":[{"confidence":"0.999","content":"楽しい"}],"start_time":"2.109","end_time":"2.579"},{"id":7,"type":"pronunciation","alternatives":[{"confidence":"0.999","content":"です"}],"start_time":"2.589","end_time":"2.91"},{"id":8,"type":"punctuation","alternatives":[{"confidence":"0.0","content":"。"}]}],"audio_segments":[{"id":0,"transcript":"半蔵動画を作るのも楽しいです。","start_time":"0.0","end_time":"3.059","items":[0,1,2,3,4,5,6,7,8]}]}}
ハンズオンが半蔵になってしまう
CloudWatchロググループ確認
コマンド
# 最新のログストリームを取得
LATEST_LOG_STREAM=$(
aws logs describe-log-streams \
--log-group-name /aws/lambda/${LAMBDA_FUNCTION_NAME_2} \
--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/${LAMBDA_FUNCTION_NAME_2} \
--log-stream-name ${LATEST_LOG_STREAM} \
--no-cli-pager
出力
[cloudshell-user@ip-10-132-73-220 ~]$ # 最新のログストリームを取得
[cloudshell-user@ip-10-132-73-220 ~]$ LATEST_LOG_STREAM=$(
> aws logs describe-log-streams \
> --log-group-name /aws/lambda/${LAMBDA_FUNCTION_NAME_2} \
> --order-by LastEventTime \
> --descending \
> --limit 1 \
> --query 'logStreams[0].logStreamName' \
> --output text
> ) \
> && echo ${LATEST_LOG_STREAM}
2024/09/29/[$LATEST]e0253d0b21344bc79dd0969b810a4d44
[cloudshell-user@ip-10-132-73-220 ~]$
[cloudshell-user@ip-10-132-73-220 ~]$ # ログの確認
[cloudshell-user@ip-10-132-73-220 ~]$ aws logs get-log-events \
> --log-group-name /aws/lambda/${LAMBDA_FUNCTION_NAME_2} \
> --log-stream-name ${LATEST_LOG_STREAM} \
> --no-cli-pager
{
"events": [
{
"timestamp": 1727599991164,
"message": "INIT_START Runtime Version: python:3.10.v38\tRuntime Version ARN: arn:aws:lambda:ap-northeast-1::runtime:cd5b19747c6f456b465655915abd7ec32c616f52b3421c0b532d90cf258e0086\n",
"ingestionTime": 1727599991827
},
{
"timestamp": 1727599991636,
"message": "START RequestId: aa5a6975-2846-4378-a020-f442159eed05 Version: $LATEST\n",
"ingestionTime": 1727599991827
},
{
"timestamp": 1727599992522,
"message": "{'Positive': 0.9988161325454712, 'Negative': 0.0001258893171325326, 'Neutral': 0.0010536931222304702, 'Mixed': 4.337752670835471e-06}\n",
"ingestionTime": 1727600001541
},
{
"timestamp": 1727599992531,
"message": "END RequestId: aa5a6975-2846-4378-a020-f442159eed05\n",
"ingestionTime": 1727600001541
},
{
"timestamp": 1727599992531,
"message": "REPORT RequestId: aa5a6975-2846-4378-a020-f442159eed05\tDuration: 895.57 ms\tBilled Duration: 896 ms\tMemory Size: 128 MB\tMax Memory Used: 81 MB\tInit Duration: 469.98 ms\t\n",
"ingestionTime": 1727600001541
}
],
"nextForwardToken": "f/38526767238417238653580422891526470985557072310587162626/s",
"nextBackwardToken": "b/38526767207932119967189061045303899093522372925797826560/s"
}
08 クリーンアップ、まとめ + Next Challenge のススメ
S3削除
コマンド
# オブジェクト一覧取得
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}
# オブジェクト一覧取得
OBJECT_LIST=$(
aws s3api list-object-versions \
--bucket ${S3_BUCKET_NAME_2} \
--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_2} \
--delete "${OBJECT_LIST}"
# S3バケットを削除
aws s3api delete-bucket \
--bucket ${S3_BUCKET_NAME_2}
出力
[cloudshell-user@ip-10-132-73-220 ~]$ # オブジェクト一覧取得
[cloudshell-user@ip-10-132-73-220 ~]$ OBJECT_LIST=$(
> aws s3api list-object-versions \
> --bucket ${S3_BUCKET_NAME} \
> --query='{Objects: Versions[].{Key:Key,VersionId:VersionId}}'
> ) \
> && echo ${OBJECT_LIST}
{ "Objects": [ { "Key": "h4b-serverless-3.mp3", "VersionId": "null" }, { "Key": "output.mp3", "VersionId": "null" } ] }
[cloudshell-user@ip-10-132-73-220 ~]$
[cloudshell-user@ip-10-132-73-220 ~]$ # JSONフォーマットの確認
[cloudshell-user@ip-10-132-73-220 ~]$ echo ${OBJECT_LIST} | python -m json.tool
{
"Objects": [
{
"Key": "h4b-serverless-3.mp3",
"VersionId": "null"
},
{
"Key": "output.mp3",
"VersionId": "null"
}
]
}
[cloudshell-user@ip-10-132-73-220 ~]$
[cloudshell-user@ip-10-132-73-220 ~]$ # バケットを空にする
[cloudshell-user@ip-10-132-73-220 ~]$ aws s3api delete-objects \
> --bucket ${S3_BUCKET_NAME} \
> --delete "${OBJECT_LIST}"
{
"Deleted": [
{
"Key": "h4b-serverless-3.mp3",
"VersionId": "null"
},
{
"Key": "output.mp3",
"VersionId": "null"
}
]
}
[cloudshell-user@ip-10-132-73-220 ~]$
[cloudshell-user@ip-10-132-73-220 ~]$ # S3バケットを削除
[cloudshell-user@ip-10-132-73-220 ~]$ aws s3api delete-bucket \
> --bucket ${S3_BUCKET_NAME}
[cloudshell-user@ip-10-132-73-220 ~]$
[cloudshell-user@ip-10-132-73-220 ~]$
[cloudshell-user@ip-10-132-73-220 ~]$ # オブジェクト一覧取得
[cloudshell-user@ip-10-132-73-220 ~]$ OBJECT_LIST=$(
> aws s3api list-object-versions \
> --bucket ${S3_BUCKET_NAME_2} \
> --query='{Objects: Versions[].{Key:Key,VersionId:VersionId}}'
> ) \
> && echo ${OBJECT_LIST}
{ "Objects": [ { "Key": ".write_access_check_file.temp", "VersionId": "null" }, { "Key": "20240929081822_Transcription.json", "VersionId": "null" }, { "Key": "20240929083905_Transcription.json", "VersionId": "null" }, { "Key": "20240929085301_Transcription.json", "VersionId": "null" }, { "Key": "Test-Job.json", "VersionId": "null" } ] }
[cloudshell-user@ip-10-132-73-220 ~]$
[cloudshell-user@ip-10-132-73-220 ~]$ # JSONフォーマットの確認
[cloudshell-user@ip-10-132-73-220 ~]$ echo ${OBJECT_LIST} | python -m json.tool
{
"Objects": [
{
"Key": ".write_access_check_file.temp",
"VersionId": "null"
},
{
"Key": "20240929081822_Transcription.json",
"VersionId": "null"
},
{
"Key": "20240929083905_Transcription.json",
"VersionId": "null"
},
{
"Key": "20240929085301_Transcription.json",
"VersionId": "null"
},
{
"Key": "Test-Job.json",
"VersionId": "null"
}
]
}
[cloudshell-user@ip-10-132-73-220 ~]$
[cloudshell-user@ip-10-132-73-220 ~]$ # バケットを空にする
[cloudshell-user@ip-10-132-73-220 ~]$ aws s3api delete-objects \
> --bucket ${S3_BUCKET_NAME_2} \
> --delete "${OBJECT_LIST}"
{
"Deleted": [
{
"Key": "20240929083905_Transcription.json",
"VersionId": "null"
},
{
"Key": "Test-Job.json",
"VersionId": "null"
},
{
"Key": "20240929081822_Transcription.json",
"VersionId": "null"
},
{
"Key": "20240929085301_Transcription.json",
"VersionId": "null"
},
{
"Key": ".write_access_check_file.temp",
"VersionId": "null"
}
]
}
[cloudshell-user@ip-10-132-73-220 ~]$
[cloudshell-user@ip-10-132-73-220 ~]$ # S3バケットを削除
[cloudshell-user@ip-10-132-73-220 ~]$ aws s3api delete-bucket \
> --bucket ${S3_BUCKET_NAME_2}
IAM削除
WSLambdaBasicExecutionRole
コマンド
# ロールにアタッチされているポリシーをリスト
POLICIES=$(
aws iam list-attached-role-policies \
--role-name ${IAM_ROLE_NAME} \
--query 'AttachedPolicies[*].PolicyArn' \
--output text
) \
&& echo ${POLICIES}
# リスト内のポリシーをデタッチする
for POLICY in ${POLICIES}; do
aws iam detach-role-policy \
--role-name ${IAM_ROLE_NAME} \
--policy-arn ${POLICY}
done
# IAMロールの削除
aws iam delete-role \
--role-name ${IAM_ROLE_NAME}
# IAMポリシーの削除
aws iam delete-policy \
--policy-arn ${IAM_POLICY_ARN_1}
aws iam delete-policy \
--policy-arn ${IAM_POLICY_ARN_2}
出力
[cloudshell-user@ip-10-132-73-220 ~]$ # ロールにアタッチされているポリシーをリスト
[cloudshell-user@ip-10-132-73-220 ~]$ POLICIES=$(
> aws iam list-attached-role-policies \
> --role-name ${IAM_ROLE_NAME} \
> --query 'AttachedPolicies[*].PolicyArn' \
> --output text
> ) \
> && echo ${POLICIES}
arn:aws:iam::999999999999:policy/AWSLambdaS3ExecutionRole-transcribe-function arn:aws:iam::999999999999:policy/AWSLambdaBasicExecutionRole-transcribe-function arn:aws:iam::aws:policy/AmazonTranscribeFullAccess arn:aws:iam::aws:policy/AmazonS3FullAccess
[cloudshell-user@ip-10-132-73-220 ~]$
[cloudshell-user@ip-10-132-73-220 ~]$ # リスト内のポリシーをデタッチする
[cloudshell-user@ip-10-132-73-220 ~]$ for POLICY in ${POLICIES}; do
> aws iam detach-role-policy \
> --role-name ${IAM_ROLE_NAME} \
> --policy-arn ${POLICY}
> done
[cloudshell-user@ip-10-132-73-220 ~]$
[cloudshell-user@ip-10-132-73-220 ~]$ # IAMロールの削除
[cloudshell-user@ip-10-132-73-220 ~]$ aws iam delete-role \
> --role-name ${IAM_ROLE_NAME}
[cloudshell-user@ip-10-132-73-220 ~]$
[cloudshell-user@ip-10-132-73-220 ~]$ # IAMポリシーの削除
[cloudshell-user@ip-10-132-73-220 ~]$ aws iam delete-policy \
> --policy-arn ${IAM_POLICY_ARN_1}
[cloudshell-user@ip-10-132-73-220 ~]$
[cloudshell-user@ip-10-132-73-220 ~]$ aws iam delete-policy \
> --policy-arn ${IAM_POLICY_ARN_2}
AWSLambdaS3ExecutionRole
コマンド
# ロールにアタッチされているポリシーをリスト
POLICIES=$(
aws iam list-attached-role-policies \
--role-name ${IAM_ROLE_NAME_2} \
--query 'AttachedPolicies[*].PolicyArn' \
--output text
) \
&& echo ${POLICIES}
# リスト内のポリシーをデタッチする
for POLICY in ${POLICIES}; do
aws iam detach-role-policy \
--role-name ${IAM_ROLE_NAME_2} \
--policy-arn ${POLICY}
done
# IAMロールの削除
aws iam delete-role \
--role-name ${IAM_ROLE_NAME_2}
# IAMポリシーの削除
aws iam delete-policy \
--policy-arn ${IAM_POLICY_ARN_3}
aws iam delete-policy \
--policy-arn ${IAM_POLICY_ARN_4}
出力
[cloudshell-user@ip-10-132-73-220 ~]$ # ロールにアタッチされているポリシーをリスト
[cloudshell-user@ip-10-132-73-220 ~]$ POLICIES=$(
> aws iam list-attached-role-policies \
> --role-name ${IAM_ROLE_NAME_2} \
> --query 'AttachedPolicies[*].PolicyArn' \
> --output text
> ) \
> && echo ${POLICIES}
arn:aws:iam::999999999999:policy/AWSLambdaBasicExecutionRole-comprehend-function arn:aws:iam::999999999999:policy/AWSLambdaS3ExecutionRole-comprehend-function arn:aws:iam::aws:policy/ComprehendFullAccess arn:aws:iam::aws:policy/AmazonS3FullAccess
[cloudshell-user@ip-10-132-73-220 ~]$
[cloudshell-user@ip-10-132-73-220 ~]$ # リスト内のポリシーをデタッチする
[cloudshell-user@ip-10-132-73-220 ~]$ for POLICY in ${POLICIES}; do
> aws iam detach-role-policy \
> --role-name ${IAM_ROLE_NAME_2} \
> --policy-arn ${POLICY}
> done
[cloudshell-user@ip-10-132-73-220 ~]$
[cloudshell-user@ip-10-132-73-220 ~]$ # IAMロールの削除
[cloudshell-user@ip-10-132-73-220 ~]$ aws iam delete-role \
> --role-name ${IAM_ROLE_NAME_2}
[cloudshell-user@ip-10-132-73-220 ~]$
[cloudshell-user@ip-10-132-73-220 ~]$ # IAMポリシーの削除
[cloudshell-user@ip-10-132-73-220 ~]$ aws iam delete-policy \
> --policy-arn ${IAM_POLICY_ARN_3}
[cloudshell-user@ip-10-132-73-220 ~]$
[cloudshell-user@ip-10-132-73-220 ~]$ aws iam delete-policy \
> --policy-arn ${IAM_POLICY_ARN_4}
ロググループの削除
コマンド
aws logs delete-log-group \
--log-group-name /aws/lambda/${LAMBDA_FUNCTION_NAME}
aws logs delete-log-group \
--log-group-name /aws/lambda/${LAMBDA_FUNCTION_NAME_2}
出力
[cloudshell-user@ip-10-132-73-220 ~]$ aws logs delete-log-group \
> --log-group-name /aws/lambda/${LAMBDA_FUNCTION_NAME}
[cloudshell-user@ip-10-132-73-220 ~]$
[cloudshell-user@ip-10-132-73-220 ~]$ aws logs delete-log-group \
> --log-group-name /aws/lambda/${LAMBDA_FUNCTION_NAME_2}
トランスクリプションジョブ削除
コマンド
# すべてのジョブ名を取得し、削除するスクリプト
for job_name in $(aws transcribe list-transcription-jobs --query 'TranscriptionJobSummaries[*].TranscriptionJobName' --output text); do
echo "Deleting transcription job: $job_name"
aws transcribe delete-transcription-job --transcription-job-name "${job_name}"
done
出力
[cloudshell-user@ip-10-132-73-220 ~]$ # すべてのジョブ名を取得し、削除するスクリプト
[cloudshell-user@ip-10-132-73-220 ~]$ for job_name in $(aws transcribe list-transcription-jobs --query 'TranscriptionJobSummaries[*].TranscriptionJobName' --output text); do
> echo "Deleting transcription job: $job_name"
> aws transcribe delete-transcription-job --transcription-job-name "${job_name}"
> done
Deleting transcription job: 20240929085301_Transcription
Deleting transcription job: 20240929083905_Transcription
Deleting transcription job: 20240929081822_Transcription
Deleting transcription job: Test-Job
Lambda削除
コマンド
aws lambda delete-function \
--function-name ${LAMBDA_FUNCTION_NAME}
aws lambda delete-function \
--function-name ${LAMBDA_FUNCTION_NAME_2}
出力
[cloudshell-user@ip-10-132-73-220 ~]$ aws lambda delete-function \
> --function-name ${LAMBDA_FUNCTION_NAME}
[cloudshell-user@ip-10-132-73-220 ~]$
[cloudshell-user@ip-10-132-73-220 ~]$ aws lambda delete-function \
> --function-name ${LAMBDA_FUNCTION_NAME_2}