diff --git a/infra/.gitignore b/infra/.gitignore new file mode 100644 index 0000000..06ddd79 --- /dev/null +++ b/infra/.gitignore @@ -0,0 +1,3 @@ +.terraform/ +terraform.tfstate.*backup +lambda_function_payload.zip diff --git a/infra/.terraform.lock.hcl b/infra/.terraform.lock.hcl new file mode 100644 index 0000000..d962954 --- /dev/null +++ b/infra/.terraform.lock.hcl @@ -0,0 +1,44 @@ +# This file is maintained automatically by "terraform init". +# Manual edits may be lost in future updates. + +provider "registry.terraform.io/hashicorp/archive" { + version = "2.4.1" + hashes = [ + "h1:JgIo+nNySG8svjXevfoTRi0jzgHbLMDrnr55WBeRupw=", + "zh:00240c042740d18d6ba545b211ff7ed5a9e8490d30be3f865e71dba90d7a34cf", + "zh:230c285beafaffd8d60da3446157b95f8fb43b359ba94b09214c1822bf310c3d", + "zh:726672a0e61a1d39695ce5e330aa3e6caa97f2a9438cf8125360e80f4cb52fa5", + "zh:78d5eefdd9e494defcb3c68d282b8f96630502cac21d1ea161f53cfe9bb483b3", + "zh:7bc8f4a4fc7059ec01e767246df7937603dbc6ec49cb3eedffe6ecb68dbe9cb4", + "zh:800d898ce8ac96b244746c5a41f4107bd3c883fe6093d9a972a28b138ac02c4e", + "zh:9a8ea216af3840af48c08ef5ed998606c556b15be30d7b42c89a62df54285903", + "zh:b9905d0ac55b61ea78ecf0e6b07d54a9863a9f02e249d0d492e68cfcede0d89f", + "zh:c822495ba01ab7cee66c892f941097971c3be122a6200d556f462a751d446df8", + "zh:e05c31f2f4dca9eaada2726d16d2ffb03d6441b4eb55547b93d62d81383cd0ef", + "zh:ec14c68ca5d881bac73dbbd298f0ca84444001a81d473f51e36c4e29df040983", + "zh:ed32ebccb20b21c112f01d73d138ba5ada28cf8ede175441738a30711c79119a", + ] +} + +provider "registry.terraform.io/hashicorp/aws" { + version = "5.31.0" + constraints = "~> 5.0" + hashes = [ + "h1:WwgMbMOhZblxZTdjHeJf9XB2/hcSHHmpuywLxuTWYw0=", + "zh:0cdb9c2083bf0902442384f7309367791e4640581652dda456f2d6d7abf0de8d", + "zh:2fe4884cb9642f48a5889f8dff8f5f511418a18537a9dfa77ada3bcdad391e4e", + "zh:36d8bdd72fe61d816d0049c179f495bc6f1e54d8d7b07c45b62e5e1696882a89", + "zh:539dd156e3ec608818eb21191697b230117437a58587cbd02ce533202a4dd520", + "zh:6a53f4b57ac4eb3479fc0d8b6e301ca3a27efae4c55d9f8bd24071b12a03361c", + "zh:6faeb8ff6792ca7af1c025255755ad764667a300291cc10cea0c615479488c87", + "zh:7d9423149b323f6d0df5b90c4d9029e5455c670aea2a7eb6fef4684ba7eb2e0b", + "zh:8235badd8a5d0993421cacf5ead48fac73d3b5a25c8a68599706a404b1f70730", + "zh:860b4f60842b2879c5128b7e386c8b49adeda9287fed12c5cd74861bb659bbcd", + "zh:9b12af85486a96aedd8d7984b0ff811a4b42e3d88dad1a3fb4c0b580d04fa425", + "zh:b021fceaf9382c8fe3c6eb608c24d01dce3d11ba7e65bb443d51ca9b90e9b237", + "zh:b38b0bfc1c69e714e80cf1c9ea06e687ee86aa9f45694be28eb07adcebbe0489", + "zh:c972d155f6c01af9690a72adfb99cfc24ef5ef311ca92ce46b9b13c5c153f572", + "zh:e0dd29920ec84fdb6026acff44dcc1fb1a24a0caa093fa04cdbc713d384c651d", + "zh:e3127ebd2cb0374cd1808f911e6bffe2f4ac4d84317061381242353f3a7bc27d", + ] +} diff --git a/infra/apigw.tf b/infra/apigw.tf new file mode 100644 index 0000000..dd01583 --- /dev/null +++ b/infra/apigw.tf @@ -0,0 +1,96 @@ +resource "aws_apigatewayv2_api" "www" { + name = "wewerewondering" + protocol_type = "HTTP" +} + +data "aws_iam_policy_document" "apigw_assume" { + statement { + principals { + type = "Service" + identifiers = ["apigateway.amazonaws.com"] + } + actions = ["sts:AssumeRole"] + } +} + +resource "aws_iam_role" "apigw_cw" { + name = "wewerewondering-api-gw" + description = "Allows API Gateway to push logs to CloudWatch Logs." + assume_role_policy = data.aws_iam_policy_document.apigw_assume.json + managed_policy_arns = ["arn:aws:iam::aws:policy/service-role/AmazonAPIGatewayPushToCloudWatchLogs"] +} + +resource "aws_api_gateway_account" "www" { + cloudwatch_role_arn = aws_iam_role.apigw_cw.arn +} + +resource "aws_apigatewayv2_stage" "www" { + api_id = aws_apigatewayv2_api.www.id + name = "$default" + auto_deploy = true + access_log_settings { + destination_arn = aws_cloudwatch_log_group.apigw.arn + format = jsonencode({ + "requestId" : "$context.requestId", + "ip" : "$context.identity.sourceIp", + "requestTime" : "$context.requestTime", + "httpMethod" : "$context.httpMethod", + "routeKey" : "$context.routeKey", + "status" : "$context.status", + "protocol" : "$context.protocol", + "responseLength" : "$context.responseLength" + }) + } + default_route_settings { + throttling_burst_limit = 250 + throttling_rate_limit = 50 + } +} + +resource "aws_apigatewayv2_integration" "www" { + api_id = aws_apigatewayv2_api.www.id + integration_type = "AWS_PROXY" + integration_method = "POST" + integration_uri = aws_lambda_function.www.invoke_arn + payload_format_version = "2.0" +} + +resource "aws_apigatewayv2_route" "api_event_post" { + api_id = aws_apigatewayv2_api.www.id + route_key = "POST /api/event" + target = "integrations/${aws_apigatewayv2_integration.www.id}" +} + +resource "aws_apigatewayv2_route" "api_event_eid_post" { + api_id = aws_apigatewayv2_api.www.id + route_key = "POST /api/event/{eid}" + target = "integrations/${aws_apigatewayv2_integration.www.id}" +} + +resource "aws_apigatewayv2_route" "api_event_eid_get" { + api_id = aws_apigatewayv2_api.www.id + route_key = "GET /api/event/{eid}" + target = "integrations/${aws_apigatewayv2_integration.www.id}" +} + +resource "aws_apigatewayv2_route" "api_route" { + for_each = { + get_eeq = "GET /api/event/{eid}/questions", + get_eeqs = "GET /api/event/{eid}/questions/{secret}", + post_toggle = "POST /api/event/{eid}/questions/{secret}/{qid}/toggle/{property}", + get_q = "GET /api/questions/{qids}", + post_vote = "POST /api/vote/{qid}/{updown}", + } + + api_id = aws_apigatewayv2_api.www.id + route_key = each.value + target = "integrations/${aws_apigatewayv2_integration.www.id}" +} + +resource "aws_lambda_permission" "www" { + statement_id = "AllowExecutionFromAPIGateway" + action = "lambda:InvokeFunction" + function_name = aws_lambda_function.www.function_name + principal = "apigateway.amazonaws.com" + source_arn = "${aws_apigatewayv2_stage.www.execution_arn}/*" +} diff --git a/infra/athena.tf b/infra/athena.tf new file mode 100644 index 0000000..31f8771 --- /dev/null +++ b/infra/athena.tf @@ -0,0 +1,236 @@ +locals { + athena = "wewerewondering-${data.aws_region.current.name}-athena" + db = "default" + tbl = "cloudfront_logs" +} + +resource "aws_s3_bucket" "athena" { + bucket = local.athena + + # TODO: lifecycle configuration + # https://docs.aws.amazon.com/athena/latest/ug/querying.html#query-results-specify-location +} + +resource "aws_s3_bucket_ownership_controls" "athena" { + bucket = aws_s3_bucket.athena.id + + rule { + object_ownership = "BucketOwnerEnforced" + } +} + +resource "aws_glue_catalog_database" "default" { + name = local.db +} + +# https://docs.aws.amazon.com/athena/latest/ug/cloudfront-logs.html +resource "aws_glue_catalog_table" "cf_logs" { + name = local.tbl + database_name = local.db + table_type = "EXTERNAL_TABLE" + owner = "hadoop" + parameters = { + EXTERNAL = "TRUE" + "skip.header.line.count" = 2 + } + depends_on = [aws_glue_catalog_database.default] + storage_descriptor { + input_format = "org.apache.hadoop.mapred.TextInputFormat" + location = "s3://${aws_s3_bucket.logs.id}/" + output_format = "org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat" + + columns { + name = "date" + type = "date" + } + columns { + name = "time" + type = "string" + } + columns { + name = "location" + type = "string" + } + columns { + name = "bytes" + type = "bigint" + } + columns { + name = "request_ip" + type = "string" + } + columns { + name = "method" + type = "string" + } + columns { + name = "host" + type = "string" + } + columns { + name = "uri" + type = "string" + } + columns { + name = "status" + type = "int" + } + columns { + name = "referrer" + type = "string" + } + columns { + name = "user_agent" + type = "string" + } + columns { + name = "query_string" + type = "string" + } + columns { + name = "cookie" + type = "string" + } + columns { + name = "result_type" + type = "string" + } + columns { + name = "request_id" + type = "string" + } + columns { + name = "host_header" + type = "string" + } + columns { + name = "request_protocol" + type = "string" + } + columns { + name = "request_bytes" + type = "bigint" + } + columns { + name = "time_taken" + type = "float" + } + columns { + name = "xforwarded_for" + type = "string" + } + columns { + name = "ssl_protocol" + type = "string" + } + columns { + name = "ssl_cipher" + type = "string" + } + columns { + name = "response_result_type" + type = "string" + } + columns { + name = "http_version" + type = "string" + } + columns { + name = "fle_status" + type = "string" + } + columns { + name = "fle_encrypted_fields" + type = "int" + } + columns { + name = "c_port" + type = "int" + } + columns { + name = "time_to_first_byte" + type = "float" + } + columns { + name = "x_edge_detailed_result_type" + type = "string" + } + columns { + name = "sc_content_type" + type = "string" + } + columns { + name = "sc_content_len" + type = "bigint" + } + columns { + name = "sc_range_start" + type = "bigint" + } + columns { + name = "sc_range_end" + type = "bigint" + } + + ser_de_info { + parameters = { + "field.delim" = "\t" + "serialization.format" = "\t" + } + serialization_library = "org.apache.hadoop.hive.serde2.lazy.LazySimpleSerDe" + } + } +} + +resource "aws_athena_workgroup" "www" { + name = "primary" + + configuration { + enforce_workgroup_configuration = false + publish_cloudwatch_metrics_enabled = false + + result_configuration { + output_location = "s3://${aws_s3_bucket.athena.bucket}/" + } + } +} + +resource "aws_athena_named_query" "common_errs" { + name = "Common errors" + workgroup = aws_athena_workgroup.www.name + database = local.db + query = <<-EOF + SELECT + request_ip, + method, + uri, + status, + COUNT(*) AS n + FROM "${local.db}"."${local.tbl}" + WHERE status >= 400 + AND from_iso8601_timestamp(concat(to_iso8601("date"), 'T', time)) > current_timestamp - interval '14' day + GROUP BY status, method, uri, request_ip + HAVING COUNT(*) > 1 + ORDER BY n DESC; + EOF +} + +resource "aws_athena_named_query" "recent_errs" { + name = "Recent errors" + workgroup = aws_athena_workgroup.www.name + database = local.db + query = <<-EOF + SELECT + from_iso8601_timestamp(concat(to_iso8601("date"), 'T', time)) AT TIME ZONE 'Europe/Oslo' as "when", + request_ip, + method, + uri, + status + FROM "${local.db}"."${local.tbl}" + WHERE status >= 400 + AND status <= 599 + AND from_iso8601_timestamp(concat(to_iso8601("date"), 'T', time)) > current_timestamp - interval '8' hour + ORDER BY "when" DESC + LIMIT 25; + EOF +} diff --git a/infra/cloudfront.tf b/infra/cloudfront.tf new file mode 100644 index 0000000..3c100c5 --- /dev/null +++ b/infra/cloudfront.tf @@ -0,0 +1,116 @@ +locals { + s3_origin_id = "wewerewondering" + gw_origin_id = "wewerewondering-api" +} + +resource "aws_cloudfront_origin_access_control" "static" { + name = aws_s3_bucket.static.bucket_regional_domain_name + origin_access_control_origin_type = "s3" + signing_behavior = "always" + signing_protocol = "sigv4" +} + +resource "aws_cloudfront_cache_policy" "cache_when_requested" { + name = "CacheWhenRequested" + default_ttl = 1 + max_ttl = 31536000 + min_ttl = 1 + parameters_in_cache_key_and_forwarded_to_origin { + cookies_config { + cookie_behavior = "none" + } + headers_config { + header_behavior = "none" + } + query_strings_config { + query_string_behavior = "none" + } + enable_accept_encoding_brotli = true + enable_accept_encoding_gzip = true + } +} + +resource "aws_cloudfront_function" "index_everywhere" { + name = "index-everywhere" + runtime = "cloudfront-js-2.0" + code = file("${path.module}/index-everywhere.js") +} + +resource "aws_cloudfront_distribution" "www" { + origin { + origin_id = local.gw_origin_id + # NOTE: this is stupid + domain_name = "${aws_apigatewayv2_api.www.id}.execute-api.${data.aws_region.current.name}.amazonaws.com" + + custom_origin_config { + http_port = 80 + https_port = 443 + origin_protocol_policy = "https-only" + origin_ssl_protocols = ["TLSv1.2"] + } + } + + origin { + origin_id = local.s3_origin_id + domain_name = aws_s3_bucket.static.bucket_regional_domain_name + origin_access_control_id = aws_cloudfront_origin_access_control.static.id + } + + enabled = true + is_ipv6_enabled = true + default_root_object = "index.html" + aliases = ["wewerewondering.com"] + price_class = "PriceClass_All" + http_version = "http2" + + logging_config { + include_cookies = false + bucket = aws_s3_bucket.logs.bucket_domain_name + } + + default_cache_behavior { + allowed_methods = ["GET", "HEAD"] + cached_methods = ["GET", "HEAD"] + target_origin_id = local.s3_origin_id + + # Using the CachingOptimized managed policy ID: + cache_policy_id = "658327ea-f89d-4fab-a63d-7e88639e58f6" + # Using the SecurityHeadersPolicy managed policy ID: + response_headers_policy_id = "67f7725c-6f97-4210-82d7-5512b31e9d03" + + compress = true + viewer_protocol_policy = "redirect-to-https" + + function_association { + event_type = "viewer-request" + function_arn = aws_cloudfront_function.index_everywhere.arn + } + } + + # Cache behavior with precedence 0 + ordered_cache_behavior { + path_pattern = "/api/*" + allowed_methods = ["DELETE", "GET", "HEAD", "OPTIONS", "PATCH", "POST", "PUT"] + cached_methods = ["GET", "HEAD"] + target_origin_id = local.gw_origin_id + compress = true + + cache_policy_id = aws_cloudfront_cache_policy.cache_when_requested.id + # Using the SecurityHeadersPolicy managed policy ID: + response_headers_policy_id = "67f7725c-6f97-4210-82d7-5512b31e9d03" + + viewer_protocol_policy = "https-only" + } + + restrictions { + geo_restriction { + restriction_type = "none" + } + } + + viewer_certificate { + acm_certificate_arn = aws_acm_certificate_validation.www.certificate_arn + minimum_protocol_version = "TLSv1.2_2021" + ssl_support_method = "sni-only" + } +} diff --git a/infra/dashboard.tf b/infra/dashboard.tf new file mode 100644 index 0000000..ca54687 --- /dev/null +++ b/infra/dashboard.tf @@ -0,0 +1,134 @@ +resource "aws_cloudwatch_dashboard" "www" { + dashboard_name = "ApiGatewayHttp" + + dashboard_body = jsonencode({ + "widgets" : [ + { + "height" : 4, + "width" : 8, + "y" : 0, + "x" : 0, + "type" : "metric", + "properties" : { + "metrics" : [ + ["AWS/ApiGateway", "Count", "ApiId", aws_apigatewayv2_api.www.id, { "period" : 300, "stat" : "Sum" }] + ], + "legend" : { + "position" : "bottom" + }, + "region" : data.aws_region.current.name, + "liveData" : false, + "title" : "Count: Sum", + "period" : 300, + "view" : "timeSeries", + "stacked" : false + } + }, + { + "height" : 4, + "width" : 8, + "y" : 0, + "x" : 8, + "type" : "metric", + "properties" : { + "metrics" : [ + ["AWS/ApiGateway", "5xx", "ApiId", aws_apigatewayv2_api.www.id, { "period" : 300, "stat" : "Sum" }] + ], + "legend" : { + "position" : "bottom" + }, + "region" : data.aws_region.current.name, + "liveData" : false, + "title" : "5XXError: Sum", + "period" : 300, + "view" : "timeSeries", + "stacked" : false + } + }, + { + "height" : 4, + "width" : 8, + "y" : 0, + "x" : 16, + "type" : "metric", + "properties" : { + "metrics" : [ + ["AWS/ApiGateway", "4xx", "ApiId", aws_apigatewayv2_api.www.id, { "period" : 300, "stat" : "Sum" }] + ], + "legend" : { + "position" : "bottom" + }, + "region" : data.aws_region.current.name, + "liveData" : false, + "title" : "4XXError: Sum", + "period" : 300, + "view" : "timeSeries", + "stacked" : false + } + }, + { + "height" : 4, + "width" : 12, + "y" : 4, + "x" : 0, + "type" : "metric", + "properties" : { + "metrics" : [ + ["AWS/ApiGateway", "Latency", "ApiId", aws_apigatewayv2_api.www.id, { "period" : 300, "stat" : "Average" }] + ], + "legend" : { + "position" : "bottom" + }, + "region" : data.aws_region.current.name, + "liveData" : false, + "title" : "Latency: Average", + "period" : 300, + "view" : "timeSeries", + "stacked" : false + } + }, + { + "height" : 4, + "width" : 12, + "y" : 4, + "x" : 12, + "type" : "metric", + "properties" : { + "metrics" : [ + ["AWS/ApiGateway", "IntegrationLatency", "ApiId", aws_apigatewayv2_api.www.id, { "period" : 300, "stat" : "Average" }] + ], + "legend" : { + "position" : "bottom" + }, + "region" : data.aws_region.current.name, + "liveData" : false, + "title" : "IntegrationLatency: Average", + "period" : 300, + "view" : "timeSeries", + "stacked" : false + } + }, + { + "height" : 4, + "width" : 24, + "y" : 8, + "x" : 0, + "type" : "metric", + "properties" : { + "metrics" : [ + ["AWS/ApiGateway", "DataProcessed", "ApiId", aws_apigatewayv2_api.www.id, { "period" : 300, "stat" : "Sum" }] + ], + "legend" : { + "position" : "bottom" + }, + "region" : data.aws_region.current.name, + "liveData" : false, + "title" : "DataProcessed: Sum", + "period" : 300, + "view" : "timeSeries", + "stacked" : false + } + } + ] + }) +} diff --git a/infra/domain.tf b/infra/domain.tf new file mode 100644 index 0000000..a2e92b5 --- /dev/null +++ b/infra/domain.tf @@ -0,0 +1,83 @@ +locals { + domain = "wewerewondering.com" +} + +resource "aws_route53_zone" "www" { + name = local.domain +} + +resource "aws_route53_record" "www_mx" { + zone_id = aws_route53_zone.www.zone_id + name = local.domain + type = "MX" + ttl = 3600 + records = [ + "10 mx1.improvmx.com", + "20 mx2.improvmx.com" + ] +} + +resource "aws_route53_record" "www_spf" { + zone_id = aws_route53_zone.www.zone_id + name = local.domain + type = "TXT" + ttl = 3600 + records = [ + "v=spf1 include:spf.improvmx.com ~all", + ] +} + +resource "aws_route53_record" "www_cf" { + zone_id = aws_route53_zone.www.zone_id + name = local.domain + type = "A" + alias { + name = aws_cloudfront_distribution.www.domain_name + zone_id = aws_cloudfront_distribution.www.hosted_zone_id + evaluate_target_health = false + } +} + +resource "aws_route53_record" "www_cf_v6" { + zone_id = aws_route53_zone.www.zone_id + name = local.domain + type = "AAAA" + alias { + name = aws_cloudfront_distribution.www.domain_name + zone_id = aws_cloudfront_distribution.www.hosted_zone_id + evaluate_target_health = false + } +} + +resource "aws_acm_certificate" "www" { + provider = aws.us-east-1 + domain_name = local.domain + validation_method = "DNS" + + lifecycle { + create_before_destroy = true + } +} + +resource "aws_route53_record" "www_cert" { + for_each = { + for dvo in aws_acm_certificate.www.domain_validation_options : dvo.domain_name => { + name = dvo.resource_record_name + record = dvo.resource_record_value + type = dvo.resource_record_type + } + } + + allow_overwrite = true + name = each.value.name + records = [each.value.record] + ttl = 60 + type = each.value.type + zone_id = aws_route53_zone.www.zone_id +} + +resource "aws_acm_certificate_validation" "www" { + provider = aws.us-east-1 + certificate_arn = aws_acm_certificate.www.arn + validation_record_fqdns = [for record in aws_route53_record.www_cert : record.fqdn] +} diff --git a/infra/dynamodb.tf b/infra/dynamodb.tf new file mode 100644 index 0000000..235ad1e --- /dev/null +++ b/infra/dynamodb.tf @@ -0,0 +1,49 @@ +resource "aws_dynamodb_table" "events" { + name = "events" + billing_mode = "PAY_PER_REQUEST" + hash_key = "id" + + attribute { + name = "id" + type = "S" + } + + ttl { + attribute_name = "expire" + enabled = true + } +} + +resource "aws_dynamodb_table" "questions" { + name = "questions" + billing_mode = "PAY_PER_REQUEST" + hash_key = "id" + + attribute { + name = "id" + type = "S" + } + + attribute { + name = "eid" + type = "S" + } + + attribute { + name = "votes" + type = "N" + } + + ttl { + attribute_name = "expire" + enabled = true + } + + global_secondary_index { + name = "top" + hash_key = "eid" + range_key = "votes" + projection_type = "INCLUDE" + non_key_attributes = ["answered", "hidden"] + } +} diff --git a/infra/index-everywhere.js b/infra/index-everywhere.js new file mode 100644 index 0000000..cd9b234 --- /dev/null +++ b/infra/index-everywhere.js @@ -0,0 +1,9 @@ +function handler(event) { + var req = event.request; + if ( + req.uri.startsWith('/event/') + ) { + req.uri = '/index.html'; + } + return req; +} diff --git a/infra/lambda.tf b/infra/lambda.tf new file mode 100644 index 0000000..44a2df6 --- /dev/null +++ b/infra/lambda.tf @@ -0,0 +1,129 @@ +data "aws_iam_policy_document" "xray" { + statement { + actions = [ + "xray:PutTraceSegments", + "xray:PutTelemetryRecords", + ] + resources = ["*"] + } +} + +resource "aws_iam_policy" "xray" { + # TODO: https://github.com/hashicorp/terraform-provider-aws/issues/32906 + name = "AWSLambdaTracerAccessExecutionRole-14a6d1b5-3a03-4b02-94ca-fec2eced24ab" + path = "/service-role/" + policy = data.aws_iam_policy_document.xray.json +} + +data "aws_iam_policy_document" "cloudwatch" { + statement { + actions = [ + "logs:CreateLogGroup", + ] + resources = [aws_cloudwatch_log_group.lambda.arn] + } + + statement { + actions = [ + "logs:CreateLogStream", + "logs:PutLogEvents", + ] + resources = ["${aws_cloudwatch_log_group.lambda.arn}:*"] + } +} + +resource "aws_iam_policy" "cloudwatch" { + # TODO: https://github.com/hashicorp/terraform-provider-aws/issues/32906 + name = "AWSLambdaBasicExecutionRole-b586114a-ba08-47b0-afe0-82c4d81857a0" + path = "/service-role/" + policy = data.aws_iam_policy_document.cloudwatch.json +} + +data "aws_iam_policy_document" "assume_role" { + statement { + principals { + type = "Service" + identifiers = ["lambda.amazonaws.com"] + } + actions = ["sts:AssumeRole"] + } +} + +resource "aws_iam_role" "www" { + name = "wewerewondering-api" + assume_role_policy = data.aws_iam_policy_document.assume_role.json + path = "/service-role/" + managed_policy_arns = [ + aws_iam_policy.cloudwatch.arn, + aws_iam_policy.xray.arn, + "arn:aws:iam::aws:policy/CloudWatchLambdaInsightsExecutionRolePolicy" + ] +} + +data "aws_iam_policy_document" "dynamodb" { + statement { + actions = [ + "dynamodb:UpdateItem", + "dynamodb:Scan", + "dynamodb:Query", + "dynamodb:PutItem", + "dynamodb:GetItem", + "dynamodb:BatchGetItem", + ] + resources = [ + aws_dynamodb_table.events.arn, + aws_dynamodb_table.questions.arn, + "${aws_dynamodb_table.questions.arn}/index/top" + ] + } +} + +resource "aws_iam_role_policy" "dynamodb" { + name = "api-db-access" + role = aws_iam_role.www.id + policy = data.aws_iam_policy_document.dynamodb.json +} + +resource "terraform_data" "cargo_lambda" { + triggers_replace = { + cargo_toml = "${base64sha256(file("${path.module}/../server/Cargo.toml"))}" + main_rs = "${base64sha256(file("${path.module}/../server/src/main.rs"))}" + } + + provisioner "local-exec" { + command = "cargo lambda build --release --arm64" + working_dir = "../server" + } +} + +data "archive_file" "lambda" { + type = "zip" + source_file = "${path.module}/../server/target/lambda/wewerewondering-api/bootstrap" + output_path = "lambda_function_payload.zip" + depends_on = [terraform_data.cargo_lambda] +} + +resource "aws_lambda_function" "www" { + function_name = "wewerewondering-api" + role = aws_iam_role.www.arn + handler = "bootstrap" + runtime = "provided.al2" + architectures = ["arm64"] + timeout = 30 + layers = [ + "arn:aws:lambda:${data.aws_region.current.name}:580247275435:layer:LambdaInsightsExtension-Arm64:5" + ] + + filename = "lambda_function_payload.zip" + source_code_hash = data.archive_file.lambda.output_base64sha256 + + environment { + variables = { + RUST_LOG = "info,tower_http=debug,wewerewondering_api=trace" + } + } + + depends_on = [ + aws_cloudwatch_log_group.lambda, + ] +} diff --git a/infra/logging.tf b/infra/logging.tf new file mode 100644 index 0000000..9cc2a17 --- /dev/null +++ b/infra/logging.tf @@ -0,0 +1,55 @@ +locals { + logs = "wewerewondering-${data.aws_region.current.name}-logs" +} + +data "aws_canonical_user_id" "current" {} + +resource "aws_s3_bucket" "logs" { + bucket = local.logs +} + +resource "aws_s3_bucket_ownership_controls" "logs" { + bucket = aws_s3_bucket.logs.id + + rule { + object_ownership = "BucketOwnerPreferred" + } +} + +resource "aws_s3_bucket_acl" "logs" { + depends_on = [aws_s3_bucket_ownership_controls.logs] + bucket = aws_s3_bucket.logs.id + + access_control_policy { + grant { + grantee { + id = data.aws_canonical_user_id.current.id + type = "CanonicalUser" + } + permission = "FULL_CONTROL" + } + + # https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/AccessLogs.html#AccessLogsBucketAndFileOwnership + grant { + grantee { + type = "CanonicalUser" + id = "c4c1ede66af53448b93c283ce9448c4ba468c9432aa01d700d3878632f77d2d0" + } + permission = "FULL_CONTROL" + } + + owner { + id = data.aws_canonical_user_id.current.id + } + } +} + +resource "aws_cloudwatch_log_group" "lambda" { + name = "/aws/lambda/wewerewondering-api" + retention_in_days = 180 +} + +resource "aws_cloudwatch_log_group" "apigw" { + name = "/aws/api-gateway/wewerewondering" + retention_in_days = 180 +} diff --git a/infra/main.tf b/infra/main.tf new file mode 100644 index 0000000..7c64bb3 --- /dev/null +++ b/infra/main.tf @@ -0,0 +1,31 @@ +terraform { + required_providers { + aws = { + source = "hashicorp/aws" + version = "~> 5.31.0" + } + } + + required_version = ">= 1.6.6" +} + +provider "aws" { + region = "eu-north-1" + assume_role { + role_arn = "arn:aws:iam::880545379339:role/OrganizationAccountAccessRole" + external_id = "terraform" + } +} + +# for ACM cert for CloudFront +# https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/cnames-and-https-requirements.html#https-requirements-aws-region +provider "aws" { + region = "us-east-1" + alias = "us-east-1" + assume_role { + role_arn = "arn:aws:iam::880545379339:role/OrganizationAccountAccessRole" + external_id = "terraform" + } +} + +data "aws_region" "current" {} diff --git a/infra/static.tf b/infra/static.tf new file mode 100644 index 0000000..da9941e --- /dev/null +++ b/infra/static.tf @@ -0,0 +1,79 @@ +locals { + static = "wewerewondering-${data.aws_region.current.name}-static" +} + +resource "aws_s3_bucket" "static" { + bucket = local.static + force_destroy = true +} + +resource "aws_s3_bucket_ownership_controls" "static" { + bucket = aws_s3_bucket.static.id + + rule { + object_ownership = "BucketOwnerEnforced" + } +} + +data "aws_iam_policy_document" "cloudfront_s3" { + policy_id = "PolicyForCloudFrontPrivateContent" + + statement { + sid = "AllowCloudFrontServicePrincipal" + + principals { + type = "Service" + identifiers = ["cloudfront.amazonaws.com"] + } + + actions = [ + "s3:GetObject", + "s3:ListBucket", + ] + + resources = [ + aws_s3_bucket.static.arn, + "${aws_s3_bucket.static.arn}/*", + ] + + condition { + test = "StringEquals" + variable = "AWS:SourceArn" + + values = [aws_cloudfront_distribution.www.arn] + } + } +} + +resource "aws_s3_bucket_policy" "cloudfront" { + bucket = aws_s3_bucket.static.id + policy = data.aws_iam_policy_document.cloudfront_s3.json +} + +resource "terraform_data" "npm_build" { + triggers_replace = { + package_json = "${base64sha256(file("${path.module}/../client/package.json"))}" + index_html = "${base64sha256(file("${path.module}/../client/index.html"))}" + } + + provisioner "local-exec" { + command = "npm run build" + working_dir = "../client" + } +} + +resource "aws_s3_object" "dist" { + depends_on = [terraform_data.npm_build] + for_each = fileset("${path.module}/../client/dist", "**") + + force_destroy = true + bucket = aws_s3_bucket.static.id + key = each.value + source = "${path.module}/../client/dist/${each.value}" + # etag makes the file update when it changes; see https://stackoverflow.com/questions/56107258/terraform-upload-file-to-s3-on-every-apply + etag = filemd5("${path.module}/../client/dist/${each.value}") + + cache_control = each.value == "index.html" ? "max-age=300" : null +} + +# TODO: delete old files in assets/ ? diff --git a/infra/terraform.tfstate b/infra/terraform.tfstate new file mode 100644 index 0000000..438134c --- /dev/null +++ b/infra/terraform.tfstate @@ -0,0 +1,3167 @@ +{ + "version": 4, + "terraform_version": "1.6.6", + "serial": 122, + "lineage": "ed8fbb99-5570-1b6d-6765-46ed4759afc0", + "outputs": {}, + "resources": [ + { + "mode": "data", + "type": "archive_file", + "name": "lambda", + "provider": "provider[\"registry.terraform.io/hashicorp/archive\"]", + "instances": [ + { + "schema_version": 0, + "attributes": { + "exclude_symlink_directories": null, + "excludes": null, + "id": "417edebc76d9f2b1e07fa34001e46a1da844155c", + "output_base64sha256": "W7E2gnu4p+aHm166MT2kMU9QoAApHKXAUl7VRfMdomE=", + "output_base64sha512": "PvRbHz++YeKjr4uuKn/QQ9T53YyJ16wpBeAoeo0XjtegozirNOwjjZlwXMEZ6HIKhw09G/IDX20DhEjcvL5xjg==", + "output_file_mode": null, + "output_md5": "bc8ad72643fac84041383858e39e25d0", + "output_path": "lambda_function_payload.zip", + "output_sha": "417edebc76d9f2b1e07fa34001e46a1da844155c", + "output_sha256": "5bb136827bb8a7e6879b5eba313da4314f50a000291ca5c0525ed545f31da261", + "output_sha512": "3ef45b1f3fbe61e2a3af8bae2a7fd043d4f9dd8c89d7ac2905e0287a8d178ed7a0a338ab34ec238d99705cc119e8720a870d3d1bf2035f6d038448dcbcbe718e", + "output_size": 4715533, + "source": [], + "source_content": null, + "source_content_filename": null, + "source_dir": null, + "source_file": "./../server/target/lambda/wewerewondering-api/bootstrap", + "type": "zip" + }, + "sensitive_attributes": [] + } + ] + }, + { + "mode": "data", + "type": "aws_canonical_user_id", + "name": "current", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [ + { + "schema_version": 0, + "attributes": { + "display_name": "", + "id": "b9eabe8fd0ee6354b459c3d797e75df89ee644b91a018bf5ff42d12b5b47daa2" + }, + "sensitive_attributes": [] + } + ] + }, + { + "mode": "data", + "type": "aws_iam_policy_document", + "name": "apigw_assume", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [ + { + "schema_version": 0, + "attributes": { + "id": "2699642182", + "json": "{\n \"Version\": \"2012-10-17\",\n \"Statement\": [\n {\n \"Effect\": \"Allow\",\n \"Action\": \"sts:AssumeRole\",\n \"Principal\": {\n \"Service\": \"apigateway.amazonaws.com\"\n }\n }\n ]\n}", + "override_policy_documents": null, + "policy_id": null, + "source_policy_documents": null, + "statement": [ + { + "actions": [ + "sts:AssumeRole" + ], + "condition": [], + "effect": "Allow", + "not_actions": [], + "not_principals": [], + "not_resources": [], + "principals": [ + { + "identifiers": [ + "apigateway.amazonaws.com" + ], + "type": "Service" + } + ], + "resources": [], + "sid": "" + } + ], + "version": "2012-10-17" + }, + "sensitive_attributes": [] + } + ] + }, + { + "mode": "data", + "type": "aws_iam_policy_document", + "name": "assume_role", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [ + { + "schema_version": 0, + "attributes": { + "id": "2690255455", + "json": "{\n \"Version\": \"2012-10-17\",\n \"Statement\": [\n {\n \"Effect\": \"Allow\",\n \"Action\": \"sts:AssumeRole\",\n \"Principal\": {\n \"Service\": \"lambda.amazonaws.com\"\n }\n }\n ]\n}", + "override_policy_documents": null, + "policy_id": null, + "source_policy_documents": null, + "statement": [ + { + "actions": [ + "sts:AssumeRole" + ], + "condition": [], + "effect": "Allow", + "not_actions": [], + "not_principals": [], + "not_resources": [], + "principals": [ + { + "identifiers": [ + "lambda.amazonaws.com" + ], + "type": "Service" + } + ], + "resources": [], + "sid": "" + } + ], + "version": "2012-10-17" + }, + "sensitive_attributes": [] + } + ] + }, + { + "mode": "data", + "type": "aws_iam_policy_document", + "name": "cloudfront_s3", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [ + { + "schema_version": 0, + "attributes": { + "id": "3895331988", + "json": "{\n \"Version\": \"2012-10-17\",\n \"Id\": \"PolicyForCloudFrontPrivateContent\",\n \"Statement\": [\n {\n \"Sid\": \"AllowCloudFrontServicePrincipal\",\n \"Effect\": \"Allow\",\n \"Action\": [\n \"s3:ListBucket\",\n \"s3:GetObject\"\n ],\n \"Resource\": [\n \"arn:aws:s3:::wewerewondering-eu-north-1-static/*\",\n \"arn:aws:s3:::wewerewondering-eu-north-1-static\"\n ],\n \"Principal\": {\n \"Service\": \"cloudfront.amazonaws.com\"\n },\n \"Condition\": {\n \"StringEquals\": {\n \"AWS:SourceArn\": \"arn:aws:cloudfront::880545379339:distribution/E1ECZRHBXFKMHK\"\n }\n }\n }\n ]\n}", + "override_policy_documents": null, + "policy_id": "PolicyForCloudFrontPrivateContent", + "source_policy_documents": null, + "statement": [ + { + "actions": [ + "s3:GetObject", + "s3:ListBucket" + ], + "condition": [ + { + "test": "StringEquals", + "values": [ + "arn:aws:cloudfront::880545379339:distribution/E1ECZRHBXFKMHK" + ], + "variable": "AWS:SourceArn" + } + ], + "effect": "Allow", + "not_actions": [], + "not_principals": [], + "not_resources": [], + "principals": [ + { + "identifiers": [ + "cloudfront.amazonaws.com" + ], + "type": "Service" + } + ], + "resources": [ + "arn:aws:s3:::wewerewondering-eu-north-1-static", + "arn:aws:s3:::wewerewondering-eu-north-1-static/*" + ], + "sid": "AllowCloudFrontServicePrincipal" + } + ], + "version": "2012-10-17" + }, + "sensitive_attributes": [] + } + ] + }, + { + "mode": "data", + "type": "aws_iam_policy_document", + "name": "cloudwatch", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [ + { + "schema_version": 0, + "attributes": { + "id": "3265722285", + "json": "{\n \"Version\": \"2012-10-17\",\n \"Statement\": [\n {\n \"Effect\": \"Allow\",\n \"Action\": \"logs:CreateLogGroup\",\n \"Resource\": \"arn:aws:logs:eu-north-1:880545379339:log-group:/aws/lambda/wewerewondering-api\"\n },\n {\n \"Effect\": \"Allow\",\n \"Action\": [\n \"logs:PutLogEvents\",\n \"logs:CreateLogStream\"\n ],\n \"Resource\": \"arn:aws:logs:eu-north-1:880545379339:log-group:/aws/lambda/wewerewondering-api:*\"\n }\n ]\n}", + "override_policy_documents": null, + "policy_id": null, + "source_policy_documents": null, + "statement": [ + { + "actions": [ + "logs:CreateLogGroup" + ], + "condition": [], + "effect": "Allow", + "not_actions": [], + "not_principals": [], + "not_resources": [], + "principals": [], + "resources": [ + "arn:aws:logs:eu-north-1:880545379339:log-group:/aws/lambda/wewerewondering-api" + ], + "sid": "" + }, + { + "actions": [ + "logs:CreateLogStream", + "logs:PutLogEvents" + ], + "condition": [], + "effect": "Allow", + "not_actions": [], + "not_principals": [], + "not_resources": [], + "principals": [], + "resources": [ + "arn:aws:logs:eu-north-1:880545379339:log-group:/aws/lambda/wewerewondering-api:*" + ], + "sid": "" + } + ], + "version": "2012-10-17" + }, + "sensitive_attributes": [] + } + ] + }, + { + "mode": "data", + "type": "aws_iam_policy_document", + "name": "dynamodb", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [ + { + "schema_version": 0, + "attributes": { + "id": "207875518", + "json": "{\n \"Version\": \"2012-10-17\",\n \"Statement\": [\n {\n \"Effect\": \"Allow\",\n \"Action\": [\n \"dynamodb:UpdateItem\",\n \"dynamodb:Scan\",\n \"dynamodb:Query\",\n \"dynamodb:PutItem\",\n \"dynamodb:GetItem\",\n \"dynamodb:BatchGetItem\"\n ],\n \"Resource\": [\n \"arn:aws:dynamodb:eu-north-1:880545379339:table/questions/index/top\",\n \"arn:aws:dynamodb:eu-north-1:880545379339:table/questions\",\n \"arn:aws:dynamodb:eu-north-1:880545379339:table/events\"\n ]\n }\n ]\n}", + "override_policy_documents": null, + "policy_id": null, + "source_policy_documents": null, + "statement": [ + { + "actions": [ + "dynamodb:BatchGetItem", + "dynamodb:GetItem", + "dynamodb:PutItem", + "dynamodb:Query", + "dynamodb:Scan", + "dynamodb:UpdateItem" + ], + "condition": [], + "effect": "Allow", + "not_actions": [], + "not_principals": [], + "not_resources": [], + "principals": [], + "resources": [ + "arn:aws:dynamodb:eu-north-1:880545379339:table/events", + "arn:aws:dynamodb:eu-north-1:880545379339:table/questions", + "arn:aws:dynamodb:eu-north-1:880545379339:table/questions/index/top" + ], + "sid": "" + } + ], + "version": "2012-10-17" + }, + "sensitive_attributes": [] + } + ] + }, + { + "mode": "data", + "type": "aws_iam_policy_document", + "name": "xray", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [ + { + "schema_version": 0, + "attributes": { + "id": "1808201367", + "json": "{\n \"Version\": \"2012-10-17\",\n \"Statement\": [\n {\n \"Effect\": \"Allow\",\n \"Action\": [\n \"xray:PutTraceSegments\",\n \"xray:PutTelemetryRecords\"\n ],\n \"Resource\": \"*\"\n }\n ]\n}", + "override_policy_documents": null, + "policy_id": null, + "source_policy_documents": null, + "statement": [ + { + "actions": [ + "xray:PutTelemetryRecords", + "xray:PutTraceSegments" + ], + "condition": [], + "effect": "Allow", + "not_actions": [], + "not_principals": [], + "not_resources": [], + "principals": [], + "resources": [ + "*" + ], + "sid": "" + } + ], + "version": "2012-10-17" + }, + "sensitive_attributes": [] + } + ] + }, + { + "mode": "data", + "type": "aws_region", + "name": "current", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [ + { + "schema_version": 0, + "attributes": { + "description": "Europe (Stockholm)", + "endpoint": "ec2.eu-north-1.amazonaws.com", + "id": "eu-north-1", + "name": "eu-north-1" + }, + "sensitive_attributes": [] + } + ] + }, + { + "mode": "managed", + "type": "aws_acm_certificate", + "name": "www", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"].us-east-1", + "instances": [ + { + "schema_version": 0, + "attributes": { + "arn": "arn:aws:acm:us-east-1:880545379339:certificate/f3e11148-9740-4b7f-a1a6-da43e045cef0", + "certificate_authority_arn": "", + "certificate_body": null, + "certificate_chain": null, + "domain_name": "wewerewondering.com", + "domain_validation_options": [ + { + "domain_name": "wewerewondering.com", + "resource_record_name": "_c7b659fc5b836da864d8c39af1a6c6b8.wewerewondering.com.", + "resource_record_type": "CNAME", + "resource_record_value": "_2466ad9183460f6cd658e384440b4c12.yzdtlljtvc.acm-validations.aws." + } + ], + "early_renewal_duration": "", + "id": "arn:aws:acm:us-east-1:880545379339:certificate/f3e11148-9740-4b7f-a1a6-da43e045cef0", + "key_algorithm": "EC_prime256v1", + "not_after": "2024-11-11T23:59:59Z", + "not_before": "2023-10-14T00:00:00Z", + "options": [ + { + "certificate_transparency_logging_preference": "ENABLED" + } + ], + "pending_renewal": false, + "private_key": null, + "renewal_eligibility": "ELIGIBLE", + "renewal_summary": [ + { + "renewal_status": "SUCCESS", + "renewal_status_reason": "", + "updated_at": "2023-10-14T06:19:52Z" + } + ], + "status": "ISSUED", + "subject_alternative_names": [ + "wewerewondering.com" + ], + "tags": {}, + "tags_all": {}, + "type": "AMAZON_ISSUED", + "validation_emails": [], + "validation_method": "DNS", + "validation_option": [] + }, + "sensitive_attributes": [], + "private": "eyJzY2hlbWFfdmVyc2lvbiI6IjAifQ==", + "create_before_destroy": true + } + ] + }, + { + "mode": "managed", + "type": "aws_acm_certificate_validation", + "name": "www", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"].us-east-1", + "instances": [ + { + "schema_version": 0, + "attributes": { + "certificate_arn": "arn:aws:acm:us-east-1:880545379339:certificate/f3e11148-9740-4b7f-a1a6-da43e045cef0", + "id": "2023-10-14 06:19:51.605 +0000 UTC", + "timeouts": null, + "validation_record_fqdns": [ + "_c7b659fc5b836da864d8c39af1a6c6b8.wewerewondering.com" + ] + }, + "sensitive_attributes": [], + "private": "eyJlMmJmYjczMC1lY2FhLTExZTYtOGY4OC0zNDM2M2JjN2M0YzAiOnsiY3JlYXRlIjo0NTAwMDAwMDAwMDAwfX0=", + "dependencies": [ + "aws_acm_certificate.www", + "aws_route53_record.www_cert", + "aws_route53_zone.www" + ] + } + ] + }, + { + "mode": "managed", + "type": "aws_api_gateway_account", + "name": "www", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [ + { + "schema_version": 0, + "attributes": { + "api_key_version": "4", + "cloudwatch_role_arn": "arn:aws:iam::880545379339:role/wewerewondering-api-gw", + "features": [ + "UsagePlans" + ], + "id": "api-gateway-account", + "throttle_settings": [ + { + "burst_limit": 5000, + "rate_limit": 10000 + } + ] + }, + "sensitive_attributes": [], + "private": "bnVsbA==", + "dependencies": [ + "aws_iam_role.apigw_cw", + "data.aws_iam_policy_document.apigw_assume" + ] + } + ] + }, + { + "mode": "managed", + "type": "aws_apigatewayv2_api", + "name": "www", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [ + { + "schema_version": 0, + "attributes": { + "api_endpoint": "https://o19hhgzpd7.execute-api.eu-north-1.amazonaws.com", + "api_key_selection_expression": "$request.header.x-api-key", + "arn": "arn:aws:apigateway:eu-north-1::/apis/o19hhgzpd7", + "body": null, + "cors_configuration": [], + "credentials_arn": null, + "description": "", + "disable_execute_api_endpoint": false, + "execution_arn": "arn:aws:execute-api:eu-north-1:880545379339:o19hhgzpd7", + "fail_on_warnings": null, + "id": "o19hhgzpd7", + "name": "wewerewondering", + "protocol_type": "HTTP", + "route_key": null, + "route_selection_expression": "$request.method $request.path", + "tags": {}, + "tags_all": {}, + "target": null, + "version": "" + }, + "sensitive_attributes": [], + "private": "bnVsbA==" + } + ] + }, + { + "mode": "managed", + "type": "aws_apigatewayv2_integration", + "name": "www", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [ + { + "schema_version": 0, + "attributes": { + "api_id": "o19hhgzpd7", + "connection_id": "", + "connection_type": "INTERNET", + "content_handling_strategy": "", + "credentials_arn": "", + "description": "", + "id": "tsl0pws", + "integration_method": "POST", + "integration_response_selection_expression": "", + "integration_subtype": "", + "integration_type": "AWS_PROXY", + "integration_uri": "arn:aws:apigateway:eu-north-1:lambda:path/2015-03-31/functions/arn:aws:lambda:eu-north-1:880545379339:function:wewerewondering-api/invocations", + "passthrough_behavior": "", + "payload_format_version": "2.0", + "request_parameters": {}, + "request_templates": {}, + "response_parameters": [], + "template_selection_expression": "", + "timeout_milliseconds": 30000, + "tls_config": [] + }, + "sensitive_attributes": [], + "private": "bnVsbA==", + "dependencies": [ + "aws_apigatewayv2_api.www", + "aws_cloudwatch_log_group.lambda", + "aws_iam_policy.cloudwatch", + "aws_iam_policy.xray", + "aws_iam_role.www", + "aws_lambda_function.www", + "data.archive_file.lambda", + "data.aws_iam_policy_document.assume_role", + "data.aws_iam_policy_document.cloudwatch", + "data.aws_iam_policy_document.xray", + "data.aws_region.current", + "terraform_data.cargo_lambda" + ] + } + ] + }, + { + "mode": "managed", + "type": "aws_apigatewayv2_route", + "name": "api_event_eid_get", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [ + { + "schema_version": 0, + "attributes": { + "api_id": "o19hhgzpd7", + "api_key_required": false, + "authorization_scopes": [], + "authorization_type": "NONE", + "authorizer_id": "", + "id": "cp9a6ld", + "model_selection_expression": "", + "operation_name": "", + "request_models": {}, + "request_parameter": [], + "route_key": "GET /api/event/{eid}", + "route_response_selection_expression": "", + "target": "integrations/tsl0pws" + }, + "sensitive_attributes": [], + "private": "bnVsbA==", + "dependencies": [ + "aws_apigatewayv2_api.www", + "aws_apigatewayv2_integration.www", + "aws_cloudwatch_log_group.lambda", + "aws_iam_policy.cloudwatch", + "aws_iam_policy.xray", + "aws_iam_role.www", + "aws_lambda_function.www", + "data.archive_file.lambda", + "data.aws_iam_policy_document.assume_role", + "data.aws_iam_policy_document.cloudwatch", + "data.aws_iam_policy_document.xray", + "data.aws_region.current", + "terraform_data.cargo_lambda" + ] + } + ] + }, + { + "mode": "managed", + "type": "aws_apigatewayv2_route", + "name": "api_event_eid_post", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [ + { + "schema_version": 0, + "attributes": { + "api_id": "o19hhgzpd7", + "api_key_required": false, + "authorization_scopes": [], + "authorization_type": "NONE", + "authorizer_id": "", + "id": "0o598vj", + "model_selection_expression": "", + "operation_name": "", + "request_models": {}, + "request_parameter": [], + "route_key": "POST /api/event/{eid}", + "route_response_selection_expression": "", + "target": "integrations/tsl0pws" + }, + "sensitive_attributes": [], + "private": "bnVsbA==", + "dependencies": [ + "aws_apigatewayv2_api.www", + "aws_apigatewayv2_integration.www", + "aws_cloudwatch_log_group.lambda", + "aws_iam_policy.cloudwatch", + "aws_iam_policy.xray", + "aws_iam_role.www", + "aws_lambda_function.www", + "data.archive_file.lambda", + "data.aws_iam_policy_document.assume_role", + "data.aws_iam_policy_document.cloudwatch", + "data.aws_iam_policy_document.xray", + "data.aws_region.current", + "terraform_data.cargo_lambda" + ] + } + ] + }, + { + "mode": "managed", + "type": "aws_apigatewayv2_route", + "name": "api_event_post", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [ + { + "schema_version": 0, + "attributes": { + "api_id": "o19hhgzpd7", + "api_key_required": false, + "authorization_scopes": [], + "authorization_type": "NONE", + "authorizer_id": "", + "id": "21aff6l", + "model_selection_expression": "", + "operation_name": "", + "request_models": {}, + "request_parameter": [], + "route_key": "POST /api/event", + "route_response_selection_expression": "", + "target": "integrations/tsl0pws" + }, + "sensitive_attributes": [], + "private": "bnVsbA==", + "dependencies": [ + "aws_apigatewayv2_api.www", + "aws_apigatewayv2_integration.www", + "aws_cloudwatch_log_group.lambda", + "aws_iam_policy.cloudwatch", + "aws_iam_policy.xray", + "aws_iam_role.www", + "aws_lambda_function.www", + "data.archive_file.lambda", + "data.aws_iam_policy_document.assume_role", + "data.aws_iam_policy_document.cloudwatch", + "data.aws_iam_policy_document.xray", + "data.aws_region.current", + "terraform_data.cargo_lambda" + ] + } + ] + }, + { + "mode": "managed", + "type": "aws_apigatewayv2_route", + "name": "api_route", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [ + { + "index_key": "get_eeq", + "schema_version": 0, + "attributes": { + "api_id": "o19hhgzpd7", + "api_key_required": false, + "authorization_scopes": [], + "authorization_type": "NONE", + "authorizer_id": "", + "id": "fua8trl", + "model_selection_expression": "", + "operation_name": "", + "request_models": {}, + "request_parameter": [], + "route_key": "GET /api/event/{eid}/questions", + "route_response_selection_expression": "", + "target": "integrations/tsl0pws" + }, + "sensitive_attributes": [], + "private": "bnVsbA==", + "dependencies": [ + "aws_apigatewayv2_api.www", + "aws_apigatewayv2_integration.www", + "aws_cloudwatch_log_group.lambda", + "aws_iam_policy.cloudwatch", + "aws_iam_policy.xray", + "aws_iam_role.www", + "aws_lambda_function.www", + "data.archive_file.lambda", + "data.aws_iam_policy_document.assume_role", + "data.aws_iam_policy_document.cloudwatch", + "data.aws_iam_policy_document.xray", + "data.aws_region.current", + "terraform_data.cargo_lambda" + ] + }, + { + "index_key": "get_eeqs", + "schema_version": 0, + "attributes": { + "api_id": "o19hhgzpd7", + "api_key_required": false, + "authorization_scopes": [], + "authorization_type": "NONE", + "authorizer_id": "", + "id": "tdcfcha", + "model_selection_expression": "", + "operation_name": "", + "request_models": {}, + "request_parameter": [], + "route_key": "GET /api/event/{eid}/questions/{secret}", + "route_response_selection_expression": "", + "target": "integrations/tsl0pws" + }, + "sensitive_attributes": [], + "private": "bnVsbA==", + "dependencies": [ + "aws_apigatewayv2_api.www", + "aws_apigatewayv2_integration.www", + "aws_cloudwatch_log_group.lambda", + "aws_iam_policy.cloudwatch", + "aws_iam_policy.xray", + "aws_iam_role.www", + "aws_lambda_function.www", + "data.archive_file.lambda", + "data.aws_iam_policy_document.assume_role", + "data.aws_iam_policy_document.cloudwatch", + "data.aws_iam_policy_document.xray", + "data.aws_region.current", + "terraform_data.cargo_lambda" + ] + }, + { + "index_key": "get_q", + "schema_version": 0, + "attributes": { + "api_id": "o19hhgzpd7", + "api_key_required": false, + "authorization_scopes": [], + "authorization_type": "NONE", + "authorizer_id": "", + "id": "whnecs5", + "model_selection_expression": "", + "operation_name": "", + "request_models": {}, + "request_parameter": [], + "route_key": "GET /api/questions/{qids}", + "route_response_selection_expression": "", + "target": "integrations/tsl0pws" + }, + "sensitive_attributes": [], + "private": "bnVsbA==", + "dependencies": [ + "aws_apigatewayv2_api.www", + "aws_apigatewayv2_integration.www", + "aws_cloudwatch_log_group.lambda", + "aws_iam_policy.cloudwatch", + "aws_iam_policy.xray", + "aws_iam_role.www", + "aws_lambda_function.www", + "data.archive_file.lambda", + "data.aws_iam_policy_document.assume_role", + "data.aws_iam_policy_document.cloudwatch", + "data.aws_iam_policy_document.xray", + "data.aws_region.current", + "terraform_data.cargo_lambda" + ] + }, + { + "index_key": "post_toggle", + "schema_version": 0, + "attributes": { + "api_id": "o19hhgzpd7", + "api_key_required": false, + "authorization_scopes": [], + "authorization_type": "NONE", + "authorizer_id": "", + "id": "7r7n45g", + "model_selection_expression": "", + "operation_name": "", + "request_models": {}, + "request_parameter": [], + "route_key": "POST /api/event/{eid}/questions/{secret}/{qid}/toggle/{property}", + "route_response_selection_expression": "", + "target": "integrations/tsl0pws" + }, + "sensitive_attributes": [], + "private": "bnVsbA==", + "dependencies": [ + "aws_apigatewayv2_api.www", + "aws_apigatewayv2_integration.www", + "aws_cloudwatch_log_group.lambda", + "aws_iam_policy.cloudwatch", + "aws_iam_policy.xray", + "aws_iam_role.www", + "aws_lambda_function.www", + "data.archive_file.lambda", + "data.aws_iam_policy_document.assume_role", + "data.aws_iam_policy_document.cloudwatch", + "data.aws_iam_policy_document.xray", + "data.aws_region.current", + "terraform_data.cargo_lambda" + ] + }, + { + "index_key": "post_vote", + "schema_version": 0, + "attributes": { + "api_id": "o19hhgzpd7", + "api_key_required": false, + "authorization_scopes": [], + "authorization_type": "NONE", + "authorizer_id": "", + "id": "rexgczk", + "model_selection_expression": "", + "operation_name": "", + "request_models": {}, + "request_parameter": [], + "route_key": "POST /api/vote/{qid}/{updown}", + "route_response_selection_expression": "", + "target": "integrations/tsl0pws" + }, + "sensitive_attributes": [], + "private": "bnVsbA==", + "dependencies": [ + "aws_apigatewayv2_api.www", + "aws_apigatewayv2_integration.www", + "aws_cloudwatch_log_group.lambda", + "aws_iam_policy.cloudwatch", + "aws_iam_policy.xray", + "aws_iam_role.www", + "aws_lambda_function.www", + "data.archive_file.lambda", + "data.aws_iam_policy_document.assume_role", + "data.aws_iam_policy_document.cloudwatch", + "data.aws_iam_policy_document.xray", + "data.aws_region.current", + "terraform_data.cargo_lambda" + ] + } + ] + }, + { + "mode": "managed", + "type": "aws_apigatewayv2_stage", + "name": "www", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [ + { + "schema_version": 0, + "attributes": { + "access_log_settings": [ + { + "destination_arn": "arn:aws:logs:eu-north-1:880545379339:log-group:/aws/api-gateway/wewerewondering", + "format": "{\"httpMethod\":\"$context.httpMethod\",\"ip\":\"$context.identity.sourceIp\",\"protocol\":\"$context.protocol\",\"requestId\":\"$context.requestId\",\"requestTime\":\"$context.requestTime\",\"responseLength\":\"$context.responseLength\",\"routeKey\":\"$context.routeKey\",\"status\":\"$context.status\"}" + } + ], + "api_id": "o19hhgzpd7", + "arn": "arn:aws:apigateway:eu-north-1::/apis/o19hhgzpd7/stages/$default", + "auto_deploy": true, + "client_certificate_id": "", + "default_route_settings": [ + { + "data_trace_enabled": false, + "detailed_metrics_enabled": false, + "logging_level": "", + "throttling_burst_limit": 250, + "throttling_rate_limit": 50 + } + ], + "deployment_id": "xopd61", + "description": "", + "execution_arn": "arn:aws:execute-api:eu-north-1:880545379339:o19hhgzpd7/$default", + "id": "$default", + "invoke_url": "https://o19hhgzpd7.execute-api.eu-north-1.amazonaws.com/", + "name": "$default", + "route_settings": [], + "stage_variables": {}, + "tags": {}, + "tags_all": {} + }, + "sensitive_attributes": [], + "private": "bnVsbA==", + "dependencies": [ + "aws_apigatewayv2_api.www", + "aws_cloudwatch_log_group.apigw" + ] + } + ] + }, + { + "mode": "managed", + "type": "aws_athena_named_query", + "name": "common_errs", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [ + { + "schema_version": 0, + "attributes": { + "database": "default", + "description": "", + "id": "e47cc71b-7176-42a9-b161-aa19b0521bf3", + "name": "Common errors", + "query": "SELECT\n request_ip,\n method,\n uri,\n status,\n COUNT(*) AS n\nFROM \"default\".\"cloudfront_logs\"\nWHERE status \u003e= 400\n AND from_iso8601_timestamp(concat(to_iso8601(\"date\"), 'T', time)) \u003e current_timestamp - interval '14' day\nGROUP BY status, method, uri, request_ip\nHAVING COUNT(*) \u003e 1\nORDER BY n DESC;\n", + "workgroup": "primary" + }, + "sensitive_attributes": [], + "private": "bnVsbA==", + "dependencies": [ + "aws_athena_workgroup.www", + "aws_s3_bucket.athena", + "data.aws_region.current" + ] + } + ] + }, + { + "mode": "managed", + "type": "aws_athena_named_query", + "name": "recent_errs", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [ + { + "schema_version": 0, + "attributes": { + "database": "default", + "description": "", + "id": "b4eecd35-9deb-4b8b-9397-cfdb80dea0bb", + "name": "Recent errors", + "query": "SELECT\n from_iso8601_timestamp(concat(to_iso8601(\"date\"), 'T', time)) AT TIME ZONE 'Europe/Oslo' as \"when\",\n request_ip,\n method,\n uri,\n status\nFROM \"default\".\"cloudfront_logs\"\nWHERE status \u003e= 400\n AND status \u003c= 599\n AND from_iso8601_timestamp(concat(to_iso8601(\"date\"), 'T', time)) \u003e current_timestamp - interval '8' hour\nORDER BY \"when\" DESC\nLIMIT 25;\n", + "workgroup": "primary" + }, + "sensitive_attributes": [], + "private": "bnVsbA==", + "dependencies": [ + "aws_athena_workgroup.www", + "aws_s3_bucket.athena", + "data.aws_region.current" + ] + } + ] + }, + { + "mode": "managed", + "type": "aws_athena_workgroup", + "name": "www", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [ + { + "schema_version": 0, + "attributes": { + "arn": "arn:aws:athena:eu-north-1:880545379339:workgroup/primary", + "configuration": [ + { + "bytes_scanned_cutoff_per_query": 0, + "enforce_workgroup_configuration": false, + "engine_version": [ + { + "effective_engine_version": "Athena engine version 3", + "selected_engine_version": "AUTO" + } + ], + "execution_role": "", + "publish_cloudwatch_metrics_enabled": false, + "requester_pays_enabled": false, + "result_configuration": [ + { + "acl_configuration": [], + "encryption_configuration": [], + "expected_bucket_owner": "", + "output_location": "s3://wewerewondering-eu-north-1-athena/" + } + ] + } + ], + "description": "", + "force_destroy": false, + "id": "primary", + "name": "primary", + "state": "ENABLED", + "tags": {}, + "tags_all": {} + }, + "sensitive_attributes": [], + "private": "bnVsbA==", + "dependencies": [ + "aws_s3_bucket.athena", + "data.aws_region.current" + ] + } + ] + }, + { + "mode": "managed", + "type": "aws_cloudfront_cache_policy", + "name": "cache_when_requested", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [ + { + "schema_version": 0, + "attributes": { + "comment": "", + "default_ttl": 1, + "etag": "E23ZP02F085DFQ", + "id": "fcc8df6d-6613-4210-8246-f45d18f04835", + "max_ttl": 31536000, + "min_ttl": 1, + "name": "CacheWhenRequested", + "parameters_in_cache_key_and_forwarded_to_origin": [ + { + "cookies_config": [ + { + "cookie_behavior": "none", + "cookies": [] + } + ], + "enable_accept_encoding_brotli": true, + "enable_accept_encoding_gzip": true, + "headers_config": [ + { + "header_behavior": "none", + "headers": [] + } + ], + "query_strings_config": [ + { + "query_string_behavior": "none", + "query_strings": [] + } + ] + } + ] + }, + "sensitive_attributes": [], + "private": "eyJzY2hlbWFfdmVyc2lvbiI6IjAifQ==" + } + ] + }, + { + "mode": "managed", + "type": "aws_cloudfront_distribution", + "name": "www", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [ + { + "schema_version": 1, + "attributes": { + "aliases": [ + "wewerewondering.com" + ], + "arn": "arn:aws:cloudfront::880545379339:distribution/E1ECZRHBXFKMHK", + "caller_reference": "b22ca123-3e1b-4b61-9a26-dd4910c7e1f6", + "comment": null, + "continuous_deployment_policy_id": "", + "custom_error_response": [], + "default_cache_behavior": [ + { + "allowed_methods": [ + "GET", + "HEAD" + ], + "cache_policy_id": "658327ea-f89d-4fab-a63d-7e88639e58f6", + "cached_methods": [ + "GET", + "HEAD" + ], + "compress": true, + "default_ttl": 0, + "field_level_encryption_id": "", + "forwarded_values": [], + "function_association": [ + { + "event_type": "viewer-request", + "function_arn": "arn:aws:cloudfront::880545379339:function/index-everywhere" + } + ], + "lambda_function_association": [], + "max_ttl": 0, + "min_ttl": 0, + "origin_request_policy_id": "", + "realtime_log_config_arn": "", + "response_headers_policy_id": "67f7725c-6f97-4210-82d7-5512b31e9d03", + "smooth_streaming": false, + "target_origin_id": "wewerewondering", + "trusted_key_groups": [], + "trusted_signers": [], + "viewer_protocol_policy": "redirect-to-https" + } + ], + "default_root_object": "index.html", + "domain_name": "d1tpt5x1e858xw.cloudfront.net", + "enabled": true, + "etag": "E2PI56HX4A1L6S", + "hosted_zone_id": "Z2FDTNDATAQYW2", + "http_version": "http2", + "id": "E1ECZRHBXFKMHK", + "in_progress_validation_batches": 0, + "is_ipv6_enabled": true, + "last_modified_time": "2023-12-30 15:18:45.217 +0000 UTC", + "logging_config": [ + { + "bucket": "wewerewondering-eu-north-1-logs.s3.amazonaws.com", + "include_cookies": false, + "prefix": "" + } + ], + "ordered_cache_behavior": [ + { + "allowed_methods": [ + "DELETE", + "GET", + "HEAD", + "OPTIONS", + "PATCH", + "POST", + "PUT" + ], + "cache_policy_id": "fcc8df6d-6613-4210-8246-f45d18f04835", + "cached_methods": [ + "GET", + "HEAD" + ], + "compress": true, + "default_ttl": 0, + "field_level_encryption_id": "", + "forwarded_values": [], + "function_association": [], + "lambda_function_association": [], + "max_ttl": 0, + "min_ttl": 0, + "origin_request_policy_id": "", + "path_pattern": "/api/*", + "realtime_log_config_arn": "", + "response_headers_policy_id": "67f7725c-6f97-4210-82d7-5512b31e9d03", + "smooth_streaming": false, + "target_origin_id": "wewerewondering-api", + "trusted_key_groups": [], + "trusted_signers": [], + "viewer_protocol_policy": "https-only" + } + ], + "origin": [ + { + "connection_attempts": 3, + "connection_timeout": 10, + "custom_header": [], + "custom_origin_config": [ + { + "http_port": 80, + "https_port": 443, + "origin_keepalive_timeout": 5, + "origin_protocol_policy": "https-only", + "origin_read_timeout": 30, + "origin_ssl_protocols": [ + "TLSv1.2" + ] + } + ], + "domain_name": "o19hhgzpd7.execute-api.eu-north-1.amazonaws.com", + "origin_access_control_id": "", + "origin_id": "wewerewondering-api", + "origin_path": "", + "origin_shield": [], + "s3_origin_config": [] + }, + { + "connection_attempts": 3, + "connection_timeout": 10, + "custom_header": [], + "custom_origin_config": [], + "domain_name": "wewerewondering-eu-north-1-static.s3.eu-north-1.amazonaws.com", + "origin_access_control_id": "E2O0QG272YYJYR", + "origin_id": "wewerewondering", + "origin_path": "", + "origin_shield": [], + "s3_origin_config": [] + } + ], + "origin_group": [], + "price_class": "PriceClass_All", + "restrictions": [ + { + "geo_restriction": [ + { + "locations": [], + "restriction_type": "none" + } + ] + } + ], + "retain_on_delete": false, + "staging": false, + "status": "Deployed", + "tags": {}, + "tags_all": {}, + "trusted_key_groups": [ + { + "enabled": false, + "items": [] + } + ], + "trusted_signers": [ + { + "enabled": false, + "items": [] + } + ], + "viewer_certificate": [ + { + "acm_certificate_arn": "arn:aws:acm:us-east-1:880545379339:certificate/f3e11148-9740-4b7f-a1a6-da43e045cef0", + "cloudfront_default_certificate": false, + "iam_certificate_id": "", + "minimum_protocol_version": "TLSv1.2_2021", + "ssl_support_method": "sni-only" + } + ], + "wait_for_deployment": true, + "web_acl_id": "" + }, + "sensitive_attributes": [], + "private": "eyJzY2hlbWFfdmVyc2lvbiI6IjEifQ==", + "dependencies": [ + "aws_acm_certificate.www", + "aws_acm_certificate_validation.www", + "aws_apigatewayv2_api.www", + "aws_cloudfront_cache_policy.cache_when_requested", + "aws_cloudfront_function.index_everywhere", + "aws_cloudfront_origin_access_control.static", + "aws_route53_record.www_cert", + "aws_route53_zone.www", + "aws_s3_bucket.logs", + "aws_s3_bucket.static", + "data.aws_region.current" + ] + } + ] + }, + { + "mode": "managed", + "type": "aws_cloudfront_function", + "name": "index_everywhere", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [ + { + "schema_version": 0, + "attributes": { + "arn": "arn:aws:cloudfront::880545379339:function/index-everywhere", + "code": "function handler(event) {\n var req = event.request;\n if (\n req.uri.startsWith('/event/')\n ) {\n req.uri = '/index.html';\n }\n return req;\n}\n", + "comment": "", + "etag": "E1VC38T7YXB528", + "id": "index-everywhere", + "live_stage_etag": "E1PA6795UKMFR9", + "name": "index-everywhere", + "publish": true, + "runtime": "cloudfront-js-2.0", + "status": "DEPLOYED" + }, + "sensitive_attributes": [], + "private": "bnVsbA==" + } + ] + }, + { + "mode": "managed", + "type": "aws_cloudfront_origin_access_control", + "name": "static", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [ + { + "schema_version": 0, + "attributes": { + "description": "Managed by Terraform", + "etag": "E1F83G8C2ARO7P", + "id": "E2O0QG272YYJYR", + "name": "wewerewondering-eu-north-1-static.s3.eu-north-1.amazonaws.com", + "origin_access_control_origin_type": "s3", + "signing_behavior": "always", + "signing_protocol": "sigv4" + }, + "sensitive_attributes": [], + "private": "bnVsbA==", + "dependencies": [ + "aws_s3_bucket.static", + "data.aws_region.current" + ] + } + ] + }, + { + "mode": "managed", + "type": "aws_cloudwatch_dashboard", + "name": "www", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [ + { + "schema_version": 0, + "attributes": { + "dashboard_arn": "arn:aws:cloudwatch::880545379339:dashboard/ApiGatewayHttp", + "dashboard_body": "{\"widgets\":[{\"height\":4,\"properties\":{\"legend\":{\"position\":\"bottom\"},\"liveData\":false,\"metrics\":[[\"AWS/ApiGateway\",\"Count\",\"ApiId\",\"o19hhgzpd7\",{\"period\":300,\"stat\":\"Sum\"}]],\"period\":300,\"region\":\"eu-north-1\",\"stacked\":false,\"title\":\"Count: Sum\",\"view\":\"timeSeries\"},\"type\":\"metric\",\"width\":8,\"x\":0,\"y\":0},{\"height\":4,\"properties\":{\"legend\":{\"position\":\"bottom\"},\"liveData\":false,\"metrics\":[[\"AWS/ApiGateway\",\"5xx\",\"ApiId\",\"o19hhgzpd7\",{\"period\":300,\"stat\":\"Sum\"}]],\"period\":300,\"region\":\"eu-north-1\",\"stacked\":false,\"title\":\"5XXError: Sum\",\"view\":\"timeSeries\"},\"type\":\"metric\",\"width\":8,\"x\":8,\"y\":0},{\"height\":4,\"properties\":{\"legend\":{\"position\":\"bottom\"},\"liveData\":false,\"metrics\":[[\"AWS/ApiGateway\",\"4xx\",\"ApiId\",\"o19hhgzpd7\",{\"period\":300,\"stat\":\"Sum\"}]],\"period\":300,\"region\":\"eu-north-1\",\"stacked\":false,\"title\":\"4XXError: Sum\",\"view\":\"timeSeries\"},\"type\":\"metric\",\"width\":8,\"x\":16,\"y\":0},{\"height\":4,\"properties\":{\"legend\":{\"position\":\"bottom\"},\"liveData\":false,\"metrics\":[[\"AWS/ApiGateway\",\"Latency\",\"ApiId\",\"o19hhgzpd7\",{\"period\":300,\"stat\":\"Average\"}]],\"period\":300,\"region\":\"eu-north-1\",\"stacked\":false,\"title\":\"Latency: Average\",\"view\":\"timeSeries\"},\"type\":\"metric\",\"width\":12,\"x\":0,\"y\":4},{\"height\":4,\"properties\":{\"legend\":{\"position\":\"bottom\"},\"liveData\":false,\"metrics\":[[\"AWS/ApiGateway\",\"IntegrationLatency\",\"ApiId\",\"o19hhgzpd7\",{\"period\":300,\"stat\":\"Average\"}]],\"period\":300,\"region\":\"eu-north-1\",\"stacked\":false,\"title\":\"IntegrationLatency: Average\",\"view\":\"timeSeries\"},\"type\":\"metric\",\"width\":12,\"x\":12,\"y\":4},{\"height\":4,\"properties\":{\"legend\":{\"position\":\"bottom\"},\"liveData\":false,\"metrics\":[[\"AWS/ApiGateway\",\"DataProcessed\",\"ApiId\",\"o19hhgzpd7\",{\"period\":300,\"stat\":\"Sum\"}]],\"period\":300,\"region\":\"eu-north-1\",\"stacked\":false,\"title\":\"DataProcessed: Sum\",\"view\":\"timeSeries\"},\"type\":\"metric\",\"width\":24,\"x\":0,\"y\":8}]}", + "dashboard_name": "ApiGatewayHttp", + "id": "ApiGatewayHttp" + }, + "sensitive_attributes": [], + "private": "bnVsbA==", + "dependencies": [ + "aws_apigatewayv2_api.www", + "data.aws_region.current" + ] + } + ] + }, + { + "mode": "managed", + "type": "aws_cloudwatch_log_group", + "name": "apigw", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [ + { + "schema_version": 0, + "attributes": { + "arn": "arn:aws:logs:eu-north-1:880545379339:log-group:/aws/api-gateway/wewerewondering", + "id": "/aws/api-gateway/wewerewondering", + "kms_key_id": "", + "log_group_class": "STANDARD", + "name": "/aws/api-gateway/wewerewondering", + "name_prefix": "", + "retention_in_days": 180, + "skip_destroy": false, + "tags": {}, + "tags_all": {} + }, + "sensitive_attributes": [], + "private": "bnVsbA==" + } + ] + }, + { + "mode": "managed", + "type": "aws_cloudwatch_log_group", + "name": "lambda", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [ + { + "schema_version": 0, + "attributes": { + "arn": "arn:aws:logs:eu-north-1:880545379339:log-group:/aws/lambda/wewerewondering-api", + "id": "/aws/lambda/wewerewondering-api", + "kms_key_id": "", + "log_group_class": "STANDARD", + "name": "/aws/lambda/wewerewondering-api", + "name_prefix": "", + "retention_in_days": 180, + "skip_destroy": false, + "tags": {}, + "tags_all": {} + }, + "sensitive_attributes": [], + "private": "bnVsbA==" + } + ] + }, + { + "mode": "managed", + "type": "aws_dynamodb_table", + "name": "events", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [ + { + "schema_version": 1, + "attributes": { + "arn": "arn:aws:dynamodb:eu-north-1:880545379339:table/events", + "attribute": [ + { + "name": "id", + "type": "S" + } + ], + "billing_mode": "PAY_PER_REQUEST", + "deletion_protection_enabled": false, + "global_secondary_index": [], + "hash_key": "id", + "id": "events", + "import_table": [], + "local_secondary_index": [], + "name": "events", + "point_in_time_recovery": [ + { + "enabled": false + } + ], + "range_key": null, + "read_capacity": 0, + "replica": [], + "restore_date_time": null, + "restore_source_name": null, + "restore_to_latest_time": null, + "server_side_encryption": [], + "stream_arn": "", + "stream_enabled": false, + "stream_label": "", + "stream_view_type": "", + "table_class": "STANDARD", + "tags": {}, + "tags_all": {}, + "timeouts": null, + "ttl": [ + { + "attribute_name": "expire", + "enabled": true + } + ], + "write_capacity": 0 + }, + "sensitive_attributes": [], + "private": "eyJlMmJmYjczMC1lY2FhLTExZTYtOGY4OC0zNDM2M2JjN2M0YzAiOnsiY3JlYXRlIjoxODAwMDAwMDAwMDAwLCJkZWxldGUiOjYwMDAwMDAwMDAwMCwidXBkYXRlIjozNjAwMDAwMDAwMDAwfSwic2NoZW1hX3ZlcnNpb24iOiIxIn0=" + } + ] + }, + { + "mode": "managed", + "type": "aws_dynamodb_table", + "name": "questions", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [ + { + "schema_version": 1, + "attributes": { + "arn": "arn:aws:dynamodb:eu-north-1:880545379339:table/questions", + "attribute": [ + { + "name": "eid", + "type": "S" + }, + { + "name": "id", + "type": "S" + }, + { + "name": "votes", + "type": "N" + } + ], + "billing_mode": "PAY_PER_REQUEST", + "deletion_protection_enabled": false, + "global_secondary_index": [ + { + "hash_key": "eid", + "name": "top", + "non_key_attributes": [ + "answered", + "hidden" + ], + "projection_type": "INCLUDE", + "range_key": "votes", + "read_capacity": 0, + "write_capacity": 0 + } + ], + "hash_key": "id", + "id": "questions", + "import_table": [], + "local_secondary_index": [], + "name": "questions", + "point_in_time_recovery": [ + { + "enabled": false + } + ], + "range_key": null, + "read_capacity": 0, + "replica": [], + "restore_date_time": null, + "restore_source_name": null, + "restore_to_latest_time": null, + "server_side_encryption": [], + "stream_arn": "", + "stream_enabled": false, + "stream_label": "", + "stream_view_type": "", + "table_class": "STANDARD", + "tags": {}, + "tags_all": {}, + "timeouts": null, + "ttl": [ + { + "attribute_name": "expire", + "enabled": true + } + ], + "write_capacity": 0 + }, + "sensitive_attributes": [], + "private": "eyJlMmJmYjczMC1lY2FhLTExZTYtOGY4OC0zNDM2M2JjN2M0YzAiOnsiY3JlYXRlIjoxODAwMDAwMDAwMDAwLCJkZWxldGUiOjYwMDAwMDAwMDAwMCwidXBkYXRlIjozNjAwMDAwMDAwMDAwfSwic2NoZW1hX3ZlcnNpb24iOiIxIn0=" + } + ] + }, + { + "mode": "managed", + "type": "aws_glue_catalog_database", + "name": "default", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [ + { + "schema_version": 0, + "attributes": { + "arn": "arn:aws:glue:eu-north-1:880545379339:database/default", + "catalog_id": "880545379339", + "create_table_default_permission": [ + { + "permissions": [ + "ALL" + ], + "principal": [ + { + "data_lake_principal_identifier": "IAM_ALLOWED_PRINCIPALS" + } + ] + } + ], + "description": "", + "id": "880545379339:default", + "location_uri": "", + "name": "default", + "parameters": {}, + "tags": {}, + "tags_all": {}, + "target_database": [] + }, + "sensitive_attributes": [], + "private": "bnVsbA==" + } + ] + }, + { + "mode": "managed", + "type": "aws_glue_catalog_table", + "name": "cf_logs", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [ + { + "schema_version": 0, + "attributes": { + "arn": "arn:aws:glue:eu-north-1:880545379339:table/default/cloudfront_logs", + "catalog_id": "880545379339", + "database_name": "default", + "description": "", + "id": "880545379339:default:cloudfront_logs", + "name": "cloudfront_logs", + "open_table_format_input": [], + "owner": "hadoop", + "parameters": { + "EXTERNAL": "TRUE", + "skip.header.line.count": "2" + }, + "partition_index": [], + "partition_keys": [], + "retention": 0, + "storage_descriptor": [ + { + "bucket_columns": [], + "columns": [ + { + "comment": "", + "name": "date", + "parameters": {}, + "type": "date" + }, + { + "comment": "", + "name": "time", + "parameters": {}, + "type": "string" + }, + { + "comment": "", + "name": "location", + "parameters": {}, + "type": "string" + }, + { + "comment": "", + "name": "bytes", + "parameters": {}, + "type": "bigint" + }, + { + "comment": "", + "name": "request_ip", + "parameters": {}, + "type": "string" + }, + { + "comment": "", + "name": "method", + "parameters": {}, + "type": "string" + }, + { + "comment": "", + "name": "host", + "parameters": {}, + "type": "string" + }, + { + "comment": "", + "name": "uri", + "parameters": {}, + "type": "string" + }, + { + "comment": "", + "name": "status", + "parameters": {}, + "type": "int" + }, + { + "comment": "", + "name": "referrer", + "parameters": {}, + "type": "string" + }, + { + "comment": "", + "name": "user_agent", + "parameters": {}, + "type": "string" + }, + { + "comment": "", + "name": "query_string", + "parameters": {}, + "type": "string" + }, + { + "comment": "", + "name": "cookie", + "parameters": {}, + "type": "string" + }, + { + "comment": "", + "name": "result_type", + "parameters": {}, + "type": "string" + }, + { + "comment": "", + "name": "request_id", + "parameters": {}, + "type": "string" + }, + { + "comment": "", + "name": "host_header", + "parameters": {}, + "type": "string" + }, + { + "comment": "", + "name": "request_protocol", + "parameters": {}, + "type": "string" + }, + { + "comment": "", + "name": "request_bytes", + "parameters": {}, + "type": "bigint" + }, + { + "comment": "", + "name": "time_taken", + "parameters": {}, + "type": "float" + }, + { + "comment": "", + "name": "xforwarded_for", + "parameters": {}, + "type": "string" + }, + { + "comment": "", + "name": "ssl_protocol", + "parameters": {}, + "type": "string" + }, + { + "comment": "", + "name": "ssl_cipher", + "parameters": {}, + "type": "string" + }, + { + "comment": "", + "name": "response_result_type", + "parameters": {}, + "type": "string" + }, + { + "comment": "", + "name": "http_version", + "parameters": {}, + "type": "string" + }, + { + "comment": "", + "name": "fle_status", + "parameters": {}, + "type": "string" + }, + { + "comment": "", + "name": "fle_encrypted_fields", + "parameters": {}, + "type": "int" + }, + { + "comment": "", + "name": "c_port", + "parameters": {}, + "type": "int" + }, + { + "comment": "", + "name": "time_to_first_byte", + "parameters": {}, + "type": "float" + }, + { + "comment": "", + "name": "x_edge_detailed_result_type", + "parameters": {}, + "type": "string" + }, + { + "comment": "", + "name": "sc_content_type", + "parameters": {}, + "type": "string" + }, + { + "comment": "", + "name": "sc_content_len", + "parameters": {}, + "type": "bigint" + }, + { + "comment": "", + "name": "sc_range_start", + "parameters": {}, + "type": "bigint" + }, + { + "comment": "", + "name": "sc_range_end", + "parameters": {}, + "type": "bigint" + } + ], + "compressed": false, + "input_format": "org.apache.hadoop.mapred.TextInputFormat", + "location": "s3://wewerewondering-eu-north-1-logs/", + "number_of_buckets": 0, + "output_format": "org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat", + "parameters": {}, + "schema_reference": [], + "ser_de_info": [ + { + "name": "", + "parameters": { + "field.delim": "\t", + "serialization.format": "\t" + }, + "serialization_library": "org.apache.hadoop.hive.serde2.lazy.LazySimpleSerDe" + } + ], + "skewed_info": [], + "sort_columns": [], + "stored_as_sub_directories": false + } + ], + "table_type": "EXTERNAL_TABLE", + "target_table": [], + "view_expanded_text": "", + "view_original_text": "" + }, + "sensitive_attributes": [], + "private": "bnVsbA==", + "dependencies": [ + "aws_glue_catalog_database.default", + "aws_s3_bucket.logs", + "data.aws_region.current" + ] + } + ] + }, + { + "mode": "managed", + "type": "aws_iam_policy", + "name": "cloudwatch", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [ + { + "schema_version": 0, + "attributes": { + "arn": "arn:aws:iam::880545379339:policy/service-role/AWSLambdaBasicExecutionRole-b586114a-ba08-47b0-afe0-82c4d81857a0", + "description": "", + "id": "arn:aws:iam::880545379339:policy/service-role/AWSLambdaBasicExecutionRole-b586114a-ba08-47b0-afe0-82c4d81857a0", + "name": "AWSLambdaBasicExecutionRole-b586114a-ba08-47b0-afe0-82c4d81857a0", + "name_prefix": "", + "path": "/service-role/", + "policy": "{\"Statement\":[{\"Action\":\"logs:CreateLogGroup\",\"Effect\":\"Allow\",\"Resource\":\"arn:aws:logs:eu-north-1:880545379339:log-group:/aws/lambda/wewerewondering-api\"},{\"Action\":[\"logs:PutLogEvents\",\"logs:CreateLogStream\"],\"Effect\":\"Allow\",\"Resource\":\"arn:aws:logs:eu-north-1:880545379339:log-group:/aws/lambda/wewerewondering-api:*\"}],\"Version\":\"2012-10-17\"}", + "policy_id": "ANPA42BEYGQFUFQP345G2", + "tags": {}, + "tags_all": {} + }, + "sensitive_attributes": [], + "private": "bnVsbA==", + "dependencies": [ + "aws_cloudwatch_log_group.lambda", + "data.aws_iam_policy_document.cloudwatch" + ] + } + ] + }, + { + "mode": "managed", + "type": "aws_iam_policy", + "name": "xray", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [ + { + "schema_version": 0, + "attributes": { + "arn": "arn:aws:iam::880545379339:policy/service-role/AWSLambdaTracerAccessExecutionRole-14a6d1b5-3a03-4b02-94ca-fec2eced24ab", + "description": "", + "id": "arn:aws:iam::880545379339:policy/service-role/AWSLambdaTracerAccessExecutionRole-14a6d1b5-3a03-4b02-94ca-fec2eced24ab", + "name": "AWSLambdaTracerAccessExecutionRole-14a6d1b5-3a03-4b02-94ca-fec2eced24ab", + "name_prefix": "", + "path": "/service-role/", + "policy": "{\"Statement\":{\"Action\":[\"xray:PutTraceSegments\",\"xray:PutTelemetryRecords\"],\"Effect\":\"Allow\",\"Resource\":[\"*\"]},\"Version\":\"2012-10-17\"}", + "policy_id": "ANPA42BEYGQFURDTSX7I6", + "tags": {}, + "tags_all": {} + }, + "sensitive_attributes": [], + "private": "eyJzY2hlbWFfdmVyc2lvbiI6IjAifQ==", + "dependencies": [ + "data.aws_iam_policy_document.xray" + ] + } + ] + }, + { + "mode": "managed", + "type": "aws_iam_role", + "name": "apigw_cw", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [ + { + "schema_version": 0, + "attributes": { + "arn": "arn:aws:iam::880545379339:role/wewerewondering-api-gw", + "assume_role_policy": "{\"Statement\":[{\"Action\":\"sts:AssumeRole\",\"Effect\":\"Allow\",\"Principal\":{\"Service\":\"apigateway.amazonaws.com\"},\"Sid\":\"\"}],\"Version\":\"2012-10-17\"}", + "create_date": "2022-11-12T17:49:12Z", + "description": "Allows API Gateway to push logs to CloudWatch Logs.", + "force_detach_policies": false, + "id": "wewerewondering-api-gw", + "inline_policy": [], + "managed_policy_arns": [ + "arn:aws:iam::aws:policy/service-role/AmazonAPIGatewayPushToCloudWatchLogs" + ], + "max_session_duration": 3600, + "name": "wewerewondering-api-gw", + "name_prefix": "", + "path": "/", + "permissions_boundary": "", + "tags": {}, + "tags_all": {}, + "unique_id": "AROA42BEYGQF3GYGY7VBN" + }, + "sensitive_attributes": [], + "private": "eyJzY2hlbWFfdmVyc2lvbiI6IjAifQ==", + "dependencies": [ + "data.aws_iam_policy_document.apigw_assume" + ] + } + ] + }, + { + "mode": "managed", + "type": "aws_iam_role", + "name": "www", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [ + { + "schema_version": 0, + "attributes": { + "arn": "arn:aws:iam::880545379339:role/service-role/wewerewondering-api", + "assume_role_policy": "{\"Statement\":[{\"Action\":\"sts:AssumeRole\",\"Effect\":\"Allow\",\"Principal\":{\"Service\":\"lambda.amazonaws.com\"}}],\"Version\":\"2012-10-17\"}", + "create_date": "2022-11-12T00:59:22Z", + "description": "", + "force_detach_policies": false, + "id": "wewerewondering-api", + "inline_policy": [ + { + "name": "api-db-access", + "policy": "{\"Version\":\"2012-10-17\",\"Statement\":[{\"Action\":[\"dynamodb:UpdateItem\",\"dynamodb:Scan\",\"dynamodb:Query\",\"dynamodb:PutItem\",\"dynamodb:GetItem\",\"dynamodb:BatchGetItem\"],\"Effect\":\"Allow\",\"Resource\":[\"arn:aws:dynamodb:eu-north-1:880545379339:table/questions/index/top\",\"arn:aws:dynamodb:eu-north-1:880545379339:table/questions\",\"arn:aws:dynamodb:eu-north-1:880545379339:table/events\"]}]}" + } + ], + "managed_policy_arns": [ + "arn:aws:iam::880545379339:policy/service-role/AWSLambdaBasicExecutionRole-b586114a-ba08-47b0-afe0-82c4d81857a0", + "arn:aws:iam::880545379339:policy/service-role/AWSLambdaTracerAccessExecutionRole-14a6d1b5-3a03-4b02-94ca-fec2eced24ab", + "arn:aws:iam::aws:policy/CloudWatchLambdaInsightsExecutionRolePolicy" + ], + "max_session_duration": 3600, + "name": "wewerewondering-api", + "name_prefix": "", + "path": "/service-role/", + "permissions_boundary": "", + "tags": {}, + "tags_all": {}, + "unique_id": "AROA42BEYGQF75AG26GYC" + }, + "sensitive_attributes": [], + "private": "eyJzY2hlbWFfdmVyc2lvbiI6IjAifQ==", + "dependencies": [ + "aws_cloudwatch_log_group.lambda", + "aws_iam_policy.cloudwatch", + "aws_iam_policy.xray", + "data.aws_iam_policy_document.assume_role", + "data.aws_iam_policy_document.cloudwatch", + "data.aws_iam_policy_document.xray" + ] + } + ] + }, + { + "mode": "managed", + "type": "aws_iam_role_policy", + "name": "dynamodb", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [ + { + "schema_version": 0, + "attributes": { + "id": "wewerewondering-api:api-db-access", + "name": "api-db-access", + "name_prefix": "", + "policy": "{\"Version\":\"2012-10-17\",\"Statement\":[{\"Action\":[\"dynamodb:UpdateItem\",\"dynamodb:Scan\",\"dynamodb:Query\",\"dynamodb:PutItem\",\"dynamodb:GetItem\",\"dynamodb:BatchGetItem\"],\"Effect\":\"Allow\",\"Resource\":[\"arn:aws:dynamodb:eu-north-1:880545379339:table/questions/index/top\",\"arn:aws:dynamodb:eu-north-1:880545379339:table/questions\",\"arn:aws:dynamodb:eu-north-1:880545379339:table/events\"]}]}", + "role": "wewerewondering-api" + }, + "sensitive_attributes": [], + "private": "bnVsbA==", + "dependencies": [ + "aws_cloudwatch_log_group.lambda", + "aws_dynamodb_table.events", + "aws_dynamodb_table.questions", + "aws_iam_policy.cloudwatch", + "aws_iam_policy.xray", + "aws_iam_role.www", + "data.aws_iam_policy_document.assume_role", + "data.aws_iam_policy_document.cloudwatch", + "data.aws_iam_policy_document.dynamodb", + "data.aws_iam_policy_document.xray" + ] + } + ] + }, + { + "mode": "managed", + "type": "aws_lambda_function", + "name": "www", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [ + { + "schema_version": 0, + "attributes": { + "architectures": [ + "arm64" + ], + "arn": "arn:aws:lambda:eu-north-1:880545379339:function:wewerewondering-api", + "code_signing_config_arn": "", + "dead_letter_config": [], + "description": "", + "environment": [ + { + "variables": { + "RUST_LOG": "info,tower_http=debug,wewerewondering_api=trace" + } + } + ], + "ephemeral_storage": [ + { + "size": 512 + } + ], + "file_system_config": [], + "filename": "lambda_function_payload.zip", + "function_name": "wewerewondering-api", + "handler": "bootstrap", + "id": "wewerewondering-api", + "image_config": [], + "image_uri": "", + "invoke_arn": "arn:aws:apigateway:eu-north-1:lambda:path/2015-03-31/functions/arn:aws:lambda:eu-north-1:880545379339:function:wewerewondering-api/invocations", + "kms_key_arn": "", + "last_modified": "2023-12-30T15:37:33.284+0000", + "layers": [ + "arn:aws:lambda:eu-north-1:580247275435:layer:LambdaInsightsExtension-Arm64:5" + ], + "memory_size": 128, + "package_type": "Zip", + "publish": false, + "qualified_arn": "arn:aws:lambda:eu-north-1:880545379339:function:wewerewondering-api:$LATEST", + "qualified_invoke_arn": "arn:aws:apigateway:eu-north-1:lambda:path/2015-03-31/functions/arn:aws:lambda:eu-north-1:880545379339:function:wewerewondering-api:$LATEST/invocations", + "replace_security_groups_on_destroy": null, + "replacement_security_group_ids": null, + "reserved_concurrent_executions": -1, + "role": "arn:aws:iam::880545379339:role/service-role/wewerewondering-api", + "runtime": "provided.al2", + "s3_bucket": null, + "s3_key": null, + "s3_object_version": null, + "signing_job_arn": "", + "signing_profile_version_arn": "", + "skip_destroy": false, + "snap_start": [], + "source_code_hash": "W7E2gnu4p+aHm166MT2kMU9QoAApHKXAUl7VRfMdomE=", + "source_code_size": 4715533, + "tags": {}, + "tags_all": {}, + "timeout": 30, + "timeouts": null, + "tracing_config": [ + { + "mode": "PassThrough" + } + ], + "version": "$LATEST", + "vpc_config": [] + }, + "sensitive_attributes": [], + "private": "eyJlMmJmYjczMC1lY2FhLTExZTYtOGY4OC0zNDM2M2JjN2M0YzAiOnsiY3JlYXRlIjo2MDAwMDAwMDAwMDAsImRlbGV0ZSI6NjAwMDAwMDAwMDAwLCJ1cGRhdGUiOjYwMDAwMDAwMDAwMH19", + "dependencies": [ + "aws_cloudwatch_log_group.lambda", + "aws_iam_policy.cloudwatch", + "aws_iam_policy.xray", + "aws_iam_role.www", + "data.archive_file.lambda", + "data.aws_iam_policy_document.assume_role", + "data.aws_iam_policy_document.cloudwatch", + "data.aws_iam_policy_document.xray", + "data.aws_region.current", + "terraform_data.cargo_lambda" + ] + } + ] + }, + { + "mode": "managed", + "type": "aws_lambda_permission", + "name": "www", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [ + { + "schema_version": 0, + "attributes": { + "action": "lambda:InvokeFunction", + "event_source_token": null, + "function_name": "wewerewondering-api", + "function_url_auth_type": null, + "id": "AllowExecutionFromAPIGateway", + "principal": "apigateway.amazonaws.com", + "principal_org_id": null, + "qualifier": "", + "source_account": null, + "source_arn": "arn:aws:execute-api:eu-north-1:880545379339:o19hhgzpd7/$default/*", + "statement_id": "AllowExecutionFromAPIGateway", + "statement_id_prefix": "" + }, + "sensitive_attributes": [], + "private": "bnVsbA==", + "dependencies": [ + "aws_apigatewayv2_api.www", + "aws_apigatewayv2_stage.www", + "aws_cloudwatch_log_group.apigw", + "aws_cloudwatch_log_group.lambda", + "aws_iam_policy.cloudwatch", + "aws_iam_policy.xray", + "aws_iam_role.www", + "aws_lambda_function.www", + "data.archive_file.lambda", + "data.aws_iam_policy_document.assume_role", + "data.aws_iam_policy_document.cloudwatch", + "data.aws_iam_policy_document.xray", + "data.aws_region.current", + "terraform_data.cargo_lambda" + ] + } + ] + }, + { + "mode": "managed", + "type": "aws_route53_record", + "name": "www_cert", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [ + { + "index_key": "wewerewondering.com", + "schema_version": 2, + "attributes": { + "alias": [], + "allow_overwrite": true, + "cidr_routing_policy": [], + "failover_routing_policy": [], + "fqdn": "_c7b659fc5b836da864d8c39af1a6c6b8.wewerewondering.com", + "geolocation_routing_policy": [], + "health_check_id": "", + "id": "Z0224639SZ3FM93JW8DU__c7b659fc5b836da864d8c39af1a6c6b8.wewerewondering.com._CNAME", + "latency_routing_policy": [], + "multivalue_answer_routing_policy": false, + "name": "_c7b659fc5b836da864d8c39af1a6c6b8.wewerewondering.com", + "records": [ + "_2466ad9183460f6cd658e384440b4c12.yzdtlljtvc.acm-validations.aws." + ], + "set_identifier": "", + "ttl": 60, + "type": "CNAME", + "weighted_routing_policy": [], + "zone_id": "Z0224639SZ3FM93JW8DU" + }, + "sensitive_attributes": [], + "private": "eyJzY2hlbWFfdmVyc2lvbiI6IjIifQ==", + "dependencies": [ + "aws_acm_certificate.www", + "aws_route53_zone.www" + ] + } + ] + }, + { + "mode": "managed", + "type": "aws_route53_record", + "name": "www_cf", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [ + { + "schema_version": 2, + "attributes": { + "alias": [ + { + "evaluate_target_health": false, + "name": "d1tpt5x1e858xw.cloudfront.net", + "zone_id": "Z2FDTNDATAQYW2" + } + ], + "allow_overwrite": null, + "cidr_routing_policy": [], + "failover_routing_policy": [], + "fqdn": "wewerewondering.com", + "geolocation_routing_policy": [], + "health_check_id": "", + "id": "Z0224639SZ3FM93JW8DU_wewerewondering.com_A", + "latency_routing_policy": [], + "multivalue_answer_routing_policy": false, + "name": "wewerewondering.com", + "records": [], + "set_identifier": "", + "ttl": 0, + "type": "A", + "weighted_routing_policy": [], + "zone_id": "Z0224639SZ3FM93JW8DU" + }, + "sensitive_attributes": [], + "private": "eyJzY2hlbWFfdmVyc2lvbiI6IjIifQ==", + "dependencies": [ + "aws_acm_certificate.www", + "aws_acm_certificate_validation.www", + "aws_apigatewayv2_api.www", + "aws_cloudfront_cache_policy.cache_when_requested", + "aws_cloudfront_distribution.www", + "aws_cloudfront_function.index_everywhere", + "aws_cloudfront_origin_access_control.static", + "aws_route53_record.www_cert", + "aws_route53_zone.www", + "aws_s3_bucket.logs", + "aws_s3_bucket.static", + "data.aws_region.current" + ] + } + ] + }, + { + "mode": "managed", + "type": "aws_route53_record", + "name": "www_cf_v6", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [ + { + "schema_version": 2, + "attributes": { + "alias": [ + { + "evaluate_target_health": false, + "name": "d1tpt5x1e858xw.cloudfront.net", + "zone_id": "Z2FDTNDATAQYW2" + } + ], + "allow_overwrite": null, + "cidr_routing_policy": [], + "failover_routing_policy": [], + "fqdn": "wewerewondering.com", + "geolocation_routing_policy": [], + "health_check_id": "", + "id": "Z0224639SZ3FM93JW8DU_wewerewondering.com_AAAA", + "latency_routing_policy": [], + "multivalue_answer_routing_policy": false, + "name": "wewerewondering.com", + "records": [], + "set_identifier": "", + "ttl": 0, + "type": "AAAA", + "weighted_routing_policy": [], + "zone_id": "Z0224639SZ3FM93JW8DU" + }, + "sensitive_attributes": [], + "private": "eyJzY2hlbWFfdmVyc2lvbiI6IjIifQ==", + "dependencies": [ + "aws_acm_certificate.www", + "aws_acm_certificate_validation.www", + "aws_apigatewayv2_api.www", + "aws_cloudfront_cache_policy.cache_when_requested", + "aws_cloudfront_distribution.www", + "aws_cloudfront_function.index_everywhere", + "aws_cloudfront_origin_access_control.static", + "aws_route53_record.www_cert", + "aws_route53_zone.www", + "aws_s3_bucket.logs", + "aws_s3_bucket.static", + "data.aws_region.current" + ] + } + ] + }, + { + "mode": "managed", + "type": "aws_route53_record", + "name": "www_mx", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [ + { + "schema_version": 2, + "attributes": { + "alias": [], + "allow_overwrite": null, + "cidr_routing_policy": [], + "failover_routing_policy": [], + "fqdn": "wewerewondering.com", + "geolocation_routing_policy": [], + "health_check_id": "", + "id": "Z0224639SZ3FM93JW8DU_wewerewondering.com_MX", + "latency_routing_policy": [], + "multivalue_answer_routing_policy": false, + "name": "wewerewondering.com", + "records": [ + "10 mx1.improvmx.com", + "20 mx2.improvmx.com" + ], + "set_identifier": "", + "ttl": 3600, + "type": "MX", + "weighted_routing_policy": [], + "zone_id": "Z0224639SZ3FM93JW8DU" + }, + "sensitive_attributes": [], + "private": "eyJzY2hlbWFfdmVyc2lvbiI6IjIifQ==", + "dependencies": [ + "aws_route53_zone.www" + ] + } + ] + }, + { + "mode": "managed", + "type": "aws_route53_record", + "name": "www_spf", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [ + { + "schema_version": 2, + "attributes": { + "alias": [], + "allow_overwrite": null, + "cidr_routing_policy": [], + "failover_routing_policy": [], + "fqdn": "wewerewondering.com", + "geolocation_routing_policy": [], + "health_check_id": "", + "id": "Z0224639SZ3FM93JW8DU_wewerewondering.com_TXT", + "latency_routing_policy": [], + "multivalue_answer_routing_policy": false, + "name": "wewerewondering.com", + "records": [ + "v=spf1 include:spf.improvmx.com ~all" + ], + "set_identifier": "", + "ttl": 3600, + "type": "TXT", + "weighted_routing_policy": [], + "zone_id": "Z0224639SZ3FM93JW8DU" + }, + "sensitive_attributes": [], + "private": "eyJzY2hlbWFfdmVyc2lvbiI6IjIifQ==", + "dependencies": [ + "aws_route53_zone.www" + ] + } + ] + }, + { + "mode": "managed", + "type": "aws_route53_zone", + "name": "www", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [ + { + "schema_version": 0, + "attributes": { + "arn": "arn:aws:route53:::hostedzone/Z0224639SZ3FM93JW8DU", + "comment": "Managed by Terraform", + "delegation_set_id": "", + "force_destroy": false, + "id": "Z0224639SZ3FM93JW8DU", + "name": "wewerewondering.com", + "name_servers": [ + "ns-1118.awsdns-11.org", + "ns-1967.awsdns-53.co.uk", + "ns-494.awsdns-61.com", + "ns-908.awsdns-49.net" + ], + "primary_name_server": "ns-1967.awsdns-53.co.uk", + "tags": {}, + "tags_all": {}, + "vpc": [], + "zone_id": "Z0224639SZ3FM93JW8DU" + }, + "sensitive_attributes": [], + "private": "bnVsbA==" + } + ] + }, + { + "mode": "managed", + "type": "aws_s3_bucket", + "name": "athena", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [ + { + "schema_version": 0, + "attributes": { + "acceleration_status": null, + "acl": null, + "arn": "arn:aws:s3:::wewerewondering-eu-north-1-athena", + "bucket": "wewerewondering-eu-north-1-athena", + "bucket_domain_name": "wewerewondering-eu-north-1-athena.s3.amazonaws.com", + "bucket_prefix": "", + "bucket_regional_domain_name": "wewerewondering-eu-north-1-athena.s3.eu-north-1.amazonaws.com", + "cors_rule": [], + "force_destroy": false, + "grant": [ + { + "id": "b9eabe8fd0ee6354b459c3d797e75df89ee644b91a018bf5ff42d12b5b47daa2", + "permissions": [ + "FULL_CONTROL" + ], + "type": "CanonicalUser", + "uri": "" + } + ], + "hosted_zone_id": "Z3BAZG2TWCNX0D", + "id": "wewerewondering-eu-north-1-athena", + "lifecycle_rule": [], + "logging": [], + "object_lock_configuration": [], + "object_lock_enabled": false, + "policy": "", + "region": "eu-north-1", + "replication_configuration": [], + "request_payer": "BucketOwner", + "server_side_encryption_configuration": [ + { + "rule": [ + { + "apply_server_side_encryption_by_default": [ + { + "kms_master_key_id": "", + "sse_algorithm": "AES256" + } + ], + "bucket_key_enabled": false + } + ] + } + ], + "tags": {}, + "tags_all": {}, + "timeouts": null, + "versioning": [ + { + "enabled": false, + "mfa_delete": false + } + ], + "website": [], + "website_domain": null, + "website_endpoint": null + }, + "sensitive_attributes": [], + "private": "eyJlMmJmYjczMC1lY2FhLTExZTYtOGY4OC0zNDM2M2JjN2M0YzAiOnsiY3JlYXRlIjoxMjAwMDAwMDAwMDAwLCJkZWxldGUiOjM2MDAwMDAwMDAwMDAsInJlYWQiOjEyMDAwMDAwMDAwMDAsInVwZGF0ZSI6MTIwMDAwMDAwMDAwMH19", + "dependencies": [ + "data.aws_region.current" + ] + } + ] + }, + { + "mode": "managed", + "type": "aws_s3_bucket", + "name": "logs", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [ + { + "schema_version": 0, + "attributes": { + "acceleration_status": null, + "acl": null, + "arn": "arn:aws:s3:::wewerewondering-eu-north-1-logs", + "bucket": "wewerewondering-eu-north-1-logs", + "bucket_domain_name": "wewerewondering-eu-north-1-logs.s3.amazonaws.com", + "bucket_prefix": "", + "bucket_regional_domain_name": "wewerewondering-eu-north-1-logs.s3.eu-north-1.amazonaws.com", + "cors_rule": [], + "force_destroy": false, + "grant": [ + { + "id": "b9eabe8fd0ee6354b459c3d797e75df89ee644b91a018bf5ff42d12b5b47daa2", + "permissions": [ + "FULL_CONTROL" + ], + "type": "CanonicalUser", + "uri": "" + }, + { + "id": "c4c1ede66af53448b93c283ce9448c4ba468c9432aa01d700d3878632f77d2d0", + "permissions": [ + "FULL_CONTROL" + ], + "type": "CanonicalUser", + "uri": "" + } + ], + "hosted_zone_id": "Z3BAZG2TWCNX0D", + "id": "wewerewondering-eu-north-1-logs", + "lifecycle_rule": [], + "logging": [], + "object_lock_configuration": [], + "object_lock_enabled": false, + "policy": "", + "region": "eu-north-1", + "replication_configuration": [], + "request_payer": "BucketOwner", + "server_side_encryption_configuration": [ + { + "rule": [ + { + "apply_server_side_encryption_by_default": [ + { + "kms_master_key_id": "", + "sse_algorithm": "AES256" + } + ], + "bucket_key_enabled": false + } + ] + } + ], + "tags": {}, + "tags_all": {}, + "timeouts": null, + "versioning": [ + { + "enabled": false, + "mfa_delete": false + } + ], + "website": [], + "website_domain": null, + "website_endpoint": null + }, + "sensitive_attributes": [], + "private": "eyJlMmJmYjczMC1lY2FhLTExZTYtOGY4OC0zNDM2M2JjN2M0YzAiOnsiY3JlYXRlIjoxMjAwMDAwMDAwMDAwLCJkZWxldGUiOjM2MDAwMDAwMDAwMDAsInJlYWQiOjEyMDAwMDAwMDAwMDAsInVwZGF0ZSI6MTIwMDAwMDAwMDAwMH19", + "dependencies": [ + "data.aws_region.current" + ] + } + ] + }, + { + "mode": "managed", + "type": "aws_s3_bucket", + "name": "static", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [ + { + "schema_version": 0, + "attributes": { + "acceleration_status": null, + "acl": null, + "arn": "arn:aws:s3:::wewerewondering-eu-north-1-static", + "bucket": "wewerewondering-eu-north-1-static", + "bucket_domain_name": "wewerewondering-eu-north-1-static.s3.amazonaws.com", + "bucket_prefix": "", + "bucket_regional_domain_name": "wewerewondering-eu-north-1-static.s3.eu-north-1.amazonaws.com", + "cors_rule": [], + "force_destroy": true, + "grant": [ + { + "id": "b9eabe8fd0ee6354b459c3d797e75df89ee644b91a018bf5ff42d12b5b47daa2", + "permissions": [ + "FULL_CONTROL" + ], + "type": "CanonicalUser", + "uri": "" + } + ], + "hosted_zone_id": "Z3BAZG2TWCNX0D", + "id": "wewerewondering-eu-north-1-static", + "lifecycle_rule": [], + "logging": [], + "object_lock_configuration": [], + "object_lock_enabled": false, + "policy": "{\"Id\":\"PolicyForCloudFrontPrivateContent\",\"Statement\":[{\"Action\":[\"s3:ListBucket\",\"s3:GetObject\"],\"Condition\":{\"StringEquals\":{\"AWS:SourceArn\":\"arn:aws:cloudfront::880545379339:distribution/E1ECZRHBXFKMHK\"}},\"Effect\":\"Allow\",\"Principal\":{\"Service\":\"cloudfront.amazonaws.com\"},\"Resource\":[\"arn:aws:s3:::wewerewondering-eu-north-1-static/*\",\"arn:aws:s3:::wewerewondering-eu-north-1-static\"],\"Sid\":\"AllowCloudFrontServicePrincipal\"}],\"Version\":\"2012-10-17\"}", + "region": "eu-north-1", + "replication_configuration": [], + "request_payer": "BucketOwner", + "server_side_encryption_configuration": [ + { + "rule": [ + { + "apply_server_side_encryption_by_default": [ + { + "kms_master_key_id": "", + "sse_algorithm": "AES256" + } + ], + "bucket_key_enabled": false + } + ] + } + ], + "tags": {}, + "tags_all": {}, + "timeouts": null, + "versioning": [ + { + "enabled": false, + "mfa_delete": false + } + ], + "website": [], + "website_domain": null, + "website_endpoint": null + }, + "sensitive_attributes": [], + "private": "eyJlMmJmYjczMC1lY2FhLTExZTYtOGY4OC0zNDM2M2JjN2M0YzAiOnsiY3JlYXRlIjoxMjAwMDAwMDAwMDAwLCJkZWxldGUiOjM2MDAwMDAwMDAwMDAsInJlYWQiOjEyMDAwMDAwMDAwMDAsInVwZGF0ZSI6MTIwMDAwMDAwMDAwMH19", + "dependencies": [ + "data.aws_region.current" + ] + } + ] + }, + { + "mode": "managed", + "type": "aws_s3_bucket_acl", + "name": "logs", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [ + { + "schema_version": 0, + "attributes": { + "access_control_policy": [ + { + "grant": [ + { + "grantee": [ + { + "display_name": "", + "email_address": "", + "id": "b9eabe8fd0ee6354b459c3d797e75df89ee644b91a018bf5ff42d12b5b47daa2", + "type": "CanonicalUser", + "uri": "" + } + ], + "permission": "FULL_CONTROL" + }, + { + "grantee": [ + { + "display_name": "", + "email_address": "", + "id": "c4c1ede66af53448b93c283ce9448c4ba468c9432aa01d700d3878632f77d2d0", + "type": "CanonicalUser", + "uri": "" + } + ], + "permission": "FULL_CONTROL" + } + ], + "owner": [ + { + "display_name": "", + "id": "b9eabe8fd0ee6354b459c3d797e75df89ee644b91a018bf5ff42d12b5b47daa2" + } + ] + } + ], + "acl": "", + "bucket": "wewerewondering-eu-north-1-logs", + "expected_bucket_owner": "", + "id": "wewerewondering-eu-north-1-logs" + }, + "sensitive_attributes": [], + "private": "bnVsbA==", + "dependencies": [ + "aws_s3_bucket.logs", + "aws_s3_bucket_ownership_controls.logs", + "data.aws_canonical_user_id.current", + "data.aws_region.current" + ] + } + ] + }, + { + "mode": "managed", + "type": "aws_s3_bucket_ownership_controls", + "name": "athena", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [ + { + "schema_version": 0, + "attributes": { + "bucket": "wewerewondering-eu-north-1-athena", + "id": "wewerewondering-eu-north-1-athena", + "rule": [ + { + "object_ownership": "BucketOwnerEnforced" + } + ] + }, + "sensitive_attributes": [], + "private": "bnVsbA==", + "dependencies": [ + "aws_s3_bucket.athena", + "data.aws_region.current" + ] + } + ] + }, + { + "mode": "managed", + "type": "aws_s3_bucket_ownership_controls", + "name": "logs", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [ + { + "schema_version": 0, + "attributes": { + "bucket": "wewerewondering-eu-north-1-logs", + "id": "wewerewondering-eu-north-1-logs", + "rule": [ + { + "object_ownership": "BucketOwnerPreferred" + } + ] + }, + "sensitive_attributes": [], + "private": "bnVsbA==", + "dependencies": [ + "aws_s3_bucket.logs", + "data.aws_region.current" + ] + } + ] + }, + { + "mode": "managed", + "type": "aws_s3_bucket_ownership_controls", + "name": "static", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [ + { + "schema_version": 0, + "attributes": { + "bucket": "wewerewondering-eu-north-1-static", + "id": "wewerewondering-eu-north-1-static", + "rule": [ + { + "object_ownership": "BucketOwnerEnforced" + } + ] + }, + "sensitive_attributes": [], + "private": "bnVsbA==", + "dependencies": [ + "aws_s3_bucket.static", + "data.aws_region.current" + ] + } + ] + }, + { + "mode": "managed", + "type": "aws_s3_bucket_policy", + "name": "cloudfront", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [ + { + "schema_version": 0, + "attributes": { + "bucket": "wewerewondering-eu-north-1-static", + "id": "wewerewondering-eu-north-1-static", + "policy": "{\"Id\":\"PolicyForCloudFrontPrivateContent\",\"Statement\":[{\"Action\":[\"s3:ListBucket\",\"s3:GetObject\"],\"Condition\":{\"StringEquals\":{\"AWS:SourceArn\":\"arn:aws:cloudfront::880545379339:distribution/E1ECZRHBXFKMHK\"}},\"Effect\":\"Allow\",\"Principal\":{\"Service\":\"cloudfront.amazonaws.com\"},\"Resource\":[\"arn:aws:s3:::wewerewondering-eu-north-1-static/*\",\"arn:aws:s3:::wewerewondering-eu-north-1-static\"],\"Sid\":\"AllowCloudFrontServicePrincipal\"}],\"Version\":\"2012-10-17\"}" + }, + "sensitive_attributes": [], + "private": "bnVsbA==", + "dependencies": [ + "aws_acm_certificate.www", + "aws_acm_certificate_validation.www", + "aws_apigatewayv2_api.www", + "aws_cloudfront_cache_policy.cache_when_requested", + "aws_cloudfront_distribution.www", + "aws_cloudfront_function.index_everywhere", + "aws_cloudfront_origin_access_control.static", + "aws_route53_record.www_cert", + "aws_route53_zone.www", + "aws_s3_bucket.logs", + "aws_s3_bucket.static", + "data.aws_iam_policy_document.cloudfront_s3", + "data.aws_region.current" + ] + } + ] + }, + { + "mode": "managed", + "type": "aws_s3_object", + "name": "dist", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [ + { + "index_key": "apple-touch-icon.png", + "schema_version": 0, + "attributes": { + "acl": null, + "bucket": "wewerewondering-eu-north-1-static", + "bucket_key_enabled": false, + "cache_control": "", + "checksum_algorithm": null, + "checksum_crc32": "", + "checksum_crc32c": "", + "checksum_sha1": "", + "checksum_sha256": "", + "content": null, + "content_base64": null, + "content_disposition": "", + "content_encoding": "", + "content_language": "", + "content_type": "application/octet-stream", + "etag": "52a5465ca4b8008b0a16f927ee7ff362", + "force_destroy": true, + "id": "apple-touch-icon.png", + "key": "apple-touch-icon.png", + "kms_key_id": null, + "metadata": {}, + "object_lock_legal_hold_status": "", + "object_lock_mode": "", + "object_lock_retain_until_date": "", + "override_provider": [], + "server_side_encryption": "AES256", + "source": "./../client/dist/apple-touch-icon.png", + "source_hash": null, + "storage_class": "STANDARD", + "tags": {}, + "tags_all": {}, + "version_id": "", + "website_redirect": "" + }, + "sensitive_attributes": [], + "private": "bnVsbA==", + "dependencies": [ + "aws_s3_bucket.static", + "data.aws_region.current", + "terraform_data.npm_build" + ] + }, + { + "index_key": "assets/index.2bd4e337.css", + "schema_version": 0, + "attributes": { + "acl": null, + "bucket": "wewerewondering-eu-north-1-static", + "bucket_key_enabled": false, + "cache_control": "", + "checksum_algorithm": null, + "checksum_crc32": "", + "checksum_crc32c": "", + "checksum_sha1": "", + "checksum_sha256": "", + "content": null, + "content_base64": null, + "content_disposition": "", + "content_encoding": "", + "content_language": "", + "content_type": "application/octet-stream", + "etag": "5a011ef78398105b0b753585d662a46a", + "force_destroy": true, + "id": "assets/index.2bd4e337.css", + "key": "assets/index.2bd4e337.css", + "kms_key_id": null, + "metadata": {}, + "object_lock_legal_hold_status": "", + "object_lock_mode": "", + "object_lock_retain_until_date": "", + "override_provider": [], + "server_side_encryption": "AES256", + "source": "./../client/dist/assets/index.2bd4e337.css", + "source_hash": null, + "storage_class": "STANDARD", + "tags": {}, + "tags_all": {}, + "version_id": "", + "website_redirect": "" + }, + "sensitive_attributes": [], + "private": "bnVsbA==", + "dependencies": [ + "aws_s3_bucket.static", + "data.aws_region.current", + "terraform_data.npm_build" + ] + }, + { + "index_key": "assets/index.61e1a11f.js", + "schema_version": 0, + "attributes": { + "acl": null, + "bucket": "wewerewondering-eu-north-1-static", + "bucket_key_enabled": false, + "cache_control": "", + "checksum_algorithm": null, + "checksum_crc32": "", + "checksum_crc32c": "", + "checksum_sha1": "", + "checksum_sha256": "", + "content": null, + "content_base64": null, + "content_disposition": "", + "content_encoding": "", + "content_language": "", + "content_type": "application/octet-stream", + "etag": "d1d29e8de8077de4849b08dc90b12067", + "force_destroy": true, + "id": "assets/index.61e1a11f.js", + "key": "assets/index.61e1a11f.js", + "kms_key_id": null, + "metadata": {}, + "object_lock_legal_hold_status": "", + "object_lock_mode": "", + "object_lock_retain_until_date": "", + "override_provider": [], + "server_side_encryption": "AES256", + "source": "./../client/dist/assets/index.61e1a11f.js", + "source_hash": null, + "storage_class": "STANDARD", + "tags": {}, + "tags_all": {}, + "version_id": "", + "website_redirect": "" + }, + "sensitive_attributes": [], + "private": "bnVsbA==", + "dependencies": [ + "aws_s3_bucket.static", + "data.aws_region.current", + "terraform_data.npm_build" + ] + }, + { + "index_key": "favicon.ico", + "schema_version": 0, + "attributes": { + "acl": null, + "bucket": "wewerewondering-eu-north-1-static", + "bucket_key_enabled": false, + "cache_control": "", + "checksum_algorithm": null, + "checksum_crc32": "", + "checksum_crc32c": "", + "checksum_sha1": "", + "checksum_sha256": "", + "content": null, + "content_base64": null, + "content_disposition": "", + "content_encoding": "", + "content_language": "", + "content_type": "application/octet-stream", + "etag": "9a5d0dd396d479d9a60ce80e008475a9", + "force_destroy": true, + "id": "favicon.ico", + "key": "favicon.ico", + "kms_key_id": null, + "metadata": {}, + "object_lock_legal_hold_status": "", + "object_lock_mode": "", + "object_lock_retain_until_date": "", + "override_provider": [], + "server_side_encryption": "AES256", + "source": "./../client/dist/favicon.ico", + "source_hash": null, + "storage_class": "STANDARD", + "tags": {}, + "tags_all": {}, + "version_id": "", + "website_redirect": "" + }, + "sensitive_attributes": [], + "private": "bnVsbA==", + "dependencies": [ + "aws_s3_bucket.static", + "data.aws_region.current", + "terraform_data.npm_build" + ] + }, + { + "index_key": "favicon.png", + "schema_version": 0, + "attributes": { + "acl": null, + "bucket": "wewerewondering-eu-north-1-static", + "bucket_key_enabled": false, + "cache_control": "", + "checksum_algorithm": null, + "checksum_crc32": "", + "checksum_crc32c": "", + "checksum_sha1": "", + "checksum_sha256": "", + "content": null, + "content_base64": null, + "content_disposition": "", + "content_encoding": "", + "content_language": "", + "content_type": "application/octet-stream", + "etag": "728e06e6955b04591e1388ba988ce7d2", + "force_destroy": true, + "id": "favicon.png", + "key": "favicon.png", + "kms_key_id": null, + "metadata": {}, + "object_lock_legal_hold_status": "", + "object_lock_mode": "", + "object_lock_retain_until_date": "", + "override_provider": [], + "server_side_encryption": "AES256", + "source": "./../client/dist/favicon.png", + "source_hash": null, + "storage_class": "STANDARD", + "tags": {}, + "tags_all": {}, + "version_id": "", + "website_redirect": "" + }, + "sensitive_attributes": [], + "private": "bnVsbA==", + "dependencies": [ + "aws_s3_bucket.static", + "data.aws_region.current", + "terraform_data.npm_build" + ] + }, + { + "index_key": "index.html", + "schema_version": 0, + "attributes": { + "acl": null, + "bucket": "wewerewondering-eu-north-1-static", + "bucket_key_enabled": false, + "cache_control": "max-age=300", + "checksum_algorithm": null, + "checksum_crc32": "", + "checksum_crc32c": "", + "checksum_sha1": "", + "checksum_sha256": "", + "content": null, + "content_base64": null, + "content_disposition": "", + "content_encoding": "", + "content_language": "", + "content_type": "application/octet-stream", + "etag": "88d8b88c12fd720a490b5d7581f7857c", + "force_destroy": true, + "id": "index.html", + "key": "index.html", + "kms_key_id": null, + "metadata": {}, + "object_lock_legal_hold_status": "", + "object_lock_mode": "", + "object_lock_retain_until_date": "", + "override_provider": [], + "server_side_encryption": "AES256", + "source": "./../client/dist/index.html", + "source_hash": null, + "storage_class": "STANDARD", + "tags": {}, + "tags_all": {}, + "version_id": "", + "website_redirect": "" + }, + "sensitive_attributes": [], + "private": "bnVsbA==", + "dependencies": [ + "aws_s3_bucket.static", + "data.aws_region.current", + "terraform_data.npm_build" + ] + }, + { + "index_key": "robots.txt", + "schema_version": 0, + "attributes": { + "acl": null, + "bucket": "wewerewondering-eu-north-1-static", + "bucket_key_enabled": false, + "cache_control": "", + "checksum_algorithm": null, + "checksum_crc32": "", + "checksum_crc32c": "", + "checksum_sha1": "", + "checksum_sha256": "", + "content": null, + "content_base64": null, + "content_disposition": "", + "content_encoding": "", + "content_language": "", + "content_type": "application/octet-stream", + "etag": "e3022ff38873f5c22cfe88800696dd13", + "force_destroy": true, + "id": "robots.txt", + "key": "robots.txt", + "kms_key_id": null, + "metadata": {}, + "object_lock_legal_hold_status": "", + "object_lock_mode": "", + "object_lock_retain_until_date": "", + "override_provider": [], + "server_side_encryption": "AES256", + "source": "./../client/dist/robots.txt", + "source_hash": null, + "storage_class": "STANDARD", + "tags": {}, + "tags_all": {}, + "version_id": "", + "website_redirect": "" + }, + "sensitive_attributes": [], + "private": "bnVsbA==", + "dependencies": [ + "aws_s3_bucket.static", + "data.aws_region.current", + "terraform_data.npm_build" + ] + } + ] + }, + { + "mode": "managed", + "type": "terraform_data", + "name": "cargo_lambda", + "provider": "provider[\"terraform.io/builtin/terraform\"]", + "instances": [ + { + "schema_version": 0, + "attributes": { + "id": "4c6bd9ba-1be1-7124-5979-44586fbcd4fb", + "input": null, + "output": null, + "triggers_replace": { + "value": { + "cargo_toml": "QpzO2eHyUPwln4nkgB6oheyQfJ9NO6yo3LAeLoizehU=", + "main_rs": "eQKjFptSzxjUOKnymQQqxAYOUsU9DU/nDSR1ggUB5VI=" + }, + "type": [ + "object", + { + "cargo_toml": "string", + "main_rs": "string" + } + ] + } + }, + "sensitive_attributes": [] + } + ] + }, + { + "mode": "managed", + "type": "terraform_data", + "name": "npm_build", + "provider": "provider[\"terraform.io/builtin/terraform\"]", + "instances": [ + { + "schema_version": 0, + "attributes": { + "id": "5619b8bf-1135-b120-d57c-da1900c8cb3c", + "input": null, + "output": null, + "triggers_replace": { + "value": { + "index_html": "4QdZTX10kZioZFfIvh/k+c9mdBVybNcJkHOd2g/JHQg=", + "package_json": "l+CUZ25vEla6sjntm9elr09fcwLu1+bzyggkJCj4CBI=" + }, + "type": [ + "object", + { + "index_html": "string", + "package_json": "string" + } + ] + } + }, + "sensitive_attributes": [] + } + ] + } + ], + "check_results": null +}