diff --git a/CHANGELOG.md b/CHANGELOG.md index 2d2d983..f26ba00 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,21 @@ All notable changes to this project will be documented in this file. ## Unreleased + +## [0.1.16] 2020-12-14 +- Added: Missing variables for proxy URLs +- Added: New parameter "reduced_metrics_whitelist" +- Added: New optional parameters and secret to proxy verification requests to a third party + + + +## [0.1.15] 2020-11-26 +- Updated: Set default "download_schedule" to offset from "upload_schedule" +- Updated: Give access to "time_zone" parameter to all services that write metrics +- Updated: Remove "CALLBACK_REQUEST" from "metrics_config". +- Added: New parameter "push_cors_origin" to control CORS headers in push service + + ## [0.1.14] 2020-11-13 - Added: self isolation notices support. - Updated: Remove "TOKEN_RENEWAL" from "metrics_config" to capture it on backend. diff --git a/ecs_api.tf b/ecs_api.tf index 81cec91..c3d2307 100644 --- a/ecs_api.tf +++ b/ecs_api.tf @@ -66,18 +66,22 @@ data "aws_iam_policy_document" "api_ecs_task_policy" { aws_ssm_parameter.security_self_isolation_notices_rate_limit_secs.arn ], aws_ssm_parameter.security_callback_rate_limit_request_count.*.arn, - aws_ssm_parameter.security_callback_rate_limit_secs.*.arn) + aws_ssm_parameter.security_callback_rate_limit_secs.*.arn, + aws_ssm_parameter.verify_proxy_url.*.arn + ) } statement { actions = ["secretsmanager:GetSecretValue"] - resources = [ + resources = concat([ data.aws_secretsmanager_secret_version.device_check.arn, data.aws_secretsmanager_secret_version.encrypt.arn, data.aws_secretsmanager_secret_version.jwt.arn, data.aws_secretsmanager_secret_version.rds_read_write_create.arn, data.aws_secretsmanager_secret_version.verify.arn - ] + ], + data.aws_secretsmanager_secret_version.verify_proxy.*.arn + ) } statement { diff --git a/ecs_push.tf b/ecs_push.tf index db15cd4..475e256 100644 --- a/ecs_push.tf +++ b/ecs_push.tf @@ -15,7 +15,7 @@ data "aws_iam_policy_document" "push_ecs_assume_role_policy" { data "aws_iam_policy_document" "push_ecs_task_policy" { statement { actions = ["ssm:GetParameter"] - resources = [ + resources = concat([ aws_ssm_parameter.cors_origin.arn, aws_ssm_parameter.db_database.arn, aws_ssm_parameter.db_host.arn, @@ -27,23 +27,30 @@ data "aws_iam_policy_document" "push_ecs_task_policy" { aws_ssm_parameter.hsts_max_age.arn, aws_ssm_parameter.log_level.arn, aws_ssm_parameter.onset_date_mandatory.arn, + aws_ssm_parameter.push_cors_origin.arn, aws_ssm_parameter.push_host.arn, aws_ssm_parameter.push_port.arn, + aws_ssm_parameter.reduced_metrics_whitelist.arn, aws_ssm_parameter.security_code_charset.arn, aws_ssm_parameter.security_code_length.arn, aws_ssm_parameter.security_code_lifetime_mins.arn, aws_ssm_parameter.sms_url.arn, aws_ssm_parameter.symptom_date_offset.arn, + aws_ssm_parameter.time_zone.arn, aws_ssm_parameter.use_test_date_as_onset_date.arn - ] + ], + aws_ssm_parameter.issue_proxy_url.*.arn + ) } statement { actions = ["secretsmanager:GetSecretValue"] - resources = [ + resources = concat([ data.aws_secretsmanager_secret_version.jwt.arn, data.aws_secretsmanager_secret_version.rds_read_write.arn - ] + ], + data.aws_secretsmanager_secret_version.verify_proxy.*.arn + ) } statement { diff --git a/lambda-callback.tf b/lambda-callback.tf index 222a402..5f2ba10 100644 --- a/lambda-callback.tf +++ b/lambda-callback.tf @@ -21,7 +21,8 @@ data "aws_iam_policy_document" "callback_policy" { aws_ssm_parameter.db_database.arn, aws_ssm_parameter.db_host.arn, aws_ssm_parameter.db_port.arn, - aws_ssm_parameter.db_ssl.arn + aws_ssm_parameter.db_ssl.arn, + aws_ssm_parameter.time_zone.arn ], aws_ssm_parameter.callback_email_notifications_sns_arn.*.arn ) diff --git a/lambda-download.tf b/lambda-download.tf index c605c49..ee709a9 100644 --- a/lambda-download.tf +++ b/lambda-download.tf @@ -15,7 +15,8 @@ module "download" { aws_ssm_parameter.db_host.arn, aws_ssm_parameter.db_port.arn, aws_ssm_parameter.db_reader_host.arn, - aws_ssm_parameter.db_ssl.arn + aws_ssm_parameter.db_ssl.arn, + aws_ssm_parameter.time_zone.arn ] aws_secret_arns = concat([data.aws_secretsmanager_secret_version.rds_read_write.arn], data.aws_secretsmanager_secret_version.interop.*.arn) cloudwatch_schedule_expression = var.download_schedule diff --git a/lambda-sms.tf b/lambda-sms.tf index 827a484..fdb819c 100644 --- a/lambda-sms.tf +++ b/lambda-sms.tf @@ -21,7 +21,8 @@ module "sms" { aws_ssm_parameter.sms_region.arn, aws_ssm_parameter.sms_sender.arn, aws_ssm_parameter.sms_template.arn, - aws_ssm_parameter.sms_url.arn + aws_ssm_parameter.sms_url.arn, + aws_ssm_parameter.time_zone.arn ] aws_secret_arns = concat([data.aws_secretsmanager_secret_version.rds_read_write.arn], data.aws_secretsmanager_secret_version.sms.*.arn) config_var_prefix = local.config_var_prefix diff --git a/lambda-upload.tf b/lambda-upload.tf index 78fee93..a0afa99 100644 --- a/lambda-upload.tf +++ b/lambda-upload.tf @@ -15,7 +15,8 @@ module "upload" { aws_ssm_parameter.db_host.arn, aws_ssm_parameter.db_port.arn, aws_ssm_parameter.db_reader_host.arn, - aws_ssm_parameter.db_ssl.arn + aws_ssm_parameter.db_ssl.arn, + aws_ssm_parameter.time_zone.arn ] aws_secret_arns = concat([data.aws_secretsmanager_secret_version.rds_read_write.arn], data.aws_secretsmanager_secret_version.interop.*.arn) cloudwatch_schedule_expression = var.upload_schedule diff --git a/modules/lambda/main.tf b/modules/lambda/main.tf index 43c3944..bf3354d 100644 --- a/modules/lambda/main.tf +++ b/modules/lambda/main.tf @@ -121,6 +121,9 @@ variable "timeout" { default = 15 } +variable "concurrency" { + default = -1 +} # ######################################### # Module content @@ -350,9 +353,13 @@ resource "aws_lambda_function" "this" { runtime = var.runtime tags = var.tags timeout = var.timeout - + depends_on = [aws_cloudwatch_log_group.this] + # See https://docs.aws.amazon.com/lambda/latest/dg/invocation-scaling.html + # Use default `concurrency` value for no limit + reserved_concurrent_executions = var.concurrency + environment { variables = { CONFIG_VAR_PREFIX = var.config_var_prefix, diff --git a/parameters.tf b/parameters.tf index 8846788..c75fd28 100644 --- a/parameters.tf +++ b/parameters.tf @@ -201,6 +201,14 @@ resource "aws_ssm_parameter" "onset_date_mandatory" { tags = module.labels.tags } +resource "aws_ssm_parameter" "push_cors_origin" { + overwrite = true + name = format("%spush_cors_origin", local.config_var_prefix) + type = "String" + value = var.push_cors_origin + tags = module.labels.tags +} + resource "aws_ssm_parameter" "push_host" { overwrite = true name = format("%spush_host", local.config_var_prefix) @@ -217,6 +225,14 @@ resource "aws_ssm_parameter" "push_port" { tags = module.labels.tags } +resource "aws_ssm_parameter" "reduced_metrics_whitelist" { + overwrite = true + name = format("%sreduced_metrics_whitelist", local.config_var_prefix) + type = "String" + value = var.reduced_metrics_whitelist + tags = module.labels.tags +} + resource "aws_ssm_parameter" "s3_assets_bucket" { overwrite = true name = format("%ss3_assets_bucket", local.config_var_prefix) @@ -432,6 +448,15 @@ resource "aws_ssm_parameter" "daily_registrations_reporter_sns_arn" { tags = module.labels.tags } +resource "aws_ssm_parameter" "issue_proxy_url" { + count = contains(var.optional_parameters_to_include, "issue_proxy_url") ? 1 : 0 + overwrite = true + name = format("%sissue_proxy_url", local.config_var_prefix) + type = "String" + value = var.issue_proxy_url + tags = module.labels.tags +} + resource "aws_ssm_parameter" "security_callback_rate_limit_request_count" { count = contains(var.optional_parameters_to_include, "security_callback_rate_limit_request_count") ? 1 : 0 overwrite = true @@ -449,3 +474,12 @@ resource "aws_ssm_parameter" "security_callback_rate_limit_secs" { value = var.callback_rate_limit_secs tags = module.labels.tags } + +resource "aws_ssm_parameter" "verify_proxy_url" { + count = contains(var.optional_parameters_to_include, "verify_proxy_url") ? 1 : 0 + overwrite = true + name = format("%sverify_proxy_url", local.config_var_prefix) + type = "String" + value = var.verify_proxy_url + tags = module.labels.tags +} diff --git a/secrets.tf b/secrets.tf index 7420227..5483683 100644 --- a/secrets.tf +++ b/secrets.tf @@ -69,3 +69,8 @@ data "aws_secretsmanager_secret_version" "sms" { count = contains(var.optional_secrets_to_include, "sms") ? 1 : 0 secret_id = "${local.config_var_prefix}sms" } + +data "aws_secretsmanager_secret_version" "verify_proxy" { + count = contains(var.optional_secrets_to_include, "verify-proxy") ? 1 : 0 + secret_id = "${local.config_var_prefix}verify-proxy" +} diff --git a/users.tf b/users.tf index 691c951..4dd2275 100644 --- a/users.tf +++ b/users.tf @@ -34,6 +34,15 @@ data "aws_iam_policy_document" "ci_user" { format("%s/*", aws_s3_bucket.assets.arn) ] } + + statement { + actions = [ + "route53:GetChange" + ] + resources = [ + "*" + ] + } } data "aws_iam_policy_document" "ci_user_lambda" { diff --git a/variables.tf b/variables.tf index e089024..5094644 100644 --- a/variables.tf +++ b/variables.tf @@ -376,7 +376,7 @@ variable "disable_valid_key_check" { } variable "download_schedule" { description = "download lambda CloudWatch schedule" - default = "cron(0 * * * ? *)" + default = "cron(30 * * * ? *)" } variable "enable_callback" { description = "Flag to determine whether the API service should enable callback endpoints" @@ -429,6 +429,10 @@ variable "hsts_max_age" { description = "The time, in seconds, that the browser should remember that a site is only to be accessed using HTTPS." default = "300" // 5 minutes } +variable "issue_proxy_url" { + description = "URL to proxy OTC issue requests if necessary" + default = "" +} variable "lambda_authorizer_memory_size" { description = "authorizer lambda memory size" default = 512 # Since this is on the hot path and we get faster CPUs with higher memory @@ -597,7 +601,7 @@ variable "native_regions" { default = "" } variable "metrics_config" { - default = "{ \"CONTACT_UPLOAD\": 60, \"CHECK_IN\": 60, \"FORGET\": 60, \"CALLBACK_OPTIN\": 60, \"DAILY_ACTIVE_TRACE\": 60, \"CONTACT_NOTIFICATION\": 60, \"LOG_ERROR\": 60, \"CALLBACK_REQUEST\": 60 }" + default = "{ \"CONTACT_UPLOAD\": 60, \"CHECK_IN\": 60, \"FORGET\": 60, \"CALLBACK_OPTIN\": 60, \"DAILY_ACTIVE_TRACE\": 60, \"CONTACT_NOTIFICATION\": 60, \"LOG_ERROR\": 60 }" } variable "migrations_custom_image" { description = "Custom image for the ECS Migrations container, overrides the default ECR repo, assumes we can pull from the repository" @@ -627,6 +631,10 @@ variable "push_allowed_ips" { description = "ECS Push service ALB allowed ingress CIDRs" default = ["0.0.0.0/0"] } +variable "push_cors_origin" { + description = "Push service CORS header value" + default = "*" +} variable "push_cpu_high_threshold" { description = "ECS Push service ASG scaling CPU high threshold" default = 15 @@ -687,6 +695,10 @@ variable "push_services_task_memory" { description = "ECS Push service task memory" default = 512 } +variable "reduced_metrics_whitelist" { + description = "Comma separated list of metrics the reduced metrics role can access" + default = "CALLBACK_OPTIN,CALLBACK_SENT,CASES,CHECK_IN,DEATHS,FORGET,INTEROP_KEYS_DOWNLOADED,INTEROP_KEYS_UPLOADED,UPLOAD" +} variable "refresh_token_expiry" { description = "Lifetime of refresh tokens generated after a user registers" default = "10y" @@ -741,6 +753,10 @@ variable "variance_offset_mins" { description = "Variance offset in minutes to add to lifetime of keys to check if they are still valid" default = "120" } +variable "verify_proxy_url" { + description = "URL to code verification requests if necessary" + default = "" +} variable "verify_rate_limit_secs" { description = "Time in seconds a user must wait before attempting to verify a one-time upload code" }