From 253c9aa03826f2fd2d04dd972e86a4babab9b912 Mon Sep 17 00:00:00 2001 From: Phuong H Date: Fri, 30 Nov 2018 12:25:13 +0700 Subject: [PATCH 1/4] Init project --- main.tf | 38 ++++++++++++++++++++++++++++ outputs.tf | 23 +++++++++++++++++ src/basic_auth.js | 59 +++++++++++++++++++++++++++++++++++++++++++ sts_role.tf | 64 +++++++++++++++++++++++++++++++++++++++++++++++ vars.tf | 29 +++++++++++++++++++++ 5 files changed, 213 insertions(+) create mode 100644 main.tf create mode 100644 outputs.tf create mode 100644 src/basic_auth.js create mode 100644 sts_role.tf create mode 100644 vars.tf diff --git a/main.tf b/main.tf new file mode 100644 index 0000000..3c90198 --- /dev/null +++ b/main.tf @@ -0,0 +1,38 @@ +resource "template_dir" "this" { + source_dir = "${path.module}/src" + destination_dir = "${path.module}/.archive" + + vars { + BUCKET_NAME = "${var.bucket_name}" + BUCKET_KEY = "${var.bucket_key}" + + BASIC_USER = "${var.basic_user}" + BASIC_PWD = "${var.basic_password}" + } +} + +data "archive_file" "this" { + depends_on = [ + "template_dir.this", + ] + + type = "zip" + output_path = "${path.module}/.archive.zip" + source_dir = "${template_dir.this.destination_dir}" +} + +resource "aws_lambda_function" "this" { + description = "Basic HTTP authentication module/function" + role = "${aws_iam_role.this.arn}" + runtime = "nodejs8.10" + + filename = "${data.archive_file.this.output_path}" + source_code_hash = "${data.archive_file.this.output_base64sha256}" + + function_name = "${var.fn_name}" + handler = "basic_auth.handler" + + timeout = "3" + memory_size = 128 + publish = true +} diff --git a/outputs.tf b/outputs.tf new file mode 100644 index 0000000..e3e576f --- /dev/null +++ b/outputs.tf @@ -0,0 +1,23 @@ +output "fn_name" { + value = "${aws_lambda_function.this.function_name}" +} + +output "arn" { + value = "${aws_lambda_function.this.arn}" +} + +output "qualified_arn" { + value = "${aws_lambda_function.this.qualified_arn}" +} + +output "invoke_arn" { + value = "${aws_lambda_function.this.invoke_arn}" +} + +output "id" { + value = "${aws_lambda_function.this.id}" +} + +output "version" { + value = "${aws_lambda_function.this.version}" +} diff --git a/src/basic_auth.js b/src/basic_auth.js new file mode 100644 index 0000000..97d81af --- /dev/null +++ b/src/basic_auth.js @@ -0,0 +1,59 @@ + +const AWS = require('aws-sdk'); +const s3 = new AWS.S3(); + +//https://medium.com/@yagonobre/automatically-invalidate-cloudfront-cache-for-site-hosted-on-s3-3c7818099868 +exports.handler = async (event, context, callback) => { + const request = event.Records[0].cf.request; + const uri = request.uri; + + if (!'${BUCKET_NAME}') { + console.log(`Bucket not defined (key is empty) => ignore`); + return callback(null, request); + } + + try { + const filesStr = await readRestrictedFiles(); + if (!filesStr) { + throw new Error(`empty protect files => ignore`); + } + + const rawFiles = JSON.parse(await readRestrictedFiles()); + if (!Array.isArray(rawFiles)) { + throw new Error('${BUCKET_KEY} is not any array => ignore') + } + const files = rawFiles.map(f => f.startsWith('/') ? f : '/' + f); + if (!files.includes(uri)) { + throw new Error(uri + ` not protected`); + } + + const headers = request.headers; + + const authUser = '${BASIC_USER}'; + const authPass = '${BASIC_PWD}'; + + const authString = 'Basic ' + new Buffer(authUser + ':' + authPass).toString('base64'); + if (typeof headers.authorization === 'undefined' || headers.authorization[0].value !== authString) { + const body = 'Unauthorized'; + const response = { + status: '401', + statusDescription: 'Unauthorized', + body: body, + headers: { + 'www-authenticate': [{key: 'WWW-Authenticate', value:'Basic'}] + }, + }; + return callback(null, response); + } + } + catch(e) { + console.error(e); + } + return callback(null, request); +}; + +async function readRestrictedFiles() { + const params = { Bucket: '${BUCKET_NAME}', Key: '${BUCKET_KEY}' }; + const data = await s3.getObject(params).promise(); + return data.Body.toString(); +} \ No newline at end of file diff --git a/sts_role.tf b/sts_role.tf new file mode 100644 index 0000000..01aa13b --- /dev/null +++ b/sts_role.tf @@ -0,0 +1,64 @@ +data "aws_iam_policy_document" "sts" { + statement { + effect = "Allow" + + actions = [ + "sts:AssumeRole", + ] + + principals { + type = "Service" + + identifiers = [ + "lambda.amazonaws.com", + "edgelambda.amazonaws.com", + ] + } + } +} + +data "aws_iam_policy_document" "this" { + statement { + effect = "Allow" + + actions = [ + "s3:GetBucketLocation", + "s3:ListBucket", + "s3:GetObject", + "logs:CreateLogGroup", + "logs:CreateLogStream", + "logs:DescribeLogGroups", + "logs:DescribeLogStreams", + "logs:PutLogEvents", + "logs:GetLogEvents", + "logs:FilterLogEvents", + ] + + resources = [ + "*", + ] + } + + statement { + effect = "Allow" + + actions = [ + "lambda:GetFunction", + ] + + resources = [ + "*", + ] + } +} + +resource "aws_iam_role_policy" "this" { + name = "${local.name}" + role = "${aws_iam_role.this.id}" + policy = "${data.aws_iam_policy_document.this.json}" +} + +resource "aws_iam_role" "this" { + name = "${local.name}" + assume_role_policy = "${data.aws_iam_policy_document.sts.json}" +} diff --git a/vars.tf b/vars.tf new file mode 100644 index 0000000..73489db --- /dev/null +++ b/vars.tf @@ -0,0 +1,29 @@ +variable "fn_name" { + type = "string" + default = "terraform-aws-lambda-edge-authentication" +} + +//https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/lambda-requirements-limits.html +variable "fn_timeout" { + default = 3 +} + +variable "memory_size" { + default = 128 +} + +variable "bucket_name" { + type = "string" +} + +variable "bucket_key" { + type = "string" +} + +variable "basic_user" { + type = "string" +} + +variable "basic_password" { + type = "string" +} From d0bce95b322c5bea95f51af4c5105544fbe5b541 Mon Sep 17 00:00:00 2001 From: Phuong H Date: Fri, 30 Nov 2018 13:40:38 +0700 Subject: [PATCH 2/4] Add gitignore --- .gitignore | 3 +++ main.tf | 4 ++-- vars.tf | 2 +- 3 files changed, 6 insertions(+), 3 deletions(-) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..386c716 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +.archive/ +.idea/ +.iml \ No newline at end of file diff --git a/main.tf b/main.tf index 3c90198..385b31d 100644 --- a/main.tf +++ b/main.tf @@ -1,6 +1,6 @@ resource "template_dir" "this" { - source_dir = "${path.module}/src" - destination_dir = "${path.module}/.archive" + source_dir = "src" + destination_dir = ".archive" vars { BUCKET_NAME = "${var.bucket_name}" diff --git a/vars.tf b/vars.tf index 73489db..d075ece 100644 --- a/vars.tf +++ b/vars.tf @@ -3,7 +3,7 @@ variable "fn_name" { default = "terraform-aws-lambda-edge-authentication" } -//https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/lambda-requirements-limits.html +// Lambda limits https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/cloudfront-limits.html variable "fn_timeout" { default = 3 } From 4b5a2964bc7074396dd83b80466bb08877fc7b23 Mon Sep 17 00:00:00 2001 From: Phuong H Date: Fri, 30 Nov 2018 16:51:50 +0700 Subject: [PATCH 3/4] Add variables --- .gitignore | 2 +- main.tf | 10 +++++----- sts_role.tf | 4 ++-- vars.tf | 9 ++------- 4 files changed, 10 insertions(+), 15 deletions(-) diff --git a/.gitignore b/.gitignore index 386c716..dd49260 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,3 @@ -.archive/ +.archive* .idea/ .iml \ No newline at end of file diff --git a/main.tf b/main.tf index 385b31d..ba481de 100644 --- a/main.tf +++ b/main.tf @@ -1,6 +1,6 @@ resource "template_dir" "this" { - source_dir = "src" - destination_dir = ".archive" + source_dir = "${path.module}/src" + destination_dir = "${path.module}/.archive" vars { BUCKET_NAME = "${var.bucket_name}" @@ -29,10 +29,10 @@ resource "aws_lambda_function" "this" { filename = "${data.archive_file.this.output_path}" source_code_hash = "${data.archive_file.this.output_base64sha256}" - function_name = "${var.fn_name}" + function_name = "${var.name}" handler = "basic_auth.handler" - timeout = "3" - memory_size = 128 + timeout = "${var.fn_timeout}" + memory_size = "${var.fn_memory_size}" publish = true } diff --git a/sts_role.tf b/sts_role.tf index 01aa13b..bb6920c 100644 --- a/sts_role.tf +++ b/sts_role.tf @@ -53,12 +53,12 @@ data "aws_iam_policy_document" "this" { } resource "aws_iam_role_policy" "this" { - name = "${local.name}" + name = "${var.name}" role = "${aws_iam_role.this.id}" policy = "${data.aws_iam_policy_document.this.json}" } resource "aws_iam_role" "this" { - name = "${local.name}" + name = "${var.name}" assume_role_policy = "${data.aws_iam_policy_document.sts.json}" } diff --git a/vars.tf b/vars.tf index d075ece..305dabc 100644 --- a/vars.tf +++ b/vars.tf @@ -1,5 +1,4 @@ -variable "fn_name" { - type = "string" +variable "name" { default = "terraform-aws-lambda-edge-authentication" } @@ -8,22 +7,18 @@ variable "fn_timeout" { default = 3 } -variable "memory_size" { +variable "fn_memory_size" { default = 128 } variable "bucket_name" { - type = "string" } variable "bucket_key" { - type = "string" } variable "basic_user" { - type = "string" } variable "basic_password" { - type = "string" } From 9343ef49daeb4294474d12c8ec74812d08570179 Mon Sep 17 00:00:00 2001 From: Phuong H Date: Fri, 30 Nov 2018 16:54:19 +0700 Subject: [PATCH 4/4] Update sts role --- sts_role.tf | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sts_role.tf b/sts_role.tf index bb6920c..b42e159 100644 --- a/sts_role.tf +++ b/sts_role.tf @@ -35,7 +35,7 @@ data "aws_iam_policy_document" "this" { ] resources = [ - "*", + "arn:aws:logs:*:*:*" ] } @@ -47,7 +47,7 @@ data "aws_iam_policy_document" "this" { ] resources = [ - "*", + "${aws_lambda_function.this.arn}:*", ] } }