GitLab CI/CD를 통해 AWS로 배포

Tier: Free, Premium, Ultimate Offering: GitLab.com, Self-Managed, GitLab Dedicated

GitLab은 AWS로 배포하는 데 필요한 라이브러리와 도구가 포함된 Docker 이미지를 제공합니다. CI/CD 파이프라인에서 이러한 이미지를 참조할 수 있습니다.

GitLab.com을 사용하고 Amazon Elastic Container Service (ECS)로 배포하는 경우 ECS로의 배포를 읽어보세요.

참고: 배포를 직접 구성하는 데 익숙하고 AWS 자격 증명만 검색하려는 경우 ID 토큰 및 OpenID Connect를 사용해보세요. ID 토큰은 CI/CD 변수에 자격 증명을 저장하는 것보다 안전하지만, 이 페이지의 안내와 호환되지 않습니다.

AWS에서 GitLab 인증

GitLab CI/CD를 AWS에 연결하려면 인증해야 합니다. 인증을 설정한 후에 CI/CD를 구성하여 배포할 수 있습니다.

  1. AWS 계정에 로그인합니다.
  2. IAM 사용자를 생성합니다.
  3. 사용자를 선택하여 해당 세부 정보에 액세스합니다. 보안 자격 증명 > 새 액세스 키 생성으로 이동합니다.
  4. 액세스 키 ID비밀 액세스 키를 기록합니다.
  5. GitLab 프로젝트에서 설정 > CI/CD로 이동합니다. 다음 CI/CD 변수를 설정합니다:

    환경 변수 이름
    AWS_ACCESS_KEY_ID 액세스 키 ID 입력
    AWS_SECRET_ACCESS_KEY 비밀 액세스 키 입력
    AWS_DEFAULT_REGION 지역 코드 입력. 사용하려는 AWS 서비스가 선택한 지역에서 사용 가능한지 확인하는 것이 좋습니다.
  6. 변수는 기본적으로 보호됩니다. 보호되지 않은 브랜치나 태그에서 GitLab CI/CD를 사용하려면 변수 보호 확인란을 지웁니다.

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 저장소로 이미지 푸시하는 방법을 알아보세요.

제3자 레지스트리에서 이미지를 사용할 수도 있습니다.

ECS로 애플리케이션 배포

애플리케이션을 Amazon ECS 클러스터로 자동화된 배포할 수 있습니다.

전제 조건:

  • GitLab과 AWS를 인증.
  • Amazon ECS에 클러스터를 생성합니다.
  • 해당 클러스터에 관련 구성요소를 생성합니다. 예를 들어, Amazon RDS에서 ECS 서비스 또는 데이터베이스를 생성합니다.
  • ECS 작업 정의를 생성합니다. 여기서 containerDefinitions[].name 속성의 값은 대상 ECS 서비스에서 정의한 컨테이너 이름과 동일해야 합니다. 작업 정의는 다음과 같을 수 있습니다:

ECS 클러스터로 배포하려면:

  1. GitLab 프로젝트에서 설정 > 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_FILECI_AWS_ECS_TASK_DEFINITION 둘 다 정의하는 경우 CI_AWS_ECS_TASK_DEFINITION_FILE이 우선됩니다.

  2. .gitlab-ci.yml에 이 템플릿을 포함합니다:

    include:
      - template: AWS/Deploy-ECS.gitlab-ci.yml
    

    AWS/Deploy-ECS 템플릿은 GitLab에 포함되어 있으며 GitLab.com에서 사용할 수 있습니다.

  3. 업데이트된 .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.ymlJobs/Deploy/ECS.gitlab-ci.yml 두 템플릿이 포함되어 있습니다. 이러한 템플릿을 개별적으로 포함하지 마십시오. AWS/Deploy-ECS.gitlab-ci.yml 템플릿만 포함하세요. 이러한 다른 템플릿은 주 템플릿과 함께만 사용하도록 설계되어 있습니다. 그리고 위치 또는 변경이 예상치 못하게 변경될 수 있습니다. 또한 이러한 템플릿 내의 작업 이름은 변경될 수 있습니다. 자신의 파이프라인에서 이러한 작업 이름을 재정의하지 마십시오. 이름이 변경되면 더 이상 작동하지 않습니다.

EC2에 애플리케이션 배포

GitLab은 Amazon EC2에 배포하는 데 도움이 되는 AWS/CF-Provision-and-Deploy-EC2라는 템플릿을 제공합니다.

관련된 JSON 객체를 구성하고 해당 템플릿을 사용하면 파이프라인이 다음을 수행합니다.

  1. 스택 생성: AWS CloudFormation API를 사용하여 인프라가 프로비저닝됩니다.
  2. S3 버킷으로 푸시: 빌드가 실행되면 아티팩트가 생성됩니다. 해당 아티팩트는 AWS S3 버킷으로 푸시됩니다.
  3. EC2에 배포: 내용이 AWS EC2 인스턴스에 배포됩니다.

CF-Provision-and-Deploy-EC2 다이어그램

템플릿 및 JSON 구성

EC2에 배포하려면 다음 단계를 완료하세요.

  1. 스택용 JSON을 생성합니다. AWS 템플릿을 사용합니다.
  2. S3로 푸시할 JSON을 생성합니다. 다음 세부 정보를 포함합니다.

    {
      "applicationName": "string",
      "source": "string",
      "s3Location": "s3://your/bucket/project_built_file...]"
    }
    

    sourcebuild 작업이 애플리케이션을 빌드한 위치입니다. 빌드된 항목은 artifacts:paths에 저장됩니다.

  3. EC2에 배포할 JSON을 생성합니다. AWS 템플릿을 사용합니다.
  4. 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 변수로 추가합니다. 위의 변수 이름과 동일한 변수 이름을 사용합니다.

  5. .gitlab-ci.yml 파일에 스택 이름을 위한 CI/CD 변수를 생성합니다. 예:

    variables:
      CI_AWS_CF_STACK_NAME: 'YourStackName'
    
  6. .gitlab-ci.yml 파일에 CI 템플릿을 추가합니다.

    include:
      - template: AWS/CF-Provision-and-Deploy-EC2.gitlab-ci.yml
    
  7. 파이프라인을 실행합니다.

    • CI_AWS_CF_CREATE_STACK_FILE 변수의 내용에 따라 AWS CloudFormation 스택이 생성됩니다. 스택이 이미 있는 경우 이 단계는 건너뛰지만 해당 단계에 속한 provision 작업은 여전히 실행됩니다.
    • 빌드된 애플리케이션이 S3 버킷으로 푸시된 후 관련 JSON 객체의 내용에 따라 EC2 인스턴스로 배포됩니다. 배포 작업은 EC2로의 배포가 완료되거나 실패할 때 완료됩니다.

문제 해결

오류 'ascii' codec can't encode character '\uxxxx'

이 오류는 Cloud Deploy 이미지에서 사용되는 aws-cli 유틸리티의 응답에 유니코드 문자가 포함되어 있을 때 발생할 수 있습니다. 제공하는 Cloud Deploy 이미지는 지정된 로캘(locale)이 없어 기본적으로 ASCII를 사용합니다. 이 오류를 해결하려면 다음 CI/CD 변수를 추가합니다:

variables:
  LANG: "UTF-8"