//
Search
Duplicate
🥉

Gitlab CI and AWS CodeDeploy

말로만 듣던 CI/CD를 직접 구축해 볼 기회가 있어서 작성하게 되었습니다. 대부분 블로그 내용을 보면 꽤 오래 걸렸다는 내용이 있는데 간과했습니다. 실제로 해보니 생각보다 Detail 한 부분까지 챙겨서 구축하지 않는다면 에러는 쉽게 잡을 수 없다는 것을 알게 되었습니다. 우선 많이 사용하고 있는 GitHub이 아니라 Gitlab을 CI로 사용하고 있었기 때문에 CodeDeploy에서 Direct 연결이 불가하고 Gitlab에서 S3 Bucket으로 tar, zip 등 파일을 Upload 하는 형태로 제공을 해줘야 CodeDeploy에서 가져갈 수 있습니다.
우선 Gitlab 내용을 간략하게 정리했습니다. Gitlab에 있는 CI/CD 기능을 구현할 때 .gitlab-ci.yml 파일을 작성해야 하는데 크게 3단계로 작성 했습니다. - image - variables - script image는 banst/awscli 사용했는데 그 이유는 Gitlab -> S3로 Upload 할 때 awscli 명령을 통해서 진행하기 때문입니다. variables는 AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, S3_BUCKET 항목을 설정했는데 이는 Gitlab -> Settings -> CI/CD -> Variables에도 설정을 했습니다. script는 명령어 형태로 작성이 가능하기 때문에 source를 압축 또는 아카이빙 해서 S3에 Upload 준비가 되어 있어야 하기 때문에 아래의 명령어 형태로 작성을 했습니다. 그리고 aws 명령어를 통해서 S3 버킷으로 올려줍니다. - tar cvf source.tar . - aws s3 cp source.tar s3://$S3_BUCKET/ // aws s3 sync . s3://$S3_BUCKET/ 방식을 처음에 이용했으나 CodeDeploy에서 tar, zip // 파일 형태만 가능해서 변경했습니다.
구성하는 단계는 아래와 같습니다. - EC2 IAM 생성 - CodeDeploy IAM 생성 - CodeDeploy Application 생성 - CodeDeploy Agent 설치 - Deploy 서버 설정 - CodeDeploy 배포 설정 - CodePipeLine을 통한 자동화
EC2 IAM 생성 - 역할 - 역할 만들기를 선택해서 EC2에 할당하는 역할을 생성합니다.
신뢰할 수 있는 엔터티 선택에서 AWS 서비스를 선택하고 일반 사용 사례에서 EC2를 선택합니다.
정책 필터 검색창에서 아래의 정책을 선택 후 다음으로 넘어갑니다. - AmazonS3FullAccess - AWSCodeDeployFullAccess - AWSCodeDeployRole 역할 세부 정보에 역할 이름을 작성하고 2단계 권한 추가에는 앞서 추가한 정책들이 들어가 있는 것을 확인할 수 있습니다.
그리고 생성한 역할을 EC2에 적용하기 위해서 배포할 개발 서버를 선택하고 작업 - 보안 - IAM 역할 수정을 선택하면 앞서 생성한 역할을 선택하고 Update IAM Role 버튼으로 적용할 수 있습니다.
CodeDeploy IAM 생성 다시 IAM - 역할 - 역할 만들기를 눌러서 다른 AWS 서비스의 사용 사례:에서 CodeDeploy 검색을 합니다. 그리고 CodeDeploy를 선택하고 다음으로 넘어갑니다.
권한 정책은 이미 AWSCodeDeployRole이 들어가 있기 때문에 수정하지 않고 다음으로 넘어갑니다. 위 EC2에 역할을 생성할 때와 마찬가지로 역할 이름, 설명, 권한 부분이 잘 들어가 있는지 확인하고 역할 생성을 해주면 됩니다.
CodeDeploy Application 생성 소스 - 빌드 - 배포 이것들을 하나로 묶어서 구성할 수 있는 파이프라인입니다. 저는 소스, 빌드는 AWS를 통해서 하지 않고 배포와 파이프라인 기능을 사용해서 구성했습니다.
CodeDeploy를 이용한 배포 방법은 Application 생성 - 배포 그룹 생성 - 배포 이렇게 진행이 되기 때문에 Application 생성을 먼저 진행하도록 합니다.
Application 이름을 작성하고 컴퓨팅 플랫폼에서는 배포 대상 서버가 EC2 또는 물리적인 온프레미스인 경우 선택해서 Application 생성을 합니다.
CodeDeploy Agent 설치 agent를 설치하기 위해서 배포 대상 서버에 접속하고 awscli 명령어를 설치합니다. 설치 방식은 ubuntu, amazon linux OS마다 다르니 아래 링크에서 확인해야 합니다. https://docs.aws.amazon.com/ko_kr/cli/v1/userguide/install-linux-al2017.html $ sudo yum install awscli $ sudo aws configure - AWS Access Key ID : <입력> - AWS Secret Access Key : <입력> - Default region name : ap-norteast-2 - Default output format : 이제 agent를 설치해야 합니다. $ wget https://bucket-name.s3.region-identifier.amazonaws.com/latest/install 여기서 bucket-name 부분은 해당 리전의 CodeDeploy 리소스 키트 파일이 포함되어 있는 Amazon S3 버킷의 이름으로 바꾸면 되는데 예를 들면 서울 리전의 경우는 aws-codedeploy-ap-northeast-2 내용을 사용하면 됩니다. 리전별 리소스 키트 버킷 이름은 아래 링크에서 확인할 수 있습니다. https://docs.aws.amazon.com/ko_kr/codedeploy/latest/userguide/resource-kit.html#resource-kit-bucket-names $ wget https://aws-codedeploy-ap-northeast-2.s3.amazonaws.com/latest/install $ chmod +x ./install $ sudo yum install ruby // OS에서 ruby 패키지가 설치 안되어 있으면 install 에러 발생합니다. $ sudo ./install auto //auto를 사용하면 최신 버전의 CodeDeploy Agent를 설치합니다. $ sudo systemctl status codedeploy-agent // agent 상태가 정상적으로 기동되었는지 확인합니다.
Deploy 서버 설정 배포할 서버 설정이라는 것은 배포할 서버 내에 루트 경로에 appspec.yml 파일을 추가해야 하는데 이 파일은 gitlab에서 배포할 브랜치에 appspec.yml 파일을 작성하고 S3로 올려도 됩니다. 내용을 보면 version, os 항목은 고정 값이며 주의할 점은 공백입니다. CodeDeploy에서 권장하는 공백을 사용하지 않을 경우 Debuging이 어려운 에러를 마주할 수 있으니 주의해야 합니다. version: 0.0 os: linux files: - source: / destination: /home/ec2-user/deploy-server overwrite: yes permissions: - object: /home/ec2-user/deploy-server owner: ec2-user mode: 755 hooks: ApplicationStop: - location: scripts/stop.sh timeout: 60 // 60초 안에 실행이 끝나지 않으면 실패합니다 runas: root //root 권한인 이유는 codedeploy-agent 실행된 권한이 root이기 때문입니다. ApplicationStart: - location: scripts/start.sh timeout: 300 /* 60초보다 길게 설정한 이유는 실행 시 추가 모듈을 외부에서 설치하는 경우가 있어서 runas: root 설치 시간이 필요하기 때문에 300초로 지정했습니다. */ * 공백 참고 예제 ([1] : 한칸, [2] : 두칸, [3] : 세칸, [4] : 네칸) * version:[1]version-number os:[1]operating-system-name files: [2]-[1]source:[1]source-files-location [4]destination:[1]destination-files-location permissions: [2]-[1]object:[1]object-specification [4]owner:[1]owner-account-name [4]mode:[1]mode-specification hooks: [4]-[1]location:[1]script-location [6]timeout:[1]timeout-in-seconds [6]runas:[1]user-name
CodeDeploy 배포 설정 이제 EC2와 CodeDeploy 연동을 하면 마무리가 됩니다. application 생성 - 배포 그룹 생성을 하면 되는데요. 아래 내용을 작성해야 합니다. - 배포 그룹 이름 : imsi-deploy - 서비스 역할 : 생성한 IAM Role - 배포 유형 : 현재 위치(Default) - 환경 구성 : Amazon EC2 인스턴스 (Tag 기반) - 배포 설정 : CodeDeployDefault.AllAtOnce - 로드 밸런서 : 로드 밸런싱 비활성화 (체크 해제)
EC2 배포 구성에는 3가지 선택이 있습니다. - CodeDeployDefault.AllAtOnce : 한 번에 가급적 많은 수의 EC2에 Application 개정을 배포 - CodeDeployDefault.HalfAtTime : 최대 절반의 EC2에 한번에 배포 - CodeDeployDefault.OneAtTime : 한 번에 한 EC2에만 Application 개정을 배포
이제 배포 생성을 해야 합니다. 배포 생성 단계에서는 배포 그룹, 배포 유형, 개정 위치, 추가 배포 동작 설정하고 배포를 만들면 배포가 진행되며 성공/실패 여부에 대한 log를 확인할 수 있습니다. 물론 log는 배포 서버 내에서도 확인이 가능 합니다.
최종 배포 만들기 진행하시면 성공/실패 여부를 확인할 수 있는 페이지를 확인할 수 있습니다.
콘솔에서 확인할 수 있는 log들은 배포 대상 서버에서 확인할 수 있는데 아래 경로에 위치합니다. /var/log/aws/codedeploy-agent/ 밑에 codedeploy-agent.log 이름으로 되어 있습니다. 배포에 성공하면 아래의 경로와 비슷한 경로에 배포 파일이 존재한다. /opt/codedeploy-agent/deployment-root/bf05f088-3283-4d87-a197-e1993abca82c/d-CPDCE21AH 위 경로에는 codedeploy-agent가 배포에 성공한 파일을 보관하고 있기 때문에 향후 용량에 문제가 생길 수 있습니다. 그래서 max_revisions 파라미터 설정을 해야 합니다. max_revisions 값을 설정하게 되면 지정된 수를 초과하는 수정 버전은 모두 삭제됩니다.
/etc/codedeploy-agent/conf 경로에 codedeployagent.yml 파일에 내용은 아래와 같습니다. --- :log_aws_wire: false :log_dir: '/var/log/aws/codedeploy-agent/' :pid_dir: '/opt/codedeploy-agent/state/.pid/' :program_name: codedeploy-agent :root_dir: '/opt/codedeploy-agent/deployment-root' :verbose: false :wait_between_runs: 1 :proxy_uri: :max_revisions: 5
// 최근에 배포된 내용을 5개까지 보관할 수 있습니다. 값을 2로 변경하면 2개만 보관하게 됩니다.
만약 다른 EC2로 옮기게 되는 경우에는 userData script에서 아래 구문을 작성해서 조정할 수 있습니다. sed -i 's/:max_revisions: 5/:max_revisions: 2/' /etc/codedeploy-agent/conf/codedeployagent.yml