Browse Source

Added course assets, sample EventBridge events.

Frederic G. MARAND 2 years ago
parent
commit
941166b90d
49 changed files with 942 additions and 0 deletions
  1. 6 0
      .idea/dynamodb_demo.iml
  2. BIN
      02/creating-simple-dynamodb-tables-slides.pdf
  3. 27 0
      02/demos.json
  4. BIN
      03/creating-elaborate-dynamodb-tables-slides.pdf
  5. BIN
      04/backing-up-and-recovering-dynamodb-tables-slides.pdf
  6. 87 0
      05/demos/DynamoDB_Communicator.py
  7. BIN
      05/monitoring-dynamodb-tables-with-cloudwatch-slides.pdf
  8. 21 0
      06/demos/BatchGetItem.py
  9. 6 0
      06/demos/BatchGetItem.sh
  10. 31 0
      06/demos/BatchWriteItem.py
  11. 6 0
      06/demos/BatchWriteItem.sh
  12. 15 0
      06/demos/DeleteItem.py
  13. 10 0
      06/demos/DeleteItem.sh
  14. 13 0
      06/demos/GetItem.py
  15. 9 0
      06/demos/GetItem.sh
  16. 22 0
      06/demos/ModifyConditionally.sh
  17. 20 0
      06/demos/PutItem.py
  18. 10 0
      06/demos/PutItem.sh
  19. 28 0
      06/demos/QueryTable.py
  20. 13 0
      06/demos/QueryTable.sh
  21. 16 0
      06/demos/ScanTable.py
  22. 12 0
      06/demos/ScanTable.sh
  23. 16 0
      06/demos/UpdateAtomicItem.py
  24. 11 0
      06/demos/UpdateAtomicItem.sh
  25. 20 0
      06/demos/UpdateItem.py
  26. 20 0
      06/demos/UpdateItem.sh
  27. 7 0
      06/demos/batch_get_items.json
  28. 17 0
      06/demos/batch_write_items.json
  29. 27 0
      06/demos/modify_conditionally_item.json
  30. 14 0
      06/demos/modify_conditionally_item_overwrite.json
  31. 6 0
      06/demos/modify_conditionally_names.json
  32. 4 0
      06/demos/modify_conditionally_values.json
  33. 11 0
      06/demos/put_item.json
  34. 33 0
      06/demos/put_item_list.json
  35. 17 0
      06/demos/put_item_recovery.json
  36. 3 0
      06/demos/query_attr_names.json
  37. 3 0
      06/demos/query_attr_values.json
  38. 1 0
      06/demos/update_item_atomic_key.json
  39. 3 0
      06/demos/update_item_atomic_values.json
  40. 4 0
      06/demos/update_item_expression_names.json
  41. 3 0
      06/demos/update_item_key.json
  42. 26 0
      06/demos/update_item_values.json
  43. BIN
      06/handling-dynamodb-objects-slides.pdf
  44. 54 0
      5-2.json
  45. 53 0
      5-3.json
  46. 59 0
      5-4.json
  47. 62 0
      5-5.json
  48. 109 0
      5-createtable-event.json
  49. 7 0
      5-monitoring.md

+ 6 - 0
.idea/dynamodb_demo.iml

@@ -1,9 +1,15 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <module type="WEB_MODULE" version="4">
+  <component name="FacetManager">
+    <facet type="Python" name="Python facet">
+      <configuration sdkName="Python 3.9" />
+    </facet>
+  </component>
   <component name="Go" enabled="true" />
   <component name="NewModuleRootManager">
     <content url="file://$MODULE_DIR$" />
     <orderEntry type="inheritedJdk" />
     <orderEntry type="sourceFolder" forTests="false" />
+    <orderEntry type="library" name="Python 3.9 interpreter library" level="application" />
   </component>
 </module>

BIN
02/creating-simple-dynamodb-tables-slides.pdf


+ 27 - 0
02/demos.json

@@ -0,0 +1,27 @@
+{
+    "Name": "Bob",
+    "Age": 55,
+    "Company": "Globomantics",
+    "Position": "DevOps",
+    "Kids": [
+      {
+        "Name": "Jane",
+        "Age": 2
+      },
+      {
+        "Name": "Peter",
+        "Age": 5
+      },
+      {
+        "Name": "Lucy",
+        "Age": 1
+      }
+    ],
+    "LotteryNumbers": [
+      4,
+      7,
+      65,
+      30,
+      10
+    ]
+}

BIN
03/creating-elaborate-dynamodb-tables-slides.pdf


BIN
04/backing-up-and-recovering-dynamodb-tables-slides.pdf


+ 87 - 0
05/demos/DynamoDB_Communicator.py

@@ -0,0 +1,87 @@
+import boto3
+import names
+import random
+import datetime
+
+
+# return dynamodb client to authenticate
+def dynamodb():
+    client = boto3.client('dynamodb', region_name=TABLE_REGION)
+    return client
+
+
+# the function will produce a random date depending on set range
+def random_date():
+    day = random.randint(10, 20)
+    month = random.randint(5, 7)
+    year = 2019
+    date = datetime.date(year, month, day).strftime("%Y%m%d")
+    return date
+
+
+# the function willl generate a random job position
+def random_position():
+    positions = [
+        'HR', 'devops', 'data scientist', 'developer', 'janitor',
+        'office coordinator'
+    ]
+    return random.choice(positions)
+
+
+# the function will generate random first name
+def random_contract_type():
+    contract_types = ['permanent', 'intern', 'contract']
+    return random.choice(contract_types)
+
+
+# the function writes to the table, item with ID partition key
+def write_items(id_number):
+    client = dynamodb()
+    client.put_item(
+        TableName=TABLE_NAME,
+        Item={
+            "id": {
+                "S": id_number
+            },
+            "contract_type": {
+                "S": random_contract_type()
+            },
+            "last_accessed": {
+                "N": random_date()
+            },
+            "name": {
+                "S": names.get_first_name()
+            },
+            "position": {
+                "S": random_position()
+            }
+        })
+    print('writing item number {}'.format(id_number))
+
+
+# the function reads from the table, item with ID partition key
+def read_items(id_number):
+    client = dynamodb()
+    client.get_item(TableName=TABLE_NAME, Key={"id": {"S": id_number}})
+    print('reading item number {}'.format(id_number))
+
+
+# set the number of requests you'd like to make to the table
+REQUESTS = 10000
+# set table name, where you want to sent the requests
+TABLE_NAME = 'elaborate_employee_table'
+# in what region does the table reside
+TABLE_REGION = 'eu-west-1'
+# which action you'd like to do write / read
+ACTION = 'read'
+
+
+# for loop that will go through request number and either write or read from the table
+# depending on action type
+for request in range(REQUESTS):
+    if ACTION == 'write':
+        write_items(str(request))
+    elif ACTION == 'read':
+        read_items(str(request))
+    else:
+        pass

BIN
05/monitoring-dynamodb-tables-with-cloudwatch-slides.pdf


+ 21 - 0
06/demos/BatchGetItem.py

@@ -0,0 +1,21 @@
+#!/usr/bin/env python
+import boto3
+import json
+
+TABLE_NAME_1='elaborate_employee_table'
+TABLE_NAME_2='simple_employee_table'
+
+client = boto3.client('dynamodb')
+
+response = client.batch_get_item(
+    RequestItems = {
+    TABLE_NAME_1: {
+      'Keys': [
+        {'id': {'N': '111'}},
+        {'id': {'N': '112'}}
+      ]
+    }
+  }
+)
+
+print(json.dumps(response['Responses'], indent=4))

+ 6 - 0
06/demos/BatchGetItem.sh

@@ -0,0 +1,6 @@
+#!/bin/bash
+
+aws \
+dynamodb \
+batch-get-item \
+--request-items file://batch_get_items.json | jq .

+ 31 - 0
06/demos/BatchWriteItem.py

@@ -0,0 +1,31 @@
+#!/usr/bin/env python
+import boto3
+import json
+
+TABLE_NAME='elaborate_employee_table'
+client = boto3.client('dynamodb')
+
+response = client.batch_write_item(
+    RequestItems = {
+    TABLE_NAME: [
+      {
+        'PutRequest': {
+          'Item': {
+            'id': {'N':'111'},
+            'status': {'S': 'Python batch write 1'}
+          }
+        }
+      },
+      {
+        'PutRequest': {
+          'Item': {
+            'id': {'N':'112'},
+            'status': {'S': 'Python batch write 2'}
+          }
+        }
+      }
+    ]
+  }
+)
+
+print(json.dumps(response, sort_keys=True, indent=4))

+ 6 - 0
06/demos/BatchWriteItem.sh

@@ -0,0 +1,6 @@
+#!/bin/bash
+
+aws \
+dynamodb \
+batch-write-item \
+--request-items file://batch_write_items.json | jq .

+ 15 - 0
06/demos/DeleteItem.py

@@ -0,0 +1,15 @@
+#!/usr/bin/env python
+import boto3
+import json
+
+TABLE_NAME='elaborate_employee_table'
+
+client = boto3.client('dynamodb')
+
+response = client.delete_item(
+    TableName = TABLE_NAME,
+    Key = {'id': {'N': '5'}},
+    ReturnValues = 'ALL_OLD'
+)
+
+print(json.dumps(response['Attributes'], indent=4))

+ 10 - 0
06/demos/DeleteItem.sh

@@ -0,0 +1,10 @@
+#!/bin/bash
+
+TABLE_NAME='elaborate_employee_table'
+
+aws \
+dynamodb \
+delete-item \
+--table-name ${TABLE_NAME} \
+--key '{"id": {"N": "157"}}' \
+--return-values ALL_OLD

+ 13 - 0
06/demos/GetItem.py

@@ -0,0 +1,13 @@
+#!/usr/bin/env python
+import boto3
+import json
+
+TABLE_NAME='elaborate_employee_table'
+
+client = boto3.client('dynamodb')
+
+response = client.get_item(
+    TableName = TABLE_NAME,
+    Key = {'id': {'N': '5'}})
+
+print(json.dumps(response['Item'], indent=4))

+ 9 - 0
06/demos/GetItem.sh

@@ -0,0 +1,9 @@
+#!/bin/bash
+
+TABLE_NAME='elaborate_employee_table'
+
+aws \
+dynamodb \
+get-item \
+--table-name ${TABLE_NAME} \
+--key '{"id": {"N": "156"}}' | jq .

+ 22 - 0
06/demos/ModifyConditionally.sh

@@ -0,0 +1,22 @@
+#!/bin/bash
+
+TABLE_NAME='elaborate_employee_table'
+
+# aws \
+# dynamodb \
+# put-item \
+# --table-name ${TABLE_NAME} \
+# --item file://modify_conditionally_item_overwrite.json \
+# --condition-expression "attribute_not_exists(id)" \
+# --return-values ALL_OLD | jq .
+
+aws \
+dynamodb \
+update-item \
+--table-name ${TABLE_NAME} \
+--key '{"id":{"N":"10"}}' \
+--expression-attribute-values file://modify_conditionally_values.json \
+--expression-attribute-names file://modify_conditionally_names.json \
+--update-expression "SET #ec = :ecn" \
+--condition-expression "attribute_not_exists(#ec) and attribute_exists(#ad.#st) and #ct = :ctv" \
+--return-values UPDATED_NEW | jq .

+ 20 - 0
06/demos/PutItem.py

@@ -0,0 +1,20 @@
+#!/usr/bin/env python
+import boto3
+import json
+
+TABLE_NAME='elaborate_employee_table'
+client = boto3.client('dynamodb')
+
+response = client.put_item(
+    TableName = TABLE_NAME,
+    Item = {
+        'id': {'N': '5'},
+        'name': {'S': 'Arlyne'},
+        'contract_type': {'S': 'permanent'},
+        'position': {'S': 'data scientist'},
+        'last_accessed': {'N': '20190513'}
+    },
+    ReturnValues = 'ALL_OLD'
+)
+
+print(json.dumps(response, indent=4))

+ 10 - 0
06/demos/PutItem.sh

@@ -0,0 +1,10 @@
+#!/bin/bash
+
+TABLE_NAME='elaborate_employee_table'
+
+aws \
+dynamodb \
+put-item \
+--table-name ${TABLE_NAME} \
+--item file://put_itemput item.json \
+--return-values ALL_OLD

+ 28 - 0
06/demos/QueryTable.py

@@ -0,0 +1,28 @@
+#!/usr/bin/env python
+import boto3
+import json
+
+TABLE_NAME='elaborate_employee_table'
+INDEX_NAME='access_application_index'
+
+client = boto3.client('dynamodb')
+
+response = client.query(
+    TableName = TABLE_NAME,
+    IndexName = INDEX_NAME,
+    KeyConditionExpression='#la = :lav and begins_with(#n, :nv)',
+    FilterExpression = '#i < :iv',
+    ExpressionAttributeValues = {
+        ':lav': {'N':'20190712'},
+        ':iv': {'N':'150'},
+        ':nv': {'S':'B'}
+    },
+    ExpressionAttributeNames = {
+        '#la': 'last_accessed',
+        '#n': 'name',
+        '#i': 'id'
+    },
+    ProjectionExpression = '#n'
+)
+
+print(json.dumps(response['Items'], indent=4))

+ 13 - 0
06/demos/QueryTable.sh

@@ -0,0 +1,13 @@
+#!/bin/bash
+
+TABLE_NAME='elaborate_employee_table'
+INDEX_NAME='position_application_index'
+
+aws \
+dynamodb \
+query \
+--table-name ${TABLE_NAME} \
+--key-condition-expression "#i = :n" \
+--expression-attribute-values file://query_attr_values.json \
+--expression-attribute-names file://query_attr_names.json \
+--profile test | jq .

+ 16 - 0
06/demos/ScanTable.py

@@ -0,0 +1,16 @@
+#!/usr/bin/env python
+import boto3
+import json
+
+TABLE_NAME='elaborate_employee_table'
+INDEX_NAME='scan_index'
+
+client = boto3.client('dynamodb')
+
+response = client.scan(
+    TableName = TABLE_NAME,
+    IndexName = INDEX_NAME,
+    ReturnConsumedCapacity = 'INDEXES'
+)
+
+print(json.dumps(response['ConsumedCapacity'], indent=4))

+ 12 - 0
06/demos/ScanTable.sh

@@ -0,0 +1,12 @@
+#!/bin/bash
+
+TABLE_NAME='elaborate_employee_table'
+INDEX_NAME='scan_index'
+
+aws \
+dynamodb \
+scan \
+--return-consumed-capacity INDEXES \
+--table-name ${TABLE_NAME} \
+--index-name ${INDEX_NAME} \
+--debug > /dev/null | jq .

+ 16 - 0
06/demos/UpdateAtomicItem.py

@@ -0,0 +1,16 @@
+#!/usr/bin/env python
+import boto3
+import json
+
+TABLE_NAME='elaborate_employee_table'
+client = boto3.client('dynamodb')
+
+response = client.update_item(
+    TableName=TABLE_NAME,
+    Key={'id': {'N': '30'}},
+    UpdateExpression='SET #ca = #ca + :val',
+    ExpressionAttributeValues={':val': {'N': '120'}},
+    ExpressionAttributeNames={'#ca': 'count_accessed'},
+    ReturnValues='UPDATED_NEW')
+
+print(json.dumps(response['Attributes'], indent=4))

+ 11 - 0
06/demos/UpdateAtomicItem.sh

@@ -0,0 +1,11 @@
+#!/bin/bash
+
+TABLE_NAME='elaborate_employee_table'
+
+aws dynamodb update-item \
+--table-name ${TABLE_NAME} \
+--key '{"id":{"N":"20"}}' \
+--update-expression "SET #ca = #ca + :val" \
+--expression-attribute-values '{":val": {"N":"5"}}' \
+--expression-attribute-names '{"#ca": "count_accessed"}' \
+--return-values UPDATED_NEW | jq .

+ 20 - 0
06/demos/UpdateItem.py

@@ -0,0 +1,20 @@
+#!/usr/bin/env python
+import boto3
+import json
+import random
+
+TABLE_NAME = 'elaborate_employee_table'
+
+id_numbers = [10, 20, 30, 40, 50, 60, 70, 90, 100]
+
+client = boto3.client('dynamodb')
+for id_number in id_numbers:
+    response = client.update_item(
+        TableName=TABLE_NAME,
+        Key={'id': {'N': '{}'.format(id_number)}},
+        UpdateExpression='SET #ct = :ctv',
+        ExpressionAttributeValues={':ctv': {'S':'permanent'}},
+        ExpressionAttributeNames={'#ct': 'contract_type'},
+        ReturnValues='UPDATED_OLD')
+
+    print(json.dumps(response['Attributes'], indent=4))

+ 20 - 0
06/demos/UpdateItem.sh

@@ -0,0 +1,20 @@
+#!/bin/bash
+
+TABLE_NAME='elaborate_employee_table'
+
+# aws \
+# dynamodb \
+# update-item \
+# --table-name ${TABLE_NAME} \
+# --key file://update_item_key.json \
+# --expression-attribute-values file://update_item_values.json \
+# --expression-attribute-names file://update_item_expression_names.json \
+# --update-expression "SET #ads = :a, #kds = :k" | jq .
+
+
+aws \
+dynamodb \
+get-item \
+--table-name ${TABLE_NAME} \
+--key file://update_item_key.json \
+--projection-expression "addresses[0].street" | jq .

+ 7 - 0
06/demos/batch_get_items.json

@@ -0,0 +1,7 @@
+{
+  "elaborate_employee_table": {
+    "Keys": [
+      {"id": {"N":"1363"}}
+    ]
+  }
+}

+ 17 - 0
06/demos/batch_write_items.json

@@ -0,0 +1,17 @@
+{
+  "elaborate_employee_table": [
+    {
+      "PutRequest": {
+        "Item": {
+          "id": {"N":"100"},
+          "status": {"S": "batch write operation here"}
+        }
+      }
+    },
+    {
+      "DeleteRequest": {
+        "Key": {"id": {"N":"1363"}}
+      }
+    }
+  ]
+}

+ 27 - 0
06/demos/modify_conditionally_item.json

@@ -0,0 +1,27 @@
+{
+  "id": {
+    "N": "10"
+  },
+  "contract_type": {
+    "S": "permanent"
+  },
+  "name": {
+    "S": "Robin"
+  },
+  "position": {
+    "S": "data scientist"
+  },
+  "address": {
+    "M": {
+      "country": {
+        "S": "Milky Way"
+      },
+      "number": {
+        "N": "12"
+      },
+      "street": {
+        "S": "Planet"
+      }
+    }
+  }
+}

+ 14 - 0
06/demos/modify_conditionally_item_overwrite.json

@@ -0,0 +1,14 @@
+{
+  "id": {
+    "N": "10"
+  },
+  "contract_type": {
+    "S": "intern"
+  },
+  "name": {
+    "S": "Jane"
+  },
+  "position": {
+    "S": "HR"
+  }
+}

+ 6 - 0
06/demos/modify_conditionally_names.json

@@ -0,0 +1,6 @@
+{
+  "#ec": "emergency_contact",
+  "#ct": "contract_type",
+  "#ad": "address",
+  "#st": "street"
+}

+ 4 - 0
06/demos/modify_conditionally_values.json

@@ -0,0 +1,4 @@
+{
+  ":ecn":{"N":"0123456789"},
+  ":ctv":{"S":"permanent"}
+}

+ 11 - 0
06/demos/put_item.json

@@ -0,0 +1,11 @@
+{
+  "id": {
+    "N": "157"
+  },
+  "name": {
+    "S": "Peter"
+  },
+  "position": {
+    "S": "DevOps"
+  }
+}

+ 33 - 0
06/demos/put_item_list.json

@@ -0,0 +1,33 @@
+{
+  "id": {
+    "N": "156"
+  },
+  "last_accessed": {
+    "N": "20191208"
+  },
+  "prices": {
+    "L": [
+      {
+        "M": {
+          "bed": {
+            "N": "400"
+          }
+        }
+      },
+      {
+        "M": {
+          "pillow": {
+            "N": "50"
+          }
+        }
+      },
+      {
+        "M": {
+          "sheets": {
+            "N": "100"
+          }
+        }
+      }
+    ]
+  }
+}

+ 17 - 0
06/demos/put_item_recovery.json

@@ -0,0 +1,17 @@
+{
+  "id": {
+    "N": "156"
+},
+  "name": {
+    "S": "Robert"
+},
+  "position": {
+    "S": "office coordinator"
+},
+  "contract_type": {
+    "S": "permanent"
+},
+  "last_accessed": {
+    "N": "20190506"
+  }
+}

+ 3 - 0
06/demos/query_attr_names.json

@@ -0,0 +1,3 @@
+{
+  "#i":"id"
+}

+ 3 - 0
06/demos/query_attr_values.json

@@ -0,0 +1,3 @@
+{
+  ":n": {"N":"100"}
+}

+ 1 - 0
06/demos/update_item_atomic_key.json

@@ -0,0 +1 @@
+{"id": {"N": "20"}}

+ 3 - 0
06/demos/update_item_atomic_values.json

@@ -0,0 +1,3 @@
+{
+  ":incr": {"N": "1"}
+}

+ 4 - 0
06/demos/update_item_expression_names.json

@@ -0,0 +1,4 @@
+{
+  "#ads": "addresses",
+  "#kds": "kids"
+}

+ 3 - 0
06/demos/update_item_key.json

@@ -0,0 +1,3 @@
+{
+    "id": {"N": "100"}
+}

+ 26 - 0
06/demos/update_item_values.json

@@ -0,0 +1,26 @@
+{
+  ":a": {
+    "L": [
+      {
+        "M": {
+          "street": {"S": "Planet"},
+          "number": {"N": "12"},
+          "country": {"S": "Milky Way"}}},
+      {
+        "M": {
+          "street": {"S": "Cosmic"},
+          "number": {"N": "32"},
+          "country": {"S": "Milky Way"}}},
+      {
+        "M": {
+          "street": {"S": "Saturn"},
+          "number": {"N": "13"},
+          "country": {"S": "Andromeda"}}}]},
+  ":k": {
+    "L": [
+      {"S": "Jane"},
+      {"S": "Peter"},
+      {"S": "Lucy"},
+      {"S": "Andy"}]
+  }
+}

BIN
06/handling-dynamodb-objects-slides.pdf


+ 54 - 0
5-2.json

@@ -0,0 +1,54 @@
+{
+  "version": "0",
+  "id": "5abe92b9-59e4-54fe-64ff-fbb72302dc71",
+  "detail-type": "AWS API Call via CloudTrail",
+  "source": "aws.dynamodb",
+  "account": "751146239996",
+  "time": "2022-04-09T16:55:28Z",
+  "region": "eu-west-1",
+  "resources": [],
+  "detail": {
+    "eventVersion": "1.08",
+    "userIdentity": {
+      "type": "Root",
+      "principalId": "751146239996",
+      "arn": "arn:aws:iam::751146239996:root",
+      "accountId": "751146239996",
+      "accessKeyId": "ASIA25Y6OA76GKPIGLFJ",
+      "userName": "osinet",
+      "sessionContext": {
+        "attributes": {
+          "creationDate": "2022-04-09T16:27:26Z",
+          "mfaAuthenticated": "false"
+        }
+      }
+    },
+    "eventTime": "2022-04-09T16:55:28Z",
+    "eventSource": "dynamodb.amazonaws.com",
+    "eventName": "ListContributorInsights",
+    "awsRegion": "eu-west-1",
+    "sourceIPAddress": "AWS Internal",
+    "userAgent": "AWS Internal",
+    "requestParameters": {
+      "tableName": "elaborate_employee_table",
+      "maxResults": 0.0
+    },
+    "responseElements": null,
+    "requestID": "OUN1QNU5KURNRKGRN06L723CTNVV4KQNSO5AEMVJF66Q9ASUAAJG",
+    "eventID": "dfac9cac-fbb3-4d79-bf88-a35ed95ee49d",
+    "readOnly": false,
+    "resources": [
+      {
+        "accountId": "751146239996",
+        "type": "AWS::DynamoDB::Table",
+        "ARN": "arn:aws:dynamodb:eu-west-1:751146239996:table/elaborate_employee_table"
+      }
+    ],
+    "eventType": "AwsApiCall",
+    "apiVersion": "2012-08-10",
+    "managementEvent": true,
+    "recipientAccountId": "751146239996",
+    "eventCategory": "Management",
+    "sessionCredentialFromConsole": "true"
+  }
+}

+ 53 - 0
5-3.json

@@ -0,0 +1,53 @@
+{
+  "version": "0",
+  "id": "d8e0d348-5fa5-5a73-eda8-fd6aa9890489",
+  "detail-type": "AWS API Call via CloudTrail",
+  "source": "aws.dynamodb",
+  "account": "751146239996",
+  "time": "2022-04-09T16:55:29Z",
+  "region": "eu-west-1",
+  "resources": [],
+  "detail": {
+    "eventVersion": "1.08",
+    "userIdentity": {
+      "type": "Root",
+      "principalId": "751146239996",
+      "arn": "arn:aws:iam::751146239996:root",
+      "accountId": "751146239996",
+      "accessKeyId": "ASIA25Y6OA76GKPIGLFJ",
+      "userName": "osinet",
+      "sessionContext": {
+        "attributes": {
+          "creationDate": "2022-04-09T16:27:26Z",
+          "mfaAuthenticated": "false"
+        }
+      }
+    },
+    "eventTime": "2022-04-09T16:55:29Z",
+    "eventSource": "dynamodb.amazonaws.com",
+    "eventName": "DescribeKinesisStreamingDestination",
+    "awsRegion": "eu-west-1",
+    "sourceIPAddress": "AWS Internal",
+    "userAgent": "AWS Internal",
+    "requestParameters": {
+      "tableName": "elaborate_employee_table"
+    },
+    "responseElements": null,
+    "requestID": "L7GNB9KRFM5GAVN1GMSEHLFO7NVV4KQNSO5AEMVJF66Q9ASUAAJG",
+    "eventID": "d3004564-e5e8-4881-b63b-6bbe50f8f599",
+    "readOnly": false,
+    "resources": [
+      {
+        "accountId": "751146239996",
+        "type": "AWS::DynamoDB::Table",
+        "ARN": "arn:aws:dynamodb:eu-west-1:751146239996:table/elaborate_employee_table"
+      }
+    ],
+    "eventType": "AwsApiCall",
+    "apiVersion": "2012-08-10",
+    "managementEvent": true,
+    "recipientAccountId": "751146239996",
+    "eventCategory": "Management",
+    "sessionCredentialFromConsole": "true"
+  }
+}

+ 59 - 0
5-4.json

@@ -0,0 +1,59 @@
+{
+  "version": "0",
+  "id": "161a3c11-8b3a-4734-4a1b-7ec222d9fa6c",
+  "detail-type": "AWS API Call via CloudTrail",
+  "source": "aws.dynamodb",
+  "account": "751146239996",
+  "time": "2022-04-09T16:55:45Z",
+  "region": "eu-west-1",
+  "resources": [],
+  "detail": {
+    "eventVersion": "1.08",
+    "userIdentity": {
+      "type": "Root",
+      "principalId": "751146239996",
+      "arn": "arn:aws:iam::751146239996:root",
+      "accountId": "751146239996",
+      "accessKeyId": "ASIA25Y6OA76GKPIGLFJ",
+      "userName": "osinet",
+      "sessionContext": {
+        "attributes": {
+          "creationDate": "2022-04-09T16:27:26Z",
+          "mfaAuthenticated": "false"
+        }
+      }
+    },
+    "eventTime": "2022-04-09T16:55:45Z",
+    "eventSource": "dynamodb.amazonaws.com",
+    "eventName": "UpdateTimeToLive",
+    "awsRegion": "eu-west-1",
+    "sourceIPAddress": "AWS Internal",
+    "userAgent": "AWS Internal",
+    "errorCode": "ValidationException",
+    "errorMessage": "Time to live has been modified multiple times within a fixed interval",
+    "requestParameters": {
+      "tableName": "elaborate_employee_table",
+      "timeToLiveSpecification": {
+        "attributeName": "expire",
+        "enabled": true
+      }
+    },
+    "responseElements": null,
+    "requestID": "LHR2N5IDJJLI4KJN35VGPKEO47VV4KQNSO5AEMVJF66Q9ASUAAJG",
+    "eventID": "24e350e3-50cf-4ef6-886b-8dacf0f17ebd",
+    "readOnly": false,
+    "resources": [
+      {
+        "accountId": "751146239996",
+        "type": "AWS::DynamoDB::Table",
+        "ARN": "arn:aws:dynamodb:eu-west-1:751146239996:table/elaborate_employee_table"
+      }
+    ],
+    "eventType": "AwsApiCall",
+    "apiVersion": "2012-08-10",
+    "managementEvent": true,
+    "recipientAccountId": "751146239996",
+    "eventCategory": "Management",
+    "sessionCredentialFromConsole": "true"
+  }
+}

+ 62 - 0
5-5.json

@@ -0,0 +1,62 @@
+{
+  "version": "0",
+  "id": "918147a9-6ef2-690c-68c3-0b99f681712c",
+  "detail-type": "AWS API Call via CloudTrail",
+  "source": "aws.dynamodb",
+  "account": "751146239996",
+  "time": "2022-04-09T16:55:38Z",
+  "region": "eu-west-1",
+  "resources": [],
+  "detail": {
+    "eventVersion": "1.08",
+    "userIdentity": {
+      "type": "Root",
+      "principalId": "751146239996",
+      "arn": "arn:aws:iam::751146239996:root",
+      "accountId": "751146239996",
+      "accessKeyId": "ASIA25Y6OA76GKPIGLFJ",
+      "userName": "osinet",
+      "sessionContext": {
+        "attributes": {
+          "creationDate": "2022-04-09T16:27:26Z",
+          "mfaAuthenticated": "false"
+        }
+      }
+    },
+    "eventTime": "2022-04-09T16:55:38Z",
+    "eventSource": "dynamodb.amazonaws.com",
+    "eventName": "UpdateTimeToLive",
+    "awsRegion": "eu-west-1",
+    "sourceIPAddress": "AWS Internal",
+    "userAgent": "AWS Internal",
+    "requestParameters": {
+      "tableName": "elaborate_employee_table",
+      "timeToLiveSpecification": {
+        "attributeName": "employment_expiry",
+        "enabled": false
+      }
+    },
+    "responseElements": {
+      "timeToLiveSpecification": {
+        "attributeName": "employment_expiry",
+        "enabled": false
+      }
+    },
+    "requestID": "HFRK9GB1ILSK9T59GN0OEDGR9JVV4KQNSO5AEMVJF66Q9ASUAAJG",
+    "eventID": "6a6d59fe-edd2-420f-bbf2-41a989ae7591",
+    "readOnly": false,
+    "resources": [
+      {
+        "accountId": "751146239996",
+        "type": "AWS::DynamoDB::Table",
+        "ARN": "arn:aws:dynamodb:eu-west-1:751146239996:table/elaborate_employee_table"
+      }
+    ],
+    "eventType": "AwsApiCall",
+    "apiVersion": "2012-08-10",
+    "managementEvent": true,
+    "recipientAccountId": "751146239996",
+    "eventCategory": "Management",
+    "sessionCredentialFromConsole": "true"
+  }
+}

+ 109 - 0
5-createtable-event.json

@@ -0,0 +1,109 @@
+{
+  "version": "0",
+  "id": "2487ab8e-b9ab-5561-6ab1-260c97fa0f5d",
+  "detail-type": "AWS API Call via CloudTrail",
+  "source": "aws.dynamodb",
+  "account": "751146239996",
+  "time": "2022-04-09T16:52:54Z",
+  "region": "eu-west-1",
+  "resources": [],
+  "detail": {
+    "eventVersion": "1.08",
+    "userIdentity": {
+      "type": "Root",
+      "principalId": "751146239996",
+      "arn": "arn:aws:iam::751146239996:root",
+      "accountId": "751146239996",
+      "accessKeyId": "ASIA25Y6OA76GKPIGLFJ",
+      "userName": "osinet",
+      "sessionContext": {
+        "attributes": {
+          "creationDate": "2022-04-09T16:27:26Z",
+          "mfaAuthenticated": "false"
+        }
+      }
+    },
+    "eventTime": "2022-04-09T16:52:54Z",
+    "eventSource": "dynamodb.amazonaws.com",
+    "eventName": "CreateTable",
+    "awsRegion": "eu-west-1",
+    "sourceIPAddress": "AWS Internal",
+    "userAgent": "AWS Internal",
+    "requestParameters": {
+      "attributeDefinitions": [
+        {
+          "attributeType": "S",
+          "attributeName": "name"
+        }
+      ],
+      "tableName": "eventbridge_events",
+      "keySchema": [
+        {
+          "keyType": "HASH",
+          "attributeName": "name"
+        }
+      ],
+      "billingMode": "PAY_PER_REQUEST",
+      "tags": [
+        {
+          "key": "temporary",
+          "value": "22D"
+        }
+      ],
+      "tableClass": "STANDARD"
+    },
+    "responseElements": {
+      "tableDescription": {
+        "tableId": "8de0050e-6f04-43c9-a63a-2793e175c539",
+        "attributeDefinitions": [
+          {
+            "attributeType": "S",
+            "attributeName": "name"
+          }
+        ],
+        "tableName": "eventbridge_events",
+        "tableThroughputModeSummary": {
+          "tableThroughputMode": "PAY_PER_REQUEST"
+        },
+        "itemCount": 0.0,
+        "creationDateTime": "Apr 9, 2022, 4:52:54 PM",
+        "provisionedThroughput": {
+          "readCapacityUnits": 0.0,
+          "writeCapacityUnits": 0.0,
+          "numberOfDecreasesToday": 0.0
+        },
+        "billingModeSummary": {
+          "billingMode": "PAY_PER_REQUEST"
+        },
+        "tableSizeBytes": 0.0,
+        "tableStatus": "CREATING",
+        "keySchema": [
+          {
+            "keyType": "HASH",
+            "attributeName": "name"
+          }
+        ],
+        "tableArn": "arn:aws:dynamodb:eu-west-1:751146239996:table/eventbridge_events",
+        "tableClassSummary": {
+          "tableClass": "STANDARD"
+        }
+      }
+    },
+    "requestID": "S3U5FMDOGHFVBIMO7IHN39QGGFVV4KQNSO5AEMVJF66Q9ASUAAJG",
+    "eventID": "55e86fd6-db57-49fe-9e68-631931fe1020",
+    "readOnly": false,
+    "resources": [
+      {
+        "accountId": "751146239996",
+        "type": "AWS::DynamoDB::Table",
+        "ARN": "arn:aws:dynamodb:eu-west-1:751146239996:table/eventbridge_events"
+      }
+    ],
+    "eventType": "AwsApiCall",
+    "apiVersion": "2012-08-10",
+    "managementEvent": true,
+    "recipientAccountId": "751146239996",
+    "eventCategory": "Management",
+    "sessionCredentialFromConsole": "true"
+  }
+}

+ 7 - 0
5-monitoring.md

@@ -0,0 +1,7 @@
+# 5. Monitoring
+## 5.5 Monitoring DDB tables changes
+
+- CloudWatch Events is now Amazon EventBridge
+- To create an even in EB (vs CW Events), you start by the name instead of the source
+
+## 5.6 Create passive monitoring