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.