Skip to content
Snippets Groups Projects
Commit 99541fd6 authored by Edouard DE BRYE's avatar Edouard DE BRYE
Browse files

Merge branch 'feature/add-dynamo-db-backend' into 'master'

Feature/add dynamo db backend

See merge request edebrye/cloud-monitor!4
parents 03fe97f9 762f8368
No related branches found
No related tags found
No related merge requests found
......@@ -33,4 +33,6 @@ override.tf.json
.terraformrc
terraform.rc
*.zip
\ No newline at end of file
*.zip
test/
**/node_modules/*
\ No newline at end of file
......@@ -2,8 +2,11 @@
# Manual edits may be lost in future updates.
provider "registry.terraform.io/hashicorp/archive" {
version = "2.1.0"
version = "2.1.0"
constraints = ">= 2.1.0"
hashes = [
"h1:K4Q9hmTnCrGbXZBq2hf6CbekHx5oXFwPBmWOwAPNqtM=",
"h1:Rjd4bHMA69V+16tiriAUTW8vvqoljzNLmEaRBCgzpUs=",
"h1:f3WXKM/FBu5EMY6j2BGt982hzVMNicrxTyEAz5EsrOU=",
"zh:033279ecbf60f565303222e9a6d26b50fdebe43aa1c6e8f565f09bb64d67c3fd",
"zh:0af998e42eb421c92e87202df5bfee436b3cfe553214394f08d786c72a9e3f70",
......@@ -23,6 +26,8 @@ provider "registry.terraform.io/hashicorp/aws" {
version = "3.30.0"
constraints = ">= 3.30.0"
hashes = [
"h1:H1Vg0BX4XMIQAE6NEOR95wst+ETcrv/tSwz+m04rszE=",
"h1:PmKa3uxO2mDA5FJfGmpX+4e0x70vFLV5Ka9NxkuMpUo=",
"h1:z9kdXY2A/+dIZrPy9hNlg/B5I/AuETQsp0jz9EgprIQ=",
"zh:01f562a6a31fe46a8ca74804f360e3452b26f71abc549ce1f0ab5a8af2484cdf",
"zh:25bacc5ed725051f0ab1f7d575e45c901e5b8e1d50da4156a31dda92b2b7e481",
......@@ -37,3 +42,20 @@ provider "registry.terraform.io/hashicorp/aws" {
"zh:ffcc43b6c5e7f26c55e2a8c539d7370fca8042722400a3e06bdce4240bd7088a",
]
}
provider "registry.terraform.io/hashicorp/template" {
version = "2.2.0"
hashes = [
"h1:94qn780bi1qjrbC3uQtjJh3Wkfwd5+tTtJHOb7KTg9w=",
"zh:01702196f0a0492ec07917db7aaa595843d8f171dc195f4c988d2ffca2a06386",
"zh:09aae3da826ba3d7df69efeb25d146a1de0d03e951d35019a0f80e4f58c89b53",
"zh:09ba83c0625b6fe0a954da6fbd0c355ac0b7f07f86c91a2a97849140fea49603",
"zh:0e3a6c8e16f17f19010accd0844187d524580d9fdb0731f675ffcf4afba03d16",
"zh:45f2c594b6f2f34ea663704cc72048b212fe7d16fb4cfd959365fa997228a776",
"zh:77ea3e5a0446784d77114b5e851c970a3dde1e08fa6de38210b8385d7605d451",
"zh:8a154388f3708e3df5a69122a23bdfaf760a523788a5081976b3d5616f7d30ae",
"zh:992843002f2db5a11e626b3fc23dc0c87ad3729b3b3cff08e32ffb3df97edbde",
"zh:ad906f4cebd3ec5e43d5cd6dc8f4c5c9cc3b33d2243c89c5fc18f97f7277b51d",
"zh:c979425ddb256511137ecd093e23283234da0154b7fa8b21c2687182d9aea8b2",
]
}
resource "aws_dynamodb_table" "main" {
name = "${local.prefix}-main-db"
hash_key = "ID"
billing_mode = "PROVISIONED"
write_capacity = 5
read_capacity = 5
attribute {
name = "ID"
type = "S"
}
tags = local.common_tags
}
\ No newline at end of file
variable "lambda_filename" {
default = "hello/index.js"
type = string
}
variable "lambda_loc" {
default = "lambda"
type = string
}
variable "layer_name" {
type = string
default = "LambdaInsightsExtension"
locals {
lambda_loc = "${path.module}/lambda"
}
resource "aws_lambda_function" "test_lambda" {
filename = data.archive_file.lambda_file.output_path
function_name = "${local.prefix}-hello"
for_each = local.files
filename = data.archive_file.lambda_file[each.key].output_path
function_name = "${local.prefix}-${each.key}-crud-dynamodb"
role = aws_iam_role.iam_for_lambda.arn
handler = "index.handler"
handler = "${each.key}.handler"
timeout = 10
# The filebase64sha256() function is available in Terraform 0.11.12 and later
# For Terraform 0.11.11 and earlier, use the base64sha256() function and the file() function:
# source_code_hash = "${base64sha256(file("lambda_function_payload.zip"))}"
source_code_hash = filebase64sha256(data.archive_file.lambda_file.output_path)
source_code_hash = filebase64sha256(data.archive_file.lambda_file[each.key].output_path)
runtime = "nodejs12.x"
reserved_concurrent_executions = 2
layers = [
"arn:aws:lambda:eu-west-1:580247275435:layer:LambdaInsightsExtension:14"
]
environment {
variables = {
TABLE_NAME = aws_dynamodb_table.main.name
TABLE_KEY = aws_dynamodb_table.main.hash_key
}
}
tags = local.common_tags
depends_on = [
......@@ -63,7 +61,15 @@ resource "aws_iam_role_policy_attachment" "lambda_insights" {
}
data "archive_file" "lambda_file" {
for_each = local.files
type = "zip"
source_file = "${var.lambda_loc}/${var.lambda_filename}"
output_path = "${var.lambda_loc}/lambda.zip"
output_path = "${local.lambda_loc}/${each.key}.zip"
source_file = "${local.lambda_loc}/hello/${each.key}.js"
}
locals{
files = toset([
for f in fileset("${local.lambda_loc}/hello", "*.js") :
replace(f, ".js", "")
])
}
\ No newline at end of file
const AWS = require('aws-sdk');
const db = new AWS.DynamoDB.DocumentClient();
const {v4:uuidv4} = require('uuid');
const TABLE_NAME = process.env.TABLE_NAME || '';
const PRIMARY_KEY = process.env.TABLE_KEY || '';
const RESERVED_RESPONSE = `Error: You're using AWS reserved keywords as attributes`, DYNAMODB_EXECUTION_ERROR = `Error: Execution update, caused a Dynamodb error, please take a look at your CloudWatch Logs.`;
exports.handler = async (event = {}) => {
if (!event.body) {
return { statusCode: 400, body: 'invalid request, you are missing the parameter body' };
}
const item = typeof event.body == 'object' ? event.body : JSON.parse(event.body);
item[PRIMARY_KEY] = uuidv4();
const params = {
TableName: TABLE_NAME,
Item: item
};
try {
await db.put(params).promise();
return { statusCode: 201, body: { id:item[PRIMARY_KEY] } };
}
catch (dbError) {
const errorResponse = dbError.code === 'ValidationException' && dbError.message.includes('reserved keyword') ?
DYNAMODB_EXECUTION_ERROR : RESERVED_RESPONSE;
return { statusCode: 500, body: errorResponse };
}
};
\ No newline at end of file
const AWS = require('aws-sdk');
const db = new AWS.DynamoDB.DocumentClient();
const TABLE_NAME = process.env.TABLE_NAME || '';
const PRIMARY_KEY = process.env.TABLE_KEY || '';
exports.handler = async (event = {}) => {
const requestedItemId = event.pathParameters.id;
if (!requestedItemId) {
return { statusCode: 400, body: `Error: You are missing the path parameter id` };
}
const params = {
TableName: TABLE_NAME,
Key: {
[PRIMARY_KEY]: requestedItemId
}
};
try {
await db.delete(params).promise();
return { statusCode: 200, body: '' };
}
catch (dbError) {
return { statusCode: 500, body: JSON.stringify(dbError) };
}
};
\ No newline at end of file
const AWS = require('aws-sdk');
const db = new AWS.DynamoDB.DocumentClient();
const TABLE_NAME = process.env.TABLE_NAME || '';
const PRIMARY_KEY = process.env.TABLE_KEY || '';
exports.handler = async (event = {}) => {
const requestedItemId = event.pathParameters.id;
if (!requestedItemId) {
return { statusCode: 400, body: `Error: You are missing the path parameter id` };
}
const params = {
TableName: TABLE_NAME,
Key: {
[PRIMARY_KEY]: requestedItemId
}
};
console.log({params:params})
try {
const response = await db.get(params).promise();
return { statusCode: 200, body: JSON.stringify(response.Item) };
}
catch (dbError) {
return { statusCode: 500, body: JSON.stringify(dbError) };
}
};
\ No newline at end of file
const vars = {};
vars.dynamodb_table = process.env.TABLE_NAME
vars.dynamodb_key = process.env.TABLE_KEY
exports.handler = async (event,context) => {
// TODO implement
console.log("ENVIRONMENT VARIABLES\n" + JSON.stringify(process.env, null, 2))
console.info("EVENT\n" + JSON.stringify(event, null, 2))
console.warn("Event not processed.")
console.log("CONTEXT\n" + JSON.stringify(context,null,2))
console.log("VARIABLES\n" + JSON.stringify(vars,null,2))
const res = {}
const response = {
statusCode: 200,
body: JSON.stringify('Hello from Lambda!'),
logStream: context.logStreamName
};
statusCode: 200,
body: JSON.stringify('Hello from Lambda!'),
logStream: context.logStreamName,
message:res
};
return response;
};
};
\ No newline at end of file
{
"requires": true,
"lockfileVersion": 1,
"dependencies": {
"uuid": {
"version": "8.3.2",
"resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz",
"integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg=="
}
}
}
const AWS = require('aws-sdk');
const db = new AWS.DynamoDB.DocumentClient();
const TABLE_NAME = process.env.TABLE_NAME || '';
const PRIMARY_KEY = process.env.TABLE_KEY || '';
const RESERVED_RESPONSE = `Error: You're using AWS reserved keywords as attributes`, DYNAMODB_EXECUTION_ERROR = `Error: Execution update, caused a Dynamodb error, please take a look at your CloudWatch Logs.`;
export const handler = async (event = {}) => {
if (!event.body) {
return { statusCode: 400, body: 'invalid request, you are missing the parameter body' };
}
const editedItemId = event.pathParameters.id;
if (!editedItemId) {
return { statusCode: 400, body: 'invalid request, you are missing the path parameter id' };
}
const editedItem = typeof event.body == 'object' ? event.body : JSON.parse(event.body);
const editedItemProperties = Object.keys(editedItem);
if (!editedItem || editedItemProperties.length < 1) {
return { statusCode: 400, body: 'invalid request, no arguments provided' };
}
const firstProperty = editedItemProperties.splice(0, 1);
const params = {
TableName: TABLE_NAME,
Key: {
[PRIMARY_KEY]: editedItemId
},
UpdateExpression: `set ${firstProperty} = :${firstProperty}`,
ExpressionAttributeValues: {},
ReturnValues: 'UPDATED_NEW'
};
params.ExpressionAttributeValues[`:${firstProperty}`] = editedItem[`${firstProperty}`];
editedItemProperties.forEach(property => {
params.UpdateExpression += `, ${property} = :${property}`;
params.ExpressionAttributeValues[`:${property}`] = editedItem[property];
});
try {
await db.update(params).promise();
return { statusCode: 204, body: '' };
}
catch (dbError) {
const errorResponse = dbError.code === 'ValidationException' && dbError.message.includes('reserved keyword') ?
DYNAMODB_EXECUTION_ERROR : RESERVED_RESPONSE;
return { statusCode: 500, body: errorResponse };
}
};
\ No newline at end of file
......@@ -13,6 +13,11 @@ terraform {
version = ">= 3.30.0"
source = "hashicorp/aws"
}
archive = {
version = ">=2.1.0"
source = "hashicorp/archive"
}
}
}
......@@ -30,14 +35,4 @@ locals {
}
}
data "aws_region" "current" {}
resource "aws_vpc" "main" {
cidr_block = "10.0.0.0/16"
instance_tenancy = "default"
tags = merge(
local.common_tags,
map("Name", "${local.prefix}-main")
)
}
\ No newline at end of file
data "aws_region" "current" {}
\ No newline at end of file
......@@ -9,6 +9,19 @@
],
"Resource": "arn:aws:logs:*:*:*",
"Effect": "Allow"
},
{
"Action":[
"dynamodb:*",
"kms:Encrypt",
"kms:Decrypt",
"kms:ReEncrypt*",
"kms:GenerateDataKey*",
"kms:CreateGrant",
"kms:DescribeKey"
],
"Resource":"*",
"Effect":"Allow"
}
]
}
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment