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 이미지를 제공합니다:

대안으로 Amazon Elastic Container Registry (ECR) 이미지를 사용할 수도 있습니다. ECR 리포지터리로 이미지를 푸시하는 방법을 알아보세요.

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

ECS에 애플리케이션 배포

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

전제 조건:

  • AWS를 GitLab으로 인증.
  • Amazon ECS에 클러스터를 생성합니다.
  • ECS 서비스 또는 Amazon RDS에서와 같은 관련 컴포넌트를 생성합니다.
  • 목표 ECS 서비스에서 정의한 Container name 속성의 값이 될 containerDefinitions[].name 속성의 값이 포함된 ECS 작업 정의를 생성합니다. 작업 정의는:
    • 기존의 ECS 작업 정의일 수 있습니다.
    • GitLab 13.3 이상에서는, GitLab 프로젝트에 JSON 파일로 저장됩니다. AWS 문서의 템플릿을 사용하여 프로젝트에 해당 파일을 저장합니다. 예: <프로젝트-루트>/ci/aws/task-definition.json.

Amazon 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부터 시작합니다.
    caution
    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에 빈 값 할당하세요.::

caution
AWS/Deploy-ECS.gitlab-ci.yml 템플릿에는 Jobs/Build.gitlab-ci.ymlJobs/Deploy/ECS.gitlab-ci.yml 두 가지 템플릿이 포함되어 있습니다. 이러한 템플릿을 개별적으로 포함하지 마세요. 주요 템플릿만 포함하세요. 이러한 다른 템플릿은 주 템플릿과만 함께 사용되도록 설계되었습니다. 위치 또는 변경될 수 있습니다. 또한 이러한 템플릿 내의 작업 이름은 변경될 수 있습니다. 사용자 고유의 파이프라인에서 이러한 작업 이름을 재정의하지 마세요.

EC2에 애플리케이션 배포하기

GitLab은 AWS/CF-Provision-and-Deploy-EC2라는 템플릿을 제공하여 Amazon 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 이미지에는 정의된 로캘이 없어 ASCII를 기본으로 사용합니다. 이 오류를 해결하려면 다음과 같은 CI/CD 변수를 추가하세요.

variables:
  LANG: "UTF-8"