How to migrate a service from an oncloud server to an ecs aws service

Written by teamember02
Updated 7 months ago

Migrating a service from an on-premises server to AWS ECS using Terraform involves several steps. Terraform allows you to define your infrastructure as code, making it easier to automate and manage. Here’s a step-by-step guide to achieve this:

### Prerequisites
1. **Install Terraform**: Ensure Terraform is installed on your local machine.
2. **AWS Account**: You need an AWS account with the necessary permissions to create and manage ECS, ECR, IAM roles, VPC, and other resources.
3. **Docker**: Install Docker to containerize your application.

### Step-by-Step Guide

#### 1. Containerize Your Application
Create a Dockerfile for your application and build the Docker image locally.

```Dockerfile
# Use an official Node.js runtime as a parent image
FROM node:14

# Set the working directory in the container
WORKDIR /usr/src/app

# Copy the package.json and package-lock.json files
COPY package*.json ./

# Install the application dependencies
RUN npm install

# Copy the rest of the application code
COPY . .

# Expose the port the app runs on
EXPOSE 8080

# Define the command to run the app
CMD ["node", "app.js"]
```

Build and test the Docker image locally.

```sh
docker build -t my-application .
docker run -p 8080:8080 my-application
```

#### 2. Push the Docker Image to Amazon ECR

Create a Terraform script (`ecr.tf`) to set up an ECR repository.

```hcl
provider "aws" {
  region = "us-west-2"
}

resource "aws_ecr_repository" "my_application" {
  name                 = "my-application"
  image_tag_mutability = "MUTABLE"
  image_scanning_configuration {
    scan_on_push = true
  }
}
```

Initialize and apply the Terraform script.

```sh
terraform init
terraform apply -auto-approve
```

Authenticate Docker with ECR and push the image.

```sh
aws ecr get-login-password --region us-west-2 | docker login --username AWS --password-stdin <your-account-id>.dkr.ecr.us-west-2.amazonaws.com
docker tag my-application:latest <your-account-id>.dkr.ecr.us-west-2.amazonaws.com/my-application:latest
docker push <your-account-id>.dkr.ecr.us-west-2.amazonaws.com/my-application:latest
```

#### 3. Set Up the ECS Cluster with Terraform

Create a Terraform script (`ecs.tf`) to set up an ECS cluster, task definition, and service.

```hcl
provider "aws" {
  region = "us-west-2"
}

resource "aws_ecs_cluster" "my_cluster" {
  name = "my-cluster"
}

resource "aws_ecs_task_definition" "my_task" {
  family                   = "my-task"
  network_mode             = "awsvpc"
  requires_compatibilities = ["FARGATE"]
  cpu                      = "256"
  memory                   = "512"

  container_definitions = jsonencode([
    {
      name  = "my-application"
      image = "<your-account-id>.dkr.ecr.us-west-2.amazonaws.com/my-application:latest"
      essential = true
      portMappings = [
        {
          containerPort = 8080
          hostPort      = 8080
        }
      ]
    }
  ])
}

resource "aws_ecs_service" "my_service" {
  name            = "my-service"
  cluster         = aws_ecs_cluster.my_cluster.id
  task_definition = aws_ecs_task_definition.my_task.arn
  desired_count   = 1
  launch_type     = "FARGATE"
  network_configuration {
    subnets         = [aws_subnet.my_subnet.id]
    security_groups = [aws_security_group.my_sg.id]
  }
}

resource "aws_vpc" "my_vpc" {
  cidr_block = "10.0.0.0/16"
}

resource "aws_subnet" "my_subnet" {
  vpc_id     = aws_vpc.my_vpc.id
  cidr_block = "10.0.1.0/24"
}

resource "aws_security_group" "my_sg" {
  vpc_id = aws_vpc.my_vpc.id

  ingress {
    from_port   = 8080
    to_port     = 8080
    protocol    = "tcp"
    cidr_blocks = ["0.0.0.0/0"]
  }

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

Initialize and apply the Terraform script.

```sh
terraform init
terraform apply -auto-approve
```

#### 4. Configure IAM Roles

Create a Terraform script (`iam.tf`) to set up the necessary IAM roles and policies.

```hcl
resource "aws_iam_role" "ecs_task_execution_role" {
  name = "ecsTaskExecutionRole"

  assume_role_policy = jsonencode({
    Version = "2012-10-17"
    Statement = [
      {
        Action = "sts:AssumeRole"
        Effect = "Allow"
        Principal = {
          Service = "ecs-tasks.amazonaws.com"
        }
      }
    ]
  })
}

resource "aws_iam_policy_attachment" "ecs_task_execution_role_policy" {
  name       = "ecs_task_execution_role_policy"
  roles      = [aws_iam_role.ecs_task_execution_role.name]
  policy_arn = "arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy"
}
```

Initialize and apply the Terraform script.

```sh
terraform init
terraform apply -auto-approve
```

#### 5. Test and Monitor

After deploying, ensure that the service is running correctly by checking the ECS console. You can also use AWS CloudWatch for logs and monitoring.

#### 6. Update DNS (if needed)

If your application needs to be accessible via a domain name, update your DNS settings to point to the ECS service’s load balancer.

### Conclusion

By following these steps, you can effectively migrate your application from an on-premises server to AWS ECS using Terraform. This approach ensures that your infrastructure is defined as code, making it easy to manage, reproduce, and scale.

Did this answer your question?