diff --git a/.github/workflows/ci-cd.yml b/.github/workflows/ci-cd.yml
new file mode 100644
index 0000000..69eed43
--- /dev/null
+++ b/.github/workflows/ci-cd.yml
@@ -0,0 +1,60 @@
+name: Deploy to AWS ECS
+on:
+ push:
+ branches: [ deploy-to-ecs ]
+jobs:
+ build-and-deploy:
+ runs-on: [ ubuntu-latest ]
+ steps:
+ - name: Checkout source
+ uses: actions/checkout@v3
+
+ - name: Setup Java
+ uses: actions/setup-java@v3
+ with:
+ distribution: 'temurin'
+ java-version: '17'
+
+ - name: Build Project
+ run: mvn clean install -DskipTests
+
+ - name: Configure AWS credentials
+ uses: aws-actions/configure-aws-credentials@v3
+ with:
+ aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY }}
+ aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
+ aws-region: 'eu-north-1'
+
+ - name: Login to Amazon ECR
+ id: login-ecr
+ uses: aws-actions/amazon-ecr-login@v1
+ with:
+ mask-password: 'true'
+
+ - name: Build, tag, and push image to Amazon ECR
+ id: build-image
+ env:
+ ECR_REGISTRY: ${{ steps.login-ecr.outputs.registry }}
+ IMAGE_TAG: ${{ github.sha }}
+ REPOSITORY: springboot-example
+ run: |
+ # Build a docker container and
+ # push it to ECR so that it can
+ # be deployed to ECS.
+ docker build -t $ECR_REGISTRY/$REPOSITORY:$IMAGE_TAG .
+ docker push $ECR_REGISTRY/$REPOSITORY:$IMAGE_TAG
+ echo "image=$ECR_REGISTRY/$REPOSITORY:$IMAGE_TAG" >> $GITHUB_OUTPUT
+ - name: Fill in the new image ID in the Amazon ECS task definition
+ id: task-def
+ uses: aws-actions/amazon-ecs-render-task-definition@v1
+ with:
+ task-definition: springboot-app-task-definition.json
+ container-name: springboot-example
+ image: ${{ steps.build-image.outputs.image }}
+ - name: Deploy Amazon ECS task definition
+ uses: aws-actions/amazon-ecs-deploy-task-definition@v1
+ with:
+ task-definition: ${{ steps.task-def.outputs.task-definition }}
+ service: springboot-example-service
+ cluster: DevCluster2
+ wait-for-service-stability: true
diff --git a/Dockerfile b/Dockerfile
new file mode 100644
index 0000000..5119b62
--- /dev/null
+++ b/Dockerfile
@@ -0,0 +1,5 @@
+FROM eclipse-temurin:17-jdk-alpine
+WORKDIR /app
+COPY target/springboot-example.jar springboot-example.jar
+EXPOSE 8080
+CMD ["java","-jar","springboot-example.jar"]
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
index aeee93a..61f0f27 100644
--- a/pom.xml
+++ b/pom.xml
@@ -32,6 +32,23 @@
org.springframework.boot
spring-boot-starter-web
+
+
+ org.springframework.boot
+ spring-boot-starter-data-jpa
+
+
+
+ org.projectlombok
+ lombok
+ true
+
+
+
+ mysql
+ mysql-connector-java
+ 8.0.29
+
diff --git a/springboot-app-task-definition.json b/springboot-app-task-definition.json
new file mode 100644
index 0000000..fa5d554
--- /dev/null
+++ b/springboot-app-task-definition.json
@@ -0,0 +1,97 @@
+{
+ "compatibilities": [
+ "EC2",
+ "FARGATE"
+ ],
+ "containerDefinitions": [
+ {
+ "cpu": 0,
+ "environment": [],
+ "environmentFiles": [],
+ "essential": true,
+ "image": "493233983811.dkr.ecr.us-east-1.amazonaws.com/springboot-example:latest",
+ "logConfiguration": {
+ "logDriver": "awslogs",
+ "options": {
+ "awslogs-group": "/ecs/springboot-app-task-definition",
+ "awslogs-create-group": "true",
+ "awslogs-region": "us-east-1",
+ "awslogs-stream-prefix": "ecs"
+ },
+ "secretOptions": []
+ },
+ "mountPoints": [],
+ "name": "springboot-example",
+ "portMappings": [
+ {
+ "appProtocol": "http",
+ "containerPort": 80,
+ "hostPort": 80,
+ "name": "springboot-example-80-tcp",
+ "protocol": "tcp"
+ },
+ {
+ "appProtocol": "http",
+ "containerPort": 8080,
+ "hostPort": 8080,
+ "name": "springboot-example-8080-tcp",
+ "protocol": "tcp"
+ }
+ ],
+ "systemControls": [],
+ "ulimits": [],
+ "volumesFrom": []
+ }
+ ],
+ "cpu": "1024",
+ "enableFaultInjection": false,
+ "executionRoleArn": "arn:aws:iam::493233983811:role/ecsTaskExecutionRole",
+ "family": "springboot-app-task-definition",
+ "memory": "3072",
+ "networkMode": "awsvpc",
+ "placementConstraints": [],
+ "registeredAt": "2025-09-23T19:14:25.667Z",
+ "registeredBy": "arn:aws:iam::493233983811:root",
+ "requiresAttributes": [
+ {
+ "name": "com.amazonaws.ecs.capability.logging-driver.awslogs"
+ },
+ {
+ "name": "ecs.capability.execution-role-awslogs"
+ },
+ {
+ "name": "com.amazonaws.ecs.capability.ecr-auth"
+ },
+ {
+ "name": "com.amazonaws.ecs.capability.docker-remote-api.1.19"
+ },
+ {
+ "name": "com.amazonaws.ecs.capability.task-iam-role"
+ },
+ {
+ "name": "ecs.capability.execution-role-ecr-pull"
+ },
+ {
+ "name": "com.amazonaws.ecs.capability.docker-remote-api.1.18"
+ },
+ {
+ "name": "ecs.capability.task-eni"
+ },
+ {
+ "name": "com.amazonaws.ecs.capability.docker-remote-api.1.29"
+ }
+ ],
+ "requiresCompatibilities": [
+ "FARGATE"
+ ],
+ "revision": 1,
+ "runtimePlatform": {
+ "cpuArchitecture": "X86_64",
+ "operatingSystemFamily": "LINUX"
+ },
+ "status": "ACTIVE",
+ "taskDefinitionArn": "arn:aws:ecs:us-east-1:493233983811:task-definition/springboot-app-task-definition:1",
+ "taskRoleArn": "arn:aws:iam::493233983811:role/ecsTaskExecutionRole",
+ "volumes": [],
+ "tags": []
+}
diff --git a/src/main/java/com/integrationninjas/springbootexample/controller/TestController.java b/src/main/java/com/integrationninjas/springbootexample/controller/TestController.java
deleted file mode 100644
index 9a5f4ba..0000000
--- a/src/main/java/com/integrationninjas/springbootexample/controller/TestController.java
+++ /dev/null
@@ -1,20 +0,0 @@
-package com.integrationninjas.springbootexample.controller;
-
-import java.util.HashMap;
-import java.util.Map;
-
-import org.springframework.web.bind.annotation.GetMapping;
-import org.springframework.web.bind.annotation.RestController;
-
-@RestController
-public class TestController {
-
- @GetMapping
- public Object hello() {
- Map object = new HashMap<>();
- object.put("name", "Integration Ninjas");
- object.put("email", "integrationninjas@gmail.com");
- return object;
- }
-
-}
diff --git a/src/main/java/com/integrationninjas/springbootexample/controller/UserController.java b/src/main/java/com/integrationninjas/springbootexample/controller/UserController.java
new file mode 100644
index 0000000..97e6421
--- /dev/null
+++ b/src/main/java/com/integrationninjas/springbootexample/controller/UserController.java
@@ -0,0 +1,36 @@
+package com.integrationninjas.springbootexample.controller;
+
+import java.util.List;
+import com.integrationninjas.springbootexample.dto.UserDto;
+import com.integrationninjas.springbootexample.service.UserService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RestController;
+
+@RestController
+public class UserController {
+
+ @Autowired
+ private UserService userService;
+
+ @GetMapping("/users")
+ public ResponseEntity> getUsers() {
+ List usersList = userService.getUsers();
+ return new ResponseEntity<>(usersList, HttpStatus.OK);
+ }
+
+ @PostMapping("/users")
+ public ResponseEntity createUser(@RequestBody UserDto userDto) {
+ try {
+ String status = userService.createUser(userDto);
+ return new ResponseEntity<>(status, HttpStatus.CREATED);
+ } catch (Exception e) {
+ return new ResponseEntity<>(e.getMessage(), HttpStatus.INTERNAL_SERVER_ERROR);
+ }
+ }
+
+}
diff --git a/src/main/java/com/integrationninjas/springbootexample/dao/UserDao.java b/src/main/java/com/integrationninjas/springbootexample/dao/UserDao.java
new file mode 100644
index 0000000..26e3038
--- /dev/null
+++ b/src/main/java/com/integrationninjas/springbootexample/dao/UserDao.java
@@ -0,0 +1,7 @@
+package com.integrationninjas.springbootexample.dao;
+
+import com.integrationninjas.springbootexample.entity.User;
+import org.springframework.data.jpa.repository.JpaRepository;
+
+public interface UserDao extends JpaRepository {
+}
diff --git a/src/main/java/com/integrationninjas/springbootexample/dto/UserDto.java b/src/main/java/com/integrationninjas/springbootexample/dto/UserDto.java
new file mode 100644
index 0000000..dd9cf92
--- /dev/null
+++ b/src/main/java/com/integrationninjas/springbootexample/dto/UserDto.java
@@ -0,0 +1,12 @@
+package com.integrationninjas.springbootexample.dto;
+
+import lombok.*;
+
+@Data
+public class UserDto {
+
+ private Long id;
+ private String firstName;
+ private String lastName;
+ private String email;
+}
diff --git a/src/main/java/com/integrationninjas/springbootexample/entity/User.java b/src/main/java/com/integrationninjas/springbootexample/entity/User.java
new file mode 100644
index 0000000..3da05fc
--- /dev/null
+++ b/src/main/java/com/integrationninjas/springbootexample/entity/User.java
@@ -0,0 +1,30 @@
+package com.integrationninjas.springbootexample.entity;
+
+import jakarta.persistence.*;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+import lombok.Setter;
+
+@Getter
+@Setter
+@NoArgsConstructor
+@AllArgsConstructor
+@Entity
+@Table(name = "users")
+public class User {
+
+ @Id
+ @GeneratedValue(strategy = GenerationType.IDENTITY)
+ private Long id;
+
+ @Column(nullable = false)
+ private String firstName;
+
+ @Column(nullable = false)
+ private String lastName;
+
+ @Column(nullable = false, unique = true)
+ private String email;
+
+}
diff --git a/src/main/java/com/integrationninjas/springbootexample/service/UserService.java b/src/main/java/com/integrationninjas/springbootexample/service/UserService.java
new file mode 100644
index 0000000..dd636a1
--- /dev/null
+++ b/src/main/java/com/integrationninjas/springbootexample/service/UserService.java
@@ -0,0 +1,13 @@
+package com.integrationninjas.springbootexample.service;
+
+import com.integrationninjas.springbootexample.dto.UserDto;
+import com.integrationninjas.springbootexample.entity.User;
+
+import java.util.List;
+
+public interface UserService {
+
+ String createUser(UserDto userDto);
+
+ List getUsers();
+}
diff --git a/src/main/java/com/integrationninjas/springbootexample/service/impl/UserServiceImpl.java b/src/main/java/com/integrationninjas/springbootexample/service/impl/UserServiceImpl.java
new file mode 100644
index 0000000..734517f
--- /dev/null
+++ b/src/main/java/com/integrationninjas/springbootexample/service/impl/UserServiceImpl.java
@@ -0,0 +1,46 @@
+package com.integrationninjas.springbootexample.service.impl;
+
+import com.integrationninjas.springbootexample.dao.UserDao;
+import com.integrationninjas.springbootexample.dto.UserDto;
+import com.integrationninjas.springbootexample.entity.User;
+import com.integrationninjas.springbootexample.service.UserService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+@Service
+public class UserServiceImpl implements UserService {
+
+ @Autowired
+ UserDao userDao;
+
+ @Override
+ public String createUser(UserDto userDto) {
+ User user = new User();
+ user.setFirstName(userDto.getFirstName());
+ user.setLastName(userDto.getLastName());
+ user.setEmail(userDto.getEmail());
+ userDao.saveAndFlush(user);
+ return "User Added Successfully";
+ }
+
+ @Override
+ public List getUsers() {
+ List usersList = userDao.findAll();
+ List dtoList = new ArrayList<>();
+ if (!usersList.isEmpty()) {
+ usersList.forEach(user -> {
+ UserDto dto = new UserDto();
+ dto.setId(user.getId());
+ dto.setFirstName(user.getFirstName());
+ dto.setLastName(user.getLastName());
+ dto.setEmail(user.getEmail());
+ dtoList.add(dto);
+ });
+ }
+ return dtoList;
+ }
+}
diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties
index 8b13789..de4b4b0 100644
--- a/src/main/resources/application.properties
+++ b/src/main/resources/application.properties
@@ -1 +1,6 @@
+spring.datasource.url=jdbc:mysql://user-management.cbvxsmsv5dwh.eu-north-1.rds.amazonaws.com:3306/user_management
+spring.datasource.username=root
+spring.datasource.password=password
+spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQLDialect
+spring.jpa.hibernate.ddl-auto=update
\ No newline at end of file