간단하게 SPRING BOOT APPLICATION을 DOCKER CONTAINER 형태로 AWS ECS Fargate에 배포를 진행하겠습니다.
SpringBoot Application에 DockerFile을 먼저 세팅합니다.
FROM openjdk:17-jdk-alpine3.13
ARG JAR_FILE=./build/libs/testest.jar
COPY ${JAR_FILE} app.jar
ENTRYPOINT ["java","-jar","/app.jar"]
DockerFile은 아래 명령어로 이미지화 시켜줍니다.
docker build -t your-application-image-name .
이미지가 완성이 되었다면 아래 명령어로 이미지를 실행시켜 줍시다.
docker run -t your-service your-application-image-name .
컨테이너가 정상적으로 실행이 된다면 이제 AWS에 배포를 진행하겠습니다.
가장 먼저 해야할 일은 VPC를 생성하는 일입니다.
VPC 메뉴에 가서 VPC 생성을 해줍시다.
테스트기 때문에 CIDR 블록은 24로 지정을 해두겠습니다.
24블록으로 지정한 이유는 테스트 환경이고 서브넷의 수도 적기 때문에 작은 규모에서 권장되는 24블록을 사용했습니다.
지금은 테스트이고 application을 public subnet에 배포하여 테스트를 진행 할 것이기 때문에 NAT 게이트웨이를 만들지 않고 생성하겠습니다.
vpc가 성공적으로 생성이 되었는지 확인합니다.
방금 위에서 만들었던 vpc에 보안그룹을 연결해줍니다.
아래와 같이 80, 8080 포트를 열어주셔야합니다.
로드밸런서에서 요청을 할 것이기 때문에 좀이따 설정할 로드밸런서도 같은 vpc를 사용할 예정이므로 동일한 vpc의 요청을 인바운드 규칙에 설정해줘야 합니다.
ECR이란 : 이미지들을 관리, 저장해주는 AWS의 Repository
aws console에 ECS 메뉴를 들어가서 좌측 메뉴에 있는 Amazon ECR을 클릭해줍니다.
ECR에 들어왔다면 아래 동그라미 친 부분들을 입력해주고 리포지토리를 생성해줍니다.
Repository가 잘 생성이 되었다면 Repository에 들어가서 이미지를 올리러갑시다.
리포지토리 이름을 누른뒤 푸시 명령 보기를 누릅니다.
누르셨다면 아래와 같은 창이 뜹니다.
이어서 위에서부터 차례대로 AWS CLI에 입력해줍니다.
만약 AWS CLI가 설치되어 있지 않거나 설정 되어있지 않으면 아래 메뉴를 잠깐 보시면 됩니다.
AWS Access Key ID와 AWS Secret Access Key는 AWS Console IAM 메뉴에서 사용자를 등록 하시고 발급 받으시면 됩니다.
키 발급을 받았다면 terminal에서 aws confiure 명령어를 사용하여 key와 region, format을 입력해줍니다.
CLI를 설치하고 도커 이미지를 ECR에 업로드 했다면 아래와 같은 결과가 나와야 합니다.
여기서 미리 이미지 URI Tab에서 URI 복사를 해주세요.
다시 ECS 메뉴로 돌아와서 클러스터 생성을 누르고 아래와 같이 생성을 해주시면 됩니다.
좌측 task 메뉴에서 새 Task 정의 생성을 누릅니다.
인프라 요구사항은 테스트이기 때문에 Fargate + 나머지 Default 값으로 설정하겠습니다.
이미지 URI에는 아까 위에서 ECR로 push한 IMAGE URL을 복사해옵니다.
그리고 컨테이너 포트는 springboot application의 port 번호를 입력하고 프로토콜을 tcp로 한 뒤 포트 이름을 설정해주시면 됩니다.
그 뒤 옵션들은 각자 상황에 맞게 추가해주시고 Task를 생성하겠습니다.
Task 를 생성했다면 Cluster에 들어와서 Service를 생성하면 됩니다.
테스트기 때문에 컴퓨팅 구성은 Default로 설정하고 패밀리에는 좀전에 만들었던 task의 family를 선택하겠습니다.
아까 만들었던 VPC와 보안그룹을 연결해줍시다.
VPC를 생성 할 때 NAT Gateway를 만들지 않았기 때문에 Public Subnet만 선택해주면 됩니다.
로드 밸런서 설정을 해줘야 배포된 컨테이너 간에 들어오는 요청을 효과적으로 분산시킬 수 있습니다.
이제 서비스를 생성 해주면됩니다.
성공적으로 이벤트가 완료됐습니다.
이제 접속을 시도해보겠습니다.
DNS 이름을 복사해서 접속하면 됩니다.
이어서 자동 배포까지 구현 해보겠습니다.
위에서 만들었던 Task에 들어갑니다.
JSON 다운로드를 눌러서 JSON 파일을 다운 받고 spring application root path에 위치 시킵니다.
이제 GitHub Action을 등록시키러 가면 됩니다.
Actions를 누르고 ecs를 검색합니다.
configure 버튼을 누르면 workflows 경로에 yml 파일이 생성됩니다.
우리가 만들었던 ecr의 이름, ecs service, task, cluster, task definition을 아래 env에 입력해주시면 됩니다.
저와 동일하게 만들었다면 아래와 같이 입력하시면 됩니다.
아까 AWS CLI에서 입력했던 AWS Access Key ID와 AWS Secret Access Key를 github secret에 입력해야합니다.
이제 main branch에 push event가 발생하면 성공합니다.
name: Deploy to Amazon ECS
on:
push:
branches: [ "main" ]
env:
AWS_REGION: ap-northeast-2
ECR_REPOSITORY: testest
ECS_SERVICE: testest-service
ECS_CLUSTER: testest-cluster
ECS_TASK_DEFINITION: testest-family-revision.json
CONTAINER_NAME: testest-container
jobs:
deploy:
name: Deploy
runs-on: ubuntu-latest
environment: production
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Set up JDK 17
uses: actions/setup-java@v3
with:
java-version: '17'
distribution: 'adopt'
- name: Grant execute permission for gradlew
run: chmod +x gradlew
- name: build with gradle
run: ./gradlew clean build -x test
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v1
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: Login to Amazon ECR
id: login-ecr
uses: aws-actions/amazon-ecr-login@v1
- name: Build, tag, and push image to Amazon ECR
id: build-image
env:
ECR_REGISTRY: ${{ steps.login-ecr.outputs.registry }}
IMAGE_TAG: ${{ github.sha }}
run: |
docker build -t $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG .
docker push $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG
echo "image=$ECR_REGISTRY/$ECR_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: ${{ env.ECS_TASK_DEFINITION }}
container-name: ${{ env.CONTAINER_NAME }}
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: ${{ env.ECS_SERVICE }}
cluster: ${{ env.ECS_CLUSTER }}
wait-for-service-stability: true