diff --git a/terraform/account/.terraform.lock.hcl b/terraform/account/.terraform.lock.hcl index 4c420d0309..5c3e517094 100644 --- a/terraform/account/.terraform.lock.hcl +++ b/terraform/account/.terraform.lock.hcl @@ -5,20 +5,7 @@ provider "registry.terraform.io/hashicorp/aws" { version = "5.84.0" constraints = ">= 5.5.0, ~> 5.84.0" hashes = [ - "h1:897cPKLnktFTBHxlPDyv52hQoR7rUy52Tzr9F/bvXW0=", - "h1:EJLTu1eqP93P4+DexFZHnuMCwEapkmHhEUirUT+tjZw=", - "h1:MVppdPvKcROdwwj1i7OMoZ/ODFZlqrYr7GVHI1Fevb8=", - "h1:MsFKMU05GLbXfXQZHqy+eC5FC5hDxyRB1irY3lvAaf8=", - "h1:N0mARumaxRCk1FmbDiEW89izbpV/3jkWowrm/78HucQ=", "h1:OJ53RNte7HLHSMxSkzu1S6H8sC0T8qnCAOcNLjjtMpc=", - "h1:TpsSFMkiuLC1V29n4Ov99g4L6jlsBmBMWxqDX3GZNww=", - "h1:X50oGSrQb2Hzf6i1BWnYOqIneJSy7TiWNtKK+VY+aGA=", - "h1:dwpeFUdcxgXVAc0JSqO57xf0/r2qOBLPloombCQWFz8=", - "h1:eeLhwhBhj96w3YFnTcOMPV0ybGER5fbv/ihcTMeoTk4=", - "h1:iBnPrv1hIjnS26jHVGXuxTDF27OaVOx2XJ0Sbp45qHs=", - "h1:lL0Ftd7QOGinm/1w/1qwfoj6urdJsmRSVxV+xfBD8R4=", - "h1:mwHAD66PY6wi858oGl5NcWGfA9X7mdxPrZrAGfJGS3A=", - "h1:p7kabmCUZYyP5A6VqtIvuy/+CTiGn03jVdcIFMbQkOI=", "zh:078f77438aba6ec8bf9154b7d223e5c71c48d805d6cd3bcf9db0cc1e82668ac3", "zh:1f6591ff96be00501e71b792ed3a5a14b21ff03afec9a1c4a3fd9300e6e5b674", "zh:2ab694e022e81dd74485351c5836148a842ed71cf640664c9d871cb517b09602", @@ -41,19 +28,7 @@ provider "registry.terraform.io/pagerduty/pagerduty" { version = "3.19.4" constraints = "3.19.4" hashes = [ - "h1:6uh2ljGz8wh8zOvgBSi1meGSEO3OdD6ZjYT0s16Cj7g=", - "h1:BArzD20N7MRjfaNUdBSEsoAmgRgpT+h31n9fesL0A08=", - "h1:LHXFrd8NVC1cLd/guTGtkzfAQOi39bCBblWhxN75cRk=", - "h1:T5zJKrF0ey4eZwSFbKAywiAEvo131bHRqEuBXyQsX3A=", - "h1:f5PRK4FVelfA7KeNYxpMouqTnpbBCYwTZ9MMkzXcRAI=", - "h1:geFJfzh5ttynHA1Upv9pbqZiMtobc5UUY7QDaTArnyc=", - "h1:jtB0ZQ6FzQ2iXxe0wy/rnJIUWKaT8g/MApztbqF4sDg=", - "h1:nWoIrb3KwSFmblHik7Zqj6spycYudn0dx+wFcSjWRlo=", - "h1:qGDMGIVi/FqFy81QbTDhDMBiWa4srpPPJ6ELhfS8H54=", - "h1:qGXN/20ud2MpBTJ+t41VhJv5jDNuezuIYPoQJMcZbf0=", - "h1:t8P6sokG6SL2NZsLjlparpW5L/T52g/FVVMiZ/NWshE=", "h1:tw/5/H9WVRowcIjDvvo4Y1iO+d4AQESdWid599txUNI=", - "h1:uVnam+RsXViojmrMQM5gnXCToxOhGeowvlz2F8gXuNQ=", "zh:086a813e9710c7190f228ef25d0386a4e1e78f5409ee7b963c0bd957de5ba7ad", "zh:0c490df8464c8d6bd2e7136e9d5200347a6bd59d45cbe95cb9f26d2012f88784", "zh:353b9107565d68bc0f8977594f328d839b83e5c6c3c485e2b5f2f89e42b88024", diff --git a/terraform/account/iam_sns_feedback_role.tf b/terraform/account/iam_sns_feedback_role.tf deleted file mode 100644 index 0253e75180..0000000000 --- a/terraform/account/iam_sns_feedback_role.tf +++ /dev/null @@ -1,9 +0,0 @@ -data "aws_iam_role" "sns_success_feedback" { - name = "SNSSuccessFeedback" - provider = aws.global -} - -data "aws_iam_role" "sns_failure_feedback" { - provider = aws.global - name = "SNSFailureFeedback" -} diff --git a/terraform/account/refactoring.tf b/terraform/account/refactoring.tf index d594465475..ea35bbf11b 100644 --- a/terraform/account/refactoring.tf +++ b/terraform/account/refactoring.tf @@ -194,3 +194,63 @@ moved { from = module.eu_west_1[0].module.aws_backup_vaults.aws_sns_topic_policy.aws_backup_failure_events to = module.aws_backup_vaults_eu_west_1.aws_sns_topic_policy.aws_backup_failure_events } + +moved { + from = aws_cloudwatch_metric_alarm.opensearch_4xx_errors + to = module.eu_west_1[0].aws_cloudwatch_metric_alarm.opensearch_4xx_errors +} + +moved { + from = aws_cloudwatch_metric_alarm.opensearch_5xx_errors + to = module.eu_west_1[0].aws_cloudwatch_metric_alarm.opensearch_5xx_errors +} + +moved { + from = aws_opensearchserverless_access_policy.github_actions_access[0] + to = module.eu_west_1[0].aws_opensearchserverless_access_policy.github_actions_access[0] +} + +moved { + from = aws_opensearchserverless_access_policy.team_operator_access[0] + to = module.eu_west_1[0].aws_opensearchserverless_access_policy.team_operator_access[0] +} + +moved { + from = aws_opensearchserverless_collection.lpas_collection + to = module.eu_west_1[0].aws_opensearchserverless_collection.lpas_collection +} + +moved { + from = aws_opensearchserverless_security_policy.lpas_collection_development_network_policy[0] + to = module.eu_west_1[0].aws_opensearchserverless_security_policy.lpas_collection_development_network_policy[0] +} + +moved { + from = aws_opensearchserverless_security_policy.lpas_collection_network_policy + to = module.eu_west_1[0].aws_opensearchserverless_security_policy.lpas_collection_network_policy +} + +moved { + from = aws_sns_topic.opensearch + to = module.eu_west_1[0].aws_sns_topic.opensearch +} + +moved { + from = aws_opensearchserverless_security_policy.lpas_collection_encryption_policy + to = module.eu_west_1[0].aws_opensearchserverless_security_policy.lpas_collection_encryption_policy +} + +moved { + from = aws_sns_topic_subscription.opensearch + to = module.eu_west_1[0].aws_sns_topic_subscription.opensearch +} + +moved { + from = pagerduty_service_integration.opensearch + to = module.eu_west_1[0].pagerduty_service_integration.opensearch +} + +moved { + from = aws_opensearchserverless_access_policy.team_breakglass_access[0] + to = module.eu_west_1[0].aws_opensearchserverless_access_policy.team_breakglass_access[0] +} diff --git a/terraform/account/opensearch.tf b/terraform/account/region/opensearch.tf similarity index 67% rename from terraform/account/opensearch.tf rename to terraform/account/region/opensearch.tf index c1327de7e7..4ac9438825 100644 --- a/terraform/account/opensearch.tf +++ b/terraform/account/region/opensearch.tf @@ -1,29 +1,29 @@ resource "aws_opensearchserverless_security_policy" "lpas_collection_encryption_policy" { - name = "policy-shared-${local.account_name}" + name = "policy-shared-${data.aws_default_tags.current.tags.account-name}" type = "encryption" description = "encryption policy for collection" policy = jsonencode({ Rules = [ { - Resource = ["collection/shared-collection-${local.account_name}"], + Resource = ["collection/shared-collection-${data.aws_default_tags.current.tags.account-name}"], ResourceType = "collection" } ], AWSOwnedKey = false - KmsARN = module.opensearch_kms.eu_west_1_target_key_arn + KmsARN = var.opensearch_kms_target_key_arn }) - provider = aws.eu_west_1 + provider = aws.region } resource "aws_opensearchserverless_collection" "lpas_collection" { - name = "shared-collection-${local.account_name}" + name = "shared-collection-${data.aws_default_tags.current.tags.account-name}" type = "SEARCH" depends_on = [aws_opensearchserverless_security_policy.lpas_collection_encryption_policy] - provider = aws.eu_west_1 + provider = aws.region } resource "aws_opensearchserverless_security_policy" "lpas_collection_network_policy" { - name = "policy-shared-${local.account_name}" + name = "policy-shared-${data.aws_default_tags.current.tags.account-name}" type = "network" description = "VPC access for collection endpoint" policy = jsonencode([ @@ -32,12 +32,12 @@ resource "aws_opensearchserverless_security_policy" "lpas_collection_network_pol Rules = [ { ResourceType = "collection", - Resource = ["collection/shared-collection-${local.account_name}"] + Resource = ["collection/shared-collection-${data.aws_default_tags.current.tags.account-name}"] } ], AllowFromPublic = false, SourceVPCEs = [ - module.eu_west_1[0].opensearch_lpas_collection_vpc_endpoint.id, + aws_opensearchserverless_vpc_endpoint.lpas_collection_vpc_endpoint.id, ] }, { @@ -45,17 +45,17 @@ resource "aws_opensearchserverless_security_policy" "lpas_collection_network_pol Description = "public access to dashboard" Rules = [ { - Resource = ["collection/shared-collection-${local.account_name}"] + Resource = ["collection/shared-collection-${data.aws_default_tags.current.tags.account-name}"] ResourceType = "dashboard" } ] } ]) - provider = aws.eu_west_1 + provider = aws.region } resource "aws_opensearchserverless_security_policy" "lpas_collection_development_network_policy" { - count = local.account_name == "development" ? 1 : 0 + count = data.aws_default_tags.current.tags.account-name == "development" ? 1 : 0 name = "development-public-access" type = "network" description = "Public access for development collection endpoints" @@ -71,11 +71,11 @@ resource "aws_opensearchserverless_security_policy" "lpas_collection_development AllowFromPublic = true, }, ]) - provider = aws.eu_west_1 + provider = aws.region } resource "aws_opensearchserverless_access_policy" "github_actions_access" { - count = local.account_name == "development" ? 1 : 0 + count = data.aws_default_tags.current.tags.account-name == "development" ? 1 : 0 name = "github-access-shared-development" type = "data" description = "allow index and collection access for team" @@ -94,16 +94,16 @@ resource "aws_opensearchserverless_access_policy" "github_actions_access" { } ], Principal = [ - "arn:aws:iam::${data.aws_caller_identity.global.account_id}:role/modernising-lpa-github-actions-opensearch-delete-index" + "arn:aws:iam::${data.aws_caller_identity.current.account_id}:role/modernising-lpa-github-actions-opensearch-delete-index" ] } ]) - provider = aws.eu_west_1 + provider = aws.region } resource "aws_opensearchserverless_access_policy" "team_operator_access" { - count = local.account_name == "production" ? 0 : 1 - name = "team-access-shared-${local.account_name}" + count = data.aws_default_tags.current.tags.account-name == "production" ? 0 : 1 + name = "team-access-shared-${data.aws_default_tags.current.tags.account-name}" type = "data" description = "allow index and collection access for team" policy = jsonencode([ @@ -111,26 +111,26 @@ resource "aws_opensearchserverless_access_policy" "team_operator_access" { Rules = [ { ResourceType = "index", - Resource = ["index/shared-collection-${local.account_name}/*"], + Resource = ["index/shared-collection-${data.aws_default_tags.current.tags.account-name}/*"], Permission = ["aoss:*"] }, { ResourceType = "collection", - Resource = ["collection/shared-collection-${local.account_name}"], + Resource = ["collection/shared-collection-${data.aws_default_tags.current.tags.account-name}"], Permission = ["aoss:*"] } ], Principal = [ - "arn:aws:iam::${data.aws_caller_identity.global.account_id}:role/operator" + "arn:aws:iam::${data.aws_caller_identity.current.account_id}:role/operator" ] } ]) - provider = aws.eu_west_1 + provider = aws.region } resource "aws_opensearchserverless_access_policy" "team_breakglass_access" { - count = local.account_name == "production" ? 1 : 0 - name = "team-access-shared-${local.account_name}" + count = data.aws_default_tags.current.tags.account-name == "production" ? 1 : 0 + name = "team-access-shared-${data.aws_default_tags.current.tags.account-name}" type = "data" description = "allow index and collection access for team" policy = jsonencode([ @@ -138,25 +138,25 @@ resource "aws_opensearchserverless_access_policy" "team_breakglass_access" { Rules = [ { ResourceType = "index", - Resource = ["index/shared-collection-${local.account_name}/*"], + Resource = ["index/shared-collection-${data.aws_default_tags.current.tags.account-name}/*"], Permission = ["aoss:*"] }, { ResourceType = "collection", - Resource = ["collection/shared-collection-${local.account_name}"], + Resource = ["collection/shared-collection-${data.aws_default_tags.current.tags.account-name}"], Permission = ["aoss:*"] } ], Principal = [ - "arn:aws:iam::${data.aws_caller_identity.global.account_id}:role/breakglass" + "arn:aws:iam::${data.aws_caller_identity.current.account_id}:role/breakglass" ] } ]) - provider = aws.eu_west_1 + provider = aws.region } resource "aws_cloudwatch_metric_alarm" "opensearch_4xx_errors" { - alarm_name = "${local.account_name}-opensearch-4xx-errors" + alarm_name = "${data.aws_default_tags.current.tags.account-name}-opensearch-4xx-errors" alarm_actions = [aws_sns_topic.opensearch.arn] comparison_operator = "GreaterThanOrEqualToThreshold" evaluation_periods = "1" @@ -165,17 +165,17 @@ resource "aws_cloudwatch_metric_alarm" "opensearch_4xx_errors" { period = "30" statistic = "Maximum" threshold = "1" - alarm_description = "This metric monitors AWS OpenSearch Service 4xx error count for ${local.account_name}" + alarm_description = "This metric monitors AWS OpenSearch Service 4xx error count for ${data.aws_default_tags.current.tags.account-name}" insufficient_data_actions = [] dimensions = { CollectionId = aws_opensearchserverless_collection.lpas_collection.id CollectionName = aws_opensearchserverless_collection.lpas_collection.name } - provider = aws.eu_west_1 + provider = aws.region } resource "aws_cloudwatch_metric_alarm" "opensearch_5xx_errors" { - alarm_name = "${local.account_name}-opensearch-5xx-errors" + alarm_name = "${data.aws_default_tags.current.tags.account-name}-opensearch-5xx-errors" alarm_actions = [aws_sns_topic.opensearch.arn] comparison_operator = "GreaterThanOrEqualToThreshold" evaluation_periods = "1" @@ -184,13 +184,13 @@ resource "aws_cloudwatch_metric_alarm" "opensearch_5xx_errors" { period = "30" statistic = "Maximum" threshold = "1" - alarm_description = "This metric monitors AWS OpenSearch Service 5xx error count for ${local.account_name}" + alarm_description = "This metric monitors AWS OpenSearch Service 5xx error count for ${data.aws_default_tags.current.tags.account-name}" insufficient_data_actions = [] dimensions = { CollectionId = aws_opensearchserverless_collection.lpas_collection.id CollectionName = aws_opensearchserverless_collection.lpas_collection.name } - provider = aws.eu_west_1 + provider = aws.region } data "pagerduty_vendor" "cloudwatch" { @@ -198,12 +198,12 @@ data "pagerduty_vendor" "cloudwatch" { } data "pagerduty_service" "main" { - name = local.account.pagerduty_service_name + name = var.pagerduty_service_name } resource "aws_sns_topic" "opensearch" { - name = "${local.account_name}-opensearch-alarms" - kms_master_key_id = module.sns_kms.eu_west_1_target_key_id + name = "${data.aws_default_tags.current.tags.account-name}-opensearch-alarms" + kms_master_key_id = var.sns_kms_key.eu_west_1_target_key_id application_failure_feedback_role_arn = data.aws_iam_role.sns_failure_feedback.arn application_success_feedback_role_arn = data.aws_iam_role.sns_success_feedback.arn application_success_feedback_sample_rate = 100 @@ -219,11 +219,11 @@ resource "aws_sns_topic" "opensearch" { sqs_failure_feedback_role_arn = data.aws_iam_role.sns_failure_feedback.arn sqs_success_feedback_role_arn = data.aws_iam_role.sns_success_feedback.arn sqs_success_feedback_sample_rate = 100 - provider = aws.eu_west_1 + provider = aws.region } resource "pagerduty_service_integration" "opensearch" { - name = "Modernising LPA Shared ${local.account_name} OpenSearch Alarm" + name = "Modernising LPA Shared ${data.aws_default_tags.current.tags.account-name} OpenSearch Alarm" service = data.pagerduty_service.main.id vendor = data.pagerduty_vendor.cloudwatch.id } @@ -233,5 +233,5 @@ resource "aws_sns_topic_subscription" "opensearch" { protocol = "https" endpoint_auto_confirms = true endpoint = "https://events.pagerduty.com/integration/${pagerduty_service_integration.opensearch.integration_key}/enqueue" - provider = aws.eu_west_1 + provider = aws.region } diff --git a/terraform/account/region/outputs.tf b/terraform/account/region/outputs.tf index 410a025bdf..4dfd2a35b7 100644 --- a/terraform/account/region/outputs.tf +++ b/terraform/account/region/outputs.tf @@ -1,7 +1,3 @@ output "ecs_autoscaling_alarm_sns_topic" { value = aws_sns_topic.ecs_autoscaling_alarms } - -output "opensearch_lpas_collection_vpc_endpoint" { - value = aws_opensearchserverless_vpc_endpoint.lpas_collection_vpc_endpoint -} diff --git a/terraform/account/region/s3_lb_access_logs.tf b/terraform/account/region/s3_lb_access_logs.tf index fad878a687..bdfe98a559 100644 --- a/terraform/account/region/s3_lb_access_logs.tf +++ b/terraform/account/region/s3_lb_access_logs.tf @@ -195,7 +195,7 @@ module "s3_event_notifications" { "s3:ObjectRemoved:*", "s3:ObjectAcl:Put", ] - sns_kms_key_alias = var.sns_kms_key_alias + sns_kms_key_alias = var.sns_kms_key.kms_key_alias_name s3_bucket_id = aws_s3_bucket.access_log.id sns_failure_feedback_role_arn = data.aws_iam_role.sns_failure_feedback.arn sns_success_feedback_role_arn = data.aws_iam_role.sns_success_feedback.arn diff --git a/terraform/account/region/sns_topics.tf b/terraform/account/region/sns_topics.tf index beed06c254..e428906cd3 100644 --- a/terraform/account/region/sns_topics.tf +++ b/terraform/account/region/sns_topics.tf @@ -1,5 +1,5 @@ data "aws_kms_alias" "sns_kms_key_alias" { - name = var.sns_kms_key_alias + name = var.sns_kms_key.kms_key_alias_name provider = aws.region } diff --git a/terraform/account/region/variables.tf b/terraform/account/region/variables.tf index ccece9257d..6a2453f36e 100644 --- a/terraform/account/region/variables.tf +++ b/terraform/account/region/variables.tf @@ -9,9 +9,9 @@ variable "cloudwatch_log_group_kms_key_alias" { description = "The alias of the KMS Key to use when encrypting Cloudwatch log data." } -variable "sns_kms_key_alias" { - description = "The alias of the KMS key used to encrypt the SNS topic" - type = string +variable "sns_kms_key" { + type = any + description = "The KMS key used to encrypt the SNS topic" } variable "secrets_manager_kms_key_alias" { @@ -33,3 +33,12 @@ variable "network_firewall_rules_file" { type = string description = "The path to the file containing the network firewall rules." } + +variable "opensearch_kms_target_key_arn" { + type = string + description = "kms target key ARN for opensearch serverless encryption" +} + +variable "pagerduty_service_name" { + type = string +} diff --git a/terraform/account/region/versions.tf b/terraform/account/region/versions.tf index e00d83fd0d..dba2aebd8f 100644 --- a/terraform/account/region/versions.tf +++ b/terraform/account/region/versions.tf @@ -11,5 +11,9 @@ terraform { aws.global, ] } + pagerduty = { + source = "PagerDuty/pagerduty" + version = "3.19.4" + } } } diff --git a/terraform/account/regions.tf b/terraform/account/regions.tf index 0c9686b33f..a1d0de0691 100644 --- a/terraform/account/regions.tf +++ b/terraform/account/regions.tf @@ -4,10 +4,12 @@ module "eu_west_1" { network_cidr_block = "10.162.0.0/16" network_firewall_rules_file = "./network_firewall_rules.rules" cloudwatch_log_group_kms_key_alias = module.cloudwatch_kms.kms_key_alias_name - sns_kms_key_alias = module.sns_kms.kms_key_alias_name + sns_kms_key = module.sns_kms secrets_manager_kms_key_alias = module.secrets_manager_kms.kms_key_alias_name reduced_fees_uploads_s3_encryption_kms_key_alias = module.reduced_fees_uploads_s3_kms.kms_key_alias_name dynamodb_exports_s3_bucket_server_side_encryption_key_id = module.dynamodb_exports_s3_bucket_kms.eu_west_1_target_key_id + opensearch_kms_target_key_arn = module.opensearch_kms.eu_west_1_target_key_arn + pagerduty_service_name = local.account.pagerduty_service_name providers = { aws.region = aws.eu_west_1 aws.management = aws.management_eu_west_1 @@ -21,10 +23,12 @@ module "eu_west_2" { network_cidr_block = "10.162.0.0/16" network_firewall_rules_file = "./network_firewall_rules.rules" cloudwatch_log_group_kms_key_alias = module.cloudwatch_kms.kms_key_alias_name - sns_kms_key_alias = module.sns_kms.kms_key_alias_name + sns_kms_key = module.sns_kms secrets_manager_kms_key_alias = module.secrets_manager_kms.kms_key_alias_name reduced_fees_uploads_s3_encryption_kms_key_alias = module.reduced_fees_uploads_s3_kms.kms_key_alias_name dynamodb_exports_s3_bucket_server_side_encryption_key_id = module.dynamodb_exports_s3_bucket_kms.eu_west_2_target_key_id + opensearch_kms_target_key_arn = module.opensearch_kms.eu_west_2_target_key_arn + pagerduty_service_name = local.account.pagerduty_service_name providers = { aws.region = aws.eu_west_2 aws.management = aws.management_eu_west_2