diff --git a/blog/config.toml b/blog/config.toml index 80398c6..44dcf57 100644 --- a/blog/config.toml +++ b/blog/config.toml @@ -1,4 +1,5 @@ -baseURL = "panaetius.io" +baseURL = "https://panaetius.io/" +# relativeURLs = true title = "panaetius.io" # theme = "panaetius-chunky-theme" theme = ["hugo-notice-admonition", "panaetius-theme"] diff --git a/infrastructure/lambda/prod-panaetius-blog-lambda/main.js b/infrastructure/lambda/prod-panaetius-blog-lambda/main.js new file mode 100644 index 0000000..8ddc9f2 --- /dev/null +++ b/infrastructure/lambda/prod-panaetius-blog-lambda/main.js @@ -0,0 +1,22 @@ +"use strict"; + +exports.handler = (event, context, callback) => { + // Extract the request from the Cloudfront event that is sent to Lambda@Edge + var request = event.Records[0].cf.request; + + // Extract the URI from the request + var oldURI = request.url; + + // Match any '/' that occurs at the end of a URI. Replace it with a default index + var newURI = oldURI.replace(/\/$, '\/index.html'/); + + // Log the URI as received by Cloudfront and the new URI to be used to fetch from the origin + console.log(`Old URI: ${oldURI}`); + console.log(`New URI: ${newURI}`); + + // Replace the received URI with the URI that includes the index page + request.uri = newURI; + + // Return to Cloudfront + return callback(null, request) +}; diff --git a/infrastructure/lambda/prod-panaetius-blog-lambda/main.zip b/infrastructure/lambda/prod-panaetius-blog-lambda/main.zip new file mode 100644 index 0000000..8913aa0 Binary files /dev/null and b/infrastructure/lambda/prod-panaetius-blog-lambda/main.zip differ diff --git a/infrastructure/main.tf b/infrastructure/main.tf index 9a3a28b..76e1ac0 100644 --- a/infrastructure/main.tf +++ b/infrastructure/main.tf @@ -1,9 +1,17 @@ +# aws config provider "aws" { region = var.region profile = var.profile version = "~> 2.66" } +provider "aws" { + alias = "us_east_1" + profile = var.profile + region = "us-east-1" +} + +# tags locals { tags = { "Project" = "panaetius-blog" @@ -11,21 +19,36 @@ locals { } } +# cloudfront module "cloudfront_s3_cdn" { - source = "git::https://github.com/cloudposse/terraform-aws-cloudfront-s3-cdn.git?ref=tags/0.23.1" - stage = var.stage - name = var.name - parent_zone_id = var.parent_zone_id - acm_certificate_arn = var.acm_certificate_arn - # log_expiration_days = var.log_expiration_days - # log_standard_transition_days = var.log_standard_transition_days + source = "git::https://github.com/cloudposse/terraform-aws-cloudfront-s3-cdn.git?ref=tags/0.23.1" + stage = var.stage + name = var.name + parent_zone_id = var.parent_zone_id + acm_certificate_arn = var.acm_certificate_arn use_regional_s3_endpoint = true origin_force_destroy = true + compress = true cors_allowed_headers = ["*"] cors_allowed_methods = ["GET", "HEAD", "PUT", "POST"] cors_allowed_origins = var.allowed_origins tags = local.tags aliases = var.aliases + index_document = "index.html" + + ordered_cache = [ + { + lambda_function_association = [ + { + event_type : "origin-request", + lambda_arn : aws_lambda_function.directory_indexes.qualified_arn, + include_body : false + } + ] + } + ] + + # this policy sets the bucket to be public for all newly created files additional_bucket_policy = <<-EOT { "Version": "2012-10-17", @@ -33,20 +56,93 @@ module "cloudfront_s3_cdn" { { "Sid":"PublicRead", "Effect":"Allow", - "Principal": "*", + "Principal":"*", "Action":["s3:GetObject"], - "Resource": "arn:aws:s3:::${module.cloudfront_s3_cdn.s3_bucket}/*" + "Resource":"arn:aws:s3:::${module.cloudfront_s3_cdn.s3_bucket}/*" } ] } EOT } -resource "aws_s3_bucket_object" "index" { - bucket = module.cloudfront_s3_cdn.s3_bucket - key = "index.html" - acl = "public-read" - source = "${path.module}/test/index.html" - content_type = "text/html" - etag = md5(file("${path.module}/test/index.html")) +# cloudfront lambda@edge + +resource "aws_s3_bucket" "lambda_s3" { + provider = aws.us_east_1 + region = var.s3_region + bucket = "${var.stage}-${var.name}-lambda-function" + acl = var.acl + tags = local.tags +} + +resource "aws_s3_bucket_object" "main" { + provider = aws.us_east_1 + bucket = aws_s3_bucket.lambda_s3.id + key = var.lambda_key + acl = var.acl + source = var.source_file +} + +resource "aws_lambda_function" "directory_indexes" { + provider = aws.us_east_1 + function_name = "${var.stage}-${var.name}-directory_indexes" + s3_bucket = aws_s3_bucket.lambda_s3.id + s3_key = var.lambda_key + handler = var.handler + runtime = var.runtime + role = aws_iam_role.lambda_role.arn + publish = true + tags = local.tags + + depends_on = [aws_iam_role_policy_attachment.lambda_logging] +} + +## Lambda iam role & policies + +resource "aws_iam_role" "lambda_role" { + name = "${var.stage}-${var.name}-lambda" + tags = local.tags + + assume_role_policy = <<-EOT + { + "Version": "2012-10-17", + "Statement": [ + { + "Effect": "Allow", + "Principal": { + "Service": [ + "lambda.amazonaws.com", + "edgelambda.amazonaws.com" + ] + }, + "Action": "sts:AssumeRole" + } + ] + } + EOT +} + +resource "aws_iam_policy" "lambda_logging" { + name = "${var.stage}-${var.name}-lambda_logging" + policy = <<-EOT + { + "Version": "2012-10-17", + "Statement": [ + { + "Action": [ + "logs:CreateLogGroup", + "logs:CreateLogStream", + "logs:PutLogEvents" + ], + "Resource": "arn:aws:logs:*:*:*", + "Effect": "Allow" + } + ] + } + EOT +} + +resource "aws_iam_role_policy_attachment" "lambda_logging" { + role = aws_iam_role.lambda_role.name + policy_arn = aws_iam_policy.lambda_logging.arn } diff --git a/infrastructure/terraform.tfstate.d/prod-eu-west-1/terraform.tfstate b/infrastructure/terraform.tfstate.d/prod-eu-west-1/terraform.tfstate index b2e19b7..4da18b0 100644 --- a/infrastructure/terraform.tfstate.d/prod-eu-west-1/terraform.tfstate +++ b/infrastructure/terraform.tfstate.d/prod-eu-west-1/terraform.tfstate @@ -1,7 +1,7 @@ { "version": 4, "terraform_version": "0.12.26", - "serial": 97, + "serial": 244, "lineage": "cda52006-90fc-4aec-a630-42e69057b365", "outputs": { "cf_arn": { @@ -13,7 +13,7 @@ "type": "string" }, "cf_etag": { - "value": "E2SEL7AYXF1CKS", + "value": "E3169NR3BVK3DJ", "type": "string" }, "cf_hosted_zone_id": { @@ -50,7 +50,7 @@ "attributes": { "id": "3493490045", "json": "{\n \"Version\": \"2012-10-17\",\n \"Statement\": [\n {\n \"Sid\": \"S3GetObjectForCloudFront\",\n \"Effect\": \"Allow\",\n \"Action\": \"s3:GetObject\",\n \"Resource\": \"arn:aws:s3:::${bucket_name}${origin_path}*\",\n \"Principal\": {\n \"AWS\": \"${cloudfront_origin_access_identity_iam_arn}\"\n }\n },\n {\n \"Sid\": \"S3ListBucketForCloudFront\",\n \"Effect\": \"Allow\",\n \"Action\": \"s3:ListBucket\",\n \"Resource\": \"arn:aws:s3:::${bucket_name}\",\n \"Principal\": {\n \"AWS\": \"${cloudfront_origin_access_identity_iam_arn}\"\n }\n },\n {\n \"Sid\": \"PublicRead\",\n \"Effect\": \"Allow\",\n \"Action\": [\n \"s3:GetObject\"\n ],\n \"Resource\": \"arn:aws:s3:::prod-panaetius-blog-origin/*\",\n \"Principal\": \"*\"\n }\n ]\n}", - "override_json": "{\n \"Version\": \"2012-10-17\",\n \"Statement\": [\n {\n \"Sid\":\"PublicRead\",\n \"Effect\":\"Allow\",\n \"Principal\": \"*\",\n \"Action\":[\"s3:GetObject\"],\n \"Resource\": \"arn:aws:s3:::prod-panaetius-blog-origin/*\"\n }\n ]\n}\n", + "override_json": "{\n \"Version\": \"2012-10-17\",\n \"Statement\": [\n {\n \"Sid\":\"PublicRead\",\n \"Effect\":\"Allow\",\n \"Principal\":\"*\",\n \"Action\":[\"s3:GetObject\"],\n \"Resource\":\"arn:aws:s3:::prod-panaetius-blog-origin/*\"\n }\n ]\n}\n", "policy_id": null, "source_json": null, "statement": [ @@ -116,7 +116,7 @@ "attributes": { "id": "736817168", "json": "{\n \"Version\": \"2012-10-17\",\n \"Statement\": [\n {\n \"Sid\": \"S3GetObjectForCloudFront\",\n \"Effect\": \"Allow\",\n \"Action\": \"s3:GetObject\",\n \"Resource\": \"arn:aws:s3:::${bucket_name}${origin_path}*\",\n \"Principal\": {\n \"AWS\": \"*\"\n }\n },\n {\n \"Sid\": \"PublicRead\",\n \"Effect\": \"Allow\",\n \"Action\": [\n \"s3:GetObject\"\n ],\n \"Resource\": \"arn:aws:s3:::prod-panaetius-blog-origin/*\",\n \"Principal\": \"*\"\n }\n ]\n}", - "override_json": "{\n \"Version\": \"2012-10-17\",\n \"Statement\": [\n {\n \"Sid\":\"PublicRead\",\n \"Effect\":\"Allow\",\n \"Principal\": \"*\",\n \"Action\":[\"s3:GetObject\"],\n \"Resource\": \"arn:aws:s3:::prod-panaetius-blog-origin/*\"\n }\n ]\n}\n", + "override_json": "{\n \"Version\": \"2012-10-17\",\n \"Statement\": [\n {\n \"Sid\":\"PublicRead\",\n \"Effect\":\"Allow\",\n \"Principal\":\"*\",\n \"Action\":[\"s3:GetObject\"],\n \"Resource\":\"arn:aws:s3:::prod-panaetius-blog-origin/*\"\n }\n ]\n}\n", "policy_id": null, "source_json": null, "statement": [ @@ -283,7 +283,7 @@ "GET", "HEAD" ], - "compress": false, + "compress": true, "default_ttl": 60, "field_level_encryption_id": "", "forwarded_values": [ @@ -303,7 +303,13 @@ "query_string_cache_keys": [] } ], - "lambda_function_association": [], + "lambda_function_association": [ + { + "event_type": "origin-request", + "include_body": false, + "lambda_arn": "arn:aws:lambda:us-east-1:745437999005:function:prod-panaetius-blog-directory_indexes:1" + } + ], "max_ttl": 31536000, "min_ttl": 0, "smooth_streaming": false, @@ -315,13 +321,13 @@ "default_root_object": "index.html", "domain_name": "d244ranky0ff54.cloudfront.net", "enabled": true, - "etag": "E2SEL7AYXF1CKS", + "etag": "E3169NR3BVK3DJ", "hosted_zone_id": "Z2FDTNDATAQYW2", "http_version": "http2", "id": "E2IHXIMPI3MZ2X", "in_progress_validation_batches": 0, "is_ipv6_enabled": true, - "last_modified_time": "2020-07-15 00:18:34.684 +0000 UTC", + "last_modified_time": "2020-07-19 01:54:58.16 +0000 UTC", "logging_config": [ { "bucket": "prod-panaetius-blog-logs.s3.amazonaws.com", @@ -378,6 +384,7 @@ }, "private": "eyJzY2hlbWFfdmVyc2lvbiI6IjEifQ==", "dependencies": [ + "aws_lambda_function.directory_indexes", "module.cloudfront_s3_cdn.aws_cloudfront_origin_access_identity.default", "module.cloudfront_s3_cdn.aws_s3_bucket.origin", "module.cloudfront_s3_cdn.module.logs.aws_s3_bucket.default" @@ -398,7 +405,7 @@ "caller_reference": "terraform-20200713232645930800000001", "cloudfront_access_identity_path": "origin-access-identity/cloudfront/E21A7YWJ1RT3K5", "comment": "prod-panaetius-blog", - "etag": "EESE0U5KF261", + "etag": "E38E5DTUJGROV", "iam_arn": "arn:aws:iam::cloudfront:user/CloudFront Origin Access Identity E21A7YWJ1RT3K5", "id": "E21A7YWJ1RT3K5", "s3_canonical_user_id": "2d7779400635ec843efe9b677769fc4f82b0d384408cf22382bf3a90540502e09e75d1346e7105b4da159515b229f39b" @@ -407,6 +414,134 @@ } ] }, + { + "mode": "managed", + "type": "aws_iam_policy", + "name": "lambda_logging", + "provider": "provider.aws", + "instances": [ + { + "schema_version": 0, + "attributes": { + "arn": "arn:aws:iam::745437999005:policy/prod-panaetius-blog-lambda_logging", + "description": "", + "id": "arn:aws:iam::745437999005:policy/prod-panaetius-blog-lambda_logging", + "name": "prod-panaetius-blog-lambda_logging", + "name_prefix": null, + "path": "/", + "policy": "{\n \"Version\": \"2012-10-17\",\n \"Statement\": [\n {\n \"Action\": [\n \"logs:CreateLogGroup\",\n \"logs:CreateLogStream\",\n \"logs:PutLogEvents\"\n ],\n \"Resource\": \"arn:aws:logs:*:*:*\",\n \"Effect\": \"Allow\"\n }\n ]\n}\n" + }, + "private": "bnVsbA==" + } + ] + }, + { + "mode": "managed", + "type": "aws_iam_role", + "name": "lambda_role", + "provider": "provider.aws", + "instances": [ + { + "schema_version": 0, + "attributes": { + "arn": "arn:aws:iam::745437999005:role/prod-panaetius-blog-lambda", + "assume_role_policy": "{\"Version\":\"2012-10-17\",\"Statement\":[{\"Effect\":\"Allow\",\"Principal\":{\"Service\":[\"lambda.amazonaws.com\",\"edgelambda.amazonaws.com\"]},\"Action\":\"sts:AssumeRole\"}]}", + "create_date": "2020-07-19T01:43:08Z", + "description": "", + "force_detach_policies": false, + "id": "prod-panaetius-blog-lambda", + "max_session_duration": 3600, + "name": "prod-panaetius-blog-lambda", + "name_prefix": null, + "path": "/", + "permissions_boundary": null, + "tags": { + "Description": "terraform resources to host the blog", + "Project": "panaetius-blog" + }, + "unique_id": "AROA23D4RF6OUVG5PVTDO" + }, + "private": "bnVsbA==" + } + ] + }, + { + "mode": "managed", + "type": "aws_iam_role_policy_attachment", + "name": "lambda_logging", + "provider": "provider.aws", + "instances": [ + { + "schema_version": 0, + "attributes": { + "id": "prod-panaetius-blog-lambda-20200719014309715500000001", + "policy_arn": "arn:aws:iam::745437999005:policy/prod-panaetius-blog-lambda_logging", + "role": "prod-panaetius-blog-lambda" + }, + "private": "bnVsbA==", + "dependencies": [ + "aws_iam_policy.lambda_logging", + "aws_iam_role.lambda_role" + ] + } + ] + }, + { + "mode": "managed", + "type": "aws_lambda_function", + "name": "directory_indexes", + "provider": "provider.aws.us_east_1", + "instances": [ + { + "schema_version": 0, + "attributes": { + "arn": "arn:aws:lambda:us-east-1:745437999005:function:prod-panaetius-blog-directory_indexes", + "dead_letter_config": [], + "description": "", + "environment": [], + "file_system_config": [], + "filename": null, + "function_name": "prod-panaetius-blog-directory_indexes", + "handler": "main.handler", + "id": "prod-panaetius-blog-directory_indexes", + "invoke_arn": "arn:aws:apigateway:us-east-1:lambda:path/2015-03-31/functions/arn:aws:lambda:us-east-1:745437999005:function:prod-panaetius-blog-directory_indexes/invocations", + "kms_key_arn": "", + "last_modified": "2020-07-19T01:48:58.316+0000", + "layers": [], + "memory_size": 128, + "publish": true, + "qualified_arn": "arn:aws:lambda:us-east-1:745437999005:function:prod-panaetius-blog-directory_indexes:1", + "reserved_concurrent_executions": -1, + "role": "arn:aws:iam::745437999005:role/prod-panaetius-blog-lambda", + "runtime": "nodejs12.x", + "s3_bucket": "prod-panaetius-blog-lambda-function", + "s3_key": "main.zip", + "s3_object_version": null, + "source_code_hash": "ltLABbdLTpAeXF5xOPf8vYj2Tq2wvINv206umQzPv0E=", + "source_code_size": 546, + "tags": { + "Description": "terraform resources to host the blog", + "Project": "panaetius-blog" + }, + "timeout": 3, + "timeouts": null, + "tracing_config": [ + { + "mode": "PassThrough" + } + ], + "version": "1", + "vpc_config": [] + }, + "private": "eyJlMmJmYjczMC1lY2FhLTExZTYtOGY4OC0zNDM2M2JjN2M0YzAiOnsiY3JlYXRlIjo2MDAwMDAwMDAwMDB9fQ==", + "dependencies": [ + "aws_iam_role.lambda_role", + "aws_iam_role_policy_attachment.lambda_logging", + "aws_s3_bucket.lambda_s3" + ] + } + ] + }, { "module": "module.cloudfront_s3_cdn.module.dns", "mode": "managed", @@ -601,6 +736,53 @@ } ] }, + { + "mode": "managed", + "type": "aws_s3_bucket", + "name": "lambda_s3", + "provider": "provider.aws.us_east_1", + "instances": [ + { + "schema_version": 0, + "attributes": { + "acceleration_status": "", + "acl": "private", + "arn": "arn:aws:s3:::prod-panaetius-blog-lambda-function", + "bucket": "prod-panaetius-blog-lambda-function", + "bucket_domain_name": "prod-panaetius-blog-lambda-function.s3.amazonaws.com", + "bucket_prefix": null, + "bucket_regional_domain_name": "prod-panaetius-blog-lambda-function.s3.amazonaws.com", + "cors_rule": [], + "force_destroy": false, + "grant": [], + "hosted_zone_id": "Z3AQBSTGFYJSTF", + "id": "prod-panaetius-blog-lambda-function", + "lifecycle_rule": [], + "logging": [], + "object_lock_configuration": [], + "policy": null, + "region": "us-east-1", + "replication_configuration": [], + "request_payer": "BucketOwner", + "server_side_encryption_configuration": [], + "tags": { + "Description": "terraform resources to host the blog", + "Project": "panaetius-blog" + }, + "versioning": [ + { + "enabled": false, + "mfa_delete": false + } + ], + "website": [], + "website_domain": null, + "website_endpoint": null + }, + "private": "bnVsbA==" + } + ] + }, { "module": "module.cloudfront_s3_cdn", "mode": "managed", @@ -677,32 +859,32 @@ { "mode": "managed", "type": "aws_s3_bucket_object", - "name": "index", - "provider": "provider.aws", + "name": "main", + "provider": "provider.aws.us_east_1", "instances": [ { "schema_version": 0, "attributes": { - "acl": "public-read", - "bucket": "prod-panaetius-blog-origin", + "acl": "private", + "bucket": "prod-panaetius-blog-lambda-function", "cache_control": "", "content": null, "content_base64": null, "content_disposition": "", "content_encoding": "", "content_language": "", - "content_type": "text/html", - "etag": "83350948ee374f30e5513497c69c0fe5", + "content_type": "binary/octet-stream", + "etag": "e93809f5fe6e069bfa1fbee683a28d8c", "force_destroy": false, - "id": "index.html", - "key": "index.html", + "id": "main.zip", + "key": "main.zip", "kms_key_id": null, "metadata": {}, "object_lock_legal_hold_status": "", "object_lock_mode": "", "object_lock_retain_until_date": "", "server_side_encryption": "", - "source": "./test/index.html", + "source": "./lambda/prod-panaetius-blog-lambda/main.zip", "storage_class": "STANDARD", "tags": {}, "version_id": "", @@ -710,7 +892,7 @@ }, "private": "bnVsbA==", "dependencies": [ - "module.cloudfront_s3_cdn.aws_s3_bucket.origin" + "aws_s3_bucket.lambda_s3" ] } ] @@ -729,7 +911,7 @@ "attributes": { "bucket": "prod-panaetius-blog-origin", "id": "prod-panaetius-blog-origin", - "policy": "{\n \"Version\": \"2012-10-17\",\n \"Statement\": [\n {\n \"Sid\": \"S3GetObjectForCloudFront\",\n \"Effect\": \"Allow\",\n \"Action\": \"s3:GetObject\",\n \"Resource\": \"arn:aws:s3:::prod-panaetius-blog-origin/*\",\n \"Principal\": {\n \"AWS\": \"arn:aws:iam::cloudfront:user/CloudFront Origin Access Identity E21A7YWJ1RT3K5\"\n }\n },\n {\n \"Sid\": \"S3ListBucketForCloudFront\",\n \"Effect\": \"Allow\",\n \"Action\": \"s3:ListBucket\",\n \"Resource\": \"arn:aws:s3:::prod-panaetius-blog-origin\",\n \"Principal\": {\n \"AWS\": \"arn:aws:iam::cloudfront:user/CloudFront Origin Access Identity E21A7YWJ1RT3K5\"\n }\n },\n {\n \"Sid\": \"PublicRead\",\n \"Effect\": \"Allow\",\n \"Action\": [\n \"s3:GetObject\"\n ],\n \"Resource\": \"arn:aws:s3:::prod-panaetius-blog-origin/*\",\n \"Principal\": \"*\"\n }\n ]\n}" + "policy": "{\"Version\":\"2012-10-17\",\"Statement\":[{\"Sid\":\"S3GetObjectForCloudFront\",\"Effect\":\"Allow\",\"Principal\":{\"AWS\":\"arn:aws:iam::cloudfront:user/CloudFront Origin Access Identity E21A7YWJ1RT3K5\"},\"Action\":\"s3:GetObject\",\"Resource\":\"arn:aws:s3:::prod-panaetius-blog-origin/*\"},{\"Sid\":\"S3ListBucketForCloudFront\",\"Effect\":\"Allow\",\"Principal\":{\"AWS\":\"arn:aws:iam::cloudfront:user/CloudFront Origin Access Identity E21A7YWJ1RT3K5\"},\"Action\":\"s3:ListBucket\",\"Resource\":\"arn:aws:s3:::prod-panaetius-blog-origin\"},{\"Sid\":\"PublicRead\",\"Effect\":\"Allow\",\"Principal\":\"*\",\"Action\":\"s3:GetObject\",\"Resource\":\"arn:aws:s3:::prod-panaetius-blog-origin/*\"}]}" }, "private": "bnVsbA==", "dependencies": [ diff --git a/infrastructure/terraform.tfstate.d/prod-eu-west-1/terraform.tfstate.backup b/infrastructure/terraform.tfstate.d/prod-eu-west-1/terraform.tfstate.backup index 18e8848..b5f0714 100644 --- a/infrastructure/terraform.tfstate.d/prod-eu-west-1/terraform.tfstate.backup +++ b/infrastructure/terraform.tfstate.d/prod-eu-west-1/terraform.tfstate.backup @@ -1,7 +1,7 @@ { "version": 4, "terraform_version": "0.12.26", - "serial": 95, + "serial": 242, "lineage": "cda52006-90fc-4aec-a630-42e69057b365", "outputs": { "cf_arn": { @@ -13,7 +13,7 @@ "type": "string" }, "cf_etag": { - "value": "E2SEL7AYXF1CKS", + "value": "E3169NR3BVK3DJ", "type": "string" }, "cf_hosted_zone_id": { @@ -48,9 +48,9 @@ { "schema_version": 0, "attributes": { - "id": "1149999058", - "json": "{\n \"Version\": \"2012-10-17\",\n \"Statement\": [\n {\n \"Sid\": \"S3GetObjectForCloudFront\",\n \"Effect\": \"Allow\",\n \"Action\": \"s3:GetObject\",\n \"Resource\": \"arn:aws:s3:::${bucket_name}${origin_path}*\",\n \"Principal\": {\n \"AWS\": \"${cloudfront_origin_access_identity_iam_arn}\"\n }\n },\n {\n \"Sid\": \"S3ListBucketForCloudFront\",\n \"Effect\": \"Allow\",\n \"Action\": \"s3:ListBucket\",\n \"Resource\": \"arn:aws:s3:::${bucket_name}\",\n \"Principal\": {\n \"AWS\": \"${cloudfront_origin_access_identity_iam_arn}\"\n }\n }\n ]\n}", - "override_json": "{}", + "id": "3493490045", + "json": "{\n \"Version\": \"2012-10-17\",\n \"Statement\": [\n {\n \"Sid\": \"S3GetObjectForCloudFront\",\n \"Effect\": \"Allow\",\n \"Action\": \"s3:GetObject\",\n \"Resource\": \"arn:aws:s3:::${bucket_name}${origin_path}*\",\n \"Principal\": {\n \"AWS\": \"${cloudfront_origin_access_identity_iam_arn}\"\n }\n },\n {\n \"Sid\": \"S3ListBucketForCloudFront\",\n \"Effect\": \"Allow\",\n \"Action\": \"s3:ListBucket\",\n \"Resource\": \"arn:aws:s3:::${bucket_name}\",\n \"Principal\": {\n \"AWS\": \"${cloudfront_origin_access_identity_iam_arn}\"\n }\n },\n {\n \"Sid\": \"PublicRead\",\n \"Effect\": \"Allow\",\n \"Action\": [\n \"s3:GetObject\"\n ],\n \"Resource\": \"arn:aws:s3:::prod-panaetius-blog-origin/*\",\n \"Principal\": \"*\"\n }\n ]\n}", + "override_json": "{\n \"Version\": \"2012-10-17\",\n \"Statement\": [\n {\n \"Sid\":\"PublicRead\",\n \"Effect\":\"Allow\",\n \"Principal\":\"*\",\n \"Action\":[\"s3:GetObject\"],\n \"Resource\":\"arn:aws:s3:::prod-panaetius-blog-origin/*\"\n }\n ]\n}\n", "policy_id": null, "source_json": null, "statement": [ @@ -114,9 +114,9 @@ { "schema_version": 0, "attributes": { - "id": "239689126", - "json": "{\n \"Version\": \"2012-10-17\",\n \"Statement\": [\n {\n \"Sid\": \"S3GetObjectForCloudFront\",\n \"Effect\": \"Allow\",\n \"Action\": \"s3:GetObject\",\n \"Resource\": \"arn:aws:s3:::${bucket_name}${origin_path}*\",\n \"Principal\": {\n \"AWS\": \"*\"\n }\n }\n ]\n}", - "override_json": "{}", + "id": "736817168", + "json": "{\n \"Version\": \"2012-10-17\",\n \"Statement\": [\n {\n \"Sid\": \"S3GetObjectForCloudFront\",\n \"Effect\": \"Allow\",\n \"Action\": \"s3:GetObject\",\n \"Resource\": \"arn:aws:s3:::${bucket_name}${origin_path}*\",\n \"Principal\": {\n \"AWS\": \"*\"\n }\n },\n {\n \"Sid\": \"PublicRead\",\n \"Effect\": \"Allow\",\n \"Action\": [\n \"s3:GetObject\"\n ],\n \"Resource\": \"arn:aws:s3:::prod-panaetius-blog-origin/*\",\n \"Principal\": \"*\"\n }\n ]\n}", + "override_json": "{\n \"Version\": \"2012-10-17\",\n \"Statement\": [\n {\n \"Sid\":\"PublicRead\",\n \"Effect\":\"Allow\",\n \"Principal\":\"*\",\n \"Action\":[\"s3:GetObject\"],\n \"Resource\":\"arn:aws:s3:::prod-panaetius-blog-origin/*\"\n }\n ]\n}\n", "policy_id": null, "source_json": null, "statement": [ @@ -234,9 +234,9 @@ "schema_version": 0, "attributes": { "filename": null, - "id": "bf2245baaea68e5cc89448356e64936cbd79d0706457d884cdd7badc903719e8", - "rendered": "{\n \"Version\": \"2012-10-17\",\n \"Statement\": [\n {\n \"Sid\": \"S3GetObjectForCloudFront\",\n \"Effect\": \"Allow\",\n \"Action\": \"s3:GetObject\",\n \"Resource\": \"arn:aws:s3:::prod-panaetius-blog-origin/*\",\n \"Principal\": {\n \"AWS\": \"arn:aws:iam::cloudfront:user/CloudFront Origin Access Identity E21A7YWJ1RT3K5\"\n }\n },\n {\n \"Sid\": \"S3ListBucketForCloudFront\",\n \"Effect\": \"Allow\",\n \"Action\": \"s3:ListBucket\",\n \"Resource\": \"arn:aws:s3:::prod-panaetius-blog-origin\",\n \"Principal\": {\n \"AWS\": \"arn:aws:iam::cloudfront:user/CloudFront Origin Access Identity E21A7YWJ1RT3K5\"\n }\n }\n ]\n}", - "template": "{\n \"Version\": \"2012-10-17\",\n \"Statement\": [\n {\n \"Sid\": \"S3GetObjectForCloudFront\",\n \"Effect\": \"Allow\",\n \"Action\": \"s3:GetObject\",\n \"Resource\": \"arn:aws:s3:::${bucket_name}${origin_path}*\",\n \"Principal\": {\n \"AWS\": \"${cloudfront_origin_access_identity_iam_arn}\"\n }\n },\n {\n \"Sid\": \"S3ListBucketForCloudFront\",\n \"Effect\": \"Allow\",\n \"Action\": \"s3:ListBucket\",\n \"Resource\": \"arn:aws:s3:::${bucket_name}\",\n \"Principal\": {\n \"AWS\": \"${cloudfront_origin_access_identity_iam_arn}\"\n }\n }\n ]\n}", + "id": "ef8d6cdd8c782d412e41e1e574ea39e8674f2d80726946a8f8dbe8ea50c1ac8b", + "rendered": "{\n \"Version\": \"2012-10-17\",\n \"Statement\": [\n {\n \"Sid\": \"S3GetObjectForCloudFront\",\n \"Effect\": \"Allow\",\n \"Action\": \"s3:GetObject\",\n \"Resource\": \"arn:aws:s3:::prod-panaetius-blog-origin/*\",\n \"Principal\": {\n \"AWS\": \"arn:aws:iam::cloudfront:user/CloudFront Origin Access Identity E21A7YWJ1RT3K5\"\n }\n },\n {\n \"Sid\": \"S3ListBucketForCloudFront\",\n \"Effect\": \"Allow\",\n \"Action\": \"s3:ListBucket\",\n \"Resource\": \"arn:aws:s3:::prod-panaetius-blog-origin\",\n \"Principal\": {\n \"AWS\": \"arn:aws:iam::cloudfront:user/CloudFront Origin Access Identity E21A7YWJ1RT3K5\"\n }\n },\n {\n \"Sid\": \"PublicRead\",\n \"Effect\": \"Allow\",\n \"Action\": [\n \"s3:GetObject\"\n ],\n \"Resource\": \"arn:aws:s3:::prod-panaetius-blog-origin/*\",\n \"Principal\": \"*\"\n }\n ]\n}", + "template": "{\n \"Version\": \"2012-10-17\",\n \"Statement\": [\n {\n \"Sid\": \"S3GetObjectForCloudFront\",\n \"Effect\": \"Allow\",\n \"Action\": \"s3:GetObject\",\n \"Resource\": \"arn:aws:s3:::${bucket_name}${origin_path}*\",\n \"Principal\": {\n \"AWS\": \"${cloudfront_origin_access_identity_iam_arn}\"\n }\n },\n {\n \"Sid\": \"S3ListBucketForCloudFront\",\n \"Effect\": \"Allow\",\n \"Action\": \"s3:ListBucket\",\n \"Resource\": \"arn:aws:s3:::${bucket_name}\",\n \"Principal\": {\n \"AWS\": \"${cloudfront_origin_access_identity_iam_arn}\"\n }\n },\n {\n \"Sid\": \"PublicRead\",\n \"Effect\": \"Allow\",\n \"Action\": [\n \"s3:GetObject\"\n ],\n \"Resource\": \"arn:aws:s3:::prod-panaetius-blog-origin/*\",\n \"Principal\": \"*\"\n }\n ]\n}", "vars": { "bucket_name": "prod-panaetius-blog-origin", "cloudfront_origin_access_identity_iam_arn": "arn:aws:iam::cloudfront:user/CloudFront Origin Access Identity E21A7YWJ1RT3K5", @@ -283,7 +283,7 @@ "GET", "HEAD" ], - "compress": false, + "compress": true, "default_ttl": 60, "field_level_encryption_id": "", "forwarded_values": [ @@ -303,7 +303,13 @@ "query_string_cache_keys": [] } ], - "lambda_function_association": [], + "lambda_function_association": [ + { + "event_type": "origin-request", + "include_body": false, + "lambda_arn": "arn:aws:lambda:us-east-1:745437999005:function:prod-panaetius-blog-directory_indexes:1" + } + ], "max_ttl": 31536000, "min_ttl": 0, "smooth_streaming": false, @@ -315,13 +321,13 @@ "default_root_object": "index.html", "domain_name": "d244ranky0ff54.cloudfront.net", "enabled": true, - "etag": "E2SEL7AYXF1CKS", + "etag": "E3169NR3BVK3DJ", "hosted_zone_id": "Z2FDTNDATAQYW2", "http_version": "http2", "id": "E2IHXIMPI3MZ2X", "in_progress_validation_batches": 0, "is_ipv6_enabled": true, - "last_modified_time": "2020-07-15 00:18:34.684 +0000 UTC", + "last_modified_time": "2020-07-19 01:54:58.16 +0000 UTC", "logging_config": [ { "bucket": "prod-panaetius-blog-logs.s3.amazonaws.com", @@ -378,6 +384,7 @@ }, "private": "eyJzY2hlbWFfdmVyc2lvbiI6IjEifQ==", "dependencies": [ + "aws_lambda_function.directory_indexes", "module.cloudfront_s3_cdn.aws_cloudfront_origin_access_identity.default", "module.cloudfront_s3_cdn.aws_s3_bucket.origin", "module.cloudfront_s3_cdn.module.logs.aws_s3_bucket.default" @@ -398,7 +405,7 @@ "caller_reference": "terraform-20200713232645930800000001", "cloudfront_access_identity_path": "origin-access-identity/cloudfront/E21A7YWJ1RT3K5", "comment": "prod-panaetius-blog", - "etag": "EESE0U5KF261", + "etag": "E38E5DTUJGROV", "iam_arn": "arn:aws:iam::cloudfront:user/CloudFront Origin Access Identity E21A7YWJ1RT3K5", "id": "E21A7YWJ1RT3K5", "s3_canonical_user_id": "2d7779400635ec843efe9b677769fc4f82b0d384408cf22382bf3a90540502e09e75d1346e7105b4da159515b229f39b" @@ -407,6 +414,134 @@ } ] }, + { + "mode": "managed", + "type": "aws_iam_policy", + "name": "lambda_logging", + "provider": "provider.aws", + "instances": [ + { + "schema_version": 0, + "attributes": { + "arn": "arn:aws:iam::745437999005:policy/prod-panaetius-blog-lambda_logging", + "description": "", + "id": "arn:aws:iam::745437999005:policy/prod-panaetius-blog-lambda_logging", + "name": "prod-panaetius-blog-lambda_logging", + "name_prefix": null, + "path": "/", + "policy": "{\n \"Version\": \"2012-10-17\",\n \"Statement\": [\n {\n \"Action\": [\n \"logs:CreateLogGroup\",\n \"logs:CreateLogStream\",\n \"logs:PutLogEvents\"\n ],\n \"Resource\": \"arn:aws:logs:*:*:*\",\n \"Effect\": \"Allow\"\n }\n ]\n}\n" + }, + "private": "bnVsbA==" + } + ] + }, + { + "mode": "managed", + "type": "aws_iam_role", + "name": "lambda_role", + "provider": "provider.aws", + "instances": [ + { + "schema_version": 0, + "attributes": { + "arn": "arn:aws:iam::745437999005:role/prod-panaetius-blog-lambda", + "assume_role_policy": "{\"Version\":\"2012-10-17\",\"Statement\":[{\"Sid\":\"\",\"Effect\":\"Allow\",\"Principal\":{\"Service\":\"lambda.amazonaws.com\"},\"Action\":\"sts:AssumeRole\"},{\"Sid\":\"\",\"Effect\":\"Allow\",\"Principal\":{\"Service\":\"edgelambda.amazonaws.com\"},\"Action\":\"sts:AssumeRole\"}]}", + "create_date": "2020-07-19T01:43:08Z", + "description": "", + "force_detach_policies": false, + "id": "prod-panaetius-blog-lambda", + "max_session_duration": 3600, + "name": "prod-panaetius-blog-lambda", + "name_prefix": null, + "path": "/", + "permissions_boundary": null, + "tags": { + "Description": "terraform resources to host the blog", + "Project": "panaetius-blog" + }, + "unique_id": "AROA23D4RF6OUVG5PVTDO" + }, + "private": "bnVsbA==" + } + ] + }, + { + "mode": "managed", + "type": "aws_iam_role_policy_attachment", + "name": "lambda_logging", + "provider": "provider.aws", + "instances": [ + { + "schema_version": 0, + "attributes": { + "id": "prod-panaetius-blog-lambda-20200719014309715500000001", + "policy_arn": "arn:aws:iam::745437999005:policy/prod-panaetius-blog-lambda_logging", + "role": "prod-panaetius-blog-lambda" + }, + "private": "bnVsbA==", + "dependencies": [ + "aws_iam_policy.lambda_logging", + "aws_iam_role.lambda_role" + ] + } + ] + }, + { + "mode": "managed", + "type": "aws_lambda_function", + "name": "directory_indexes", + "provider": "provider.aws.us_east_1", + "instances": [ + { + "schema_version": 0, + "attributes": { + "arn": "arn:aws:lambda:us-east-1:745437999005:function:prod-panaetius-blog-directory_indexes", + "dead_letter_config": [], + "description": "", + "environment": [], + "file_system_config": [], + "filename": null, + "function_name": "prod-panaetius-blog-directory_indexes", + "handler": "main.handler", + "id": "prod-panaetius-blog-directory_indexes", + "invoke_arn": "arn:aws:apigateway:us-east-1:lambda:path/2015-03-31/functions/arn:aws:lambda:us-east-1:745437999005:function:prod-panaetius-blog-directory_indexes/invocations", + "kms_key_arn": "", + "last_modified": "2020-07-19T01:48:58.316+0000", + "layers": [], + "memory_size": 128, + "publish": true, + "qualified_arn": "arn:aws:lambda:us-east-1:745437999005:function:prod-panaetius-blog-directory_indexes:1", + "reserved_concurrent_executions": -1, + "role": "arn:aws:iam::745437999005:role/prod-panaetius-blog-lambda", + "runtime": "nodejs12.x", + "s3_bucket": "prod-panaetius-blog-lambda-function", + "s3_key": "main.zip", + "s3_object_version": null, + "source_code_hash": "ltLABbdLTpAeXF5xOPf8vYj2Tq2wvINv206umQzPv0E=", + "source_code_size": 546, + "tags": { + "Description": "terraform resources to host the blog", + "Project": "panaetius-blog" + }, + "timeout": 3, + "timeouts": null, + "tracing_config": [ + { + "mode": "PassThrough" + } + ], + "version": "1", + "vpc_config": [] + }, + "private": "eyJlMmJmYjczMC1lY2FhLTExZTYtOGY4OC0zNDM2M2JjN2M0YzAiOnsiY3JlYXRlIjo2MDAwMDAwMDAwMDB9fQ==", + "dependencies": [ + "aws_iam_role.lambda_role", + "aws_iam_role_policy_attachment.lambda_logging", + "aws_s3_bucket.lambda_s3" + ] + } + ] + }, { "module": "module.cloudfront_s3_cdn.module.dns", "mode": "managed", @@ -601,6 +736,53 @@ } ] }, + { + "mode": "managed", + "type": "aws_s3_bucket", + "name": "lambda_s3", + "provider": "provider.aws.us_east_1", + "instances": [ + { + "schema_version": 0, + "attributes": { + "acceleration_status": "", + "acl": "private", + "arn": "arn:aws:s3:::prod-panaetius-blog-lambda-function", + "bucket": "prod-panaetius-blog-lambda-function", + "bucket_domain_name": "prod-panaetius-blog-lambda-function.s3.amazonaws.com", + "bucket_prefix": null, + "bucket_regional_domain_name": "prod-panaetius-blog-lambda-function.s3.amazonaws.com", + "cors_rule": [], + "force_destroy": false, + "grant": [], + "hosted_zone_id": "Z3AQBSTGFYJSTF", + "id": "prod-panaetius-blog-lambda-function", + "lifecycle_rule": [], + "logging": [], + "object_lock_configuration": [], + "policy": null, + "region": "us-east-1", + "replication_configuration": [], + "request_payer": "BucketOwner", + "server_side_encryption_configuration": [], + "tags": { + "Description": "terraform resources to host the blog", + "Project": "panaetius-blog" + }, + "versioning": [ + { + "enabled": false, + "mfa_delete": false + } + ], + "website": [], + "website_domain": null, + "website_endpoint": null + }, + "private": "bnVsbA==" + } + ] + }, { "module": "module.cloudfront_s3_cdn", "mode": "managed", @@ -677,32 +859,32 @@ { "mode": "managed", "type": "aws_s3_bucket_object", - "name": "index", - "provider": "provider.aws", + "name": "main", + "provider": "provider.aws.us_east_1", "instances": [ { "schema_version": 0, "attributes": { - "acl": "public-read", - "bucket": "prod-panaetius-blog-origin", + "acl": "private", + "bucket": "prod-panaetius-blog-lambda-function", "cache_control": "", "content": null, "content_base64": null, "content_disposition": "", "content_encoding": "", "content_language": "", - "content_type": "text/html", - "etag": "83350948ee374f30e5513497c69c0fe5", + "content_type": "binary/octet-stream", + "etag": "e93809f5fe6e069bfa1fbee683a28d8c", "force_destroy": false, - "id": "index.html", - "key": "index.html", + "id": "main.zip", + "key": "main.zip", "kms_key_id": null, "metadata": {}, "object_lock_legal_hold_status": "", "object_lock_mode": "", "object_lock_retain_until_date": "", "server_side_encryption": "", - "source": "./test/index.html", + "source": "./lambda/prod-panaetius-blog-lambda/main.zip", "storage_class": "STANDARD", "tags": {}, "version_id": "", @@ -710,7 +892,7 @@ }, "private": "bnVsbA==", "dependencies": [ - "module.cloudfront_s3_cdn.aws_s3_bucket.origin" + "aws_s3_bucket.lambda_s3" ] } ] @@ -729,7 +911,7 @@ "attributes": { "bucket": "prod-panaetius-blog-origin", "id": "prod-panaetius-blog-origin", - "policy": "{\n \"Version\": \"2012-10-17\",\n \"Statement\": [\n {\n \"Sid\": \"S3GetObjectForCloudFront\",\n \"Effect\": \"Allow\",\n \"Action\": \"s3:GetObject\",\n \"Resource\": \"arn:aws:s3:::prod-panaetius-blog-origin/*\",\n \"Principal\": {\n \"AWS\": \"arn:aws:iam::cloudfront:user/CloudFront Origin Access Identity E21A7YWJ1RT3K5\"\n }\n },\n {\n \"Sid\": \"S3ListBucketForCloudFront\",\n \"Effect\": \"Allow\",\n \"Action\": \"s3:ListBucket\",\n \"Resource\": \"arn:aws:s3:::prod-panaetius-blog-origin\",\n \"Principal\": {\n \"AWS\": \"arn:aws:iam::cloudfront:user/CloudFront Origin Access Identity E21A7YWJ1RT3K5\"\n }\n }\n ]\n}" + "policy": "{\"Version\":\"2012-10-17\",\"Statement\":[{\"Sid\":\"S3GetObjectForCloudFront\",\"Effect\":\"Allow\",\"Principal\":{\"AWS\":\"arn:aws:iam::cloudfront:user/CloudFront Origin Access Identity E21A7YWJ1RT3K5\"},\"Action\":\"s3:GetObject\",\"Resource\":\"arn:aws:s3:::prod-panaetius-blog-origin/*\"},{\"Sid\":\"S3ListBucketForCloudFront\",\"Effect\":\"Allow\",\"Principal\":{\"AWS\":\"arn:aws:iam::cloudfront:user/CloudFront Origin Access Identity E21A7YWJ1RT3K5\"},\"Action\":\"s3:ListBucket\",\"Resource\":\"arn:aws:s3:::prod-panaetius-blog-origin\"},{\"Sid\":\"PublicRead\",\"Effect\":\"Allow\",\"Principal\":\"*\",\"Action\":\"s3:GetObject\",\"Resource\":\"arn:aws:s3:::prod-panaetius-blog-origin/*\"}]}" }, "private": "bnVsbA==", "dependencies": [ diff --git a/infrastructure/variables.tf b/infrastructure/variables.tf index f6ef5db..55a7186 100644 --- a/infrastructure/variables.tf +++ b/infrastructure/variables.tf @@ -30,11 +30,26 @@ variable "allowed_origins" { } +variable "acl" { -# variable "log_expiration_days" { +} -# } +variable "lambda_key" { -# variable "log_standard_transition_days" { +} -# } +variable "source_file" { + +} + +variable "handler" { + +} + +variable "runtime" { + +} + +variable "s3_region" { + +} diff --git a/infrastructure/variables/prod-eu-west-1.tfvars b/infrastructure/variables/prod-eu-west-1.tfvars index d100a69..f2da85f 100644 --- a/infrastructure/variables/prod-eu-west-1.tfvars +++ b/infrastructure/variables/prod-eu-west-1.tfvars @@ -1,10 +1,19 @@ -name = "panaetius-blog" -region = "eu-west-1" -stage = "prod" -profile = "admin" +# module +name = "panaetius-blog" +region = "eu-west-1" +stage = "prod" +profile = "admin" + +# cloudfront acm_certificate_arn = "arn:aws:acm:us-east-1:745437999005:certificate/60af49f0-07bb-4680-8f5b-3c9a33f756e5" parent_zone_id = "Z05316671VABVSMAAF1RC" aliases = ["panaetius.io"] allowed_origins = ["*.panaetius.io"] -# log_expiration_days = 60 -# log_standard_transition_days = 60 + +# s3 & lambda +acl = "private" +lambda_key = "main.zip" +source_file = "./lambda/prod-panaetius-blog-lambda/main.zip" +handler = "main.handler" +runtime = "nodejs12.x" +s3_region = "us-east-1"