AWS 기술 블로그

Terraform, GitHub Actions, AWS Proton을 사용하여 IaC 및 CI/CD 파이프라인 확장하기

이 글은 AWS Machine Learning Blog에 게시된 Scaling IaC and CI/CD pipelines with Terraform, GitHub Actions, and AWS Proton by John Ritsema을 한국어로 번역 및 편집하였습니다.

소개

최신 애플리케이션은 AWS Lambda, AWS App Runner, 그리고 AWS Fargate와 같은 서버리스 서비스를 포함해 AWS의 다양한 컴퓨팅 플랫폼에서 실행됩니다. 오늘날의 조직들은 종종 이러한 고유의 런타임 특성을 제공하는 AWS 서비스들의 다양한 아키텍처를 지원해야 하는데, 이러한 특성에는 동시성과 확장성이 포함되며, 이들은 특정 작업 부하에 대해 목적에 맞게 최적화될 수 있습니다.

이때 고객이 Infrastructure as Code(IaC) 및 지속적 통합 및 지속적 배포(CI/CD) 와 같은 방법론을 사용하여 이러한 서비스를 채택하는 경우, 조직 내에서 서비스를 확장하는 방법에 대한 문제에 직면하는 경우가 많습니다. 단일 팀이 애플리케이션을 개발하고 운영하는 DevOps의 원래 개념인 Two-Pizza Team 접근법과는 대조적으로, 최근 DevOps 엔지니어와 플랫폼 엔지니어와 같은 새로운 역할이 산업에서 등장하고 있습니다. 이러한 새로운 역할들은 보통 클라우드 인프라와 운영 작업에 더 집중되어 있어, 개발자들이 프론트엔드 그래픽 사용자 인터페이스(GUI), 백엔드 API, 데이터베이스 쿼리와 같은 애플리케이션 코드를 작성하는데 집중할 수 있게 도와줍니다.

새로운 DevOps 및 플랫폼 엔지니어링 역할들은 IaC와 CI/CD로 많은 개발팀을 어떻게 지원할 것인지에 대한 도전을 맞이하고 있습니다. 이들은 개발팀이 보안, 신뢰성, 비용 최적화에 대한 조직의 표준 및 가이드라인을 준수하도록 하고 싶지만, 한편으로 개발팀이 빠르게 움직이고 새로운 서비스를 신속하게 배포하는데 있어 병목현상이 되고 싶지는 않습니다. 이러한 문제를 해결하는 데 도움을 주기 위해, 내부 개발자 플랫폼(Internal Developer Platform)이 플랫폼 엔지니어와 개발팀이 협업하고 신뢰성과 일관성을 높여 더 빠르게 움직일 수 있도록 하는 메커니즘으로서 점점 더 주목받고 있습니다. 현대의 클라우드 운영을 위해 회사들이 어떻게 조직을 운영하는지 더 알고 싶다면, 이 게시물을 참조하세요.

IaC 및 CI/CD 템플릿을 대규모로 사용할 때 가장 큰 어려움은 시간이 지남에 따라 템플릿을 유지 관리하고 발전시키는 것입니다. 템플릿을 구성하는 도구들은 훌륭하지만, 변경이 필요할 때 어떻게 될까요? 예를 들어, Amazon Elastic Container Service(ECS)AWS Fargate를 사용하여 웹 애플리케이션을 프로비저닝하는 템플릿이 있다고 가정해 보겠습니다. AWS가 Amazon ECS Service Connect과 같은 새로운 기능을 출시하고, 이 새로운 기능을 템플릿 사용자가 선택할 수 있도록 하려고 합니다. 만약 여러 개의 CI/CD 파이프라인을 구성했는데 나중에 보안 스캔 단계를 추가하고 싶은 경우는 어떻게 될까요? AWS Proton은 지속적으로 발생하는 이러한 상황에 대응하기 위해 플랫폼 엔지니어에게 템플릿을 버전화하고 추적하며 업데이트를 게시하여 개발팀이 사용할 수 있도록 하는 메커니즘을 제공합니다. AWS Proton은 플랫폼 팀이 인프라를 정의하고 업데이트하여 셀프 서비스 배포를 위한 인프라를 확장하는 데 도움을 주는 서비스입니다. AWS Proton은 AWS 계정 전체에서 템플릿 사용 가시성과 추적성을 제공하는 중앙 대시보드를 통해 관리되는 배포 메커니즘을 제공합니다.

AWS Proton은 다양한 사용 사례를 지원할 수 있지만, 이 게시글에서는 AWS Proton을 사용하여 GitHub Actions에서 실행되는 CI/CD 파이프라인을 통해 Amazon ECS Fargate에서 실행되는 웹 애플리케이션 컨테이너 아키텍처를 프로비저닝하는 방법을 보여줄 것입니다. 웹 애플리케이션과 CI/CD 파이프라인을 제공하는 IaC는 AWS Proton 서비스 템플릿 내에 캡슐화되어 있으며, 이는 개발자들이 셀프서비스 방식으로 쉽게 사용하고 시간이 지나도 유지 관리할 수 있습니다. 이 게시글에서는 Terraform을 사용하여 구현된 샘플 AWS Protons 템플릿을 사용하여 샘플 Python Flask 웹 애플리케이션을 프로비저닝하고 배포합니다. 개발자가 AWS에서 새로운 웹 애플리케이션을 시작하는 데 필요한 모든 것을 제공하는 두 개의 AWS Proton 템플릿과 코드를 빌드하고 배포하는 CI/CD 파이프라인을 게시하고 배포하는 방법을 안내해드립니다.

솔루션 개요

다음은 이 아키텍처를 설명하는 개략적인 다이어그램입니다:

실습해보기

(역주: 실습 환경은 us-east-1 리전에서 동작할 수 있도록 제공됩니다. 다른 리전에서 실습을 원하는 경우 제공되는 제공되는 샘플의 일부 파일 수정이 필요합니다.)

템플릿 등록

시작하기 위해서는 웹 애플리케이션을 배포할 환경이 필요합니다. 웹 애플리케이션은 인터넷에서의 트래픽을 받아들이고, Amazon Relational Database Service (Amazon RDS) 와 같은 내부 리소스에 연결해야 할 수도 있습니다. 이 게시물에서는 VPC ECS Cluster 샘플 템플릿을 활용하여 Amazon Virtual Private Cloud (VPC) 네트워크를 프로비저닝하는 AWS Proton 환경 템플릿을 사용합니다.

먼저, 템플릿을 AWS 계정에 등록해야 합니다. 샘플 저장소를 클론하고 아래 명령을 사용하여 환경 템플릿을 등록할 수 있습니다. 등록 중에 템플릿 아티팩트를 저장하기 위해 Amazon Simple Storage Service (Amazon S3) 버킷을 사전에 생성하여 제공해야 합니다. 다음 명령에서 S3_BUCKET이라는 환경 변수를 설정하거나 ${S3_BUCKET}을 사전에 생성한 버킷 이름으로 대체 합니다. 다른 방법으로 AWS Proton의 템플릿 동기화 기능을 사용하여 Git 저장소에서 템플릿을 자동으로 등록할 수도 있습니다. 템플릿 동기화를 사용하려면 저장소를 자체 GitHub 조직으로 포크하고 AWS CodeStar connection을 사용하여 저장소에 접근하여 AWS Proton에서 사용할 수 있도록 설정해야 합니다. 템플릿 동기화 기능에 대해서는 여기에서 자세히 확인 할 수 있습니다. 단, 실습에서는 Amazon S3 버킷을 사용하여 템플릿 등록을 수행하겠습니다.

git clone git@github.com:aws-containers/proton-codebuild-provisioning-examples.git proton-examples 

cd proton-examples/terraform/environment-templates/tf-vpc-ecs-cluster/v1
make template bucket=${S3_BUCKET} version=1

이어서, 소스 코드 저장소에서 컨테이너를 빌드하고 배포할 수 있는 로드 밸런싱된 웹 애플리케이션과 CI/CD 파이프라인을 프로비저닝하는 AWS Proton 서비스 템플릿을 등록합니다.

cd ../../../service-templates/tf-ecs-fargate-lb-service-cicd-gh-actions/v1
make template bucket=${S3_BUCKET} version=1

(역주: 위 과정을 완료하면 S3 버킷에는 proton-environment-template.tar.gz, proton-service-template.tar.gz 파일이 생성됩니다.)

환경 만들기

템플릿을 등록했으므로, 환경에 새로운 인스턴스를 생성할 수 있습니다. 이를 위해 AWS Management Console에 로그인하여 AWS Proton으로 이동한 다음, 좌측 메뉴의 Environments를 선택, Create environment를 선택하고, ECS Fargate 템플릿을 선택하면 됩니다. 앞으로 이어지는 설명은 AWS Management Console을 사용한 설정 과정을 안내합니다. 이 작업은 AWS Command Line Interface (AWS CLI) 또는 Application Programming Interfaces (APIs) 를 사용하여 자동화할 수 있습니다.

환경 이름으로 dev로 설정하고 설명을 입력한 후, AWS CodeBuild 프로비저닝 역할을 선택합니다. 이 역할은 환경 템플릿과 관련된 서비스 템플릿이 프로비저닝할 수 있는 인프라의 범위를 결정합니다. AWS Proton은 템플릿 명령을 실행하기 위한 환경으로 AWS CodeBuild를 사용합니다. (역주: CodeBuild 프로비저닝 역할 생성은 해당 문서를 참고합니다.) 이어서 Next를 선택하면  AWS Proton은 환경 템플릿에 대한 입력 매개변수를 지정할 수 있도록 합니다. 그래픽 인터페이스를 선호하는 고객을 위해, AWS Proton은 proton 템플릿에 포함된 스키마 파일을 기반으로 이 사용자 인터페이스를 동적으로 생성합니다. GitOps 스타일의 프로비저닝을 선호하는 고객을 위해, AWS Proton은 서비스 동기화 기능을 지원합니다. 해당 기능은 여기에서 자세히 살펴볼 수 있습니다. 실습에서는 기본값으로 템플릿을 설정하고 Next를 선택한 후, Create를 선택합니다.

이 시점에서 AWS Proton은 환경 리소스를 프로비저닝합니다. 여기에는 VPC 네트워크, Amazon ECS 클러스터, AWS IAM 역할 및 Terraform 원격 상태를 저장하기 위한 Amazon S3 버킷이 포함됩니다. 예시 템플릿은 Terraform을 사용하여 구축되었지만, AWS Proton의 CodeBuild 프로비저닝 기능을 사용하면 원하는 IaC 도구 (예: AWS Cloud Development Kit (CDK)) 또는 스크립트를 사용할 수 있습니다.

몇 분 후, AWS Proton은 AWS CodeBuild 프로비저닝을 사용하여 템플릿의 Terraform을 적용하여 개발 환경 프로비저닝을 완료합니다. 프로비저닝이 완료되면 환경의 배포 상태가 Succeeded로 변경되고, 이 환경에 웹 애플리케이션을 배포할 준비가 됩니다.

서비스, 파이프라인, 인스턴스 생성하기

웹 애플리케이션과 CI/CD 파이프라인을 설정하기 위해서, 먼저 서비스(Services)로 이동한 다음 서비스 생성(Create Service)을 선택하고 ‘Load Balanced ECS Fargate Service with a GitHub Actions CI/CD Pipeline’를 선택합니다.

서비스 이름(예: web-app)을 입력한 후 애플리케이션 소스 코드가 포함된 GitHub 저장소에 서비스를 연결합니다. 자체 애플리케이션 저장소를 사용할 수 있지만, 이 예제에서는 aws-proton-sample-services 저장소를 GitHub 조직으로 포크하거나 저장소 템플릿에서 새 저장소를 생성하여 사용하겠습니다. ‘Link another Git repository’ 옵션을 선택하면 GitHub과 AWS CodeStar connection을 선택하고 저장소와 main 브랜치를 선택할 수 있습니다.

다음으로 AWS Proton 서비스 인스턴스를 구성합니다. dev라는 이름으로 단일 인스턴스를 생성하고, 이전에 생성한 dev라는 AWS Proton 환경을 선택합니다. 결국 ecs-backend 샘플 앱을 배포할 것이므로 샘플 애플리케이션 구성에 따라 포트 80과 헬스체크 경로를 /ping으로 입력합니다. 샘플 애플리케이션은 Flask web framework를 사용하는 매우 간단한 Python 애플리케이션입니다. 선택한 포트와 헬스체크를 동적으로 사용하는 템플릿의 기본 public.ecr.aws/aws-containers/proton-demo-image 컨테이너 이미지를 수락합니다. 이 이미지는 다음 CI/CD 파이프라인 작업에서 빌드된 새 이미지로 업데이트 및 교체됩니다.

AWS Proton 서비스의 ‘파이프라인 입력(Pipeline Inputs)’ 섹션에는, 워크플로우 YAML 파일을 우리의 애플리케이션 저장소로 보내는 GitHub Actions CI/CD 파이프라인을 제공하는 서비스를 허용하는 GitHub Personal Access Token(PAT)이 필요합니다. 워크플로우 범위가 포함된 PAT를 만들려면 GitHub 문서를 참조하세요. PAT를 생성한 후에는 AWS Proton 서비스에서 사용할 수 있도록 AWS Secrets Manager에 추가합니다. 이렇게 하려면 AWS 콘솔에서 새 탭을 열고 시크릿 관리자로 이동한 다음 새 시크릿 저장 옵션을 선택합니다. Other 유형의 시크릿을 선택하고 일반 텍스트 탭에 GitHub PAT를 입력합니다. 다음과 같이 표시되어야 합니다.

이어서 시크릿 키 이름을 github/token/sample-app으로 지정하고, 설명을 추가한 후 다음(Next), 다음(Next), 그리고 저장(Store)을 차례대로 클릭 합니다.

시크릿 키가 Secrets Manager에 안전하게 저장되면, AWS Proton 탭으로 돌아가 ‘파이프라인 입력(Pipeline inputs)’ 섹션에 비밀 키의 이름을 입력할 수 있습니다. Docker Path에는 ./ecs-backend를 입력하여 적절한 하위 디렉토리가 구성되도록 합니다.

다음(Next) 버튼을 선택하면 AWS Proton은 서비스 템플릿을 프로비저닝합니다. 이 과정은 중요한 두 가지 단계를 포함합니다.

  1. 서비스 인스턴스에 대한 웹 애플리케이션 인프라를 프로비저닝합니다. 이 과정에서는 애플리케이션 로드 밸런서와 기본 컨테이너를 실행하는 Amazon ECS 서비스를 프로비저닝합니다.
  2. 파이프라인 인프라를 프로비저닝합니다. 이 과정에는 Amazon Elastic Container Registry(Amazon ECR) 저장소, GitHub Actions이 수행할 AWS IAM 역할, 그리고 애플리케이션 저장소로 풀 요청(PR)으로 보내지는 GitHub Actions 워크플로우 YAML 파일을 프로비저닝하는 것이 포함됩니다.

(역주: 만약 프로비저닝 도중 ‘AccountSettings.pipelineCodeBuildRoleArn has not been configured.’ 오류가 발생하면 AWS Proton 메뉴의 Account settings 설정을 진행합니다. 또는 ‘exit status 128’ 에러가 발생한다면 GitHub PAT의 저장소 접근 설정과 권한을 확인합니다. 이 경우 PR 생성 권한이 있어야 합니다.)

CI/CD 파이프라인 실행하기

AWS Proton 서비스 상태가 Active로 변경되고 파이프라인 프로비저닝 상태가 Succeeded로 변경되면, 파이프라인 탭의 Outputs 섹션에 워크플로우 PR URL이 나타날 것입니다. 이 링크를 선택하면 “Proton generated GitHub Actions CI/CD pipeline“라는 이름의 PR을 볼 수 있습니다.

이 PR을 병합하면, GitHub Actions는 워크플로우 작업을 실행하여 Python 애플리케이션을 컨테이너 이미지로 빌드하고, 이를 Amazon ECR에 푸시하며, 새로 빌드한 이미지를 서비스 인스턴스에 배포하도록 AWS Proton 서비스를 업데이트합니다.

GitHub Actions 워크플로우 작업이 완료되면, Amazon ECS에서 새로운 배포를 진행하는 것을 확인할 수 있습니다.

Amazon ECS 배포가 완료되면, AWS Proton 서비스 인스턴스 출력에 위치한 엔드포인트를 선택하고 Python 애플리케이션이 실행되는 것을 확인할 수 있습니다. 이 파이프라인을 통해 향후 메인 브랜치에 푸시되거나 병합된 코드 커밋은 이 파이프라인을 트리거하게 됩니다.

지금까지 위에서 소개한 내용은 단지 한 가지 워크플로우의 예제일 뿐입니다. 중요한 것은 이 워크플로우가 시간이 지나면서 변경될 수 있는 AWS Proton 서비스 템플릿에 캡슐화되어 있다는 것입니다. 플랫폼 엔지니어링 팀은 대체 워크플로우를 가진 추가 서비스 템플릿을 제공하거나, 템플릿 사용자가 사용자 정의 입력 파라미터를 지정하여 워크플로우를 커스터마이징할 수 있도록 허용 할 수도 있습니다. 예를 들어 GitHub PR에서 CI를 트리거하는 것, 컨테이너 이미지를 빌드하고 Amazon ECR에 푸시하는 것이 있을 수 있습니다. 배포는 AWS Proton의 service sync 기능을 사용하여 GitOps 접근법으로 트리거할 수도 있습니다. 이 기능을 사용하면 AWS Proton이 감시하고 배포해주는 Git 저장소에 있는 파일에 선언적으로 AWS Proton 서비스의 입력 파라미터를 지정할 수 있습니다. 핵심은 유연성을 가지며, 워크플로우를 시간이 지나면서 버전 관리, 추적, 유지 관리가 가능한 템플릿 내에 캡슐화할 수 있다는 것입니다.

유지 관리

각 워크로드의 CI/CD 파이프라인은 해당 워크로드의 GitHub 저장소에 존재하지만, AWS Proton은 개발팀이 플랫폼 팀이 설정한 표준과 모범 사례와 동기를 유지하고 최신 상태를 유지할 수 있도록 느슨하게 결합된 메커니즘을 제공합니다. 예를 들어, 템플릿을 사용하여 워크로드를 배포한 후 몇 달이 지난 후에, 플랫폼 엔지니어링 팀이 모든 사람들이 새로운 보안 스캐닝 도구를 실행하고 이를 통과한 경우에만 배포하도록 하려고 결정한다고 가정해보겠습니다. 플랫폼 엔지니어링 팀은 이 새로운 자동화를 포함하도록 서비스 템플릿을 업데이트하고, 새로운 버전을 게시하고, 그런 다음 사용중인 팀들이 자유롭게 템플릿을 업그레이드하도록 허용하거나 AWS Proton API를 사용하여 모든 환경이나 서비스를 한 번에 업데이트할 수 있습니다. 다음 스크린샷은 개발자가 권장되는 버전으로 업데이트할 수 있도록 하는 새로운 템플릿 버전이 있음을 알리는 방법을 보여줍니다. 이 버튼을 선택하면 새 파이프라인이 배포되며, 최신 파이프라인 변경 사항이 포함된 또 다른 PR이 생성됩니다.

실습 전제 조건

이번 실습을 자신의 AWS 계정에서 따라하고 싶다면, AWS Proton 사전 전제 조건을 완료해야 합니다. 여기에는 AWS Identity and Access Management (AWS IAM) 역할 및 GitHub 계정에 대한 AWS CodeStar connection 설정이 포함됩니다. 이를 위해서는 상위 권한을 가진 AWS 계정 권한이 필요합니다.

리소스 정리하기

만약 실습과정 동안 생성된 AWS 리소스를 제거하고 싶다면, AWS Proton 서비스를 삭제하면 서비스 파이프라인과 인스턴스에 의해 생성된 모든 리소스가 자동으로 삭제됩니다. 서비스가 삭제되면, 공유 리소스를 삭제하기 위해 AWS Proton 환경을 삭제할 수 있습니다. 단, Terraform 원격 상태를 저장하는 환경의 일부로 생성된 Amazon S3 버킷은 이전 리소스를 복원해야 할 경우를 대비하여 자동으로 삭제되지 않습니다. 이 버킷은 수동으로 비워야 하고 삭제해야 합니다. 서비스와 환경이 삭제된 후에는 안전하게 AWS Proton 서비스 및 환경 템플릿을 삭제할 수 있습니다.

결론

이 게시물에서는 AWS Proton 템플릿을 사용하여 구축할 수 있는 예제 중 하나를 보여드렸습니다. 플랫폼 엔지니어로서, AWS Proton 템플릿을 게시하여 개발자들이 AWS에서 새로운 웹 애플리케이션을 구성하고, 코드를 빌드하고 배포하는 CI/CD 파이프라인을 제공받을 수 있도록 했습니다. 이를 통해 개발자들은 애플리케이션 개발에 집중할 수 있으며, 플랫폼 팀은 시간이 지남에 따라 클라우드 리소스와 CI/CD 파이프라인에 대한 가드레일과 업데이트를 제공할 수 있는 메커니즘을 갖게 됩니다. AWS Proton의 가치는 인프라와 파이프라인 규칙 및 로직을 AWS 계정 전체에서 버전 관리, 업데이트 및 추적이 가능한 리소스로 캡슐화할 수 있다는 점입니다.

proton-codebuild-provisioning-examples 저장소에서 Terraform, CDK, Pulumi를 사용하는 예제 템플릿을 확인할 수 있습니다. 또한, GitHub Actions 대신 AWS CodePipeline을 사용하는 또 다른 Terraform 예제 템플릿도 있습니다. AWS Proton의 CodeBuild 프로비저닝 기능을 사용하면 선호하는 도구를 사용하여 템플릿을 빌드할 수 있습니다. 만약 IaC 도구로 AWS CloudFormation을 선호한다면, 우리는 여기에서 샘플 템플릿을 게시했습니다. 샘플 템플릿을 시도해보고 AWS Proton 공개 로드맵 GitHub 저장소에 피드백을 남겨주세요.

Jungseob Shin

Jungseob Shin

신정섭 Solutions Architect는 다양한 분야의 Backend 서버 개발 경험을 바탕으로 Startup 고객이 비즈니스 목표를 달성하도록 AWS 서비스의 효율적인 사용을 위한 아키텍처 설계 가이드와 기술을 지원하는 역할을 수행하고 있습니다. 컨테이너와 서버리스 기술에 관심이 많습니다.