Deployment

ECS

In this section, you'll learn how to set up your backend infrastructure using an ECS (Elastic Container Service) cluster on EC2 instances. We'll guide you through using Terraform modules to create an ECS cluster, deploy services, and manage secrets.

Step 1: Setting Up the ECS Cluster

The ECS cluster is the backbone of your application, where your Docker containers will run on EC2 instances. Below is the Terraform code to set it up:

module "cluster" {
  source = "../modules/ecs-cluster/"
  
  context = {
    namespace = "test"
    stage     = "staging"
    name      = "api"
  }
  
  name_prefix    = "staging-test-api"
  vpc_id         = module.vpc.id
  subnet_ids     = module.public_subnet.ids
  instance_type  = "t3.medium"
  allow_ssh      = true
  ssh_cidr_ipv4  = ["your IP for SSH connection in CIDR notation"] # 0.0.0.0/0 - for all IPs (not recommended)

  autoscaling_group = {
    min_size         = 1
    max_size         = 5
    desired_capacity = 1
  }
}

What This Does:

  • Creates an ECS Cluster: The cluster module sets up an ECS cluster on EC2 instances.
  • Configures Networking: The vpc_id and subnet_ids link the ECS cluster to the VPC and subnets you created earlier.
  • Enables Scaling: The autoscaling group manages the number of EC2 instances based on the traffic and load.
  • Allows SSH Access: The allow_ssh and ssh_cidr_ipv4 settings allow secure SSH access to the instances.

Using VPC Outputs

Notice how vpc_id and subnet_ids are used here. These values are outputs from the VPC and public subnet modules you set up earlier, ensuring the ECS cluster is properly connected to your network.

Step 2: Deploying a Service on the ECS Cluster

Next, you'll deploy a service to your ECS cluster. This is where your application runs.

module "service" {
  source = "../modules/ecs-service/"

  context = {
    namespace = "test"
    stage     = "staging"
    name      = "api"
  }

  secrets                 = ["/test/staging/api/terraform", "/test/staging/api/editable"]
  name                    = "api"
  vpc_id                  = module.vpc.id
  subnet_ids              = module.public_subnet.ids
  cluster_id              = module.cluster.id
  desired_count           = 1
  create_alb_target_group = false
  port                    = 3000

  depends_on = [module.secrets]
}

module "ecr" {
  source = "../modules/ecr-repository"

  context = {
    namespace = "test"
    stage     = "staging"
    name      = "ecr"
  }
}

What This Does:

  • Uses Secrets: Sensitive information like API keys are handled securely via the secrets module.
  • Links to the ECS Cluster: The cluster_id, vpc_id, and subnet_ids ensure the service is correctly placed within your network.
  • Creates ECR repository for Docker images: The module "ecr" creates Elastic Container Repository, where docker images will be stored.

Step 3: Managing Secrets

Now you'll manage the secrets required by your service. This includes sensitive information like database URLs and API keys.

module "secrets" {
  source = "../modules/parameters"

  context = {
    namespace = "test"
    stage     = "staging"
    name      = "api"
  }

  secrets = {
    ENVIRONMENT  = "production"
    API_KEY      = random_id.api_key.hex
    POSTGRES_URL = module.db.url
    PORT         = "3000"
  }
}

What This Does:

  • Stores Secrets Securely: The secrets module manages key-value pairs of sensitive data, ensuring they are stored securely and used by your services.

Step 4: Creating load balancer

The final step in your ECS setup involves creating an Application Load Balancer (ALB), which will route incoming traffic from the internet to your ECS application.

module "lb" {
  source = "../modules/lb/alb"

  name        = random_id.example.hex
  vpc_id      = module.vpc.id
  subnet_ids  = module.public_subnets.ids
  force_https = false

  context = {
    namespace = "test"
    stage     = "staging"
    name      = "api"
  }
}

resource "aws_alb_listener" "tcp" {
  load_balancer_arn = module.lb.id
  port              = 3000
  protocol          = "TCP"

  default_action {
    target_group_arn = module.service.lb_target_group_id
    type             = "forward"
  }
}

output "lb_dns" {
  value = "http://${module.lb.dns_name}"
}

What This Does:

  • Listener and Protocol: In this example, an ALB listener is created to listen on port 3000 using the TCP protocol. The listener forwards traffic to the target group associated with your ECS service.
  • Target Group Forwarding: The ALB forwards the traffic to your ECS service using the target group specified by target group ID.
  • Load Balancer DNS: The output lb_dns provides the DNS name of the load balancer, allowing you to access your application using the load balancer's public address.

Connection Summary

  1. ECS Cluster: Creates an ECS cluster in your VPC, with autoscaling and SSH access.
  2. Service Deployment: Deploys a service using Docker containers, linked to the ECS cluster and network.
  3. Secrets Management: Handles and secures sensitive information required by the service.
  4. Load Balancer: Redirects the traffic to specfified ECS Cluster.

This setup ensures your backend is scalable, secure, and well-organized, making it easier to manage and deploy applications on AWS.

On this page