
[AWS] 아키텍쳐 구현(1) : HTTPS 및 로드밸런서 적용
현재 내가 완성시키고자 하는 아키택쳐는 아래와 같다.사전 준비 상태1) VPC 생성 완료2) private subnet 2개, public subnet 2개 ig와 연결 완료3) kafka용 ec2 설치 완료4) public 도메인 구매 완료 이번 포스팅
2hy2on.tistory.com
지난 시간에 이어서 ecs와 lb 연결 및 배포 테스트를 진행해보겠다.
1. ECR 생성
Private registory > Repositories > 리포지토리 생성 클릭

2. Task 생성
ECS > 테스크 정의 >y > Repositories > 새 테스크 정의 생성 클릭


아까 생성한 ecr에 들어가 푸시 명령어 보기에 있는 이미지 URL을 복사해온다.
컨테이너 포트는 8080으로 설정해준다.

정상적으로 task가 생성된 것을 확인할 수 있다.
3. Cluster 생성
ECS > 클러스터 > 클러스터 생성 클릭

4. Service 생성
클러스터 > 생성한 클러스터 > 서비스 삭제 옆 생성 클릭


패밀리에는 아까 생성한 task를 선택해준다.

보안 그룹은 HTTPS, HTTP가 아닌 8080으로 해준다!!!! (아래 이슈 참고)

이전에 만들었던 로드밸런서를 설정해준다.

상태확인은 HTTP로 설정한다. 스프링 부트 애플리케이션이 동작할 때 기본적으로 HTTP 프로토콜을 사용하게 설정했기 때문이다.
5. IAM 설정
IAM > 사용자 > 사용자 이름 > 권한 > 권한 추가 > 직접 정책 연결하기

AmazonEC2ContainerRegistryFullAccess와 AmazonECS_FullAccess 를 추가해준다.

엑세스 키2 밑에 엑세스 키 만들기를 눌러주었다.
CLI를 선택해 생성해주었다.
6. github action yml 작성
1) yml 파일
name: Deploy to Amazon ECS CI/CD
on:
push:
branches: [ "main" ]
env:
AWS_REGION: # AWS region, e.g. us-west-1
ECR_REPOSITORY: # Amazon ECR repository name
ECS_SERVICE: # Amazon ECS service name
ECS_CLUSTER: # Amazon ECS cluster name
ECS_TASK_DEFINITION: # Amazon ECS task definition 경로 (json 파일경로)
CONTAINER_NAME: # container name
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: 'temurin'
- name: Grant execute permission for gradlew
run: chmod +x gradlew
# - name: Copy Secret
# env:
# CREATE_SECRET: ${{secrets.APPLICATION_YML}}
# CREATE_SECRET_DIR: src/main/resources
# CREATE_SECRET_DIR_FILE_NAME: application.yml
# run: echo $CREATE_SECRET | base64 --decode > $CREATE_SECRET_DIR/$CREATE_SECRET_DIR_FILE_NAME
- name: Build with Gradle
run: ./gradlew build -x test
shell: bash
- 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
2) JSON 파일 생성
아까 만든 task에서 JSON > AWS CLI 입력 다운로드 클릭


경로는 루트에 넣어주면 된다.
7. 배포 성공



public 도메인 이름으로 했을 때와 lb DNS로 접속했을 때 둘 다 잘 실행되는 것을 확인할 수 있다.
이슈!!!!
ecs 배포를 진행하면서 이슈가 정말 많았다... 그 중 몇개만 요약해보겠다.
1. target group 포트를 HTTPS 로 설정해준 점이다.
ECS에서 배포한 애플리케이션의 Target Group 포트를 HTTPS로 설정한 것이 문제였다. CloudWatch 로그를 살펴보니 아래와 같은 에러가 발생했다.
--- [apigateway-service] [nio-8080-exec-1] o.apache.coyote.http11.Http11Processor : Error parsing HTTP request header ecs
이 에러의 원인은 HTTP 요청이 HTTPS 포트로 전달되면서 발생한 문제였다.
스프링 부트 애플리케이션이 동작할 때 기본적으로 HTTP, HTTPS 프로토콜을 사용하지만 나는 HTTP 프로토콜을 사용했다.(HTTPS를 사용하려면 ssl 추가설정 필요)
따라서, Target Group 포트를 HTTP로 설정해야 하지만, 이를 HTTPS로 설정하면서 요청이 잘못된 포트로 전달되었고, 이로 인해 HTTP 요청 헤더를 파싱하는 과정에서 오류가 발생한 것이다.
2. Security 인바운드 규칙

위와 같은 에러는 현재 접근하고 싶은 service security 인바운드 규칙에 해당 container포트, 즉 8080을 추가 안해줘서 생긴일이다.
'AWS' 카테고리의 다른 글
| [AWS] private subnet에서 ECR 접근할 때 필요한 VPC 설정 (0) | 2024.08.26 |
|---|---|
| [AWS] 아키텍쳐 구현(1) : HTTPS 및 로드밸런서 적용 (0) | 2024.08.09 |
| [AWS S3] Spring boot + AWS S3 를 이용한 파일 업로드 (0) | 2024.01.29 |