{X-Ray}Using the AWS X-Ray API with the AWS CLI

https://docs.aws.amazon.com/ja_jp/lambda/latest/dg/services-apigateway-tutorial.html

https://qiita.com/mksamba/items/448c538236ab2989eba9

https://qiita.com/Ricordanza/items/d68d708e274e28b6bfa2

https://docs.aws.amazon.com/ja_jp/apigateway/latest/developerguide/apigateway-enabling-xray.html#apigateway-xray-cli-setup

 

 

-- 1. コマンド等のインストール

-- 1.1 aws cli version 2 インストール

curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
unzip awscliv2.zip
sudo ./aws/install

aws --version

-- 1.2 jqインストール
sudo yum -y install jq

 

-- 1.3 クライアントEC2(Amazon Linux2)にPython3.8をインストール

amazon-linux-extras list | grep python
sudo amazon-linux-extras install -y python3.8
python3.8 -V


-- 2. IAMポリシー作成

※xrayへの権限も追加

vim policy01.json

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "Stmt1428341300017",
      "Action": [
        "dynamodb:DeleteItem",
        "dynamodb:GetItem",
        "dynamodb:PutItem",
        "dynamodb:Query",
        "dynamodb:Scan",
        "dynamodb:UpdateItem"
      ],
      "Effect": "Allow",
      "Resource": "*"
    },
    {
      "Sid": "",
      "Resource": "*",
      "Action": [
        "logs:CreateLogGroup",
        "logs:CreateLogStream",
        "logs:PutLogEvents"
      ],
      "Effect": "Allow"
    },
    {
      "Sid": "X",
      "Resource": "*",
      "Action": [
        "xray:PutTraceSegments",
        "xray:PutTelemetryRecords"
      ],
      "Effect": "Allow"
    }
  ]
}

aws iam create-policy \
--policy-name policy01 \
--policy-document file://policy01.json

-- 3. IAMロール作成
vim role01.json

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Service": "lambda.amazonaws.com"
      },
      "Action": "sts:AssumeRole"
    }
  ]
}

aws iam create-role \
--role-name role01 \
--assume-role-policy-document file://role01.json

-- 4. ポリシーをロールにアタッチ
aws iam attach-role-policy \
--policy-arn arn:aws:iam::999999999999:policy/policy01 \
--role-name role01


-- 5. Lambda Layer 作成

 


mkdir python
pip3.8 install requests -t python/
pip3.8 install aws-xray-sdk -t python/

vim python/layer.py

from aws_xray_sdk.core import xray_recorder
from aws_xray_sdk.core import patch_all
patch_all()

zip -r python.zip python/

aws lambda publish-layer-version \
--layer-name ll01 \
--description ll01 \
--compatible-architectures "x86_64" \
--compatible-runtimes python3.8 \
--zip-file fileb://python.zip


aws lambda list-layers


-- 6. Lambda関数作成
AWS X-Ray トレースの有効化も実施

vim test.py


from __future__ import print_function
import boto3
import json

import layer

print('Loading function')
def handler(event, context):
    '''Provide an event that contains the following keys:

      - operation: one of the operations in the operations dict below
      - tableName: required for operations that interact with DynamoDB
      - payload: a parameter to pass to the operation being performed
    '''
    #print("Received event: " + json.dumps(event, indent=2))

    operation = event['operation']

    if 'tableName' in event:
        dynamo = boto3.resource('dynamodb').Table(event['tableName'])

    operations = {
        'create': lambda x: dynamo.put_item(**x),
        'read': lambda x: dynamo.get_item(**x),
        'update': lambda x: dynamo.update_item(**x),
        'delete': lambda x: dynamo.delete_item(**x),
        'list': lambda x: dynamo.scan(**x),
        'echo': lambda x: x,
        'ping': lambda x: 'pong'
    }

    if operation in operations:
        return operations[operation](event.get('payload'))
    else:
        raise ValueError('Unrecognized operation "{}"'.format(operation))


chmod 755 test.py
zip test.zip test.py

aws lambda create-function \
--function-name func01 \
--zip-file fileb://test.zip \
--handler test.handler \
--runtime python3.8 \
--role arn:aws:iam::999999999999:role/role01 \
--layers arn:aws:lambda:ap-northeast-1:999999999999:layer:ll01:6 \
--tracing-config '{"Mode": "Active"}'

 

aws lambda list-functions | grep func01

aws lambda get-function --function-name func01

 

-- 7. 関数をテストする

vim input.txt
{
    "operation": "echo",
    "payload": {
        "somekey1": "somevalue1",
        "somekey2": "somevalue2"
    }
}

aws lambda invoke \
--function-name func01 \
--payload file://input.txt \
output.txt \
--cli-binary-format raw-in-base64-out

cat output.txt


-- 8. API Gateway を使用して REST API を作成する

-- 8.1 API を作成する

aws apigateway create-rest-api \
--name api01 \
--description "api01" \
--endpoint-configuration '{"types": ["REGIONAL"]}'

aws apigateway get-rest-apis

aws apigateway get-rest-api \
--rest-api-id 1111111111

 

-- 8.2 API でリソースを作成する
aws apigateway get-resources \
--rest-api-id 1111111111

aws apigateway create-resource \
--rest-api-id 1111111111 \
--parent-id 2222222222 \
--path-part "dynamodbmanager"

 

-- 8.3 リソースに POST メソッドを作成する

aws apigateway put-method \
--rest-api-id 1111111111 \
--resource-id 333333 \
--http-method POST \
--authorization-type NONE \
--no-api-key-required \
--request-parameters {}

aws apigateway put-integration \
--rest-api-id 1111111111 \
--resource-id 333333 \
--http-method POST \
--type AWS \
--integration-http-method POST \
--content-handling CONVERT_TO_TEXT \
--uri "arn:aws:apigateway:ap-northeast-1:lambda:path/2015-03-31/functions/arn:aws:lambda:ap-northeast-1:999999999999:function:func01/invocations"

aws apigateway put-integration-response \
--rest-api-id 1111111111 \
--resource-id 333333 \
--http-method POST \
--status-code 200 \
--response-templates '{"application/json": ""}'


aws apigateway put-method-response \
--rest-api-id 1111111111 \
--resource-id 333333 \
--http-method POST \
--status-code 200 \
--response-models '{"application/json": "Empty"}'

 

aws apigateway get-method \
--rest-api-id 1111111111 \
--resource-id 333333 \
--http-method POST

 

-- 8.4 API をデプロイする
AWS X-Ray トレースの有効化も実施


aws apigateway get-deployments \
--rest-api-id 1111111111

aws apigateway get-stages \
--rest-api-id 1111111111


aws apigateway create-deployment \
--rest-api-id 1111111111

aws apigateway create-stage \
--rest-api-id 1111111111 \
--stage-name stage01 \
--deployment-id 444444 \
--tracing-enabled

 

 

-- 8.5 Lambda関数に権限を追加する

aws lambda add-permission \
--function-name func01 \
--statement-id apigw \
--action lambda:InvokeFunction \
--principal apigateway.amazonaws.com \
--source-arn arn:aws:execute-api:ap-northeast-1:999999999999:1111111111/*/POST/dynamodbmanager

 

aws lambda get-policy \
--function-name func01 | jq -r .Policy  | jq .

 

 

-- 9. DynamoDB テーブルの作成

aws dynamodb create-table \
--table-name tab1 \
--attribute-definitions \
    AttributeName=col1,AttributeType=S \
--key-schema \
    AttributeName=col1,KeyType=HASH \
--billing-mode=PAY_PER_REQUEST


aws dynamodb list-tables
aws dynamodb describe-table --table-name tab1


-- 10. セットアップをテストする

aws apigateway test-invoke-method \
--rest-api-id 1111111111 \
--resource-id 333333 \
--http-method POST \
--path-with-query-string '' \
--body '{
  "operation": "create",
  "tableName": "tab1",
  "payload": {
    "Item": {
      "col1": "1234ABCD",
      "number": 5
    }
  }
}'

aws dynamodb scan --table-name tab1

aws apigateway test-invoke-method \
--rest-api-id 1111111111 \
--resource-id 333333 \
--http-method POST \
--path-with-query-string '' \
--body '{
    "operation": "update",
    "tableName": "tab1",
    "payload": {
        "Key": {
            "col1": "1234ABCD"
        },
        "AttributeUpdates": {
            "number": {
                "Value": 10
            }
        }
    }
}'


aws dynamodb scan --table-name tab1

-- 11. APIをテストする

curl -v -X POST \
-H 'content-type: application/json' \
-d '{
  "operation": "create",
  "tableName": "tab1",
  "payload": {
    "Item": {
      "col1": "2222ABCD",
      "number": 50
    }
  }
}' \
https://1111111111.execute-api.ap-northeast-1.amazonaws.com/stage01/dynamodbmanager

aws dynamodb scan --table-name tab1


curl -v -X POST \
-H 'content-type: application/json' \
-d '{
    "operation": "update",
    "tableName": "tab1",
    "payload": {
        "Key": {
            "col1": "2222ABCD"
        },
        "AttributeUpdates": {
            "number": {
                "Value": 100
            }
        }
    }
}' \
https://1111111111.execute-api.ap-northeast-1.amazonaws.com/stage01/dynamodbmanager


aws dynamodb scan --table-name tab1

 

-- 12. X-Ray 動作確認

EPOCH=$(date +%s)
aws xray get-service-graph \
--start-time $*1 \
--end-time $EPOCH

 


EPOCH=$(date +%s)
aws xray get-trace-summaries \
--start-time $*2 \
--end-time $EPOCH \
--query 'TraceSummaries[*].Http.HttpURL'

 


EPOCH=$(date +%s)
TRACEIDS=$(aws xray get-trace-summaries \
--start-time $*3 \
--end-time $EPOCH \
--query 'TraceSummaries[*].Id' --output text)

aws xray batch-get-traces \
--trace-ids $TRACEIDS \
--query 'Traces[*]'

 

 

 

-- 13. クリーンアップ

-- DynamoDB テーブル削除
aws dynamodb list-tables
aws dynamodb delete-table --table-name tab1

 

-- API削除

aws apigateway get-rest-apis

aws apigateway delete-rest-api \
--rest-api-id 1111111111


-- Lambda関数の削除
aws lambda get-function --function-name func01
aws lambda delete-function --function-name func01


-- Lambda Layerの削除

aws lambda list-layers

aws lambda delete-layer-version \
--layer-name ll01 \
--version-number 6


-- IAMロールの削除
aws iam list-roles | grep role01

aws iam detach-role-policy \
--role-name role01 \
--policy-arn arn:aws:iam::999999999999:policy/policy01

aws iam delete-role --role-name role01


-- IAMポリシーの削除
aws iam list-policies | grep policy01

aws iam delete-policy \
--policy-arn arn:aws:iam::999999999999:policy/policy01

 

 

*1:$EPOCH-600

*2:$EPOCH-600

*3:$EPOCH-600