GitLab CI/CD에서 AWS로 배포하기
GitLab CI/CD에서 AWS로 배포하기
GitLab은 AWS로 배포하는 데 필요한 라이브러리와 도구가 담긴 Docker 이미지를 제공해요. 이 이미지들을 CI/CD 파이프라인에서 참조하면 aws 명령어를 잡 안에서 바로 쓸 수 있습니다. GitLab.com에서 Amazon ECS로 배포한다면 별도의 ECS 배포 가이드도 함께 보세요.
출처: 문서
본문
GitLab은 AWS로 배포하는 데 필요한 라이브러리와 도구가 포함된 Docker 이미지를 제공합니다. CI/CD 파이프라인에서 이 이미지들을 참조할 수 있어요.
GitLab.com을 사용하면서 Amazon Elastic Container Service(ECS)로 배포한다면 ECS로 배포하기 문서를 읽어 보세요.
직접 배포를 구성하는 데 익숙하고 AWS 자격 증명만 얻으면 된다면 ID 토큰과 OpenID Connect를 고려해 보세요. ID 토큰은 CI/CD 변수에 자격 증명을 저장하는 것보다 더 안전하지만, 이 페이지의 안내와는 함께 동작하지 않습니다.
GitLab과 AWS 인증
GitLab CI/CD로 AWS에 연결하려면 인증이 필요합니다. 인증을 설정한 후에 CI/CD가 배포하도록 구성할 수 있어요.
- AWS 계정에 로그인합니다.
- IAM 사용자를 만듭니다.
- 사용자를 선택해 세부 정보에 접근합니다. Security credentials > Create a new access key로 이동하세요.
- Access key ID와 Secret access key를 적어 둡니다.
- GitLab 프로젝트에서 Settings > CI/CD로 이동합니다. 다음 CI/CD 변수를 설정하세요.
| 환경 변수 이름 | 값 |
|---|---|
AWS_ACCESS_KEY_ID |
접근 키 ID. |
AWS_SECRET_ACCESS_KEY |
시크릿 접근 키. |
AWS_DEFAULT_REGION |
리전 코드. 사용하려는 AWS 서비스가 선택한 리전에서 사용 가능한지 확인해 두는 게 좋아요. |
- 변수는 기본적으로 보호됩니다. 보호되지 않은 브랜치나 태그에서 GitLab CI/CD를 사용하려면 Protect variable 체크박스를 해제하세요.
이미지로 AWS 명령어 실행하기
이미지에 AWS Command Line Interface가 포함되어 있다면, 프로젝트의 .gitlab-ci.yml 파일에서 그 이미지를 참조할 수 있어요. 그러면 CI/CD 잡에서 aws 명령어를 실행할 수 있습니다.
예를 들어:
deploy:
stage: deploy
image: registry.gitlab.com/gitlab-org/cloud-deploy/aws-base:latest
script:
- aws s3 ...
- aws create-deployment ...
environment: production
GitLab은 AWS CLI를 포함하는 Docker 이미지를 제공합니다.
- 이미지는 GitLab 컨테이너 레지스트리에 호스팅됩니다. 최신 이미지는
registry.gitlab.com/gitlab-org/cloud-deploy/aws-base:latest입니다. - 이미지는 GitLab 저장소에 저장됩니다.
대신 Amazon Elastic Container Registry(ECR) 이미지를 사용할 수도 있어요. 이미지를 ECR 저장소에 푸시하는 방법을 참고하세요.
서드파티 레지스트리의 이미지도 사용할 수 있습니다.
애플리케이션을 ECS에 배포하기
Amazon ECS 클러스터에 애플리케이션 배포를 자동화할 수 있습니다.
전제 조건:
- AWS를 GitLab과 인증합니다.
- Amazon ECS에 클러스터를 만듭니다.
- ECS 서비스나 Amazon RDS의 데이터베이스 같은 관련 구성 요소를 만듭니다.
containerDefinitions[].name속성 값이 대상 ECS 서비스에 정의된Container name과 같은 ECS 태스크 정의를 만듭니다. 태스크 정의는 다음과 같을 수 있습니다. ECS의 기존 태스크 정의. 또는 GitLab 프로젝트의 JSON 파일. AWS 문서의 템플릿을 사용해 파일을 프로젝트에 저장하세요. 예:<project-root>/ci/aws/task-definition.json.
ECS 클러스터에 배포하려면:
- GitLab 프로젝트에서 Settings > CI/CD로 이동합니다. 다음 CI/CD 변수를 설정하세요. 이 이름들은 Amazon ECS 대시보드에서 대상 클러스터를 선택하면 찾을 수 있어요.
| 환경 변수 이름 | 값 |
|---|---|
CI_AWS_ECS_CLUSTER |
배포 대상으로 삼는 AWS ECS 클러스터의 이름. |
CI_AWS_ECS_SERVICE |
AWS ECS 클러스터에 연결된 대상 서비스의 이름. 이 변수가 적절한 환경(production, staging, review/*)으로 범위 지정되어 있는지 확인하세요. |
CI_AWS_ECS_TASK_DEFINITION |
태스크 정의가 ECS에 있다면, 서비스에 연결된 태스크 정의의 이름. |
CI_AWS_ECS_TASK_DEFINITION_FILE |
태스크 정의가 GitLab의 JSON 파일이라면 경로를 포함한 파일명. 예: ci/aws/my_task_definition.json. JSON 파일의 태스크 정의 이름이 ECS의 기존 태스크 정의 이름과 같으면 CI/CD 실행 시 새 리비전이 만들어집니다. 그렇지 않으면 리비전 1부터 시작하는 완전히 새로운 태스크 정의가 생성됩니다. CI_AWS_ECS_TASK_DEFINITION_FILE과 CI_AWS_ECS_TASK_DEFINITION을 둘 다 정의하면 CI_AWS_ECS_TASK_DEFINITION_FILE이 우선합니다. |
.gitlab-ci.yml에 이 템플릿을 포함합니다.
include:
- template: AWS/Deploy-ECS.gitlab-ci.yml
AWS/Deploy-ECS 템플릿은 GitLab과 함께 제공되며 GitLab.com에서 사용할 수 있습니다.
- 업데이트된
.gitlab-ci.yml을 커밋하고 프로젝트 저장소에 푸시합니다.
애플리케이션 Docker 이미지가 다시 빌드되어 GitLab 컨테이너 레지스트리로 푸시됩니다. 이미지가 프라이빗 레지스트리에 있다면 태스크 정의가 repositoryCredentials 속성으로 구성되어 있는지 확인하세요.
대상 태스크 정의가 새 Docker 이미지의 위치로 업데이트되고, 그 결과 ECS에 새 리비전이 만들어집니다.
마지막으로 AWS ECS 서비스가 태스크 정의의 새 리비전으로 업데이트되어, 클러스터가 애플리케이션의 최신 버전을 가져오게 됩니다.
ECS 배포 잡은 롤아웃이 완료될 때까지 기다린 후 종료됩니다. 이 동작을 비활성화하려면 CI_AWS_ECS_WAIT_FOR_ROLLOUT_COMPLETE_DISABLED를 비어 있지 않은 값으로 설정하세요.
AWS/Deploy-ECS.gitlab-ci.yml템플릿에는Jobs/Build.gitlab-ci.yml과Jobs/Deploy/ECS.gitlab-ci.yml두 템플릿이 포함됩니다. 이 템플릿들은 단독으로 include하지 마세요.AWS/Deploy-ECS.gitlab-ci.yml템플릿만 include하면 됩니다. 다른 템플릿들은 메인 템플릿과 함께만 쓰이도록 설계되었어요. 이 템플릿들은 예상치 못하게 이동하거나 변경될 수 있습니다. 또한 이 템플릿들의 잡 이름도 바뀔 수 있어요. 자신의 파이프라인에서 이 잡 이름들을 override하지 마세요. 이름이 바뀌면 override가 더 이상 동작하지 않기 때문입니다.
애플리케이션을 EC2에 배포하기
GitLab은 Amazon EC2에 배포하는 데 도움을 주는 AWS/CF-Provision-and-Deploy-EC2라는 템플릿을 제공합니다.
관련 JSON 객체를 구성하고 템플릿을 사용하면 파이프라인은:
- 스택을 만듭니다: AWS CloudFormation API로 인프라가 프로비저닝됩니다.
- S3 버킷으로 푸시합니다: 빌드가 실행되면 아티팩트를 만들고, 그 아티팩트를 AWS S3 버킷으로 푸시합니다.
- EC2에 배포합니다: 아래 다이어그램처럼 AWS EC2 인스턴스에 콘텐츠가 배포됩니다.
템플릿과 JSON 구성하기
EC2에 배포하려면 다음 단계를 완료하세요.
- 스택용 JSON을 만듭니다. AWS 템플릿을 사용하세요.
- S3로 푸시할 JSON을 만듭니다. 다음 세부 정보를 포함합니다.
{
"applicationName": "string",
"source": "string",
"s3Location": "s3://your/bucket/project_built_file...]"
}
source는 build 잡이 애플리케이션을 빌드한 위치입니다. 빌드는 artifacts:paths에 저장됩니다.
- EC2에 배포할 JSON을 만듭니다. AWS 템플릿을 사용하세요.
- JSON 객체를 파이프라인에서 접근할 수 있게 만듭니다. 이 JSON 객체들을 저장소에 저장하고 싶다면 세 개의 별도 파일로 저장하세요.
.gitlab-ci.yml파일에서 프로젝트 루트 기준의 파일 경로를 가리키는 CI/CD 변수를 추가합니다. 예를 들어 JSON 파일이<project_root>/aws폴더에 있다면:
variables:
CI_AWS_CF_CREATE_STACK_FILE: 'aws/cf_create_stack.json'
CI_AWS_S3_PUSH_FILE: 'aws/s3_push.json'
CI_AWS_EC2_DEPLOYMENT_FILE: 'aws/create_deployment.json'
이 JSON 객체들을 저장소에 저장하고 싶지 않다면, 각 객체를 프로젝트 설정의 별도 파일 타입 CI/CD 변수로 추가하세요. 이전과 같은 변수 이름을 사용합니다.
.gitlab-ci.yml파일에 스택 이름용 CI/CD 변수를 만듭니다. 예:
variables:
CI_AWS_CF_STACK_NAME: 'YourStackName'
.gitlab-ci.yml파일에 CI 템플릿을 추가합니다.
include:
- template: AWS/CF-Provision-and-Deploy-EC2.gitlab-ci.yml
- 파이프라인을 실행합니다.
CI_AWS_CF_CREATE_STACK_FILE변수의 내용을 기반으로 AWS CloudFormation 스택이 생성됩니다. 스택이 이미 존재하면 이 단계는 건너뛰지만, 속한provision잡은 여전히 실행됩니다. 빌드된 애플리케이션은 S3 버킷으로 푸시된 후 관련 JSON 객체의 내용에 기반해 EC2 인스턴스에 배포됩니다. EC2 배포가 끝나거나 실패하면 배포 잡이 종료됩니다.
문제 해결
'ascii' codec can't encode character '\uxxxx' 오류
이 오류는 Cloud Deploy 이미지가 사용하는 aws-cli 유틸리티의 응답에 Unicode 문자가 포함될 때 발생할 수 있어요. Cloud Deploy 이미지에는 locale이 정의되어 있지 않아 기본적으로 ASCII를 사용합니다. 이 오류를 해결하려면 다음 CI/CD 변수를 추가하세요.
variables:
LANG: "UTF-8"
더 알아보기
AWS 배포의 핵심은 자격 증명(인증)을 안전하게 설정한 뒤, GitLab이 제공하는 클라우드 배포 이미지나 템플릿을 활용하는 것이에요. ECS는 템플릿 하나로 빌드·배포가 자동화되고, EC2는 CloudFormation 기반으로 인프라까지 함께 다룹니다. 다음으로는 ID 토큰·OIDC 방식과 ECS 상세 가이드를 함께 보면 보안과 실습 두 측면을 모두 잡을 수 있어요.
