무중단 배포 삽질 (ASG + ALB + CodeDeploy + BlueGreen + EC2 + GithubAction)

공부는 혼자하는 거·2023년 11월 6일
0

환경

목록 보기
20/23

VPC + Subnet + EC2 생성

기본적으로 VPC + Subnet + Domain 설정이 완료되어있다고 가정하겠다. 어플리케이션을 EC2 인스턴스 위에 배포한 상태로 가정하고 진행하겠다. 인스턴스는 Private Subnet 에 위치하므로, IG를 가지고 있지 않다. 별도의 ALB를 이용해서 연결해주도록 하자. 주의할 점은 나중에 이 인스턴스에 CodeDeploy Agent를 설치한 후 이미지를 ASG 용도로 따줄 건데, Private Subnet에 위치하므로 외부에서 패키지를 땡겨올 수 있도록 Nat GateWay를 따로 만들어서 연결지어주자. 이 모든 자세한 과정은 알아서 검색해서 하도록 하자.

나중에 CodeDeploy Agent 로그에서 Error validating the SSL configuration: Invalid server certificate 이 발생하면 NAT GW 이 내가 배포한 서브넷에 잘 연결되었는지 확인하자.

ALB + Route53 생성

Target Group 생성

로드 밸런서를 만들기 전에 내 인스턴스의 어플리케이션으로 호스팅하는 대상그룹을 하나 만들어둔다. 당연히 인스턴스의 보안그룹에는 포트를 열어놔야겠지? 굳이 이런 거 설명 자세히 안 하겠다. 프로토콜은 HTTP로

ALB 생성

어플리케이션 로드 밸런서 생성해준다. VPC, 서브넷, 보안그룹, 미리 만들어둔 TargetGroup 를 연결해주자. 만약 ACM 인증서를 발급받았다면, HTTPS 리스너도 추가하여 주자.

미리 구매한 도메인을 기반으로 서브 도메인을 생성해서 ALB에게 호스트 도메인으로 라우팅해주겠다는 규칙을 만들자.

Route53 + ALB 설정

지정해둔 도메인 주소로 이동하게끔 셋팅

테스트해서, api 가 잘 나오는지 확인해보자.

IAM 역할 생성

여기부터 약간 삽질한 구석이 있는데, 기본적으로 EC2, CodeDeploy, Github Action용 각각 IAM 롤을 구성한다.

EC2

CodeDeploy

Github Action Ttigger 용도

AutoScalling inline 정책

{
	"Version": "2012-10-17",
	"Statement": [
		{
			"Sid": "VisualEditor0",
			"Effect": "Allow",
			"Action": [
				"iam:PassRole",
				"ec2:CreateTags",
				"ec2:RunInstances"
			],
			"Resource": "*"
		}
	]
}

ASG 시작 템플릿 생성

AMI 생성

어플리케이션을 배포한 인스턴스의 이미지를 따주자.

EC2 인스턴스 중지 없이 AMI를 생성하도록 체크

템플릿 구성

만들어둔 AMI, 키 페어, 보안그룹을 선택하고 진행한다. 유의사항으로는 이미 CodeDeploy Agent 를 설치한 상태에서 AMI 를 딴 게 아니라면, 아래와 같은 실행스크립트를 구성하고, 기존에 EC2 용도로 만들어둔 IAM 프로파일을 선택해주자.

ASG 그룹 생성

만들어둔 템플릿을 기반으로 ASG 그룹을 만들자. 만들면 자동으로 실행된다. 여기서 SubNet을 할당하고, 기존 타겟 그룹을 연결해주면 된다.

Name TAG를 추가해, 인스턴스 이름을 지정해주도록 하자.

CodeDeploy + S3 생성

이쯤오면 반은 왔다.. CodeDeploy 와, 배포용 압축파일이 올라갈 S3를 생성해주자.

CodeDeploy 배포그룹 생성

원본 인스턴스는 종료되기까지 1시간을 대기하도록 셋팅했다.

S3 Bucket 생성

만든 버킷에 프로젝트명으로 폴더 하나 생성해두자.

GitHub Action

액션용으로 만든 IAM 사용자 ACCESSKEY와 SecretKey

# workflow의 이름
name: codeDeploy-BlueGreen workflow
 
on:
  workflow_dispatch:   # manullay trigger
    inputs:
      BRANCH:
        description: 'Branch to use'
        required: true
        default: 'prod'
        type: choice
        options:
        - prod

 
permissions:
  contents: read

env:
 BRANCH_NAME: ${{ github.head_ref || github.ref_name }}
 
jobs:
  build:  # build job
    runs-on: [self-hosted, macOS, ARM64, kang]
    steps:
      - uses: actions/checkout@v3
        with:
          #ref: ${{ github.event.inputs.target-branch }}  
          ref: ${{ inputs.branch }}  # 내가 선택한 브랜치로 체크아웃

          
      - name: Set up JDK 17
        uses: actions/setup-java@v3
        with:
          distribution: 'corretto'
          java-version: '17'
          
      - name: Build with Gradle
        run: ./gradlew clean build -x test  
        shell: bash

      - name: Make Directory
        run: mkdir dist

      - name: Move Jar
        run: mv ./build/libs/*.jar ./dist/application.jar

      - name: Move CodeDeploy Script
        run: mv ./scripts/* ./dist/

      - name: make zip
        run: zip -r ./$GITHUB_SHA.zip ./dist
        shell: bash
    
      - 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: ap-northeast-2

      - name: Upload to S3
        run: |
          aws s3 cp \
          --region ap-northeast-2 \
          --acl private \
          ./$GITHUB_SHA.zip \
          s3://deploy-action-s3/프로젝트명/$GITHUB_SHA.zip  \
          
        
      - name: Call CodeDeploy
        run: |
          aws deploy create-deployment \
          --application-name 어플리케이션이름 \
          --deployment-group-name 어플리케이션그룹이름 \
          --region ap-northeast-2 \
          --s3-location bucket=deploy-action-s3,bundleType=zip,key=프로젝트명/$GITHUB_SHA.zip \
  • name: Move CodeDeploy Script

이게 중요한 부분이다. 어플리케이션 프로젝트로 최상단 경로에 scripts 폴더를 만들어서, 관련 스크립트를 집어넣자.

deploy-prod.sh

최적화


돌아보면 별 거 아닌데, 삽질 많이 했다.. 나중에 추가설명 쓸 수 있으면 보강..

참고

https://ballenabox.tistory.com/223
https://keencho.github.io/posts/aws-cicd-6/
https://velog.io/@bona/Trouble-Shooting-CodeDeploy-UnknownError

profile
시간대비효율

0개의 댓글