diff --git a/main.tf b/main.tf index c9a5df79..68693a57 100644 --- a/main.tf +++ b/main.tf @@ -1,12 +1,14 @@ module "kms" { - source = "./terraform-modules/kms" + source = "./terraform-modules/kms" + project = var.project region = var.region environment = local.env } -module "lambda-role" { - source = "./terraform-modules/iam" +module "lambda_role" { + source = "./terraform-modules/iam" + project = var.project region = var.region security_audit_role_name = var.security_audit_role_name @@ -15,16 +17,17 @@ module "lambda-role" { environment = local.env } -module "lambda-slack" { - source = "./terraform-modules/lambda-slack" +module "lambda_slack" { + source = "./terraform-modules/lambda-slack" + runtime = var.runtime platform = var.platform memory_size = var.memory_size_slack project = var.project - lambda_role_arn = module.lambda-role.lambda_role_arn + lambda_role_arn = module.lambda_role.lambda_role_arn kms_arn = module.kms.kms_arn sns_topic_arn = module.sns.sns_topic_arn - dlq_sns_topic_arn = module.sns-dead-letter-queue.sns_topic_arn + dlq_sns_topic_arn = module.sns_dead_letter_queue.sns_topic_arn slack_channels = local.env == "dev" ? var.slack_channels_dev : var.slack_channels slack_webhook_urls = local.env == "dev" && length(var.slack_webhook_urls_dev) > 0 ? var.slack_webhook_urls_dev : var.slack_webhook_urls slack_webhook_type = var.slack_webhook_type @@ -36,7 +39,8 @@ module "lambda-slack" { } module "lambda" { - source = "./terraform-modules/lambda" + source = "./terraform-modules/lambda" + lambdas = var.lambdas runtime = var.runtime platform = var.platform @@ -45,18 +49,19 @@ module "lambda" { security_audit_role_name = var.security_audit_role_name external_id = var.external_id org_primary_account = var.org_primary_account - lambda_role_arn = module.lambda-role.lambda_role_arn + lambda_role_arn = module.lambda_role.lambda_role_arn kms_arn = module.kms.kms_arn sns_topic_arn = module.sns.sns_topic_arn - dlq_sns_topic_arn = module.sns-dead-letter-queue.sns_topic_arn - state_machine_arn = module.step-function.state_machine_arn + dlq_sns_topic_arn = module.sns_dead_letter_queue.sns_topic_arn + state_machine_arn = module.step_function.state_machine_arn allowed_regions = var.allowed_regions ip_time_limit = var.ip_time_limit environment = local.env } -module "lambda-accounts" { - source = "./terraform-modules/lambda-accounts" +module "lambda_accounts" { + source = "./terraform-modules/lambda-accounts" + lambdas = ["accounts"] runtime = var.runtime platform = var.platform @@ -65,28 +70,30 @@ module "lambda-accounts" { security_audit_role_name = var.security_audit_role_name external_id = var.external_id org_primary_account = var.org_primary_account - lambda_role_arn = module.accounts-role.lambda_role_arn + lambda_role_arn = module.accounts_role.lambda_role_arn kms_arn = module.kms.kms_arn sns_topic_arn = module.sns.sns_topic_arn - dlq_sns_topic_arn = module.sns-dead-letter-queue.sns_topic_arn - state_machine_arn = module.step-function.state_machine_arn + dlq_sns_topic_arn = module.sns_dead_letter_queue.sns_topic_arn + state_machine_arn = module.step_function.state_machine_arn environment = local.env } -module "accounts-role" { - source = "./terraform-modules/iam" +module "accounts_role" { + source = "./terraform-modules/iam" + project = var.project region = var.region security_audit_role_name = var.security_audit_role_name kms_arn = module.kms.kms_arn - state_machine_arn = module.step-function.state_machine_arn + state_machine_arn = module.step_function.state_machine_arn policy = "accounts" permissions_boundary_arn = var.permissions_boundary_arn environment = local.env } -module "lambda-scan" { - source = "./terraform-modules/lambda-scan" +module "lambda_scan" { + source = "./terraform-modules/lambda-scan" + lambdas = ["scan"] runtime = var.runtime platform = var.platform @@ -95,10 +102,10 @@ module "lambda-scan" { security_audit_role_name = var.security_audit_role_name external_id = var.external_id org_primary_account = var.org_primary_account - lambda_role_arn = module.lambda-role.lambda_role_arn + lambda_role_arn = module.lambda_role.lambda_role_arn kms_arn = module.kms.kms_arn sns_topic_arn = module.sns.sns_topic_arn - dlq_sns_topic_arn = module.sns-dead-letter-queue.sns_topic_arn + dlq_sns_topic_arn = module.sns_dead_letter_queue.sns_topic_arn bugcrowd = var.bugcrowd bugcrowd_api_key = var.bugcrowd_api_key bugcrowd_email = var.bugcrowd_email @@ -109,24 +116,26 @@ module "lambda-scan" { production_environment = local.production_environment } -module "lambda-takeover" { +module "lambda_takeover" { #checkov:skip=CKV_AWS_274:role is ElasticBeanstalk admin, not full Administrator Access - count = local.takeover ? 1 : 0 - source = "./terraform-modules/lambda-takeover" + count = local.takeover ? 1 : 0 + source = "./terraform-modules/lambda-takeover" + runtime = var.runtime platform = var.platform memory_size = var.memory_size_slack project = var.project - lambda_role_arn = module.takeover-role.*.lambda_role_arn[0] + lambda_role_arn = module.takeover_role[*].lambda_role_arn[0] kms_arn = module.kms.kms_arn sns_topic_arn = module.sns.sns_topic_arn - dlq_sns_topic_arn = module.sns-dead-letter-queue.sns_topic_arn + dlq_sns_topic_arn = module.sns_dead_letter_queue.sns_topic_arn environment = local.env } -module "takeover-role" { - count = local.takeover ? 1 : 0 - source = "./terraform-modules/iam" +module "takeover_role" { + count = local.takeover ? 1 : 0 + source = "./terraform-modules/iam" + project = var.project region = var.region security_audit_role_name = var.security_audit_role_name @@ -137,23 +146,25 @@ module "takeover-role" { environment = local.env } -module "lambda-resources" { - count = local.takeover ? 1 : 0 - source = "./terraform-modules/lambda-resources" +module "lambda_resources" { + count = local.takeover ? 1 : 0 + source = "./terraform-modules/lambda-resources" + lambdas = ["resources"] runtime = var.runtime memory_size = var.memory_size_slack project = var.project - lambda_role_arn = module.resources-role.*.lambda_role_arn[0] + lambda_role_arn = module.resources_role[*].lambda_role_arn[0] kms_arn = module.kms.kms_arn sns_topic_arn = module.sns.sns_topic_arn - dlq_sns_topic_arn = module.sns-dead-letter-queue.sns_topic_arn + dlq_sns_topic_arn = module.sns_dead_letter_queue.sns_topic_arn environment = local.env } -module "resources-role" { - count = local.takeover ? 1 : 0 - source = "./terraform-modules/iam" +module "resources_role" { + count = local.takeover ? 1 : 0 + source = "./terraform-modules/iam" + project = var.project region = var.region security_audit_role_name = var.security_audit_role_name @@ -163,8 +174,9 @@ module "resources-role" { environment = local.env } -module "cloudwatch-event" { - source = "./terraform-modules/cloudwatch" +module "cloudwatch_event" { + source = "./terraform-modules/cloudwatch" + project = var.project lambda_function_arns = module.lambda.lambda_function_arns lambda_function_names = module.lambda.lambda_function_names @@ -176,13 +188,14 @@ module "cloudwatch-event" { environment = local.env } -module "resources-event" { - count = local.takeover ? 1 : 0 - source = "./terraform-modules/cloudwatch" +module "resources_event" { + count = local.takeover ? 1 : 0 + source = "./terraform-modules/cloudwatch" + project = var.project - lambda_function_arns = module.lambda-resources[0].lambda_function_arns - lambda_function_names = module.lambda-resources[0].lambda_function_names - lambda_function_alias_names = module.lambda-resources[0].lambda_function_alias_names + lambda_function_arns = module.lambda_resources[0].lambda_function_arns + lambda_function_names = module.lambda_resources[0].lambda_function_names + lambda_function_alias_names = module.lambda_resources[0].lambda_function_alias_names schedule = var.reports_schedule takeover = local.takeover update_schedule = local.env == local.production_environment ? var.scan_schedule : var.scan_schedule_nonprod @@ -190,12 +203,13 @@ module "resources-event" { environment = local.env } -module "accounts-event" { - source = "./terraform-modules/cloudwatch" +module "accounts_event" { + source = "./terraform-modules/cloudwatch" + project = var.project - lambda_function_arns = module.lambda-accounts.lambda_function_arns - lambda_function_names = module.lambda-accounts.lambda_function_names - lambda_function_alias_names = module.lambda-accounts.lambda_function_alias_names + lambda_function_arns = module.lambda_accounts.lambda_function_arns + lambda_function_names = module.lambda_accounts.lambda_function_names + lambda_function_alias_names = module.lambda_accounts.lambda_function_alias_names schedule = local.env == local.production_environment ? var.scan_schedule : var.scan_schedule_nonprod takeover = local.takeover update_schedule = local.env == local.production_environment ? var.scan_schedule : var.scan_schedule_nonprod @@ -204,15 +218,17 @@ module "accounts-event" { } module "sns" { - source = "./terraform-modules/sns" + source = "./terraform-modules/sns" + project = var.project region = var.region kms_arn = module.kms.kms_arn environment = local.env } -module "sns-dead-letter-queue" { - source = "./terraform-modules/sns" +module "sns_dead_letter_queue" { + source = "./terraform-modules/sns" + project = var.project region = var.region dead_letter_queue = true @@ -220,22 +236,23 @@ module "sns-dead-letter-queue" { environment = local.env } -module "lambda-cloudflare" { - count = var.cloudflare ? 1 : 0 - source = "./terraform-modules/lambda-cloudflare" +module "lambda_cloudflare" { + count = var.cloudflare ? 1 : 0 + source = "./terraform-modules/lambda-cloudflare" + lambdas = var.cloudflare_lambdas runtime = var.runtime platform = var.platform memory_size = var.memory_size project = var.project cf_api_key = var.cf_api_key - lambda_role_arn = module.lambda-role.lambda_role_arn + lambda_role_arn = module.lambda_role.lambda_role_arn kms_arn = module.kms.kms_arn security_audit_role_name = var.security_audit_role_name external_id = var.external_id org_primary_account = var.org_primary_account sns_topic_arn = module.sns.sns_topic_arn - dlq_sns_topic_arn = module.sns-dead-letter-queue.sns_topic_arn + dlq_sns_topic_arn = module.sns_dead_letter_queue.sns_topic_arn production_environment = local.production_environment bugcrowd = var.bugcrowd bugcrowd_api_key = var.bugcrowd_api_key @@ -246,13 +263,14 @@ module "lambda-cloudflare" { environment = local.env } -module "cloudflare-event" { - count = var.cloudflare ? 1 : 0 - source = "./terraform-modules/cloudwatch" +module "cloudflare_event" { + count = var.cloudflare ? 1 : 0 + source = "./terraform-modules/cloudwatch" + project = var.project - lambda_function_arns = module.lambda-cloudflare[0].lambda_function_arns - lambda_function_names = module.lambda-cloudflare[0].lambda_function_names - lambda_function_alias_names = module.lambda-cloudflare[0].lambda_function_alias_names + lambda_function_arns = module.lambda_cloudflare[0].lambda_function_arns + lambda_function_names = module.lambda_cloudflare[0].lambda_function_names + lambda_function_alias_names = module.lambda_cloudflare[0].lambda_function_alias_names schedule = local.env == local.production_environment ? var.scan_schedule : var.scan_schedule_nonprod takeover = local.takeover update_schedule = local.env == local.production_environment ? var.scan_schedule : var.scan_schedule_nonprod @@ -261,17 +279,19 @@ module "cloudflare-event" { } module "dynamodb" { - source = "./terraform-modules/dynamodb" - project = var.project + source = "./terraform-modules/dynamodb" + project = var.project + kms_arn = module.kms.kms_arn rcu = var.rcu wcu = var.wcu environment = local.env } -module "step-function-role" { - source = "./terraform-modules/iam" - project = var.project +module "step_function_role" { + source = "./terraform-modules/iam" + project = var.project + region = var.region security_audit_role_name = var.security_audit_role_name kms_arn = module.kms.kms_arn @@ -281,37 +301,41 @@ module "step-function-role" { environment = local.env } -module "step-function" { - source = "./terraform-modules/step-function" - project = var.project - lambda_arn = module.lambda-scan.lambda_function_arns["scan"] - role_arn = module.step-function-role.lambda_role_arn +module "step_function" { + source = "./terraform-modules/step-function" + project = var.project + + lambda_arn = module.lambda_scan.lambda_function_arns["scan"] + role_arn = module.step_function_role.lambda_role_arn kms_arn = module.kms.kms_arn environment = local.env } -module "dynamodb-ips" { - count = var.ip_address ? 1 : 0 - source = "./terraform-modules/dynamodb-ips" +module "dynamodb_ips" { + count = var.ip_address ? 1 : 0 + source = "./terraform-modules/dynamodb-ips" + project = var.project kms_arn = module.kms.kms_arn environment = local.env } -module "step-function-ips" { - count = var.ip_address ? 1 : 0 - source = "./terraform-modules/step-function" +module "step_function_ips" { + count = var.ip_address ? 1 : 0 + source = "./terraform-modules/step-function" + project = var.project purpose = "ips" - lambda_arn = module.lambda-scan-ips[0].lambda_function_arns["scan-ips"] - role_arn = module.step-function-role.lambda_role_arn + lambda_arn = module.lambda_scan_ips[0].lambda_function_arns["scan-ips"] + role_arn = module.step_function_role.lambda_role_arn kms_arn = module.kms.kms_arn environment = local.env } -module "lambda-role-ips" { - count = var.ip_address ? 1 : 0 - source = "./terraform-modules/iam" +module "lambda_role_ips" { + count = var.ip_address ? 1 : 0 + source = "./terraform-modules/iam" + project = var.project region = var.region security_audit_role_name = var.security_audit_role_name @@ -322,9 +346,10 @@ module "lambda-role-ips" { environment = local.env } -module "lambda-scan-ips" { - count = var.ip_address ? 1 : 0 - source = "./terraform-modules/lambda-scan-ips" +module "lambda_scan_ips" { + count = var.ip_address ? 1 : 0 + source = "./terraform-modules/lambda-scan-ips" + lambdas = ["scan-ips"] runtime = var.runtime platform = var.platform @@ -333,10 +358,10 @@ module "lambda-scan-ips" { security_audit_role_name = var.security_audit_role_name external_id = var.external_id org_primary_account = var.org_primary_account - lambda_role_arn = module.lambda-role-ips[0].lambda_role_arn + lambda_role_arn = module.lambda_role_ips[0].lambda_role_arn kms_arn = module.kms.kms_arn sns_topic_arn = module.sns.sns_topic_arn - dlq_sns_topic_arn = module.sns-dead-letter-queue.sns_topic_arn + dlq_sns_topic_arn = module.sns_dead_letter_queue.sns_topic_arn production_environment = local.production_environment allowed_regions = var.allowed_regions ip_time_limit = var.ip_time_limit @@ -349,23 +374,25 @@ module "lambda-scan-ips" { environment = local.env } -module "accounts-role-ips" { - count = var.ip_address ? 1 : 0 - source = "./terraform-modules/iam" +module "accounts_role_ips" { + count = var.ip_address ? 1 : 0 + source = "./terraform-modules/iam" + project = var.project region = var.region security_audit_role_name = var.security_audit_role_name kms_arn = module.kms.kms_arn - state_machine_arn = module.step-function-ips[0].state_machine_arn + state_machine_arn = module.step_function_ips[0].state_machine_arn policy = "accounts" role_name = "accounts-ips" permissions_boundary_arn = var.permissions_boundary_arn environment = local.env } -module "lambda-accounts-ips" { - count = var.ip_address ? 1 : 0 - source = "./terraform-modules/lambda-accounts" +module "lambda_accounts_ips" { + count = var.ip_address ? 1 : 0 + source = "./terraform-modules/lambda-accounts" + lambdas = ["accounts-ips"] runtime = var.runtime platform = var.platform @@ -374,21 +401,22 @@ module "lambda-accounts-ips" { security_audit_role_name = var.security_audit_role_name external_id = var.external_id org_primary_account = var.org_primary_account - lambda_role_arn = module.accounts-role-ips[0].lambda_role_arn + lambda_role_arn = module.accounts_role_ips[0].lambda_role_arn kms_arn = module.kms.kms_arn sns_topic_arn = module.sns.sns_topic_arn - dlq_sns_topic_arn = module.sns-dead-letter-queue.sns_topic_arn - state_machine_arn = module.step-function-ips[0].state_machine_arn + dlq_sns_topic_arn = module.sns_dead_letter_queue.sns_topic_arn + state_machine_arn = module.step_function_ips[0].state_machine_arn environment = local.env } -module "accounts-event-ips" { - count = var.ip_address ? 1 : 0 - source = "./terraform-modules/cloudwatch" +module "accounts_event_ips" { + count = var.ip_address ? 1 : 0 + source = "./terraform-modules/cloudwatch" + project = var.project - lambda_function_arns = module.lambda-accounts-ips[0].lambda_function_arns - lambda_function_names = module.lambda-accounts-ips[0].lambda_function_names - lambda_function_alias_names = module.lambda-accounts-ips[0].lambda_function_alias_names + lambda_function_arns = module.lambda_accounts_ips[0].lambda_function_arns + lambda_function_names = module.lambda_accounts_ips[0].lambda_function_names + lambda_function_alias_names = module.lambda_accounts_ips[0].lambda_function_alias_names schedule = local.env == local.production_environment ? var.ip_scan_schedule : var.ip_scan_schedule_nonprod takeover = local.takeover update_schedule = local.env == local.production_environment ? var.ip_scan_schedule : var.ip_scan_schedule_nonprod @@ -396,16 +424,17 @@ module "accounts-event-ips" { environment = local.env } -module "lamdba-stats" { - source = "./terraform-modules/lambda-stats" +module "lamdba_stats" { + source = "./terraform-modules/lambda-stats" + runtime = var.runtime platform = var.platform memory_size = var.memory_size project = var.project kms_arn = module.kms.kms_arn - lambda_role_arn = module.lambda-role.lambda_role_arn + lambda_role_arn = module.lambda_role.lambda_role_arn sns_topic_arn = module.sns.sns_topic_arn - dlq_sns_topic_arn = module.sns-dead-letter-queue.sns_topic_arn + dlq_sns_topic_arn = module.sns_dead_letter_queue.sns_topic_arn schedule_expression = var.stats_schedule org_primary_account = var.org_primary_account security_audit_role_name = var.security_audit_role_name diff --git a/terraform-modules/iam/variables.tf b/terraform-modules/iam/variables.tf index 4b1751c8..d6ebbe2e 100644 --- a/terraform-modules/iam/variables.tf +++ b/terraform-modules/iam/variables.tf @@ -30,7 +30,7 @@ variable "role_name" { variable "permissions_boundary_arn" { description = "permissions boundary ARN" - default = "" + default = null } variable "environment" { diff --git a/variables.tf b/variables.tf index d37ad774..09aa079a 100644 --- a/variables.tf +++ b/variables.tf @@ -1,71 +1,85 @@ variable "project" { description = "abbreviation for the project, forms first part of resource names" default = "domain-protect" + type = string } variable "region" { description = "AWS region to deploy Lambda functions" default = "eu-west-1" + type = string } variable "org_primary_account" { description = "The AWS account number of the organization primary account" default = "" + type = string } variable "security_audit_role_name" { description = "security audit role name which needs to be the same in all AWS accounts" default = "domain-protect-audit" + type = string } variable "external_id" { description = "external ID for security audit role to be defined in tvars file. Leave empty if not configured" default = "" + type = string } variable "ip_time_limit" { description = "maximum time in hours since IP last detected, before considering IP as no longer belonging to organisation" default = "48" + type = string } variable "reports_schedule" { description = "schedule for running reports, e.g. 24 hours. Irrespective of setting, you will be immediately notified of new vulnerabilities" default = "24 hours" + type = string } variable "scan_schedule" { description = "schedule for running domain-protect scans, e.g. 60 minutes, does not affect frequency of regular Slack reports" default = "60 minutes" + type = string } variable "scan_schedule_nonprod" { description = "schedule for running domain-protect scans in non-prod, reduced to save costs, e.g. 12 hours" default = "24 hours" + type = string } variable "update_schedule" { description = "schedule for running domain-protect update function, e.g. 60 minutes" default = "3 hours" + type = string } variable "update_schedule_nonprod" { description = "schedule for running domain-protect update function in non-prod, e.g. 12 hours" default = "24 hours" + type = string } variable "ip_scan_schedule" { description = "schedule for IP address scanning used in A record checks" default = "24 hours" + type = string } variable "ip_scan_schedule_nonprod" { description = "schedule for IP address scans in non-prod, reduced to save costs, e.g. 24 hours" default = "24 hours" + type = string } variable "stats_schedule" { description = "Cron schedule for the stats message" default = "cron(0 9 1 * ? *)" # 9am on the first of the month + type = string } variable "lambdas" { @@ -77,6 +91,7 @@ variable "lambdas" { variable "takeover" { description = "Create supported resource types to prevent malicious subdomain takeover" default = true + type = bool } variable "update_lambdas" { @@ -88,36 +103,43 @@ variable "update_lambdas" { variable "environment" { description = "Environment deploying to, defaults to terraform.workspace - optionally enter in tfvars file" default = "" + type = string } variable "production_environment" { description = "Name of production environment - takeover is only turned on in this environment" default = "" + type = string } variable "production_workspace" { description = "Deprecated, use production_environment. Will be removed in a future release" default = "prd" + type = string } variable "runtime" { description = "Lambda language runtime" default = "python3.11" + type = string } variable "platform" { description = "Python platform used for install of Regex and other libraries" default = "manylinux2014_x86_64" + type = string } variable "memory_size" { description = "Memory allocation for scanning Lambda functions" default = 128 + type = number } variable "memory_size_slack" { description = "Memory allocation for Slack Lambda functions" default = 128 + type = number } variable "slack_channels" { description = "List of Slack Channels - enter in tfvars file" @@ -146,66 +168,82 @@ variable "slack_webhook_urls_dev" { variable "slack_webhook_type" { description = "Slack webhook type, can be legacy or app" default = "legacy" + type = string } variable "slack_emoji" { description = "Slack emoji" default = ":warning:" + type = string } variable "slack_fix_emoji" { description = "Slack fix emoji" default = ":white_check_mark:" + type = string } variable "slack_new_emoji" { description = "Slack emoji for new vulnerability" default = ":octagonal_sign:" + type = string } variable "slack_username" { description = "Slack username appearing in the from field in the Slack message" default = "Domain Protect" + type = string } variable "bugcrowd" { description = "Set to enabled for Bugcrowd integration" default = "disabled" + type = string } variable "bugcrowd_api_key" { description = "Bugcrowd API token" default = "" + type = string + sensitive = true } variable "bugcrowd_email" { description = "Email address of Bugcrowd researcher service account" default = "" + type = string } variable "bugcrowd_state" { description = "State in which issue is created, e.g. new, triaged, unresolved, resolved" default = "unresolved" + type = string } variable "hackerone" { description = "Set to enabled for HackerOne integration" default = "disabled" + type = string } variable "hackerone_api_token" { description = "HackerOne API token" default = "" + type = string + sensitive = true } variable "cloudflare" { description = "Set to true to enable CloudFlare" default = false + type = bool } variable "cf_api_key" { description = "Cloudflare API token" default = "" + type = string + sensitive = true } variable "cloudflare_lambdas" { @@ -217,30 +255,29 @@ variable "cloudflare_lambdas" { variable "rcu" { description = "DynamoDB Read Capacity Units for vulnerability database" default = 3 + type = number } variable "wcu" { description = "DynamoDB Write Capacity Units for vulnerability database" default = 2 + type = number } variable "ip_address" { description = "Set to true to enable A record checks using IP address scans" default = false + type = bool } variable "allowed_regions" { description = "If SCPs block certain regions across all accounts, optionally replace with string formatted list of allowed regions" default = "['all']" # example "['eu-west-1', 'us-east-1']" + type = string } variable "permissions_boundary_arn" { description = "permissions boundary ARN to attach to every IAM role" - default = "" -} - -variable "default_tags" { - description = "Default tags for supported resources" - type = map(string) - default = {} + default = null + type = string } diff --git a/provider.tf b/versions.tf similarity index 65% rename from provider.tf rename to versions.tf index bf2e2272..a6a9d305 100644 --- a/provider.tf +++ b/versions.tf @@ -1,20 +1,22 @@ terraform { + required_version = "> 1" + required_providers { aws = { source = "hashicorp/aws" - version = "~> 5.12.0" + version = "> 5.12.0" } archive = { source = "hashicorp/archive" - version = "~> 2.2.0" + version = "> 2.2.0" } null = { source = "hashicorp/null" - version = "~> 3.1.0" + version = "> 3.1.0" } random = { source = "hashicorp/random" - version = "~> 3.1.0" + version = "> 3.1.0" } } }