Skip to content

Commit

Permalink
DSND-2696: Implement terraform setup (#116)
Browse files Browse the repository at this point in the history
* DSND-2696: WIP Add terraform

* DSND-2696: change lb priority and path

* DSND-2696: Uncomment public LB config

---------

Co-authored-by: cgregoryCH <[email protected]>
  • Loading branch information
sthompsonCH and cgregoryCH committed Jul 8, 2024
1 parent 0605cb8 commit 6647605
Show file tree
Hide file tree
Showing 12 changed files with 488 additions and 0 deletions.
77 changes: 77 additions & 0 deletions terraform/groups/ecs-service/data.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@

data "vault_generic_secret" "stack_secrets" {
path = "applications/${var.aws_profile}/${var.environment}/${local.stack_name}-stack"
}

data "vault_generic_secret" "service_secrets" {
path = "applications/${var.aws_profile}/${var.environment}/${local.stack_name}-stack/${local.service_name}"
}

data "aws_kms_key" "kms_key" {
key_id = local.kms_alias
}

data "aws_vpc" "vpc" {
filter {
name = "tag:Name"
values = [local.vpc_name]
}
}

#Get application subnet IDs
data "aws_subnets" "application" {
filter {
name = "tag:Name"
values = [local.application_subnet_pattern]
}
}

data "aws_lb" "service_lb" {
name = "${var.environment}-chs-apichgovuk"
}

data "aws_lb_listener" "service_lb_listener" {
load_balancer_arn = data.aws_lb.service_lb.arn
port = 443
}

data "aws_lb" "secondary_lb" {
name = "${var.environment}-chs-apichgovuk-private"
}

data "aws_lb_listener" "secondary_lb_listener" {
load_balancer_arn = data.aws_lb.secondary_lb.arn
port = 443
}

data "aws_ecs_cluster" "ecs_cluster" {
cluster_name = "${local.name_prefix}-cluster"
}
data "aws_iam_role" "ecs_cluster_iam_role" {
name = "${local.name_prefix}-ecs-task-execution-role"
}

# retrieve all secrets for this stack using the stack path
data "aws_ssm_parameters_by_path" "secrets" {
path = "/${local.name_prefix}"
}
# create a list of secrets names to retrieve them in a nicer format and lookup each secret by name
data "aws_ssm_parameter" "secret" {
for_each = toset(data.aws_ssm_parameters_by_path.secrets.names)
name = each.key
}

# retrieve all global secrets for this env using global path
data "aws_ssm_parameters_by_path" "global_secrets" {
path = "/${local.global_prefix}"
}
# create a list of secrets names to retrieve them in a nicer format and lookup each secret by name
data "aws_ssm_parameter" "global_secret" {
for_each = toset(data.aws_ssm_parameters_by_path.global_secrets.names)
name = each.key
}

// --- s3 bucket for shared services config ---
data "vault_generic_secret" "shared_s3" {
path = "aws-accounts/shared-services/s3"
}
79 changes: 79 additions & 0 deletions terraform/groups/ecs-service/locals.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
# Define all hardcoded local variable and local variables looked up from data resources
locals {
stack_name = "public-data" # this must match the stack name the service deploys into
name_prefix = "${local.stack_name}-${var.environment}"
global_prefix = "global-${var.environment}"
service_name = "psc-data-api"
container_port = "8080"
eric_port = "10000"
docker_repo = "psc-data-api"
kms_alias = "alias/${var.aws_profile}/environment-services-kms"
lb_listener_rule_priority = 84
lb_listener_paths = [
"/psc-data-api/healthcheck", "/company/*/persons-with-significant-control*"
]
healthcheck_path = "/psc-data-api/healthcheck" #healthcheck path for psc-data-api
healthcheck_matcher = "200"
vpc_name = local.stack_secrets["vpc_name"]
s3_config_bucket = data.vault_generic_secret.shared_s3.data["config_bucket_name"]
app_environment_filename = "psc-data-api.env"
use_set_environment_files = var.use_set_environment_files
application_subnet_ids = data.aws_subnets.application.ids

stack_secrets = jsondecode(data.vault_generic_secret.stack_secrets.data_json)
application_subnet_pattern = local.stack_secrets["application_subnet_pattern"]

service_secrets = jsondecode(data.vault_generic_secret.service_secrets.data_json)

# create a map of secret name => secret arn to pass into ecs service module
# using the trimprefix function to remove the prefixed path from the secret name
secrets_arn_map = {
for sec in data.aws_ssm_parameter.secret :
trimprefix(sec.name, "/${local.name_prefix}/") => sec.arn
}

global_secrets_arn_map = {
for sec in data.aws_ssm_parameter.global_secret :
trimprefix(sec.name, "/${local.global_prefix}/") => sec.arn
}

global_secret_list = flatten([for key, value in local.global_secrets_arn_map :
{ name = upper(key), valueFrom = value }
])

ssm_global_version_map = [
for sec in data.aws_ssm_parameter.global_secret : {
name = "GLOBAL_${var.ssm_version_prefix}${replace(upper(basename(sec.name)), "-", "_")}", value = sec.version
}
]

service_secrets_arn_map = {
for sec in module.secrets.secrets:
trimprefix(sec.name, "/${local.service_name}-${var.environment}/") => sec.arn
}

service_secret_list = flatten([for key, value in local.service_secrets_arn_map :
{ name = upper(key), valueFrom = value }
])

ssm_service_version_map = [
for sec in module.secrets.secrets : {
name = "${replace(upper(local.service_name), "-", "_")}_${var.ssm_version_prefix}${replace(upper(basename(sec.name)), "-", "_")}", value = sec.version
}
]

# secrets to go in list
task_secrets = concat(local.service_secret_list,local.global_secret_list)

task_environment = concat(local.ssm_global_version_map,local.ssm_service_version_map,[
{ name : "PORT", value : local.container_port },
{ name : "LOGLEVEL", value : var.log_level }
])

# get eric secrets from global secrets map
eric_secrets = [
{ "name": "API_KEY", "valueFrom": local.global_secrets_arn_map.eric_api_key },
{ "name": "AES256_KEY", "valueFrom": local.global_secrets_arn_map.eric_aes256_key }
]
eric_environment_filename = "eric.env"
}
104 changes: 104 additions & 0 deletions terraform/groups/ecs-service/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
provider "aws" {
region = var.aws_region
}

terraform {
backend "s3" {
}
required_version = "~> 1.3"
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 4.54.0"
}
vault = {
source = "hashicorp/vault"
version = "~> 3.18.0"
}
}
}

module "ecs-service" {
source = "[email protected]:companieshouse/terraform-modules//aws/ecs/ecs-service?ref=1.0.278"


# Environmental configuration
environment = var.environment
aws_region = var.aws_region
aws_profile = var.aws_profile
vpc_id = data.aws_vpc.vpc.id
ecs_cluster_id = data.aws_ecs_cluster.ecs_cluster.id
task_execution_role_arn = data.aws_iam_role.ecs_cluster_iam_role.arn

# Load balancer configuration
lb_listener_arn = data.aws_lb_listener.service_lb_listener.arn
lb_listener_rule_priority = local.lb_listener_rule_priority
lb_listener_paths = local.lb_listener_paths
multilb_setup = true
multilb_listeners = {
"priva-api-lb": {
listener_arn = data.aws_lb_listener.secondary_lb_listener.arn,
load_balancer_arn = data.aws_lb.secondary_lb.arn
}
"publ-api-lb": {
load_balancer_arn = data.aws_lb.service_lb.arn
listener_arn = data.aws_lb_listener.service_lb_listener.arn
}
}

# ECS Task container health check
use_task_container_healthcheck = true
healthcheck_path = local.healthcheck_path
healthcheck_matcher = local.healthcheck_matcher

# Docker container details
docker_registry = var.docker_registry
docker_repo = local.docker_repo
container_version = var.psc_data_api_version
container_port = local.container_port

# Service configuration
service_name = local.service_name
name_prefix = local.name_prefix

# Service performance and scaling configs
desired_task_count = var.desired_task_count
max_task_count = var.max_task_count
required_cpus = var.required_cpus
required_memory = var.required_memory
service_autoscale_enabled = var.service_autoscale_enabled
service_autoscale_target_value_cpu = var.service_autoscale_target_value_cpu
service_scaledown_schedule = var.service_scaledown_schedule
service_scaleup_schedule = var.service_scaleup_schedule
use_capacity_provider = var.use_capacity_provider
use_fargate = var.use_fargate
fargate_subnets = local.application_subnet_ids

# Cloudwatch
cloudwatch_alarms_enabled = var.cloudwatch_alarms_enabled
multilb_cloudwatch_alarms_enabled = var.multilb_cloudwatch_alarms_enabled

# Service environment variable and secret configs
task_environment = local.task_environment
task_secrets = local.task_secrets
app_environment_filename = local.app_environment_filename
use_set_environment_files = local.use_set_environment_files

# eric options for eric running API module
use_eric_reverse_proxy = true
eric_version = var.eric_version
eric_cpus = var.eric_cpus
eric_memory = var.eric_memory
eric_port = local.eric_port
eric_environment_filename = local.eric_environment_filename
eric_secrets = local.eric_secrets
}

module "secrets" {
source = "[email protected]:companieshouse/terraform-modules//aws/ecs/secrets?ref=1.0.278"

name_prefix = "${local.service_name}-${var.environment}"
environment = var.environment
kms_key_id = data.aws_kms_key.kms_key.id
secrets = nonsensitive(local.service_secrets)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
environment = "cidev"
aws_profile = "development-eu-west-2"

# service configs
use_set_environment_files = true
log_level = "trace"
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
environment = "live"
aws_profile = "live-eu-west-2"

# service configs
use_set_environment_files = true
log_level = "trace"
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
environment = "staging"
aws_profile = "staging-eu-west-2"

# service configs
use_set_environment_files = true
log_level = "trace"

# Scheduled scaling of tasks
service_autoscale_enabled = true
service_scaledown_schedule = "55 19 * * ? *"
service_scaleup_schedule = "5 6 * * ? *"
Loading

0 comments on commit 6647605

Please sign in to comment.