기본적으로 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 이 내가 배포한 서브넷에 잘 연결되었는지 확인하자.
로드 밸런서를 만들기 전에 내 인스턴스의 어플리케이션으로 호스팅하는 대상그룹을 하나 만들어둔다. 당연히 인스턴스의 보안그룹에는 포트를 열어놔야겠지? 굳이 이런 거 설명 자세히 안 하겠다. 프로토콜은 HTTP로
어플리케이션 로드 밸런서 생성해준다. VPC, 서브넷, 보안그룹, 미리 만들어둔 TargetGroup 를 연결해주자. 만약 ACM 인증서를 발급받았다면, HTTPS 리스너도 추가하여 주자.
미리 구매한 도메인을 기반으로 서브 도메인을 생성해서 ALB에게 호스트 도메인으로 라우팅해주겠다는 규칙을 만들자.
지정해둔 도메인 주소로 이동하게끔 셋팅
테스트해서, api 가 잘 나오는지 확인해보자.
여기부터 약간 삽질한 구석이 있는데, 기본적으로 EC2, CodeDeploy, Github Action용 각각 IAM 롤을 구성한다.
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "VisualEditor0",
"Effect": "Allow",
"Action": [
"iam:PassRole",
"ec2:CreateTags",
"ec2:RunInstances"
],
"Resource": "*"
}
]
}
어플리케이션을 배포한 인스턴스의 이미지를 따주자.
EC2 인스턴스 중지 없이 AMI를 생성하도록 체크
만들어둔 AMI, 키 페어, 보안그룹을 선택하고 진행한다. 유의사항으로는 이미 CodeDeploy Agent 를 설치한 상태에서 AMI 를 딴 게 아니라면, 아래와 같은 실행스크립트를 구성하고, 기존에 EC2 용도로 만들어둔 IAM 프로파일을 선택해주자.
만들어둔 템플릿을 기반으로 ASG 그룹을 만들자. 만들면 자동으로 실행된다. 여기서 SubNet을 할당하고, 기존 타겟 그룹을 연결해주면 된다.
Name TAG를 추가해, 인스턴스 이름을 지정해주도록 하자.
이쯤오면 반은 왔다.. CodeDeploy 와, 배포용 압축파일이 올라갈 S3를 생성해주자.
원본 인스턴스는 종료되기까지 1시간을 대기하도록 셋팅했다.
만든 버킷에 프로젝트명으로 폴더 하나 생성해두자.
액션용으로 만든 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 \
이게 중요한 부분이다. 어플리케이션 프로젝트로 최상단 경로에 scripts 폴더를 만들어서, 관련 스크립트를 집어넣자.
돌아보면 별 거 아닌데, 삽질 많이 했다.. 나중에 추가설명 쓸 수 있으면 보강..
https://ballenabox.tistory.com/223
https://keencho.github.io/posts/aws-cicd-6/
https://velog.io/@bona/Trouble-Shooting-CodeDeploy-UnknownError