「AWS Hands-on for Beginners Serverless #3 AWS Lambda と AWS AI Services を組み合わせて作る音声文字起こし & 感情分析パイプライン」をAWS CLIでやってみる

https://pages.awscloud.com/JAPAN-event-OE-Hands-on-for-Beginners-Serverless-3-2022-reg-event.html?trk=aws_introduction_page

上記、「AWS Hands-on for Beginners Serverless #3 AWS Lambda と AWS AI Services を組み合わせて作る音声文字起こし & 感情分析パイプライン」 をAWS CLIでやってみる

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3297641/de799de6-3293-eb51-4710-8764f7f12825.png)
ハンズオンから引用

# 03 S3 トリガーで Lambda ファンクションを起動する
## S3バケット作成
### 変数
```bash:コマンド
# バケット名
date_var=$(date +%Y%m%d) \
&& echo ${date_var}
S3_BUCKET_NAME="h4b-serverless-3-input-${date_var}" \
&& echo ${S3_BUCKET_NAME}

```
```bash:出力
[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バケット作成
```bash:コマンド
# S3バケット作成
aws s3 mb s3://${S3_BUCKET_NAME}

```
```bash:出力
[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関数作成
### 変数
```bash:コマンド
# 関数名
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}

```
```bash:出力
[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
```bash:コマンド
# 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}

```
```bash:出力
[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
```bash:コマンド
# 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}

```
```bash:出力
[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ロール作成
```bash:コマンド
# 信頼関係ポリシードキュメントの作成
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}

```
```bash:出力
[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ソースコード
```bash:コマンド
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

```
```bash:出力
[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
```
### デプロイパッケージの作成
```bash:コマンド
zip function.zip lambda_function.py

```
```bash:出力
[cloudshell-user@ip-10-132-73-220 ~]$ zip function.zip lambda_function.py
  adding: lambda_function.py (deflated 45%)
```
### Lambda関数の作成
```bash:コマンド
# 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}

```
```bash:出力
[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
```
### リソースベースのポリシーステートメント追加
```bash:コマンド
# リソースベースのポリシーステートメント追加
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}

```
```bash:出力
[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
```bash:コマンド
# イベント通知設定用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

```
```bash:出力
[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 をトリガー
```bash:コマンド
aws s3api put-bucket-notification-configuration \
    --bucket ${S3_BUCKET_NAME} \
    --notification-configuration "${S3_NOTIFICATION_CONFIGURATION}"

```
```bash:出力
[cloudshell-user@ip-10-132-73-220 ~]$ aws s3api put-bucket-notification-configuration \
>     --bucket ${S3_BUCKET_NAME} \
>     --notification-configuration "${S3_NOTIFICATION_CONFIGURATION}"
```
### S3にファイルをアップロード
```bash:コマンド
# アップロードファイル名
UPLOAD_FILENAME="h4b-serverless-3.mp3" \
&& echo ${UPLOAD_FILENAME}

# アップロード
aws s3 cp ${UPLOAD_FILENAME} s3://${S3_BUCKET_NAME}/

```
```bash:出力
[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ロググループ確認
```bash:コマンド
# 最新のログストリームを取得
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

```
```bash:出力
[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関数更新
### ソースコード更新
```bash:コマンド
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

```
```bash:出力
[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
```
### デプロイパッケージの作成
```bash:コマンド
zip function.zip lambda_function.py

```
```bash:出力
[cloudshell-user@ip-10-132-73-220 ~]$ zip function.zip lambda_function.py
updating: lambda_function.py (deflated 45%)
```
### Lambda関数の更新
```bash:コマンド
aws lambda update-function-code \
    --function-name ${LAMBDA_FUNCTION_NAME}  \
    --zip-file fileb://function.zip

```
```bash:出力
[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にファイルをアップロード
```bash:コマンド
# アップロードファイル名
UPLOAD_FILENAME="h4b-serverless-3.mp3" \
&& echo ${UPLOAD_FILENAME}

# アップロード
aws s3 cp ${UPLOAD_FILENAME} s3://${S3_BUCKET_NAME}/

```
```bash:出力
[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ロググループ確認
```bash:コマンド
# 最新のログストリームを取得
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

```
```bash:出力
[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バケット作成
### 変数
```bash:コマンド
# バケット名
date_var=$(date +%Y%m%d) \
&& echo ${date_var}
S3_BUCKET_NAME_2="h4b-serverless-3-output-${date_var}" \
&& echo ${S3_BUCKET_NAME_2}

```
```bash:出力
[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バケット作成
```bash:コマンド
# S3バケット作成
aws s3 mb s3://${S3_BUCKET_NAME_2}

```
```bash:出力
[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
```
## トランスクリプションジョブ作成
### 変数
```bash:コマンド
TRANSCRIPTION_JOB_NAME="Test-Job" \
&& echo ${TRANSCRIPTION_JOB_NAME}

TRANSCRIPTION_LANG_CODE="ja-JP" \
&& echo ${TRANSCRIPTION_LANG_CODE}

```
```bash:出力
[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
```
### トランスクリプションジョブ作成
```bash:コマンド
# トランスクリプションジョブ作成
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}"

```
```bash:出力
[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"
    }
}
```
### 確認
```bash:コマンド
# 確認
aws transcribe get-transcription-job \
    --transcription-job-name "${TRANSCRIPTION_JOB_NAME}"

```
```bash:出力
[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バケット内のオブジェクトを確認
```bash:コマンド
aws s3api list-object-versions \
    --bucket ${S3_BUCKET_NAME_2}

```
```bash:出力
[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からファイルをダウンロード
```bash:コマンド
# ダウンロードファイル名
DOWNLOAD_FILENAME="Test-Job.json" \
&& echo ${DOWNLOAD_FILENAME}

# ダウンロード
aws s3 cp s3://${S3_BUCKET_NAME_2}/${DOWNLOAD_FILENAME} ./

```
```bash:出力
[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
```
## ダウンロードしたファイルを確認
```bash:コマンド
cat ${DOWNLOAD_FILENAME}

```
```bash:出力
[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]}]}}
```
:::note warn
ハンズオンが半音になってしまう
:::
# 05 S3 への音声ファイルアップロードをトリガに Lambda を起動し Transcribe するパイプラインを作る
## IAM修正
```bash:コマンド
# 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}

```
```bash:出力
[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関数更新
### ソースコード更新
```bash:コマンド
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

```
```bash:出力
[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
```
### デプロイパッケージの作成
```bash:コマンド
zip function.zip lambda_function.py

```
```bash:出力
[cloudshell-user@ip-10-132-73-220 ~]$ zip function.zip lambda_function.py
updating: lambda_function.py (deflated 46%)
```
### Lambda関数の更新
```bash:コマンド
# Lambda関数の更新
aws lambda update-function-code \
    --function-name ${LAMBDA_FUNCTION_NAME}  \
    --zip-file fileb://function.zip

```
```bash:出力
[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にファイルをアップロード
```bash:コマンド
# アップロードファイル名
UPLOAD_FILENAME="h4b-serverless-3.mp3" \
&& echo ${UPLOAD_FILENAME}

# アップロード
aws s3 cp ${UPLOAD_FILENAME} s3://${S3_BUCKET_NAME}/

```
```bash:出力
[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
```
### トランスクリプションジョブ一覧確認
```bash:コマンド
# トランスクリプションジョブ一覧確認
aws transcribe list-transcription-jobs

```
```bash:出力
[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バケット内のオブジェクトを確認
```bash:コマンド
# S3バケット内のオブジェクトを確認
aws s3api list-object-versions \
    --bucket ${S3_BUCKET_NAME_2}

```
```bash:出力
[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からファイルをダウンロード
```bash:コマンド
# ダウンロードファイル名
DOWNLOAD_FILENAME="20240929081822_Transcription.json" \
&& echo ${DOWNLOAD_FILENAME}

# ダウンロード
aws s3 cp s3://${S3_BUCKET_NAME_2}/${DOWNLOAD_FILENAME} ./

```
```bash:出力
[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
```
## ダウンロードしたファイルを確認
```bash:コマンド
cat ${DOWNLOAD_FILENAME}

```
```bash:出力
[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]}]}}
```
:::note warn
ハンズオンが半音になってしまう
:::
# 06 パイプラインで文字起こししたテキストを Comprehend で感情分析する
## Comprehend作成
### テスト1
```bash:コマンド
ARTICLE="ハンズオン楽しいです！" \
&& echo ${ARTICLE}

aws comprehend detect-sentiment --language-code "ja" --text "${ARTICLE}"

```
```bash:出力
[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
```bash:コマンド
ARTICLE="ハンズオン難しいです！" \
&& echo ${ARTICLE}

aws comprehend detect-sentiment --language-code "ja" --text "${ARTICLE}"

```
```bash:出力
[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関数作成
### 変数
```bash:コマンド
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}

```
```bash:出力
[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
```bash:コマンド
# 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}

```
```bash:出力
[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
```bash:コマンド
# 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}

```
```bash:出力
[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ロール
```bash:コマンド
# 信頼関係ポリシードキュメントの作成
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}

```
```bash:出力
[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ソースコード
```bash:コマンド
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

```
```bash:出力
[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
```
### デプロイパッケージの作成
```bash:コマンド
zip function.zip lambda_function.py

```
```bash:出力
[cloudshell-user@ip-10-132-73-220 ~]$ zip function.zip lambda_function.py
updating: lambda_function.py (deflated 51%)
```
### Lambda関数の作成
```bash:コマンド
# 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}

```
```bash:出力
[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
```
### リソースベースのポリシーステートメント追加
```bash:コマンド
# リソースベースのポリシーステートメント追加
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}

```
```bash:出力
[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
```bash:コマンド
# イベント通知設定用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

```
```bash:出力
[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 をトリガー
```bash:コマンド
aws s3api put-bucket-notification-configuration \
    --bucket ${S3_BUCKET_NAME_2} \
    --notification-configuration "${S3_NOTIFICATION_CONFIGURATION}"

```
```bash:出力
[cloudshell-user@ip-10-132-73-220 ~]$ aws s3api put-bucket-notification-configuration \
>     --bucket ${S3_BUCKET_NAME_2} \
>     --notification-configuration "${S3_NOTIFICATION_CONFIGURATION}"
```
### S3にファイルをアップロード
```bash:コマンド
# アップロードファイル名
UPLOAD_FILENAME="h4b-serverless-3.mp3" \
&& echo ${UPLOAD_FILENAME}

# アップロード
aws s3 cp ${UPLOAD_FILENAME} s3://${S3_BUCKET_NAME}/

```
```bash:出力
[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
```
### トランスクリプションジョブ一覧確認
```bash:コマンド
# トランスクリプションジョブ一覧確認
aws transcribe list-transcription-jobs

```
```bash:出力
[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バケット内のオブジェクトを確認
```bash:コマンド
# S3バケット内のオブジェクトを確認
aws s3api list-object-versions \
    --bucket ${S3_BUCKET_NAME_2}

```
```bash:出力
[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ロググループ確認
```bash:コマンド
# 最新のログストリームを取得
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

```
```bash:出力
[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テスト
```bash:コマンド
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

```
```bash:出力
[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"
}
```
### プレーンテキストテスト
```bash:コマンド
ARTICLE="ハンズオン動画を作るのも楽しいですよ" \
&& echo ${ARTICLE}

aws polly synthesize-speech \
    --output-format mp3 \
    --text "${ARTICLE}" \
    --voice-id Takumi \
    output.mp3

```
```bash:出力
[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にファイルをアップロード
```bash:コマンド
# アップロードファイル名
UPLOAD_FILENAME="output.mp3" \
&& echo ${UPLOAD_FILENAME}

# アップロード
aws s3 cp ${UPLOAD_FILENAME} s3://${S3_BUCKET_NAME}/

```
```bash:出力
[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
```
### トランスクリプションジョブ一覧確認
```bash:コマンド
# トランスクリプションジョブ一覧確認
aws transcribe list-transcription-jobs

```
```bash:出力
[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バケット内のオブジェクトを確認
```bash:コマンド
# S3バケット内のオブジェクトを確認
aws s3api list-object-versions \
    --bucket ${S3_BUCKET_NAME_2}

```
```bash:出力
[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からファイルをダウンロード
```bash:コマンド
# ダウンロードファイル名
DOWNLOAD_FILENAME="20240929085301_Transcription.json" \
&& echo ${DOWNLOAD_FILENAME}

# ダウンロード
aws s3 cp s3://${S3_BUCKET_NAME_2}/${DOWNLOAD_FILENAME} ./

```
```bash:出力
[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
```
### ダウンロードしたファイルを確認
```bash:コマンド
cat ${DOWNLOAD_FILENAME}

```
```bash:出力
[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]}]}}
```
:::note warn
ハンズオンが半蔵になってしまう
:::
### CloudWatchロググループ確認
```bash:コマンド
# 最新のログストリームを取得
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

```
```bash:出力
[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削除
```bash:コマンド
# オブジェクト一覧取得
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}

```
```bash:出力
[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
```bash:コマンド
# ロールにアタッチされているポリシーをリスト
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}

```
```bash:出力
[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
```bash:コマンド
# ロールにアタッチされているポリシーをリスト
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}

```
```bash:出力
[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}
```
## ロググループの削除
```bash:コマンド
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}
```
```bash:出力
[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}
```
## トランスクリプションジョブ削除
```bash:コマンド
# すべてのジョブ名を取得し、削除するスクリプト
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

```
```bash:出力
[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削除
```bash:コマンド
aws lambda delete-function \
    --function-name ${LAMBDA_FUNCTION_NAME}

aws lambda delete-function \
    --function-name ${LAMBDA_FUNCTION_NAME_2}

```
```bash:出力
[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}
```