Elastic Container Service - amresh087/newronaRepos GitHub Wiki
File name : app/Dockerfile
FROM eclipse-temurin:17
COPY target/loan-service.jar app.jar
ENTRYPOINT ["java","-jar","app.jar"]
Explanation:
- Uses Java 17
- Copies Spring Boot jar
- Runs app on port 8080
File name : app/Dockerfile
server:
port: 8080
spring:
datasource:
url: jdbc:postgresql://rds-url:5432/loan_db
username: admin
password: password
management:
endpoints:
web:
exposure:
include: health
provider "aws" {
region = "ap-south-1"
}
Explanation:
- AWS region configuration
variable "app_name" {
default = "springboot-ecs"
}
variable "container_port" {
default = 8080
}
Explanation:
- Reusable variables
resource "aws_vpc" "main" {
cidr_block = "10.0.0.0/16"
}
resource "aws_subnet" "subnet1" {
vpc_id = aws_vpc.main.id
cidr_block = "10.0.1.0/24"
availability_zone = "ap-south-1a"
map_public_ip_on_launch = true
}
resource "aws_subnet" "subnet2" {
vpc_id = aws_vpc.main.id
cidr_block = "10.0.2.0/24"
availability_zone = "ap-south-1b"
map_public_ip_on_launch = true
}
resource "aws_internet_gateway" "igw" {
vpc_id = aws_vpc.main.id
}
resource "aws_route_table" "rt" {
vpc_id = aws_vpc.main.id
}
resource "aws_route" "internet_access" {
route_table_id = aws_route_table.rt.id
destination_cidr_block = "0.0.0.0/0"
gateway_id = aws_internet_gateway.igw.id
}
resource "aws_route_table_association" "a1" {
subnet_id = aws_subnet.subnet1.id
route_table_id = aws_route_table.rt.id
}
resource "aws_route_table_association" "a2" {
subnet_id = aws_subnet.subnet2.id
route_table_id = aws_route_table.rt.id
}
Explanation:
- Creates VPC
- Creates 2 public subnets
- Internet access enabled
resource "aws_security_group" "alb_sg" {
vpc_id = aws_vpc.main.id
ingress {
from_port = 80
to_port = 80
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"]
}
}
resource "aws_security_group" "ecs_sg" {
vpc_id = aws_vpc.main.id
ingress {
from_port = 8080
to_port = 8080
protocol = "tcp"
security_groups = [aws_security_group.alb_sg.id]
}
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
}
Explanation:
- ALB accepts internet traffic
- ECS accepts only ALB traffic
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_role_policy_attachment" "ecs_task_execution_policy" {
role = aws_iam_role.ecs_task_execution_role.name
policy_arn = "arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy"
}
Explanation:
- ECS needs permissions
- Pull Docker image
- Send logs to CloudWatch
resource "aws_ecr_repository" "repo" {
name = "springboot-repo"
}
Explanation:
- Docker image storage
resource "aws_ecs_cluster" "main" {
name = "springboot-cluster"
}
Explanation:
- ECS cluster creation
resource "aws_cloudwatch_log_group" "logs" {
name = "/ecs/springboot-app"
}
Explanation:
- Stores application logs
resource "aws_ecs_task_definition" "app" {
family = "springboot-task"
network_mode = "awsvpc"
requires_compatibilities = ["FARGATE"]
cpu = 512
memory = 1024
execution_role_arn = aws_iam_role.ecs_task_execution_role.arn
container_definitions = jsonencode([
{
name = "springboot-container"
image = "${aws_ecr_repository.repo.repository_url}:latest"
essential = true
portMappings = [
{
containerPort = 8080
hostPort = 8080
}
]
logConfiguration = {
logDriver = "awslogs"
options = {
awslogs-group = aws_cloudwatch_log_group.logs.name
awslogs-region = "ap-south-1"
awslogs-stream-prefix = "ecs"
}
}
}
])
}
Explanation:
- Defines Docker container
- CPU + memory
- CloudWatch logging
resource "aws_lb" "alb" {
name = "springboot-alb"
internal = false
load_balancer_type = "application"
security_groups = [aws_security_group.alb_sg.id]
subnets = [
aws_subnet.subnet1.id,
aws_subnet.subnet2.id
]
}
resource "aws_lb_target_group" "tg" {
name = "springboot-tg"
port = 8080
protocol = "HTTP"
target_type = "ip"
vpc_id = aws_vpc.main.id
health_check {
path = "/actuator/health"
}
}
resource "aws_lb_listener" "listener" {
load_balancer_arn = aws_lb.alb.arn
port = 80
protocol = "HTTP"
default_action {
type = "forward"
target_group_arn = aws_lb_target_group.tg.arn
}
}
Explanation:
- ALB distributes traffic
- Health check validates app health
resource "aws_ecs_service" "service" {
name = "springboot-service"
cluster = aws_ecs_cluster.main.id
task_definition = aws_ecs_task_definition.app.arn
desired_count = 2
launch_type = "FARGATE"
network_configuration {
subnets = [
aws_subnet.subnet1.id,
aws_subnet.subnet2.id
]
security_groups = [
aws_security_group.ecs_sg.id
]
assign_public_ip = true
}
load_balancer {
target_group_arn = aws_lb_target_group.tg.arn
container_name = "springboot-container"
container_port = 8080
}
depends_on = [
aws_lb_listener.listener
]
}
Explanation:
- Runs 2 containers
- Connected with ALB
- Fargate serverless deployment
resource "aws_appautoscaling_target" "ecs_target" {
max_capacity = 5
min_capacity = 2
resource_id = "service/${aws_ecs_cluster.main.name}/${aws_ecs_service.service.name}"
scalable_dimension = "ecs:service:DesiredCount"
service_namespace = "ecs"
}
resource "aws_appautoscaling_policy" "cpu_policy" {
name = "cpu-autoscaling"
policy_type = "TargetTrackingScaling"
resource_id = aws_appautoscaling_target.ecs_target.resource_id
scalable_dimension = aws_appautoscaling_target.ecs_target.scalable_dimension
service_namespace = aws_appautoscaling_target.ecs_target.service_namespace
target_tracking_scaling_policy_configuration {
target_value = 50
predefined_metric_specification {
predefined_metric_type = "ECSServiceAverageCPUUtilization"
}
}
}
Explanation:
- Auto scale when CPU > 50%
- Minimum 2 tasks
- Maximum 5 tasks
output "alb_url" {
value = aws_lb.alb.dns_name
}
Explanation:
- Shows ALB URL after deployment
Initialize:
terraform init
Check:
terraform plan
Deploy:
terraform apply
Destroy:
terraform destroy
=================================================================================
- EC2
- Forgot
To deploy a Spring Boot application on AWS Elastic Container Service (ECS), you'll typically follow these general steps:
-
Containerize your Spring Boot application: You need to create a Docker image of your Spring Boot application. This involves writing a Dockerfile that defines the environment and dependencies required to run your application.
-
Push Docker image to a container registry: You need to push the Docker image to a container registry like Amazon Elastic Container Registry (ECR) so that ECS can access it during deployment.
-
Set up ECS Cluster: Create an ECS cluster where your containers will run. This involves defining task definitions, which specify how your containers should be run.
-
Create ECS Service: Define a service within ECS that manages your tasks. This includes specifying the number of tasks you want to run, the load balancer configuration (if applicable), and other settings.
-
Configure Load Balancer (optional): If your application requires load balancing, set up an Elastic Load Balancer (ELB) or Application Load Balancer (ALB) to distribute traffic to your ECS service.
Assuming you have a Spring Boot application with a Dockerfile like this:
Dockerfile
FROM openjdk:11-jre-slim
COPY target/my-spring-app.jar /app/my-spring-app.jar
CMD ["java", "-jar", "/app/my-spring-app.jar"]
docker build -t my-spring-app .
Push Docker image to ECR:
First, ensure you have the AWS CLI configured and Docker installed.
docker tag my-spring-app:latest <your-account-id>.dkr.ecr.<region>.amazonaws.com/my-spring-app:latest
aws ecr get-login-password --region <region> | docker login --username AWS --password-stdin <your-account-id>.dkr.ecr.<region>.amazonaws.com
docker push <your-account-id>.dkr.ecr.<region>.amazonaws.com/my-spring-app:latest
You can create an ECS cluster via the AWS Management Console or AWS CLI. You'll also need to create a task definition that specifies how your container should be run.
Define a service within ECS to manage your tasks. Specify the task definition, desired number of tasks, and any load balancer configuration.
Set up an Elastic Load Balancer (ELB) or Application Load Balancer (ALB) to distribute traffic to your ECS service if required.