diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index e53f4023..727e0b2f 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -27,3 +27,6 @@ jobs: AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} AWS_REGION: ${{ secrets.AWS_REGION }} + - name: terraform init + run: cd devops && terraform init + diff --git a/devops/alb.tf b/devops/alb.tf new file mode 100644 index 00000000..c7819700 --- /dev/null +++ b/devops/alb.tf @@ -0,0 +1,36 @@ +resource "aws_alb" "main" { + name = "jmsth-load-balancer" + subnets = aws_subnet.public.*.id + security_groups = [aws_security_group.lb.id] +} + +resource "aws_alb_target_group" "app" { + name = "jmsth-target-group" + port = 80 + protocol = "HTTP" + vpc_id = aws_vpc.main.id + target_type = "ip" + + health_check { + healthy_threshold = "3" + interval = "30" + protocol = "HTTP" + matcher = "200" + timeout = "3" + path = var.health_check_path + unhealthy_threshold = "2" + } +} + +# Redirect all traffic from the ALB to the target group +resource "aws_alb_listener" "front_end" { + load_balancer_arn = aws_alb.main.id + port = var.app_port + protocol = "HTTP" + + default_action { + target_group_arn = aws_alb_target_group.app.id + type = "forward" + } +} + diff --git a/devops/auto_scaling.tf b/devops/auto_scaling.tf new file mode 100644 index 00000000..3a4fd81f --- /dev/null +++ b/devops/auto_scaling.tf @@ -0,0 +1,87 @@ +resource "aws_appautoscaling_target" "target" { + service_namespace = "ecs" + resource_id = "service/${aws_ecs_cluster.main.name}/${aws_ecs_service.main.name}" + scalable_dimension = "ecs:service:DesiredCount" + min_capacity = 2 + max_capacity = 4 +} + +# Automatically scale capacity up by one +resource "aws_appautoscaling_policy" "up" { + name = "cb_scale_up" + service_namespace = "ecs" + resource_id = "service/${aws_ecs_cluster.main.name}/${aws_ecs_service.main.name}" + scalable_dimension = "ecs:service:DesiredCount" + + step_scaling_policy_configuration { + adjustment_type = "ChangeInCapacity" + cooldown = 60 + metric_aggregation_type = "Maximum" + + step_adjustment { + metric_interval_lower_bound = 0 + scaling_adjustment = 1 + } + } + + depends_on = [aws_appautoscaling_target.target] +} + +# Automatically scale capacity down by one +resource "aws_appautoscaling_policy" "down" { + name = "cb_scale_down" + service_namespace = "ecs" + resource_id = "service/${aws_ecs_cluster.main.name}/${aws_ecs_service.main.name}" + scalable_dimension = "ecs:service:DesiredCount" + + step_scaling_policy_configuration { + adjustment_type = "ChangeInCapacity" + cooldown = 60 + metric_aggregation_type = "Maximum" + + step_adjustment { + metric_interval_upper_bound = 0 + scaling_adjustment = -1 + } + } + + depends_on = [aws_appautoscaling_target.target] +} + +# CloudWatch alarm that triggers the autoscaling up policy +resource "aws_cloudwatch_metric_alarm" "service_cpu_high" { + alarm_name = "cb_cpu_utilization_high" + comparison_operator = "GreaterThanOrEqualToThreshold" + evaluation_periods = "2" + metric_name = "CPUUtilization" + namespace = "AWS/ECS" + period = "60" + statistic = "Average" + threshold = "85" + + dimensions = { + ClusterName = aws_ecs_cluster.main.name + ServiceName = aws_ecs_service.main.name + } + + alarm_actions = [aws_appautoscaling_policy.up.arn] +} + +# CloudWatch alarm that triggers the autoscaling down policy +resource "aws_cloudwatch_metric_alarm" "service_cpu_low" { + alarm_name = "cb_cpu_utilization_low" + comparison_operator = "LessThanOrEqualToThreshold" + evaluation_periods = "2" + metric_name = "CPUUtilization" + namespace = "AWS/ECS" + period = "60" + statistic = "Average" + threshold = "10" + + dimensions = { + ClusterName = aws_ecs_cluster.main.name + ServiceName = aws_ecs_service.main.name + } + + alarm_actions = [aws_appautoscaling_policy.down.arn] +} diff --git a/devops/backend.tf b/devops/backend.tf new file mode 100644 index 00000000..e660ae0d --- /dev/null +++ b/devops/backend.tf @@ -0,0 +1,11 @@ + +#terraform { +# backend "s3" { +# bucket = "jms-terraform-backend" +# key = "jmsth_jenkins.tfstate" +# region = "ap-south-1" +# encrypt = true +# dynamodb_table = "terraform-state-lock-dynamo" +# } +# } + diff --git a/devops/ecs.tf b/devops/ecs.tf new file mode 100644 index 00000000..d5874115 --- /dev/null +++ b/devops/ecs.tf @@ -0,0 +1,50 @@ +resource "aws_ecs_cluster" "main" { + name = "jms-cluster" +} +data "aws_ecr_repository" "springapp" { + name = "spring" +} +data "template_file" "cb_app" { + template = file("./templates/ecs/cb_app.json.tpl") + + vars = { + app_image = data.aws_ecr_repository.springapp.repository_url + app_port = var.app_port + fargate_cpu = var.fargate_cpu + fargate_memory = var.fargate_memory + aws_region = var.aws_region + tag = var.tag + } +} + +resource "aws_ecs_task_definition" "app" { + family = "jms-app-task" + execution_role_arn = aws_iam_role.ecs_task_execution_role.arn + network_mode = "awsvpc" + requires_compatibilities = ["FARGATE"] + cpu = var.fargate_cpu + memory = var.fargate_memory + container_definitions = data.template_file.cb_app.rendered +} + +resource "aws_ecs_service" "main" { + name = "jms-service1" + cluster = aws_ecs_cluster.main.id + task_definition = aws_ecs_task_definition.app.arn + desired_count = var.app_count + launch_type = "FARGATE" + + network_configuration { + security_groups = [aws_security_group.ecs_tasks.id] + subnets = aws_subnet.private.*.id + assign_public_ip = true + } + + load_balancer { + target_group_arn = aws_alb_target_group.app.id + container_name = "jms-app" + container_port = var.app_port + } + + depends_on = [aws_alb_listener.front_end, aws_iam_role_policy_attachment.ecs_task_execution_role] +} diff --git a/devops/graph.dot b/devops/graph.dot new file mode 100644 index 00000000..977cdbbd Binary files /dev/null and b/devops/graph.dot differ diff --git a/devops/graph1.svg b/devops/graph1.svg new file mode 100644 index 00000000..9ee474c0 --- /dev/null +++ b/devops/graph1.svg @@ -0,0 +1,748 @@ + + + + + + + + + +[root] aws_alb.main (expand) + +aws_alb.main + + + +[root] aws_security_group.lb (expand) + +aws_security_group.lb + + + +[root] aws_alb.main (expand)->[root] aws_security_group.lb (expand) + + + + + +[root] aws_subnet.public (expand) + +aws_subnet.public + + + +[root] aws_alb.main (expand)->[root] aws_subnet.public (expand) + + + + + +[root] aws_alb_listener.front_end (expand) + +aws_alb_listener.front_end + + + +[root] aws_alb_listener.front_end (expand)->[root] aws_alb.main (expand) + + + + + +[root] aws_alb_target_group.app (expand) + +aws_alb_target_group.app + + + +[root] aws_alb_listener.front_end (expand)->[root] aws_alb_target_group.app (expand) + + + + + +[root] aws_vpc.main (expand) + +aws_vpc.main + + + +[root] aws_alb_target_group.app (expand)->[root] aws_vpc.main (expand) + + + + + +[root] var.health_check_path + + + +var.health_check_path + + + +[root] aws_alb_target_group.app (expand)->[root] var.health_check_path + + + + + +[root] aws_appautoscaling_policy.down (expand) + +aws_appautoscaling_policy.down + + + +[root] aws_appautoscaling_target.target (expand) + +aws_appautoscaling_target.target + + + +[root] aws_appautoscaling_policy.down (expand)->[root] aws_appautoscaling_target.target (expand) + + + + + +[root] aws_appautoscaling_policy.up (expand) + +aws_appautoscaling_policy.up + + + +[root] aws_appautoscaling_policy.up (expand)->[root] aws_appautoscaling_target.target (expand) + + + + + +[root] aws_ecs_service.main (expand) + +aws_ecs_service.main + + + +[root] aws_appautoscaling_target.target (expand)->[root] aws_ecs_service.main (expand) + + + + + +[root] aws_cloudwatch_log_group.cb_log_group (expand) + +aws_cloudwatch_log_group.cb_log_group + + + +[root] provider["registry.terraform.io/hashicorp/aws"] + +provider["registry.terraform.io/hashicorp/aws"] + + + +[root] aws_cloudwatch_log_group.cb_log_group (expand)->[root] provider["registry.terraform.io/hashicorp/aws"] + + + + + +[root] aws_cloudwatch_log_stream.cb_log_stream (expand) + +aws_cloudwatch_log_stream.cb_log_stream + + + +[root] aws_cloudwatch_log_stream.cb_log_stream (expand)->[root] aws_cloudwatch_log_group.cb_log_group (expand) + + + + + +[root] aws_cloudwatch_metric_alarm.service_cpu_high (expand) + +aws_cloudwatch_metric_alarm.service_cpu_high + + + +[root] aws_cloudwatch_metric_alarm.service_cpu_high (expand)->[root] aws_appautoscaling_policy.up (expand) + + + + + +[root] aws_cloudwatch_metric_alarm.service_cpu_low (expand) + +aws_cloudwatch_metric_alarm.service_cpu_low + + + +[root] aws_cloudwatch_metric_alarm.service_cpu_low (expand)->[root] aws_appautoscaling_policy.down (expand) + + + + + +[root] aws_ecs_cluster.main (expand) + +aws_ecs_cluster.main + + + +[root] aws_ecs_cluster.main (expand)->[root] provider["registry.terraform.io/hashicorp/aws"] + + + + + +[root] aws_ecs_service.main (expand)->[root] aws_alb_listener.front_end (expand) + + + + + +[root] aws_ecs_service.main (expand)->[root] aws_ecs_cluster.main (expand) + + + + + +[root] aws_ecs_task_definition.app (expand) + +aws_ecs_task_definition.app + + + +[root] aws_ecs_service.main (expand)->[root] aws_ecs_task_definition.app (expand) + + + + + +[root] aws_iam_role_policy_attachment.ecs_task_execution_role (expand) + +aws_iam_role_policy_attachment.ecs_task_execution_role + + + +[root] aws_ecs_service.main (expand)->[root] aws_iam_role_policy_attachment.ecs_task_execution_role (expand) + + + + + +[root] aws_security_group.ecs_tasks (expand) + +aws_security_group.ecs_tasks + + + +[root] aws_ecs_service.main (expand)->[root] aws_security_group.ecs_tasks (expand) + + + + + +[root] aws_subnet.private (expand) + +aws_subnet.private + + + +[root] aws_ecs_service.main (expand)->[root] aws_subnet.private (expand) + + + + + +[root] var.app_count + + + +var.app_count + + + +[root] aws_ecs_service.main (expand)->[root] var.app_count + + + + + +[root] aws_iam_role.ecs_task_execution_role (expand) + +aws_iam_role.ecs_task_execution_role + + + +[root] aws_ecs_task_definition.app (expand)->[root] aws_iam_role.ecs_task_execution_role (expand) + + + + + +[root] data.template_file.cb_app (expand) + +data.template_file.cb_app + + + +[root] aws_ecs_task_definition.app (expand)->[root] data.template_file.cb_app (expand) + + + + + +[root] aws_eip.gw (expand) + +aws_eip.gw + + + +[root] aws_internet_gateway.gw (expand) + +aws_internet_gateway.gw + + + +[root] aws_eip.gw (expand)->[root] aws_internet_gateway.gw (expand) + + + + + +[root] var.az_count + + + +var.az_count + + + +[root] aws_eip.gw (expand)->[root] var.az_count + + + + + +[root] data.aws_iam_policy_document.ecs_task_execution_role (expand) + +data.aws_iam_policy_document.ecs_task_execution_role + + + +[root] aws_iam_role.ecs_task_execution_role (expand)->[root] data.aws_iam_policy_document.ecs_task_execution_role (expand) + + + + + +[root] var.ecs_task_execution_role_name + + + +var.ecs_task_execution_role_name + + + +[root] aws_iam_role.ecs_task_execution_role (expand)->[root] var.ecs_task_execution_role_name + + + + + +[root] aws_iam_role_policy_attachment.ecs_task_execution_role (expand)->[root] aws_iam_role.ecs_task_execution_role (expand) + + + + + +[root] aws_internet_gateway.gw (expand)->[root] aws_vpc.main (expand) + + + + + +[root] aws_nat_gateway.gw (expand) + +aws_nat_gateway.gw + + + +[root] aws_nat_gateway.gw (expand)->[root] aws_eip.gw (expand) + + + + + +[root] aws_nat_gateway.gw (expand)->[root] aws_subnet.public (expand) + + + + + +[root] aws_route.internet_access (expand) + +aws_route.internet_access + + + +[root] aws_route.internet_access (expand)->[root] aws_internet_gateway.gw (expand) + + + + + +[root] aws_route_table.private (expand) + +aws_route_table.private + + + +[root] aws_route_table.private (expand)->[root] aws_nat_gateway.gw (expand) + + + + + +[root] aws_route_table_association.private (expand) + +aws_route_table_association.private + + + +[root] aws_route_table_association.private (expand)->[root] aws_route_table.private (expand) + + + + + +[root] aws_route_table_association.private (expand)->[root] aws_subnet.private (expand) + + + + + +[root] aws_security_group.ecs_tasks (expand)->[root] aws_security_group.lb (expand) + + + + + +[root] aws_security_group.lb (expand)->[root] aws_vpc.main (expand) + + + + + +[root] var.app_port + + + +var.app_port + + + +[root] aws_security_group.lb (expand)->[root] var.app_port + + + + + +[root] aws_subnet.private (expand)->[root] aws_vpc.main (expand) + + + + + +[root] data.aws_availability_zones.available (expand) + +data.aws_availability_zones.available + + + +[root] aws_subnet.private (expand)->[root] data.aws_availability_zones.available (expand) + + + + + +[root] aws_subnet.private (expand)->[root] var.az_count + + + + + +[root] aws_subnet.public (expand)->[root] aws_vpc.main (expand) + + + + + +[root] aws_subnet.public (expand)->[root] data.aws_availability_zones.available (expand) + + + + + +[root] aws_subnet.public (expand)->[root] var.az_count + + + + + +[root] aws_vpc.main (expand)->[root] provider["registry.terraform.io/hashicorp/aws"] + + + + + +[root] data.aws_availability_zones.available (expand)->[root] provider["registry.terraform.io/hashicorp/aws"] + + + + + +[root] data.aws_ecr_repository.nodeapp (expand) + +data.aws_ecr_repository.nodeapp + + + +[root] data.aws_ecr_repository.nodeapp (expand)->[root] provider["registry.terraform.io/hashicorp/aws"] + + + + + +[root] data.aws_iam_policy_document.ecs_task_execution_role (expand)->[root] provider["registry.terraform.io/hashicorp/aws"] + + + + + +[root] data.template_file.cb_app (expand)->[root] data.aws_ecr_repository.nodeapp (expand) + + + + + +[root] provider["registry.terraform.io/hashicorp/template"] + +provider["registry.terraform.io/hashicorp/template"] + + + +[root] data.template_file.cb_app (expand)->[root] provider["registry.terraform.io/hashicorp/template"] + + + + + +[root] data.template_file.cb_app (expand)->[root] var.app_port + + + + + +[root] var.fargate_cpu + + + +var.fargate_cpu + + + +[root] data.template_file.cb_app (expand)->[root] var.fargate_cpu + + + + + +[root] var.fargate_memory + + + +var.fargate_memory + + + +[root] data.template_file.cb_app (expand)->[root] var.fargate_memory + + + + + +[root] var.tag + + + +var.tag + + + +[root] data.template_file.cb_app (expand)->[root] var.tag + + + + + +[root] output.alb_hostname + + + +output.alb_hostname + + + +[root] output.alb_hostname->[root] aws_alb.main (expand) + + + + + +[root] var.aws_region + + + +var.aws_region + + + +[root] provider["registry.terraform.io/hashicorp/aws"]->[root] var.aws_region + + + + + +[root] var.ecs_auto_scale_role_name + + + +var.ecs_auto_scale_role_name + + + +[root] meta.count-boundary (EachMode fixup) + +[root] meta.count-boundary (EachMode fixup) + + + +[root] meta.count-boundary (EachMode fixup)->[root] aws_cloudwatch_log_stream.cb_log_stream (expand) + + + + + +[root] meta.count-boundary (EachMode fixup)->[root] aws_cloudwatch_metric_alarm.service_cpu_high (expand) + + + + + +[root] meta.count-boundary (EachMode fixup)->[root] aws_cloudwatch_metric_alarm.service_cpu_low (expand) + + + + + +[root] meta.count-boundary (EachMode fixup)->[root] aws_route.internet_access (expand) + + + + + +[root] meta.count-boundary (EachMode fixup)->[root] aws_route_table_association.private (expand) + + + + + +[root] meta.count-boundary (EachMode fixup)->[root] output.alb_hostname + + + + + +[root] meta.count-boundary (EachMode fixup)->[root] var.ecs_auto_scale_role_name + + + + + +[root] provider["registry.terraform.io/hashicorp/aws"] (close) + +[root] provider["registry.terraform.io/hashicorp/aws"] (close) + + + +[root] provider["registry.terraform.io/hashicorp/aws"] (close)->[root] aws_cloudwatch_log_stream.cb_log_stream (expand) + + + + + +[root] provider["registry.terraform.io/hashicorp/aws"] (close)->[root] aws_cloudwatch_metric_alarm.service_cpu_high (expand) + + + + + +[root] provider["registry.terraform.io/hashicorp/aws"] (close)->[root] aws_cloudwatch_metric_alarm.service_cpu_low (expand) + + + + + +[root] provider["registry.terraform.io/hashicorp/aws"] (close)->[root] aws_route.internet_access (expand) + + + + + +[root] provider["registry.terraform.io/hashicorp/aws"] (close)->[root] aws_route_table_association.private (expand) + + + + + +[root] provider["registry.terraform.io/hashicorp/template"] (close) + +[root] provider["registry.terraform.io/hashicorp/template"] (close) + + + +[root] provider["registry.terraform.io/hashicorp/template"] (close)->[root] data.template_file.cb_app (expand) + + + + + +[root] root + +[root] root + + + +[root] root->[root] meta.count-boundary (EachMode fixup) + + + + + +[root] root->[root] provider["registry.terraform.io/hashicorp/aws"] (close) + + + + + +[root] root->[root] provider["registry.terraform.io/hashicorp/template"] (close) + + + + + diff --git a/devops/logs.tf b/devops/logs.tf new file mode 100644 index 00000000..308336ef --- /dev/null +++ b/devops/logs.tf @@ -0,0 +1,14 @@ +# Set up CloudWatch group and log stream and retain logs for 30 days +resource "aws_cloudwatch_log_group" "cb_log_group" { + name = "/ecs/cb-app" + retention_in_days = 30 + + tags = { + Name = "cb-log-group" + } +} + +resource "aws_cloudwatch_log_stream" "cb_log_stream" { + name = "cb-log-stream" + log_group_name = aws_cloudwatch_log_group.cb_log_group.name +} diff --git a/devops/network.tf b/devops/network.tf new file mode 100644 index 00000000..cd0d575e --- /dev/null +++ b/devops/network.tf @@ -0,0 +1,66 @@ +data "aws_availability_zones" "available" { +} + +resource "aws_vpc" "main" { + cidr_block = "172.17.0.0/16" +} + +# Create var.az_count private subnets, each in a different AZ +resource "aws_subnet" "private" { + count = var.az_count + cidr_block = cidrsubnet(aws_vpc.main.cidr_block, 8, count.index) + availability_zone = data.aws_availability_zones.available.names[count.index] + vpc_id = aws_vpc.main.id +} + +# Create var.az_count public subnets, each in a different AZ +resource "aws_subnet" "public" { + count = var.az_count + cidr_block = cidrsubnet(aws_vpc.main.cidr_block, 8, var.az_count + count.index) + availability_zone = data.aws_availability_zones.available.names[count.index] + vpc_id = aws_vpc.main.id + map_public_ip_on_launch = true +} + +# Internet Gateway for the public subnet +resource "aws_internet_gateway" "gw" { + vpc_id = aws_vpc.main.id +} + +# Route the public subnet traffic through the IGW +resource "aws_route" "internet_access" { + route_table_id = aws_vpc.main.main_route_table_id + destination_cidr_block = "0.0.0.0/0" + gateway_id = aws_internet_gateway.gw.id +} + +# Create a NAT gateway with an Elastic IP for each private subnet to get internet connectivity +resource "aws_eip" "gw" { + count = var.az_count + vpc = true + depends_on = [aws_internet_gateway.gw] +} + +resource "aws_nat_gateway" "gw" { + count = var.az_count + subnet_id = element(aws_subnet.public.*.id, count.index) + allocation_id = element(aws_eip.gw.*.id, count.index) +} + +# Create a new route table for the private subnets, make it route non-local traffic through the NAT gateway to the internet +resource "aws_route_table" "private" { + count = var.az_count + vpc_id = aws_vpc.main.id + + route { + cidr_block = "0.0.0.0/0" + nat_gateway_id = element(aws_nat_gateway.gw.*.id, count.index) + } +} + +# Explicitly associate the newly created route tables to the private subnets (so they don't default to the main route table) +resource "aws_route_table_association" "private" { + count = var.az_count + subnet_id = element(aws_subnet.private.*.id, count.index) + route_table_id = element(aws_route_table.private.*.id, count.index) +} diff --git a/devops/outputs.tf b/devops/outputs.tf new file mode 100644 index 00000000..0d8c93d2 --- /dev/null +++ b/devops/outputs.tf @@ -0,0 +1,3 @@ +output "alb_hostname" { + value = aws_alb.main.dns_name +} diff --git a/devops/provider.tf b/devops/provider.tf new file mode 100644 index 00000000..0e636fdb --- /dev/null +++ b/devops/provider.tf @@ -0,0 +1,3 @@ +provider "aws" { + region = var.aws_region +} diff --git a/devops/roles.tf b/devops/roles.tf new file mode 100644 index 00000000..29bfd9ff --- /dev/null +++ b/devops/roles.tf @@ -0,0 +1,26 @@ +data "aws_iam_policy_document" "ecs_task_execution_role" { + version = "2012-10-17" + statement { + sid = "" + effect = "Allow" + actions = ["sts:AssumeRole"] + + principals { + type = "Service" + identifiers = ["ecs-tasks.amazonaws.com"] + } + } +} + +# ECS task execution role +resource "aws_iam_role" "ecs_task_execution_role" { + name = var.ecs_task_execution_role_name + assume_role_policy = data.aws_iam_policy_document.ecs_task_execution_role.json +} + +# ECS task execution role policy attachment +resource "aws_iam_role_policy_attachment" "ecs_task_execution_role" { + role = aws_iam_role.ecs_task_execution_role.name + policy_arn = "arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy" +} + diff --git a/devops/security.tf b/devops/security.tf new file mode 100644 index 00000000..4aad0894 --- /dev/null +++ b/devops/security.tf @@ -0,0 +1,41 @@ +# ALB Security Group: Edit to restrict access to the application +resource "aws_security_group" "lb" { + name = "jms-load-balancer-security-group" + description = "controls access to the ALB" + vpc_id = aws_vpc.main.id + + ingress { + protocol = "tcp" + from_port = var.app_port + to_port = var.app_port + cidr_blocks = ["0.0.0.0/0"] + } + + egress { + protocol = "-1" + from_port = 0 + to_port = 0 + cidr_blocks = ["0.0.0.0/0"] + } +} + +# Traffic to the ECS cluster should only come from the ALB +resource "aws_security_group" "ecs_tasks" { + name = "jms-ecs-tasks-security-group" + description = "allow inbound access from the ALB only" + vpc_id = aws_vpc.main.id + + ingress { + protocol = "tcp" + from_port = var.app_port + to_port = var.app_port + security_groups = [aws_security_group.lb.id] + } + + egress { + protocol = "-1" + from_port = 0 + to_port = 0 + cidr_blocks = ["0.0.0.0/0"] + } +} diff --git a/devops/templates/ecs/cb_app.json.tpl b/devops/templates/ecs/cb_app.json.tpl new file mode 100644 index 00000000..36231a15 --- /dev/null +++ b/devops/templates/ecs/cb_app.json.tpl @@ -0,0 +1,24 @@ +[ + { + "name": "jms-app", + "image": "${app_image}:${tag}", + "cpu": ${fargate_cpu}, + "memory": ${fargate_memory}, + "networkMode": "awsvpc", + "logConfiguration": { + "logDriver": "awslogs", + "options": { + "awslogs-group": "/ecs/cb-app", + "awslogs-region": "${aws_region}", + "awslogs-stream-prefix": "ecs" + } + }, + "portMappings": [ + { + "containerPort": ${app_port}, + "hostPort": ${app_port} + } + ] + } +] + diff --git a/devops/variables.tf b/devops/variables.tf new file mode 100644 index 00000000..d2d8fb05 --- /dev/null +++ b/devops/variables.tf @@ -0,0 +1,45 @@ +variable "aws_region" { + description = "The AWS region things are created in" + default = "ap-south-1" +} + +variable "ecs_task_execution_role_name" { + description = "ECS task execution role name" + default = "myEcsTaskExecutionRole" +} + +variable "ecs_auto_scale_role_name" { + description = "ECS auto scale role Name" + default = "myEcsAutoScaleRole" +} + +variable "az_count" { + description = "Number of AZs to cover in a given region" + default = "2" +} + +variable "app_port" { + description = "Port exposed by the docker image to redirect traffic to" + default = 8080 +} + +variable "app_count" { + description = "Number of docker containers to run" + default = 2 +} + +variable "health_check_path" { + default = "/" +} + +variable "fargate_cpu" { + description = "Fargate instance CPU units to provision (1 vCPU = 1024 CPU units)" + default = "1024" +} + +variable "fargate_memory" { + description = "Fargate instance memory to provision (in MiB)" + default = "2048" +} +variable "tag" { +} diff --git a/devops/versions.tf b/devops/versions.tf new file mode 100644 index 00000000..d9b6f790 --- /dev/null +++ b/devops/versions.tf @@ -0,0 +1,3 @@ +terraform { + required_version = ">= 0.12" +}