diff --git a/terraform/modules/baseline/rds_instance.tf b/terraform/modules/baseline/rds_instance.tf index 6c3264fd26f..1987c6420ce 100644 --- a/terraform/modules/baseline/rds_instance.tf +++ b/terraform/modules/baseline/rds_instance.tf @@ -7,6 +7,9 @@ module "db_instance" { aws.core-vpc = aws.core-vpc } + application_name = var.environment.application_name + environment = var.environment.environment + identifier = each.value.instance.identifier instance = merge(each.value.instance, { @@ -18,5 +21,13 @@ module "db_instance" { parameter_group = each.value.parameter_group subnet_group = each.value.subnet_group + ssm_parameters_prefix = each.value.config.ssm_parameters_prefix + ssm_parameters = each.value.ssm_parameters + + instance_profile_policies = [ + for policy in each.value.config.instance_profile_policies : + lookup(aws_iam_policy.this, policy, null) != null ? aws_iam_policy.this[policy].arn : policy + ] + tags = merge(local.tags, each.value.tags) } \ No newline at end of file diff --git a/terraform/modules/baseline/variables.tf b/terraform/modules/baseline/variables.tf index 0aecdce0145..2395a76476d 100644 --- a/terraform/modules/baseline/variables.tf +++ b/terraform/modules/baseline/variables.tf @@ -245,6 +245,11 @@ variable "ec2_instances" { variable "rds_instances" { description = "map of rds instances to create where the map key is the tags.Name. See rds_instance module for more variable details" type = map(object({ + config = object({ + iam_resource_names_prefix = optional(string, "rds_db") + instance_profile_policies = list(string) + ssm_parameters_prefix = optional(string, "") + }) instance = object({ identifier = string create = optional(bool, true) @@ -292,7 +297,11 @@ variable "rds_instances" { engine_name = string major_engine_version = string options = list(object({ - name = string + option_name = string + port = optional(number) + version = optional(string) + db_security_group_memberships = optional(list(string)) + vpc_security_group_memberships = optional(list(string)) settings = list(object({ name = string value = string @@ -306,12 +315,10 @@ variable "rds_instances" { description = string family = string major_engine_version = string - parameter = list(object({ - name = string - settings = list(object({ - name = string - value = string - })) + parameters = list(object({ + name = string + value = string + apply_method = optional(string, "immediate") })) tags = optional(list(string)) }) diff --git a/terraform/modules/rds_instance/data.tf b/terraform/modules/rds_instance/data.tf index d78fce49cf5..e0933572e69 100644 --- a/terraform/modules/rds_instance/data.tf +++ b/terraform/modules/rds_instance/data.tf @@ -1 +1,15 @@ -data "aws_caller_identity" "current" {} \ No newline at end of file +data "aws_caller_identity" "current" {} + +data "aws_route53_zone" "internal" { + provider = aws.core-vpc + + name = "${var.business_unit}-${var.environment}.modernisation-platform.internal." + private_zone = true +} + +data "aws_route53_zone" "external" { + provider = aws.core-vpc + + name = "${var.business_unit}-${var.environment}.modernisation-platform.service.justice.gov.uk." + private_zone = false +} \ No newline at end of file diff --git a/terraform/modules/rds_instance/locals.tf b/terraform/modules/rds_instance/locals.tf index 3d7348554b4..864eadde99a 100644 --- a/terraform/modules/rds_instance/locals.tf +++ b/terraform/modules/rds_instance/locals.tf @@ -1,6 +1,6 @@ locals { default_tags = { - instance-name = var.instance.db_name + identifier = var.identifier } tags = merge(local.default_tags, var.tags) } \ No newline at end of file diff --git a/terraform/modules/rds_instance/main.tf b/terraform/modules/rds_instance/main.tf index f81ef1f8185..a81d7b4f977 100644 --- a/terraform/modules/rds_instance/main.tf +++ b/terraform/modules/rds_instance/main.tf @@ -14,7 +14,7 @@ resource "aws_db_instance" "this" { kms_key_id = var.instance.kms_key_id license_model = var.instance.license_model - name = var.instance.name + db_name = var.instance.db_name username = var.instance.username password = var.instance.password port = var.instance.port @@ -24,12 +24,12 @@ resource "aws_db_instance" "this" { snapshot_identifier = var.instance.snapshot_identifier - vpc_security_group_ids = [var.instance.vpc_security_group_ids] + vpc_security_group_ids = var.instance.vpc_security_group_ids db_subnet_group_name = var.instance.db_subnet_group_name parameter_group_name = var.instance.parameter_group_name option_group_name = var.instance.option_group_name - availability_zone = var.instance.availability_zone + availability_zone = var.availability_zone multi_az = var.instance.multi_az iops = var.instance.iops publicly_accessible = var.instance.publicly_accessible @@ -49,7 +49,9 @@ resource "aws_db_instance" "this" { character_set_name = var.instance.character_set_name - tags = merge(var.tags, map("Name", format("%s", var.instance.identifier))) + tags = merge(local.tags, { + Name = var.identifier + }) enabled_cloudwatch_logs_exports = var.instance.enabled_cloudwatch_logs_exports } @@ -70,8 +72,26 @@ resource "aws_db_option_group" "this" { option_group_description = var.option_group.description == "" ? format("Option group for %s", var.identifier) : var.option_group.description engine_name = var.option_group.engine_name major_engine_version = var.option_group.major_engine_version - option = var.option_group.options - tags = merge(var.option_group.tags, map("Name", format("%s", var.identifier))) + dynamic "option" { + for_each = var.option_group.options + content { + option_name = option.value.option_name + port = option.value.port + version = option.value.version + db_security_group_memberships = option.value.db_security_group_memberships + vpc_security_group_memberships = option.value.vpc_security_group_memberships + dynamic "option_settings" { + for_each = option.value.settings + content { + name = option_settings.value.name + value = option_settings.value.value + } + } + } + } + tags = merge(local.tags, { + Name = var.option_group.name_prefix + }) } #------------------------------------------------------------------------------ @@ -85,9 +105,17 @@ resource "aws_db_parameter_group" "this" { description = "Database parameter group for ${var.identifier}" family = var.parameter_group.family - parameter = var.parameter_group.parameters - - tags = merge(var.parameter_group.tags, map("Name", format("%s", var.identifier))) + dynamic "parameter" { + for_each = var.parameter_group.parameters + content { + name = parameter.value.name + value = parameter.value.value + apply_method = parameter.value.apply_method + } + } + tags = merge(local.tags, { + Name = var.parameter_group.name_prefix + }) lifecycle { create_before_destroy = true @@ -101,7 +129,43 @@ resource "aws_db_parameter_group" "this" { resource "aws_db_subnet_group" "this" { name_prefix = var.subnet_group.name_prefix description = "Database subnet group for ${var.identifier}" - subnet_ids = [var.subnet_group.subnet_ids] + subnet_ids = var.subnet_group.subnet_ids + + tags = merge(local.tags, { + Name = var.subnet_group.name_prefix + }) +} + +#------------------------------------------------------------------------------ +# IAM +#------------------------------------------------------------------------------ - tags = merge(var.tags, map("Name", format("%s", var.identifier))) -} \ No newline at end of file +# resource "aws_iam_role" "this" { +# name = "${var.iam_resource_names_prefix}-role-${var.identifier}" +# path = "/" +# max_session_duration = "3600" +# assume_role_policy = jsonencode( +# { +# "Version" : "2012-10-17", +# "Statement" : [ +# { +# "Effect" : "Allow", +# "Principal" : { +# "Service" : "rds.amazonaws.com" +# } +# "Action" : "sts:AssumeRole", +# "Condition" : {} +# } +# ] +# } +# ) + +# managed_policy_arns = var.instance_profile_policies + +# tags = merge( +# local.tags, +# { +# Name = "${var.iam_resource_names_prefix}-role-${var.identifier}" +# }, +# ) +# } \ No newline at end of file diff --git a/terraform/modules/rds_instance/variables.tf b/terraform/modules/rds_instance/variables.tf index db1c7c79ab4..813a90e34e5 100644 --- a/terraform/modules/rds_instance/variables.tf +++ b/terraform/modules/rds_instance/variables.tf @@ -1,3 +1,26 @@ +variable "business_unit" { + type = string + description = "This corresponds to the VPC in which the application resides" + default = "hmpps" + nullable = false +} + +variable "application_name" { + type = string + description = "The name of the application. This will be name of the environment in Modernisation Platform" + default = "nomis" + nullable = false + validation { + condition = can(regex("^[A-Za-z0-9][A-Za-z0-9-.]{1,61}[A-Za-z0-9]$", var.application_name)) + error_message = "Invalid name for application supplied in variable app_name." + } +} + +variable "environment" { + type = string + description = "Application environment - i.e. the terraform workspace" +} + variable "identifier" { type = string description = "The identifier of the resource" @@ -78,7 +101,11 @@ variable "option_group" { engine_name = string major_engine_version = string options = list(object({ - name = string + option_name = string + port = optional(number) + version = optional(string) + db_security_group_memberships = optional(list(string)) + vpc_security_group_memberships = optional(list(string)) settings = list(object({ name = string value = string @@ -91,17 +118,14 @@ variable "option_group" { variable "parameter_group" { description = "RDS instance parameter group settings" type = object({ - create = bool - name_prefix = string - description = string - family = string - major_engine_version = string - parameter = list(object({ - name = string - settings = list(object({ - name = string - value = string - })) + create = bool + name_prefix = string + description = string + family = string + parameters = list(object({ + name = string + value = string + apply_method = optional(string, "immediate") })) tags = optional(list(string)) }) @@ -116,4 +140,33 @@ variable "subnet_group" { subnet_ids = list(string) tags = optional(list(string)) }) +} + +variable "iam_resource_names_prefix" { + type = string + description = "Prefix IAM resources with this prefix, e.g. rds_instance-blabla" + default = "rds_instance" +} + +variable "instance_profile_policies" { + type = list(string) + description = "A list of managed IAM policy document ARNs to be attached to the database instance profile" +} + +variable "ssm_parameters_prefix" { + type = string + description = "Optionally prefix ssm parameters with this prefix. Add a trailing /" + default = "" +} + +variable "ssm_parameters" { + description = "A map of SSM parameters to create. If parameters are manually created, set to {} so IAM role still created" + type = map(object({ + random = object({ + length = number + special = bool + }) + description = string + })) + default = null } \ No newline at end of file