Lambda活用

サーバリソースを定義せずに実現したいサービスのみを定義し、APIで呼び出して利用するサービスとしてAWSではLambdaが提供されている。

 

AWS Lambdaによるサーバレスなサービスとは:

AWS Lambdaハンズオンの内容に基づいて作成。(もの凄く分かりやすい!)

https://pages.awscloud.com/event_JAPAN_Hands-on-for-Beginners-Serverless-2019_Contents.html

 

 

初期状態のLambda関数。

 

テストイベントで実行

 

ログ出力を追加する。

printでコンソールへの出力が可能。

loggingではAWS CloudWatchへの出力が可能。

Lambda関数のコード変更後はDeployが必要!

 

ログがCloudWatchに出力されている。

 

boto3=AWS SDK for Pythonの使い方:

https://aws.amazon.com/jp/sdk-for-python/

 

LambdaAmazon Translateを呼び出せるようにするための権限を追加するには:

実行ロールの設定をIAMで変更する。

 

 

テスト成功!

 

REST API:

RESTは、Representational State Transferの略。「具体的に状態を定義した情報のやり取り」を規定するもの。

 

REST4原則:

1.   ステートを持たない。(やり取りされる情報はそれ自体で完結して解釈することができる。前の問い合わせは覚えていない。並列処理がシンプルになる)

2.   処理のためのインターフェース(メソッド)が統一されている。(HTTPGETPOSTメソッドなどでCRUDを実現する)

3.   リソースが一意な識別子を持ち、一意に識別される。(URIなどでリソースを表現する。URIには名詞のみを含め、動詞は含めない)

4.   情報の内部に、別の情報やその情報の別の状態へのリンク(ハイパーリンク)を含めることができる。

 

APIGatewayを単体で使うには:

Mockデータを返すREST APIを作成する。

/sampleリソースを作成し、GETメソッドを作成する。

統合タイプにはMockを選択する

 

新しいRESTAPIを作成する。

 

/sampleリソースを作成する。

 

 

/sampleを扱うGETメソッドを作成する。統合タイプにはMockを指定する。

  

 

APIの骨格が作成される。

 

固定のjsonを返すために統合レスポンスの設定を差し替える。

メソッドレスポンスの設定にマッピングテンプレートとしてapplication/jsonを追加する。

 

メソッドをテストする。

 

APIをデプロイする。

 

 

APIの呼び出しが可能となる。

 

Lambda関数を実際に呼び出すAPI Gatewayを設定するには:

/tranlateリソースをGETメソッドで呼び出す

Lambdaプロキシ統合を利用する事で、inputoutputLambdaにパススルーする。

これはつまり、統合リクエストと統合レスポンスでは処理を行わずメソッドリクエストをそのままLambdaに渡し、Lambdaの戻り値をメソッドレスポンスにそのまま渡すという事。

 

メソッドリクエストでクエリパラメータを設定する。

ここでは、input_textを必須にする。

 

Lambda関数を編集する。APIGatewayが統合レスポンスであるため、APIGatewayのルールに従い、戻り値を定義する。

https://docs.aws.amazon.com/ja_jp/apigateway/latest/developerguide/api-gateway-integration-settings-integration-response.html

 

戻り値のルール:

{

    statusCode: "...",            // a valid HTTP status code

    headers: {

        custom-header: "..."      // any API-specific custom header

    },

    body: "...",                  // a JSON string.

    isBase64Encoded:  true|false  // for binary support

}

※上記4項目は必須。

 

APIGatewayAWS Proxyを用いてテストイベントを作成する。

queryStringParametersinput_textに翻訳対象の文字列をテスト用に指定している。

{

  "body": "eyJ0ZXN0IjoiYm9keSJ9",

  "resource": "/{proxy+}",

  "path": "/path/to/resource",

  "httpMethod": "POST",

  "isBase64Encoded": true,

  "queryStringParameters": {

    "input_text": "日本酒飲みたい!"

  },

  "multiValueQueryStringParameters": {

    "foo": [

      "bar"

    ]

  },

 

URLに必須パラメタを追加してアクセスする。

 

DynamoDBの特徴:

NonSQLのデータベース。

PrimaryKey:主キー。Itemを一意に識別するキー。PartitionKeyとソートのための要素であるSortKeyで構成される。(PartitionKeyのみでもPrimaryKeyを構成することは可能)PartitionKeySortKeyの組合せが一意であればItemを登録する事が出来る。

Item:主キーごとの項目。RDBでの行に相当する。

Attribute:各Itemに所属する属性。PrimaryKey以外は不揃いであっても問題ない。

 

DynamoDBと接続するには:

 

テーブルの設定。

 

IAMDynamoDBへの読み書き権限を追加。

 

AWS Server Application Model (SAM)を用いてサーバレス環境を自動構築する

 

ハンズオンシリーズの第二弾:

https://pages.awscloud.com/event_JAPAN_Ondemand_Hands-on-for-Beginners-Serverless-2_CP.html

 

まず、Cloud9環境を作成する。

 

Cloud9環境の構成中。。。

 

Cloud9の環境作成完了。

 

オマケ)Cloud9の右端にあるAWS Resourcesの表示・非表示を切り替える

 

Cloud9からSAMを利用してLambdaを開発するには:

 

まず、s3Lambdaのバイナリを格納するための新しいバケットを準備する。

$ aws s3 mb s3://doikota-handson

 

Cloud9上にラムダ関数のソースコード(translate-function.py)とテンプレートファイル(template.yaml)を作成する。

目標とするファイル構成:

packaged-template.yamlaws packageコマンドが作成する。

 

CloudFormation用にパッケージする。

aws cloudformation package --template-file template.yaml --s3-bucket doikota-handson --output-template-file packaged-template.yaml

 

packaged-template.yamlが作られる。

CloudFormationLambdaリソースをデプロイする。

aws cloudformation deploy --template-file /home/ec2-user/environment/doikota-handson/packaged-template.yaml --stack-name=doikota-handson --capabilities=CAPABILITY_IAM

 

テスト実施成功!

 

SAMを使ってAmazon Translateと連携させるには:

パッケージ、デプロイする。

$ aws cloudformation package --template-file template.yaml --s3-bucket doikota-handson --output-template-file packaged-template.yaml

$ aws cloudformation deploy --template-file /home/ec2-user/environment/doikota-handson/packaged-template.yaml --stack-name=doikota-handson --capabilities=CAPABILITY_IAM

 

Lambdaが参照する実行ロールにTranslateFullAccessのポリシーが追加されている。

 

テスト成功!

 

SAMを使ってAPIGatewayと連携させるには:

※ハンズオンのソースコード参照。

パッケージ、デプロイする。

$ aws cloudformation package --template-file template.yaml --s3-bucket doikota-handson --output-template-file packaged-template.yaml

$ aws cloudformation deploy --template-file /home/ec2-user/environment/doikota-handson/packaged-template.yaml --stack-name=doikota-handson --capabilities=CAPABILITY_IAM

 

オマケ SAM CLI

https://docs.aws.amazon.com/ja_jp/serverless-application-model/latest/developerguide/serverless-sam-cli-install-linux.html

 

SAM構成の初期化状態を作成する。

$ sam init

 

作成されたSAM構成が、正しい構成かを検証する。

$ sam validate

 

ローカル環境でビルドする。

$ sam build

 

AWS環境にデプロイする。

$ sam deploy

この時点で、AWS上でLambdaの実行やAPIの呼び出しが可能となっている。

 

ローカルでlambda関数の待ち受けを開始する。

$ sam local start-lambda

 

ローカルでlambda関数を呼び出す。

$ aws lambda invoke --function-name "HelloWorldFunction" --endpoint-url "http://127.0.0.1:3001" --no-verify-ssl out.txt

{

    "StatusCode": 200

}

 

out.txtに戻り値が書き込まれる。

$ more out.txt

{"statusCode": 200, "body": "{\"message\": \"hello world 2022/02/26 03:33:15\"}"}

 

ローカルでinvokeする。

$ sam local invoke

Invoking app.lambda_handler (python3.7)

Skip pulling image and use local one: public.ecr.aws/sam/emulation-python3.7:rapid-1.33.0-x86_64.

 

Mounting /home/ec2-user/environment/sam-app/.aws-sam/build/HelloWorldFunction as /var/task:ro,delegated inside runtime container

END RequestId: a6557c76-eb80-4f4c-8c39-69eb7ab4d233

REPORT RequestId: a6557c76-eb80-4f4c-8c39-69eb7ab4d233  Init Duration: 1.44 ms  Duration: 90.56 ms      Billed Duration: 91 ms    Memory Size: 128 MB     Max Memory Used: 128 MB

{"statusCode": 200, "body": "{\"message\": \"hello world 22/02/26 03:58:41\"}"}

 

ローカルでAPIGatewayの待ち受けを開始する。

$ sam local start-api

 

ローカルでAPIの呼び出しをする。

$ curl http://127.0.0.1:3000/hello

{"message": "hello world 22/02/26 06:38:15"}

 

translateでもSAMが使えた。

$ sam validate

$ sam build

$ sam local invoke -e event.json

$ sam deploy --stack-name=doikota-handson --s3-bucket doikota-handson --capabilities=CAPABILITY_IAM

 

 

AWS LambdaAWS AIサービスの組み合わせ

https://pages.awscloud.com/event_JAPAN_Ondemand_Hands-on-for-Beginners-Serverless-3_CP.html

 

 

Blueprint(設計図)を使って、Lambda関数を作成。

注)「実行ロールをAWSポリシーテンプレートから新しいロールを作成」を選ばないと関数作成がうまくいかなかった。(基本的な…だと関数作成時にイベント作成のエラーが出た)

 

関数作成後、S3からのトリガーも作成したのが以下。

 

Transcribeで音声を文字起こしを行い、テキストファイルをS3に保存する。

 

NameTest-Job

LanguageJapanese

Input Datas3://handson-doikota-s3/h4b-serverless-3.mp3

Output datas3://handson-doikota-s3-output

 

 

ComprehendAIでテキストの内容の感情度合を返すサービス

Polly:テキストを音声に変換するサービス

 

 

AWS Step Functions 入門

ビジュアルツールを使ってローコードにワークフローを作成する

https://pages.awscloud.com/JAPAN-event-OE-Hands-on-for-Beginners-StepFunctions-2022-confirmation-556.html

 

 

 

 

 

InputPath、パラメータ、および ResultSelector

https://docs.aws.amazon.com/ja_jp/step-functions/latest/dg/input-output-inputpath-params.html

 

上流から流れてくるJSONメッセージのある項目の値を使いたい場合、ResultSelectorを使う。$.ある項目”とすればそのある項目の値を取得できる。

また、上記の$.ある項目を後続に流したい場合には、”指定したい項目.$”として項目名を定義する。

例)

{

  "result1.$": "$.Payload.key1",

  "result2.$": "$.Payload.key2",

  "result3.$": "$.Payload.key3"

}

Payloadとは、Lambdaハンドラが戻り値をStepFunctionに渡すときに戻り値の内容を詰める要素名で、Lambdaハンドラ内でreturnで指定されたデータはここから取り出す。

 

AWS Step FunctionsInput/Outputを紐解いてみる:

https://zenn.dev/ken_11/articles/4c61683629f45f

Lambda InvokeでラムダにJSONを渡し、Lambda内で値を取り出してそれをreturnすると、そのステップのステップ出力にreturnした内容が出力される。

 

Step Functionsの変数要素:

・入力制御:InputPath

・出力制御:OutputPath

・結果制御:ResultSelectorResultPath

 

InputPathは、そのステップに渡す引数を$.以下で指定したJSONパスのみに絞る仕組み。($.はルートを意味する)

OutputPathは、そのステップから返す戻り値を$.以下で指定したJSONパスのみに絞る仕組み。

ReusltSelectorは、出力前に結果を再編集することが出来る仕組み。

ResultPath1つ目の機能は、ステップ入力をそのままステップ出力にすること。

 

JSONPath Online Evaluator - jsonpath.com

https://jsonpath.com/

 

JSONPath Syntax

https://support.smartbear.com/alertsite/docs/monitors/api/endpoint/jsonpath.html

・ドット表現とカッコ表現は本質的に同じ。

$はルート(一番最初の中カッコ)を指す。

@は現在のノードを指す。

..キーを指定すると、そのキー名を含む要素すべてが抽出される(レベルに関係なく)。

*でワイルドカード指定が出来る。

[]でインデックス指定ができる。[0:3]などでインデックス0番から3番目までなど指定できる。[0:][:3]なども可。[-3:]で最後の3要素。

?によるフィルター機能は配列にしか使えない。[?(@.キー)]などとして使う。

?の後の()には、論理式(@.キー) でキーが存在する要素や、論理式(@.キー==’値’)でキーと値が一致する要素の抽出が行える。

 

JSON読み込み、変換、書き込み:

JSONの基本操作をPyCharm上でおさらいしておく。

jsontest.py

import json
import copy
from datetime import datetime, timedelta
from pytz import timezone
 
# JSON読み込み

 
 
 
 
with open('sample.json', 'r') as file:

 
 
 
 
    # ファイルから辞書型に

 
 
 
 
    js1 = json.load(file)

 
 
 
 
 
# 別変数に深いコピー(参照なし)

 
 
 
 
js2 = copy.deepcopy(js1)

 
 
 
 
 
# JSON書き換え

 
 
 
 
js2['key1'] = "Hello " + js1['key1']

 
 
 
 
js2['key2'] = (js1['key2'] + 2) * 2

 
 
 
 
 
# 文字列解析しdatetime型に

 
 
 
 
t2 = datetime.strptime(js1['key3'], "%Y-%m-%dT%H:%M:%S.%f")

 
 
 
 
 
# タイムゾーン指定(元の時刻がnaiveの場合、awareにする)

 
 
 
 
t2 = t2.astimezone(timezone('Asia/Tokyo'))

 
 
 
 
# タイムゾーン変換(元の時刻をベースに別のタイムゾーンでの時刻表示に切り替えられる)

 
 
 
 
# t2 = t2.astimezone(timezone('UTC'))

 
 
 
 
# 日付を1日繰り上げる

 
 
 
 
t2 = t2 + timedelta(days=1)

 
 
 
 
js2['key3'] = t2.strftime("%Y-%m-%dT%H:%M:%S.%f%z")

 
 
 
 
 
# JSON書き込み

 
 
 
 
with open('result.json', 'w') as file:

 
 
 
 
    json.dump(js2, file, indent=2, ensure_ascii=False)

 

sample.json

{

 
 
 
 
  "key1": "value1",

 
 
 
 
  "key2": 100,

 
 
 
 
  "key3": "2022-05-04T09:08:34.123000"

 
 
 
 
}

 

result.json

{

 
 
 
 
  "key1": "Hello value1",

 
 
 
 
  "key2": 204,

 
 
 
 
  "key3": "2022-05-05T09:08:34.123000+0900"

 
 
 
 
}

 

上記ソースをLambdaで使えるようにするには、pytzLambda実行環境にアップロードする必要がある。

参考)

https://www.playfulit.net/articles/2019/01/28/aws-lambda-no-module-named-pytz-error/

 

 

 

アップロード前にpytzlambda_function.pyを予めローカルのPCにダウンロードし、zipしておく。

$ py -m pip install pytz -t .

pyプログラムにより、-m指定のためスクリプト実行を行う。対象はpipで、pipはインストールをpytzライブラリに対して行う。-tにより場所指定が行えて、「.」すなわちカレントディレクトリ。

Lambda環境上にzipをアップロードすると、zipの中身が解凍され全て展開されると同時に、それまで保存されていたファイルはすべて消えてしまうので要注意。

 

StepFunction上でReusltSelectorを指定する。

StepFunctionの実行結果。

 

■チャレンジ!S3->RDSStep Functionsで実現

S3にあるJSONファイルを、Step Functionsを用いてRDS(Serverless AuroraMySQL互換)に登録する。

目標とする構成:

 

Step Functionsでの実装は以下。

 

RDSにあるFamilyテーブルの定義は以下。

Database: golden

Table: Family
Columns:

id

int(11) PK

firstname

varchar(45)

lastname

varchar(45)

age

int(11)

 

Step Functionsに付与したIAMロールの許可ポリシー:

 

注意)Serverless AuroraにはServerlessでないAuroraの様に例えセキュリティグループがAuroraのポート3306を開放していたとしても、VPCの外部からパブリックアクセスは出来ない。

アクセスが出来るのは同一VPC上にあるEC2からのみとなっている。それでは何かと不便なので、同一VPC上にあるEC2を踏み台にしてアクセスする方法がある。

参考)https://stackoverflow.com/questions/51716530/aws-aurora-mysql-serverless-how-to-connect-from-mysql-workbench

 

MySQL Workbenchの設定例:

- Standard TCP/IP over SSH

- SSH Hostname : <YOUR EC2 パブリック IP>

- SSH Username : <YOUR username> #よくあるのは、ubuntu, ec2-user, adminなど

- SSH KeyFile: <YOUR EC2 .pem file>

- MYSQL Hostname: <databaseのエンドポイント>

- MYSQL Port: 3306

- Username : <databaseのユーザ名>

 

@JSON読み込み:

S3に格納されているJSONファイルを読み込む。

 

Family.json

{
 
"family": [
    {
     
"firstname": "John",
     
"lastname": "Walker",
     
"age": 39
   
},
   
{
     
"firstname": "Emily",
     
"lastname": "Walker",
     
"age": 26
   
},
   
{
     
"firstname": "Susan",
     
"lastname": "Walker",
     
"age": 6
   
},
   
{
     
"firstname": "Mike",
     
"lastname": "Walker",
     
"age": 4
   
}
  ]
}

 

JSON読み込みの箇所での工夫は、S3に格納されたJSON形式ではあるが文字列であるファイルの内容を、Step Functionsに用意されている組み込み関数「"States.StringToJson」を用いてJSONオブジェクトとして取り扱えるようにしたところ。S3 GetObject APIの出力のResultSelectorにて以下を実施。

 

(参考)Step Functions 組み込み関数ドキュメント:

https://docs.aws.amazon.com/ja_jp/step-functions/latest/dg/amazon-states-language-intrinsic-functions.html

 

StackOverflow投稿)S3にあるJSONファイルをのS3 APIであるGetObjectを使ってStep Functionsに取り込む。

https://stackoverflow.com/questions/63621720/is-there-any-way-to-read-the-contents-of-an-s3-file-from-an-aws-step-function/72151746#72151746

 

A最大行番号取得

RDSServerless Auroraにアクセスするためには、予めSecret Managerを用いてシークレットを作成しておき、APIのパラメタにシークレットのarnを渡す必要がある。

以下はシークレットの準備(ユーザ、PWAuroraのユーザ、PW

]

 

またStep FunctionsRDSAPIを使うには、Serverless Aurora側でData APIを有効化しておく必要がある。

なお、Serverless Auroraが利用可能なMySQLのバージョンは(5.6.10a, 2.07.1)のみ。(2022/05/06現在)

 

B行存在確認

FamilyテーブルのMax IDは、テーブルに1行以上レコードが存在すればその値とし、無い場合はデフォルトの処理を行う。

 

CデフォルトID設定

行が存在しない場合、便宜上現時点での最大のIDには-1を設定する。よくある手法かと。

 

Map処理:

Mapの入力で、上流から流れてくるデータであるFamilyテーブルのidの最大値とMapのコンテキストオブジェクトを用いて、JSONの各配列要素を組み替えて後続処理が配列処理を行える様にする。

 

Mapステート特有のコンテキストオブジェクト($$.Map.Item.Index$$.Map.Item.Value)を使って、配列のインデックスと要素が取得できる。

参考)マップステートのコンテキストオブジェクトデータ

https://docs.aws.amazon.com/ja_jp/step-functions/latest/dg/input-output-contextobject.html#contextobject-map

 

DID生成

残念ながらStep Functionsは数値の計算処理が出来ない模様(2022/05/08現在)。

この箇所のみ仕方なく、Lambdaのマイクロサービスで実現する。

 

lambda_function.py

import json

 

def lambda_handler(event, context):

    event['id'] = event['mapindex'] + 1 + event['maxid']

    return event

Lambda関数名の箇所は、実装済みのLambda関数のarnを入力しておく。

 

EInsert文作成

ここではPassステートでの入力のParameters変換において、組み込み関数States.Formatを用いて文字列結合を行う。

{

  "Insert.$": "States.Format('Insert into golden.Family values ({}, \\'{}\\', \\'{}\\', {})', $.id, $.firstname, $.lastname, $.age)"

}

 

※上記の図では切れているが、文全体は上掲の通り。{}をプレースホルダとして複数の{}を後続の変数値で置き換えられる。シングルクォートを記述する場合には、\\'としてエスケープ文字として扱う。

 

F行挿入

ここまで来たらあとはEで作成したInsert文を実行するのみ。

 

ご参考)ソースコード全文

注意:筆者固有のリソース名称は<YOUR...>のプレースホルダーとしたので適宜差し替えが必要。

{

  "StartAt": "Get JSON from S3",

  "States": {

    "Get JSON from S3": {

      "Type": "Task",

      "Parameters": {

        "Bucket": "<YOUR S3 Bucket>",

        "Key": "<YOUR S3 File>"

      },

      "Resource": "arn:aws:states:::aws-sdk:s3:getObject",

      "ResultSelector": {

        "myJson.$": "States.StringToJson($.Body)"

      },

      "Next": "Select max id from Family",

      "Comment": "S3 -> JSON"

    },

    "Select max id from Family": {

      "Type": "Task",

      "Parameters": {

        "ResourceArn": "<YOUR RDS arn>",

        "SecretArn": "<YOUR Secret arn>",

        "Sql": "select max(id) from golden.Family;"

      },

      "Resource": "arn:aws:states:::aws-sdk:rdsdata:executeStatement",

      "ResultPath": "$.MaxId",

      "Next": "Check row exists"

    },

    "Check row exists": {

      "Type": "Choice",

      "Choices": [

        {

          "Variable": "$.MaxId.Records[0][0].LongValue",

          "IsPresent": true,

          "Next": "For each myJson.family"

        }

      ],

      "Default": "Set default max id"

    },

    "Set default max id": {

      "Type": "Pass",

      "Next": "For each myJson.family",

      "ResultPath": "$.MaxId",

      "Result": {

        "Records": [

          [

            {

              "LongValue": -1

            }

          ]

        ]

      }

    },

    "For each myJson.family": {

      "Type": "Map",

      "End": true,

      "Iterator": {

        "StartAt": "Increment id = current max id + 1 + map index",

        "States": {

          "Increment id = current max id + 1 + map index": {

            "Type": "Task",

            "Resource": "arn:aws:states:::lambda:invoke",

            "Parameters": {

              "Payload.$": "$",

              "FunctionName": "<YOUR Lambda arn>"

            },

            "Retry": [

              {

                "ErrorEquals": [

                  "Lambda.ServiceException",

                  "Lambda.AWSLambdaException",

                  "Lambda.SdkClientException"

                ],

                "IntervalSeconds": 2,

                "MaxAttempts": 6,

                "BackoffRate": 2

              }

            ],

            "Next": "Generate insert statement",

            "OutputPath": "$.Payload"

          },

          "Generate insert statement": {

            "Type": "Pass",

            "Next": "Insert row into Family",

            "Parameters": {

              "Insert.$": "States.Format('Insert into golden.Family values ({}, \\'{}\\', \\'{}\\', {})', $.id, $.firstname, $.lastname, $.age)"

            }

          },

          "Insert row into Family": {

            "Type": "Task",

            "End": true,

            "Parameters": {

          "ResourceArn": "<YOUR RDS arn>",

              "SecretArn": "<YOUR Secret arn>",

              "Sql.$": "$.Insert"

            },

            "Resource": "arn:aws:states:::aws-sdk:rdsdata:executeStatement"

          }

        }

      },

      "MaxConcurrency": 4,

      "ItemsPath": "$.myJson.family",

      "ResultPath": "$.MapResult",

      "Parameters": {

        "maxid.$": "$.MaxId.Records[0][0].LongValue",

        "mapindex.$": "$$.Map.Item.Index",

        "firstname.$": "$$.Map.Item.Value.firstname",

        "lastname.$": "$$.Map.Item.Value.lastname",

        "age.$": "$$.Map.Item.Value.age"

      }

    }

  },

  "Comment": "S3 -> JSON -> RDS",

  "TimeoutSeconds": 30

}

 

 

CloudFrontWAFを使ったエッジサービス

Amazon CloudFrontおよびAWS WAFを用いて エッジサービスの活用方法を学ぼう

https://pages.awscloud.com/JAPAN-event-OE-Hands-on-for-Beginners-CF_WAF-2021-confirmation-343.html

CloudFrontがファイルをキャッシュしているか(オリジンサーバからファイルを取って来ているかどうか)の確認方法:

x-cache: Miss from cloudfrontとなっており、cloudfront上に存在せず、オリジンサーバからファイルを取って来ていることが分かる。

 

キャッシュポリシーを編集し、

 

ビヘイビアのキャッシュポリシーに追加すると、、、

 

x-cache: Hit from cloudfrontとなり、キャッシュから取得できるようになったのが分かる。

 

オリジンリクエストポリシー:

https://docs.aws.amazon.com/ja_jp/AmazonCloudFront/latest/DeveloperGuide/controlling-origin-requests.html

 

CloudFrontへのビューワーリクエストにより、キャッシュミスが発生した場合、CloudFrontはオブジェクトを取得するためのリクエストをオリジンに送信するが、これはオリジンリクエストと呼ばれる。

オリジンリクエストには、ビューワーリクエストの次の情報が常に含まれます。

URLパス(URLクエリ文字列またはドメイン名を含まないパスのみ)

・リクエストボディ(存在する場合)

CloudFrontがすべてのオリジンリクエストに自動的に含めるHTTPヘッダー(HostUser-AgentX-Amz-Cf-Idなど)

 

ビューワーリクエストのその他の情報(URLクエリ文字列、HTTPヘッダー、Cookieなど)は、デフォルトではオリジンリクエストに含まれない。

オリジンリクエストポリシーを使用することで、オリジンでこのその他の情報を受信することができるようになる。

オリジンリクエストポリシーは、キャッシュキーを制御するキャッシュポリシーとは別もの。

この分離により、オリジンで追加情報を受信し、良好なキャッシュヒット率(キャッシュヒットとなるビューワーリクエストの割合)を維持することができる。

 

ハンバーガーメニューのポリシーから、オリジンリクエストポリシーを編集する。

 

クエリ文字列許可に今回オリジンに渡したいパラメタであるinput_textを設定する。

 

動的パラメータであるクエリ文字列を含むAPIの処理対象として、オリジンを追加する。

 


APIGateway
向けのオリジンが追加された。

 

ビヘイビアが新しいオリジンに向かう様にする。

 

apiというパスパターンにオリジンリクエストポリシーを紐づける。

 

AWS WAFWeb Application Firewall)によるACLRuleの設定:

可用性、セキュリティ侵害、リソースの過剰消費に影響を与えるような、ウェブの脆弱性を利用した一般的な攻撃やボットから、ウェブアプリケーションまたは API を保護するウェブアプリケーションファイアウォール。

各種AWSサービスにWASを紐づけるには、Web ACLの単位で行う。

一つのACLの中に複数のRuleを設けることが出来る。

Ruleの中に複数のStatementを設ける事が出来て、StatementAND条件やOR条件で組み合わせる事が出来る。

Statementで指定した条件にマッチした場合、アクションが実行される。

指定回数によるRule設定も可能で、これはRate based Ruleと呼ばれる。

 

ACLを定義し、CloudFrontを紐づける。

 

特定の地域以外からのアクセス(例:海外からのアクセス)は拒否(Block)といったRuleを作成し、ACLに登録する。

 

Rule設定後、アクセス不能となる。

 

ActionAllowにすると、アクセス可能となる。

 

 

AWS Amplify を用いた Web サイトの構築方法

https://pages.awscloud.com/JAPAN-event-OE-Hands-on-for-Beginners-amplify-2022-confirmation-774.html

 

 

Amplify Docs for React

https://docs.amplify.aws/start/q/integration/react/

 

AWS Amplifyとは:

AWSWeb各種サービスを組み合わせ、エンドユーザ向けWebアプリケーションの構築、立ち上げを効率的に行うためのサービス。

 

AWS Amplifyの構成要素:

Ø  Amplifyライブラリ

WebやモバイルアプリとAWSを統合するためのOSSライブラリ

Ø  Amplify CLI

Webやモバイルアプリのバックエンドを対話的に構築するためのOSSツール群

Ø  Amplifyコンソール

サーバレスWebアプリをビルド、テスト、デプロイ、ホスティングするためのサービス

Ø  Amplify AdminUI

Webやモバイルアプリのバックエンドとコンテンツを管理するためのGUI

 

 

Cloud9構築時のポイント

u  EC2t3.smallを指定(t2.microだとメモリ不足エラーを起こす可能性があるため)

u  AWSが管理する一時的な認証情報を無効化する。Cloud9コンソールを開くときに払い出される一次認証情報を、Amplify CLIで発行する認証情報に置き換えるために、無効化する。

 

u  Cloud9のインスタンスにEBSEC2ブロックストレージ)ボリュームを引き上げる。(10->32GB

 

Amplifyを設定する。

iamdoikota01:~/environment $ npm install -g @aws-amplify/cli

added 26 packages, and audited 27 packages in 14s

7 packages are looking for funding

  run `npm fund` for details

found 0 vulnerabilities

iamdoikota01:~/environment $ amplify configure

Follow these steps to set up access to your AWS account:

Sign in to your AWS administrator account:

https://console.aws.amazon.com/

Press Enter to continue

Specify the AWS Region

? region:  ap-northeast-1

Specify the username of the new IAM user:

? user name:  amplify-0LLT1

Complete the user creation using the AWS console

https://console.aws.amazon.com/iam/home?region=ap-northeast-1#/users$new?step=final&accessKey&userNames=amplify-0LLT1&permissionType=policies&policies=arn:aws:iam::aws:policy%2FAdministratorAccess-Amplify

Press Enter to continue

Enter the access key of the newly created user:

? accessKeyId:  ********************

? secretAccessKey:  ****************************************

This would update/create the AWS Profile in your local machine

? Profile Name:  Amplify

Successfully set up the new user.