
본 블로그의 [AWS] EC2 Deployment with CodeDeploy + Github Actions (Single EC2 Instance) 글과 연계되며, 단일 EC2 인스턴스에 CodeDeploy를 적용하는 것을 응용하여 오토 스케일링이 적용된 아키텍처에 CodeDeploy를 적용하는 포스팅입니다.
개념 설명은 위 글에서 다루며, 본 포스팅에선 아키텍처를 구축하는 과정만 제공합니다.
작은 서버라면 단일 EC2 인스턴스에서 돌려도 괜찮겠지만 실제 서비스에선 오토스케일링이 핵심이다.
그러한 오토스케일링이 적용된 아키텍처에서도 당연히 CodeDeploy를 적용할 수 있는데, 저번에 단일 EC2 인스턴스엔 In Place 방식으로 간단히 진행해봤다면 이번엔 Blue/Green 배포 방식을 사용해볼 것이다.
초반 구축 과정과 AppSpec, 스크립트 등은 비슷하나 Blue/Green 방식이기 때문에 살짝의 차이는 있다.
소스 코드의 경우 전 포스팅과 구분하여 아래의 깃허브 레포지토리에 올려두었다.
https://github.com/eocndp/aws-codedeploy-example-asg

아키텍처는 위와 같다. CodeDeploy에 대한 큰 차이는 없고, 오토스케일링과 로드밸런싱이 적용됐다는 차이, 그리고 조금 더 응용되어 VPC 구성이 살짝 더 복잡해졌다는 점이다.
프라이빗 서브넷에 EC2를 올려두기 때문에 인터넷 엑세스를 위해선 NAT Gateway나 VPC 엔드포인트가 필요하다.
필자는 NAT Gateway를 사용할 것이고, 각 퍼블릭 서브넷에 NAT Gateway를 올려둬도 되지만 NAT Gateway 요금이 살짝 빡세기 때문에 하나만 만들고 라우팅 테이블을 고쳐 사용할 것이다.
그리고 앞서 설명했듯 배포 방식은 Blue/Green으로 사용하며, 이를 위해선 CodeDeploy 설정을 하기 전 로드밸런싱(ALB) 설정이 꼭 필요하다.
전 포스팅과 마찬가지로 서비스의 이름은 exam 접두사로 통일한다.
VPC를 만들고 아키텍처의 CIDR을 바탕으로 서브넷을 만든다. 참고로 프리티어에서 주로 사용하는 EC2 인스턴스 타입인 t2.micro는 ap-northeast-2a와 ap-northeast-2c AZ만 지원한다. 떄문에 a, c AZ를 선택해주었다.

잘 만들어졌다.
EC2와 CodeDeploy에 붙일 IAM을 먼저 만들어주는게 편한데, 전 포스팅에서 만들어둔 IAM이 있으므로 생략한다.
[AWS] EC2 Deployment with CodeDeploy + Github Actions (Single EC2 Instance) - IAM
다음으로 오토스케일링 그룹의 시작 템플릿에 적용할 AMI 이미지를 만들어보자. 먼저 EC2 하나를 생성한다. 원활한 진행을 위해 퍼블릭 서브넷에 배치하고 퍼블릭 IP 할당을 하자. 꼭 만들어둔 VPC에 생성하지 않아도 된다.
SSH로 접속한 다음 아래의 명령어를 통해 CodeDeploy와 NodeJS, NPM 등을 설치한다. (원활히 진행하기 위해 루트로 실행하는 것을 추천한다.)
sudo apt-get update
sudo apt-get install -y ruby wget nodejs npm
cd /home/ubuntu
wget https://aws-codedeploy-ap-northeast-2.s3.ap-northeast-2.amazonaws.com/latest/install
chmod +x ./install
sudo ./install auto
npm install -g pm2
설치가 되었다면 아래의 명령어로 잘 설치되었는지 확인해보자.
sudo service codedeploy-agent status
node -v
npm -v
pm2 -v

다음으로 이 EC2의 AMI를 만들자.

AMI를 생성하는 동안 추후 로그 확인이나 디버깅 등을 위해 Bastion Host를 하나 만들어두자. 물론 필수는 아니다.
Bastion Host에 대해선 블로그에서 다룬 글이 있으니 참고하길 바란다.

만들어둔 VPC의 퍼블릭 서브넷에 만들고 퍼블릭 IP를 할당한다.
그리고 SSH로 접속한 뒤 AMI를 만들때 생성하였던 키페어 파일을 옮겨놓도록 하자.



그리고 오토스케일링 그룹에 사용할 시작 템플릿을 만들어보자.


별다른 설정은 하지 않는다. 아래 고급 세부 정보에서 IAM 설정은 붙여주도록 하자.


다음으로 오토스케일링 그룹을 설정해보자.


그리고 로드밸런싱은 아직 만들지 않았으니 선택하진 않는다.

나머지는 그대로 냅두거나 적절하게 선택하고, ASG를 만들자.

만들면 새로운 인스턴스가 생성될 것이다.
다음으로 ALB 설정을 해보자. CodeDeploy에서 In Place 방식을 선택했다면 나중에 만들어도 되나 Blue/Green 방식을 선택하였기 때문에 미리 만들어둬야 한다.
먼저 대상 그룹을 하나 만들어주자.

그리고 ASG에 대상 그룹을 붙인다.

다음으로 ALB를 만들자.




이제 로드밸런서까지 만들어졌으나 Health Check에서 실패할 것이다. 당연히 아직 코드를 올리진 않았기 때문.

이제 CodeDeploy 세팅을 해보자.

애플리케이션을 만드는데 전 포스팅과 마찬가지로 EC2/온프레미스를 선택한다.
다음으로 배포 그룹을 만들고 IAM은 전에 만들어둔 IAM으로 연결해주자.

그리고 배포 방식은 Blue/Green 방식을 선택한다.

그리고 오토스케일링 그룹을 선택한다. 이러면 업데이트 시 오토스케일링 단위로 Blue, Green으로 나뉘고 업데이트되며 업데이트 후엔 자동으로 Green 쪽으로 트래픽이 전환된다.

로드밸런서의 대상 그룹도 선택해준다.
이 목차는 이전 포스팅의 내용과 똑같으므로 아래의 링크로 대체한다.
[AWS] EC2 Deployment with CodeDeploy + Github Actions (Single EC2 Instance) - IAM
하지만 약간 다른 점이 있다면 CodeDeploy Lifecycle 중 ApplicationStop은 Blue/Green 방식에선 필요하지 않고, 오히려 추후 롤백 시 문제가 생길 수 있으므로 빼는 것이 좋다.
애초에 Blue/Green 방식에선 설정한 시간이 지나면 인스턴스가 종료되기 때문에 빼도 된다.
이 목차도 이전 포스팅의 내용과 똑같으므로 아래의 링크로 대체한다.
[AWS] EC2 Deployment with CodeDeploy + Github Actions (Single EC2 Instance) - IAM
이제 깃허브에 Push하게 된다면 아래와 같이 Actions가 작동하면서 배포가 진행될 것이다.


CodeDeploy에서 그 과정을 확인할 수 있으며, 아래와 같이 인스턴스와 오토스케일링 그룹이 새롭게 만들어지는 것을 볼 수 있다. (In Place에선 볼 수 없음)


또한 CodeDeploy에서 Lifecycle 이벤트에 대한 과정도 볼 수 있으며, In Place에선 없던 AllowTraffic과 AfterAllowTraffic이 보이는 것을 볼 수 있다.



배포가 끝났다면 ALB의 DNS에 접속해보자.

잘 배포된 것을 볼 수 있다. 이제 자동화 배포 설정이 끝이 났다.

위와 같이 코드를 수정한 뒤 다시 Push해보자.

잘 작동하는 것을 볼 수 있다. 끝...

CodeDeploy에서 배포 시 위와 같은 에러가 발생할 수 있다.
해외 포럼을 찾아보니 관련 오류가 있는 듯 하다.
찾아보니 추가적인 IAM 정책이 필요하다고 한다. 아래와 같이 IAM 정책을 추가한뒤 다시 배포를 실행하면 잘 작동한다.



대충 보니 오래 전 부터 있던 오류같은데 왜 고쳐지지 않는지는 의문이다.
그리고 AllowTraffic이나 BlockTraffic 과정에서 무한 로딩이 걸려 넘어가지 않을 때가 있다. 그럴땐 원본 인스턴스나 새롭게 생성된 인스턴스가 Health한지 체크해보도록 하자.
ALB 대상 그룹에서 Health하지 않으면 무한로딩이 되는 듯 싶다. 특히 필자는 테스트로 서버에서 3000번 포트로 열었기 때문에 대상 그룹에서 3000번 포트로 설정되어 있는지 체크해보자.