Skip to content

Commit

Permalink
cdpt-chaps ecs config (#4171)
Browse files Browse the repository at this point in the history
  • Loading branch information
vertism authored Dec 7, 2023
1 parent e76f158 commit 171e142
Show file tree
Hide file tree
Showing 7 changed files with 427 additions and 8 deletions.
12 changes: 6 additions & 6 deletions terraform/environments/cdpt-chaps/application_variables.json
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
{
"accounts": {
"development": {
"example_var": "dev-data"
},
"test": {
"example_var": "test-data"
"region": "eu-west-2",
"docker_image_tag": "development"
},
"preproduction": {
"example_var": "preproduction-data"
"region": "eu-west-2",
"docker_image_tag": "preproduction"
},
"production": {
"example_var": "production-data"
"region": "eu-west-2",
"docker_image_tag": "production"
}
}
}
244 changes: 244 additions & 0 deletions terraform/environments/cdpt-chaps/ecs.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,244 @@
data "aws_ecs_task_definition" "task_definition" {
task_definition = "${local.application_name}-task-definition"
depends_on = [aws_ecs_task_definition.chaps_task_definition]
}

resource "aws_ecs_cluster" "ecs_cluster" {
name = "${local.application_name}-ecs-cluster"
setting {
name = "containerInsights"
value = "enabled"
}
}

resource "aws_cloudwatch_log_group" "deployment_logs" {
name = "/aws/events/deploymentLogs"
retention_in_days = "7"
}

resource "aws_ecs_task_definition" "chaps_task_definition" {
family = "chapsFamily"
requires_compatibilities = ["FARGATE"]
network_mode = "awsvpc"
execution_role_arn = aws_iam_role.app_execution.arn
task_role_arn = aws_iam_role.app_task.arn
cpu = 1024
memory = 2048
container_definitions = jsonencode([
{
name = local.application_name
image = "${local.ecr_url}:${local.application_data.accounts[local.environment].docker_image_tag}"
cpu = 1024
memory = 2048
essential = true
portMappings = [
{
containerPort = 80
protocol = "tcp"
hostPort = 80
}
]
environment = [
]
}
])
runtime_platform {
operating_system_family = "WINDOWS_SERVER_2019_CORE"
cpu_architecture = "X86_64"
}
}

resource "aws_ecs_service" "ecs_service" {
depends_on = [
aws_lb_listener.listener
]

name = var.networking[0].application
cluster = aws_ecs_cluster.ecs_cluster.id
task_definition = aws_ecs_task_definition.chaps_task_definition.arn
launch_type = "FARGATE"
enable_execute_command = true
desired_count = 2
health_check_grace_period_seconds = 180

network_configuration {
subnets = data.aws_subnets.shared-public.ids
security_groups = [aws_security_group.ecs_service.id]
assign_public_ip = true
}

load_balancer {
target_group_arn = aws_lb_target_group.chaps_target_group.arn
container_name = local.application_name
container_port = 80
}

deployment_controller {
type = "ECS"
}
}

resource "aws_iam_role" "app_execution" {
name = "execution-${var.networking[0].application}"

assume_role_policy = <<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Action": "sts:AssumeRole",
"Principal": {
"Service": "ecs-tasks.amazonaws.com"
},
"Effect": "Allow",
"Sid": ""
}
]
}
EOF

tags = merge(
local.tags,
{
Name = "execution-${var.networking[0].application}"
},
)
}

resource "aws_iam_role_policy" "app_execution" {
name = "execution-${var.networking[0].application}"
role = aws_iam_role.app_execution.id

policy = <<-EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Action": [
"ecr:*",
"logs:CreateLogGroup",
"logs:CreateLogStream",
"logs:PutLogEvents",
"logs:DescribeLogStreams",
"secretsmanager:GetSecretValue"
],
"Resource": "*",
"Effect": "Allow"
}
]
}
EOF
}

resource "aws_iam_role" "app_task" {
name = "task-${var.networking[0].application}"

assume_role_policy = <<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Action": "sts:AssumeRole",
"Principal": {
"Service": "ecs-tasks.amazonaws.com"
},
"Effect": "Allow",
"Sid": ""
}
]
}
EOF

tags = merge(
local.tags,
{
Name = "task-${var.networking[0].application}"
},
)
}

resource "aws_iam_role_policy" "app_task" {
name = "task-${var.networking[0].application}"
role = aws_iam_role.app_task.id

policy = <<-EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"logs:CreateLogStream",
"logs:PutLogEvents",
"ecr:*",
"iam:*",
"ec2:*"
],
"Resource": "*"
}
]
}
EOF
}

resource "aws_security_group" "ecs_service" {
name_prefix = "ecs-service-sg-"
vpc_id = data.aws_vpc.shared.id

ingress {
from_port = 80
to_port = 80
protocol = "tcp"
description = "Allow traffic on port 80 from load balancer"
security_groups = [aws_security_group.chaps_lb_sc.id]
}

egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
}

# AWS EventBridge rule
resource "aws_cloudwatch_event_rule" "ecs_events" {
name = "ecs-events"
description = "Capture all ECS events"

event_pattern = jsonencode({
"source" : ["aws.ecs"],
"detail" : {
"clusterArn" : [aws_ecs_cluster.ecs_cluster.arn]
}
})
}

# AWS EventBridge target
resource "aws_cloudwatch_event_target" "logs" {
depends_on = [aws_cloudwatch_log_group.deployment_logs]
rule = aws_cloudwatch_event_rule.ecs_events.name
target_id = "send-to-cloudwatch"
arn = aws_cloudwatch_log_group.deployment_logs.arn
}

resource "aws_cloudwatch_log_resource_policy" "ecs_logging_policy" {
policy_document = jsonencode({
"Version" : "2012-10-17",
"Statement" : [
{
"Sid" : "TrustEventsToStoreLogEvent",
"Effect" : "Allow",
"Principal" : {
"Service" : ["events.amazonaws.com", "delivery.logs.amazonaws.com"]
},
"Action" : [
"logs:CreateLogStream",
"logs:PutLogEvents"
],
"Resource" : "arn:aws:logs:eu-west-2:${data.aws_caller_identity.current.account_id}:log-group:/aws/events/*:*"
}
]
})
policy_name = "TrustEventsToStoreLogEvents"
}
98 changes: 98 additions & 0 deletions terraform/environments/cdpt-chaps/loadbalancer.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
resource "aws_security_group" "chaps_lb_sc" {
name = "load balancer security group"
description = "control access to the load balancer"
vpc_id = data.aws_vpc.shared.id

ingress {
description = "allow access on HTTP"
from_port = 80
to_port = 80
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}

ingress {
description = "allow access on HTTPS"
from_port = 443
to_port = 443
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}

egress {
description = "allow all outbound traffic for port 80"
from_port = 80
to_port = 80
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}

egress {
description = "allow all outbound traffic for port 443"
from_port = 443
to_port = 443
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
}

resource "aws_lb" "chaps_lb" {
name = "chaps-load-balancer"
load_balancer_type = "application"
security_groups = [aws_security_group.chaps_lb_sc.id]
subnets = data.aws_subnets.shared-public.ids
enable_deletion_protection = false
internal = false
depends_on = [aws_security_group.chaps_lb_sc]
}

resource "aws_lb_target_group" "chaps_target_group" {
name = "chaps-target-group"
port = 80
protocol = "HTTP"
vpc_id = data.aws_vpc.shared.id
target_type = "ip"
deregistration_delay = 30

stickiness {
type = "lb_cookie"
}

health_check {
healthy_threshold = "3"
interval = "30"
protocol = "HTTP"
port = "80"
unhealthy_threshold = "5"
matcher = "200-302"
timeout = "10"
}

}

resource "aws_lb_listener" "listener" {
load_balancer_arn = aws_lb.chaps_lb.arn
port = 80
protocol = "HTTP"

default_action {
target_group_arn = aws_lb_target_group.chaps_target_group.id
type = "forward"
}
}

# resource "aws_lb_listener" "chaps_lb" {
# depends_on = [
# aws_acm_certificate.external
# ]
# certificate_arn = aws_acm_certificate.external.arn
# load_balancer_arn = aws_lb.chaps_lb.arn
# port = 443
# protocol = "HTTPS"
# ssl_policy = "ELBSecurityPolicy-2016-08"

# default_action {
# type = "forward"
# target_group_arn = aws_lb_target_group.chaps_target_group.arn
# }
# }
18 changes: 17 additions & 1 deletion terraform/environments/cdpt-chaps/locals.tf
Original file line number Diff line number Diff line change
@@ -1 +1,17 @@
#### This file can be used to store locals specific to the member account ####
locals {
domain_types = { for dvo in aws_acm_certificate.external.domain_validation_options : dvo.domain_name => {
name = dvo.resource_record_name
record = dvo.resource_record_value
type = dvo.resource_record_type
}
}

domain_name_main = [for k, v in local.domain_types : v.name if k == "modernisation-platform.service.justice.gov.uk"]
domain_name_sub = [for k, v in local.domain_types : v.name if k != "modernisation-platform.service.justice.gov.uk"]
domain_record_main = [for k, v in local.domain_types : v.record if k == "modernisation-platform.service.justice.gov.uk"]
domain_record_sub = [for k, v in local.domain_types : v.record if k != "modernisation-platform.service.justice.gov.uk"]
domain_type_main = [for k, v in local.domain_types : v.type if k == "modernisation-platform.service.justice.gov.uk"]
domain_type_sub = [for k, v in local.domain_types : v.type if k != "modernisation-platform.service.justice.gov.uk"]

ecr_url = "${local.environment_management.account_ids["core-shared-services-production"]}.dkr.ecr.eu-west-2.amazonaws.com/cdpt-chaps-ecr-repo"
}
3 changes: 3 additions & 0 deletions terraform/environments/cdpt-chaps/outputs.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
output "task_definition" {
value = data.aws_ecs_task_definition.task_definition
}
1 change: 0 additions & 1 deletion terraform/environments/cdpt-chaps/platform_locals.tf
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
locals {

application_name = "cdpt-chaps"

environment_management = jsondecode(data.aws_secretsmanager_secret_version.environment_management.secret_string)
Expand Down
Loading

0 comments on commit 171e142

Please sign in to comment.