본문 바로가기
AWS

AWS CodeDeploy 실습 중 이모저모

by ballena 2022. 10. 25.

Github Action + CodeDeploy 구성 진행 간 참고한 블로그.

이런 쪽으로는 생각보다 자료가 별로 없었다.

내가 작성한 내용은 실습 진행 간 발생한 의문이나 문제 해결 등에 초점을 맞췄고, 실제로 구성을 어떻게 하느냐는 이분들 글을 참고하는 것이 나을 것이다.

더보기

일단 상황 설명.

Github Action과 CodeDeploy를 연동하는 과정이다.

정확히는 Github Action -> S3 -> CodeDeploy -> 배포 대상(EC2/ECS 등)으로 이루어진 구성이다.

흐름은 다음과 같다.

1. Github Action에서 빌드가 끝난 파일을 압축해 S3로 넘긴다.

2. Github Action의 deploy.yml 파일에 근거해 배포에 관련된 대부분의 정보가 설정된다.
   - CodeDeploy가 어떤 S3를 찾아가서 어떤 배포 파일을 어떤 배포 그룹에 뿌릴 것인지
   - 배포 시 어떻게 배포할 것인지 : 한 번에 전부/한 번에 하나씩 등

   - 각 배포 단계(AllowTraffic, BlockTraffic 등)의 Timeout 값 설정

   - S3에서 끌어온 빌드된 파일을 배포 대상에 뿌리고, 그 파일을 서버 내에서 어떻게 작업할 것인지(.sh 스크립트)

3. CodeDeploy에서 위와 같은 작업들을 지정된 단계에 따라 수행하며 성공/실패 여부를 나타낸다.

    (실패 시 설정에 따라 롤백될 수 있다)

4. 배포 대상으로 뿌려진 압축된 파일 묶음(Bundle)은 묶음 안의 appspec.yml 파일에 설정에 따라 설치된다.

 

쭉 보면 알겠지만 CodeDeploy가 주체적으로 뭘 시작하는 모양새는 아니다.

트리거는 Github Action 측에서 당기고, CodeDeploy는 당겨진 트리거에 따라 다음 동작을 실행할 뿐이다.


아래 케이스들은 Github Action + CodeDeploy + Auto Scaling(EC2) 구성을 진행하던 중 발생한 문제들이다.

 

1. 배포 유형을 블루/그린으로 선택하고 배포하면 권한 문제 발생

더보기

CodeDeploy가 AWS 리소스에 접근 가능하도록 하려면 AWS 관리형 정책 AWSCodeDeployRole만 주면 된다.

하지만 배포 유형을 블루/그린으로 설정했다면 추가 권한을 줘야 한다.

인라인 정책으로 

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

위 정책을 추가했다.

 

 

2. 블루/그린 배포 시  Auto Scaling Group 찌꺼기 문제

더보기

배포 대상이 AutoScaling Group인 경우 신 버전(그린) ASG를 생성하고, 구 버전(블루) ASG를 버리게 되는데... 당연하겠지만 구 버전의 ASG는 삭제되지 않고 남아있다. 블루/그린 배포의 장점 중 하나가 롤백이 가능하다는 점이니까. 

일반적으로 CodeDeploy에서 롤백 설정을 활성화하고 배포에 실패하면 마지막으로 성공한 배포로 롤백된다.

블루/그린 배포일 경우 이전 ASG가 남아 있으니 그리로 롤백되겠지.

 

※ ASG를 신규 생성하는 것이지 대상 그룹은 그대로다.

 

그렇다면 이전 ASG들은 언제 삭제되는가? 딱히 설정 부분에서 이 찌꺼기들을 삭제하는 설정은 보이지 않았다.

별도의 프로세스를 개발하거나, 수동으로 삭제하는 수밖에 없는 것 같다.

 

 

3. 배포 중 대상 그룹의 Health Check 문제 : AllowTraffic

더보기

ELB에 연결된 배포 대상이라면 대상 그룹 내에 위치해 Health Check를 받고 있을 것이다.

배포 시작 및 배포 단계에서는 Health Chcek가 Unhealthy로 떠도 상관없으나, AllowTraffic 단계에서는 Healthy가 떠야 한다고 한다.

 

 

4. 배포 실패 후 로그 보기

더보기

배포 실패 후 배포 대상이 남아 있다면, 접속해서 CodeDeploy Agent의 로그를 볼 수 있다.

로그 경로는 /var/log/aws/codedeploy-agent/ 다.

 

CloudWatch에서도 볼 수 있다.

https://aws.amazon.com/ko/blogs/devops/view-aws-codedeploy-logs-in-amazon-cloudwatch-console/

 

View AWS CodeDeploy logs in Amazon CloudWatch console | Amazon Web Services

AWS CodeDeploy helps users deploy software to a fleet of Amazon EC2 or on-premises instances. The AWS CodeDeploy agent must be installed and configured on those instances in order for them to be used in a deployment. The agent generates three log files: Ag

aws.amazon.com

 

배포에 실패하면 자꾸 인스턴스가 삭제되길래 EC2 하나를 그냥 종료 방지 설정을 걸어버렸다.

효과가 있었는지는 모르겠다.

 

 

5. 배포 실패 시 Rollback 문제

더보기

롤백 설정을 활성화했다는 가정 하에, 배포 실패 시 마지막으로 성공한 배포로 롤백된다.

그렇다면 이런 상황에서는 어떻게 될까?

 

(1) 배포에 성공

(2) 배포 그룹의 설정을 수정

(3) 다시 배포. 그리고 배포 실패

 

이 경우, 배포 그룹을 수정했다고 해서 성공했던 이전 배포를 별개로 분리해서 생각할 것인가?

아니면 설정 수정 여부와 관계없이 똑같이 롤백될 것인가?

 

요약하자면 배포 그룹을 나무라고 생각한다면, 설정을 수정함에 따라 잔가지가 갈라져 나와 다른 배포 그룹으로 취급되는 것인지 궁금했다.

 

AWS Support에 문의한 결과 아니라고 한다. 배포 그룹의 설정을 수정한다고 해서 이전 배포를 다른 배포 그룹으로 취급해 롤백이 안 되는 경우는 없다고 한다.

 

 

6. 배포 실패 시 인스턴스 삭제 문제 + Rollback 실패 문제

더보기

가장 혼란스러웠던 문제. 배포 실패 후 배포를 시도했던 인스턴스들이 삭제되었다.

그리고 롤백 작업도 실패했다. 이후 해당 Auto Scaling group은 그냥 비어 있는 상태로 있다.

인스턴스 새로고침 등을 실행해도 새로운 인스턴스가 올라오지도 않았다.

 

(1) 일단 배포 실패 시 인스턴스가 삭제되는 것은 정상이라고 한다.

CodeDeploy Routine

   대충 이런 방식으로 루틴이 굴러간다고 한다.

   인스턴스가 삭제되는 것은 배포 단계 중 수명 주기 훅(appspec.yml의 hooks 부분)의 설정에 따른 것이다.

   이 설정은 CONTINUE/ABANDON 2가지로 나뉘는데, 성공 시에는 CONTINUE, 실패 시에는 ABANDON이다.

   CONTINUE는 다음 작업으로 계속 진행한다는 것이고, ABANDON은 버린다는 의미(= 삭제).

   이 설정은 수정 불가.

 

   Auto Scaling 정보를 보며 훅을 만들면 어떨까, 라는 생각을 했는데 무의미한 짓이다.

   배포 중 수명 주기 훅은 올라왔다 내려갔다를 반복하니 만들어 두는 의미가 없다.

 

(2) 롤백 실패

   (1)은 어찌어찌 납득했다. 그런데 정작 롤백해서 새로운 인스턴스가 올라와야 했는데... 이것도 실패했다.

   이 문제가 특정 상황에서만 벌어진 거라 정확한 원인을 찾지는 못했다.

   롤백 배포 시에도 AllowTraffic HealthCheck를 통과해야 하고, 이것저것 배포 성공을 위한 조건을 동일하게
   만족해야 하기 때문이다.

 

   일단은 당시 상황이 문제였다고 생각하고 있다. 애초에 이전 배포도 엉망이었으면 롤백을 해도 엉망일테니...

   첫 배포에서 실패 시 시작 템플릿을 기반으로 롤백될 것이라고 생각했는데, 아닌 것 같다.

 

 

7. Volume 부족 문제

더보기

배포를 반복하던 중 EBS 용량이 모자라다는 에러 발생(대충 space 어쩌고).

 

멀쩡히 잘 배포되다 갑자기 이러는 이유는 이전 배포 패키지들이 대상 인스턴스에 저장되기 때문이다.

 

이 설정을 지정하는 값이 max_revision 값인데, 기본값이 5다. 이전 5개 배포를 로컬에 저장해 놓고 있다는 것.

 

/etc/codedeploy-agent/conf/codedeployagent.yml에서 max_revisions를 2로 수정 후 codedeploy-agent 재실행

 

굳이 이전 배포들을 손수 삭제할 필요 없이 저 설정만 수정해 주면 알아서 삭제된다고 한다.

 

 

8. 기타 CodeDeploy 이슈

더보기

자잘한 문제들도 있었다. Human Error가 아닌 CodeDeploy 자체 문제.

 

(1) CodeDeploy Agent가 Ruby 3.0을 지원하지 않음

   Github Issue탭을 보니 과거에는 이 문제로 한창 시끄러웠던 것 같다.

   지금이야 그냥 Ruby 2.x를 설치한 후 해당 버전으로 고정시키는 방법으로 해결하는 것 같다.

 

(2) 배포 단계별 script 실행 시 권한 문제

   Appspec.yml에서 각종 script 실행 시 사용자 지정 문제. 

   script를 실행하는 사용자는 root로 해놓고 script 내의 명령어에서 sudo를 붙이면 권한이 뒤집혀서 일반 사용자로
   실행된다고 한다. 

   그러니 root로 설정했으면 script 내의 명령어들은 sudo를 뺄 것.

 

   또한 script 파일의 권한 문제도 있다. script를 읽어서 실행하기에 711이 아니라 755로 해야 하는 것으로 보인다.

 

(3) script의 특정 명령어가 실행되지 않음

   이건 CodeDeploy의 문제라기보단 TroubleShooting의 영역이다.

   해당 script에 결과를 확인할 수 있는 다른 명령어를 추가해 해당 명령어 문제인지, script 문제인지 확인이 필요하다

 

(4) 배포 실패 후 에러 로그가 뜨지 않음

The deployment failed because no instances were found for your deployment group. 
Check your deployment group settings to make sure the tags for your Amazon EC2 instances or Auto Scaling groups correctly identify the instances you want to deploy to, and then try again.

   

   배포 실패 후 콘솔에 어떤 에러가 떠있는지 보려고 갔는데 이런 꼴이었다.

   배포 실패 후 배포 대상(인스턴스)가 삭제되어서 사라진 것.

   그래서 에러 내역이 발생 직후에는 보였는데 배포 대상이 사라진 후에는 위 에러로 바뀐다.

   해결 방법? 모르겠다. 조치를 취해 놓은 후에는 무슨 이유에선지 인스턴스들이 배포 실패해도 삭제가 안되더라.

 

 

CI/CD 분야도 파고들수록 어렵다.

deploy.yml 파일이나 Appspec.yml에 연동되는 script들을 보면 단순히 CI/CD 프로세스를 이해하는 것 뿐만 아니라

스크립트 작성/명령어 작성 등의 기본기도 중요하다고 생각된다.

Git 세트(Git, Github, Github Action)의 사용법도 당연히 익혀야 하고...

댓글