Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
85 changes: 85 additions & 0 deletions .github/workflows/ecsCd.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
name: Deploy Spring Boot to ECS (Fargate)

on:
push:
branches:
- mainDeploy

env:
AWS_REGION: ap-northeast-2
ECR_REPOSITORY: spring-app
ECS_CLUSTER: prod-cluster
ECS_SERVICE: spring-service
IMAGE_TAG: latest
CONTAINER_NAME: spring-container

jobs:
deploy:
runs-on: ubuntu-latest

steps:
- name: Checkout code
uses: actions/checkout@v2

- name: Create resources folder if not exists
run: mkdir -p ./src/main/resources

- name: Create application.yml from GitHub Secret
run: echo "${{ secrets.APPLICATION_YML }}" > ./src/main/resources/application.yml

- name: Set up JDK 23
uses: actions/setup-java@v3
with:
java-version: '23'

- name: Build Spring Boot app
run: ./gradlew clean build -x test

- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v2
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: ${{ env.AWS_REGION }}

- name: Log in to Amazon ECR
uses: aws-actions/amazon-ecr-login@v1

- name: Get AWS Account ID
id: aws-account
run: |
ACCOUNT_ID=$(aws sts get-caller-identity --query Account --output text)
echo "ACCOUNT_ID=$ACCOUNT_ID" >> $GITHUB_ENV
echo "::set-output name=account_id::$ACCOUNT_ID"

- name: Build and push Docker image to ECR
run: |
IMAGE_URI=${{ steps.aws-account.outputs.account_id }}.dkr.ecr.${{ env.AWS_REGION }}.amazonaws.com/${{ env.ECR_REPOSITORY }}
docker build -t $IMAGE_URI:$IMAGE_TAG .
docker push $IMAGE_URI:$IMAGE_TAG
echo "IMAGE_URI=$IMAGE_URI:$IMAGE_TAG" >> $GITHUB_ENV
echo "::set-output name=image_uri::$IMAGE_URI:$IMAGE_TAG"

- name: Replace placeholders in ecs-task-def.json
run: |
sed -i "s|<ACCOUNT_ID>|${{ steps.aws-account.outputs.account_id }}|g" ecs-task-def.json
sed -i "s|<IMAGE_URI>|${{ steps.build-and-push.outputs.image_uri }}|g" ecs-task-def.json
cat ecs-task-def.json

- name: Register new ECS task definition
id: register-task
run: |
TASK_DEF_ARN=$(aws ecs register-task-definition \
--cli-input-json file://ecs-task-def.json \
--query "taskDefinition.taskDefinitionArn" \
--output text)
echo "TASK_DEF_ARN=$TASK_DEF_ARN"
echo "::set-output name=task_definition_arn::$TASK_DEF_ARN"

- name: Deploy to ECS (Fargate)
uses: aws-actions/amazon-ecs-deploy-task-definition@v1
with:
cluster: ${{ env.ECS_CLUSTER }}
service: ${{ env.ECS_SERVICE }}
task-definition: ${{ steps.register-task.outputs.task_definition_arn }}
wait-for-service-stability: true
10 changes: 10 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
FROM eclipse-temurin:23-jdk-jammy as build
WORKDIR /app
COPY . .
RUN ./gradlew clean build -x test
FROM eclipse-temurin:23-jre-jammy
WORKDIR /app
COPY --from=build /app/build/libs/*.jar app.jar
COPY src/main/resources/application.yml ./src/main/resources/application.yml
EXPOSE 8080
ENTRYPOINT ["java", "-jar", "app.jar"]
29 changes: 29 additions & 0 deletions ecs-task-def.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
{
"family": "spring-app",
"networkMode": "awsvpc",
"requiresCompatibilities": ["FARGATE"],
"cpu": "1024",
"memory": "2048",
"executionRoleArn": "arn:aws:iam::<ACCOUNT_ID>:role/ecsTaskExecutionRole",
"containerDefinitions": [
{
"name": "spring-container",
"image": "<IMAGE_URI>",
"essential": true,
"portMappings": [
{
"containerPort": 8080,
"protocol": "tcp"
}
],
"logConfiguration": {
"logDriver": "awslogs",
"options": {
"awslogs-group": "/ecs/spring-app",
"awslogs-region": "ap-northeast-2",
"awslogs-stream-prefix": "ecs"
}
}
}
]
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,25 @@ public class ConferenceFactory {

public Conference createConference(ConferenceCreateRequest request) {

String imageKey = parseS3ImageKeyFromUrl(request.imageUrl());

return Conference.builder()
.name(request.name())
.description(request.description())
.capacity(request.capacity())
.location(request.location())
.startTime(request.startTime())
.endTime(request.endTime())
.imageKey(request.imageUrl())
.imageKey(imageKey)
.isActive(true)
.hasSessions(request.hasSessions())
.build();
}

private String parseS3ImageKeyFromUrl(String imageUrl) {
if (imageUrl == null || !imageUrl.contains("/conference/images/")) {
throw new IllegalArgumentException("Invalid image url");
}
return imageUrl.substring(imageUrl.indexOf("conference/images"));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ public Set<SessionDto> createSessionDtos(List<Reservation> reservations) {

public Session createSession(SessionCreateRequest request, Conference conference) {

String speakerImageKey = parseSpeakerImageKey(request.speakerImage());

return Session.builder()
.name(request.name())
.capacity(request.capacity())
Expand All @@ -40,8 +42,15 @@ public Session createSession(SessionCreateRequest request, Conference conference
.speakerName(request.speakerName())
.speakerOrganization(request.speakerOrganization())
.isActive(true)
.speakerImageKey(request.speakerImage())
.speakerImageKey(speakerImageKey)
.conference(conference)
.build();
}

private String parseSpeakerImageKey(String speakerImage) {
if (speakerImage == null || !speakerImage.contains("/conference/speaker/")) {
throw new IllegalArgumentException("Invalid speaker image url");
}
return speakerImage.substring(speakerImage.indexOf("conference/speaker/"));
}
}