본문 바로가기

AWS

[CICD / ECS] CodePipeline으로 ECS Fargate 배포 자동화 #1 - 개요, 아키텍처

반응형

개요

간단한 Hello world를 출력하는 Node.js Express 애플리케이션을 Code Pipeline으로 CI/CD 파이프라인 구성을 해볼것이다.

 

1. IAM

IAM이 필요한 서비스로는 Code Pipeline, Code Deploy, Code Build, S3, EC2, ECS 등이 있다. 이에 대한 접근 권한을 각각 알맞게 부여해주어야 한다.

API Endpoint 접근 → API Action 권한 2가지 모두 허용이 되어야 한다.

 

만약 VPC 내부에서만 접근이 가능한 서비스라면 내부용 엔드포인트 서비스를 사용해야 할 것이며 그게 아니라면 Endpoint에 대해서는 걱정하지 않아도 될 것이다.

하지만 API Action에 대해서는 고려해봐야 한다. 특정 서비스에 Endpoint로 접근은 했지만 Action이 Allow 되어 있지 않는다면 인가에서 제한이 발생하기 때문이다.

 

1) CodeBuild
    - S3의 특정 Bucket에 대한 권한
    - ECR에 이미지를 적재하는 권한 (Dockerfile에서 Dockerhub에서 가져오는 것이 아닌 초기 Container 이미지를 갖춘 Base image를 ECR에서 가져오는 경우도 고려해야 할 수도 있음. 그 외에는 Push 관련된 권한만 있으면 될 것으로 보임)
    - secrets manager 관련 권한
    - ..

2) CodeDeploy
    - Managed Policy 사용, ECS 용 CodeDeploy Role 생성

3) CodePipeline
    - Managed Policy 사용

4) ECS Task Execution Role
    - Managed Policy 사용

5) ECSServiceRole
    - Managed Policy 사용

 

그 외 추가적으로 필요한 IAM Policy가 생길 수 있으니 Error log 발생하면 확인 후 추가해준다.

 

2. CI

Image build 부분이며, Jenkins 혹은 CodeBuild 툴을 사용하여 Image를 생성 후 ECR로 Push 할 수 있을 것이다.

여기에서는 CodeBuild 툴을 사용할 것이다.

*** CodeBuild는 AWS 관리형 서비스로 Jenkins 처럼 직접 서버 내에 CI 서비스를 설치 및 관리하지 않아도 된다는 장점이 있다.

3. CD

CodeDeploy를 사용하여 ECS에 간편하게 Blue-Green 배포할 수 있을 것이다.

 

 

파이프라인 흐름도

 

파이프라인 흐름도

 

개발자는 Git 저장소의 특정 브랜치에서 Push를 할 경우 원격 레포지토리에서 변경 사항이 감지되며, Code Pipeline이 이를 감지한 뒤 Pipeline을 동작시키게 된다.

 

CodeBuild에서는 Git으로부터 가져온 Source를 buildspec.yml에 정의된대로 수행을 하며, 빌드에 성공할 경우 ECR에 해당 Image를 Push 하고 Build artifact로 appspec.yml과 taskdef.json을 S3에 저장한다. 이 파일들은 CodeDeploy에게 Source Input 파일로 전달될 예정이다.

 

Build에 성공하였으니 Deploy Stage가 Trigger되며, Code Deploy는 appspec.yml과 taskdef.json에 정의된 대로 배포를 수행한다. 배포 이전에 CodeDploy - Application, Deployment group이 미리 생성되어 있어야 한다.

 

배포에 성공하고 트래픽 테스트도 정상적으로 성공할 경우 Blue 타겟 그룹 (v1)에서 Green 타겟 그룹 (v2)로 ALB의 타겟이 변경된다. 아주 잠깐의 순단을 제외하고 무중단 배포가 이루어진 것이다.

 

 

변수

CodeBuild 자체에서 제공하는 변수 또한 유용하게 사용할 수 있다.

값을 받아온 뒤 파싱하여 Account id를 구한다던지, Region을 구한다던지, Build Number 또한 구할 수 있다.

참고 : https://docs.aws.amazon.com/codebuild/latest/userguide/build-env-ref-env-vars.html

 

 

환경 변수는 CodeBuild에서 Env: 섹션에서 설정할 수 있다.

스크립트 내부에서 직접 선언하는 Variables와 Parameter Store, Secrets manager로부터 가져올 수 있는데,

 

1) Variables : 굳이 별도로 외부 서비스를 사용하지 않아도 buildspec.yml 내부에서 직접 수정 및 설정할 수 있지만, Code에 결국 Value가 노출된다는 단점이 존재한다.

보안적으로 중요하지 않은 내용들, 예를 들어 ECS_CLUSTER_NAME, ECS_SERVICE_NAME 등은 직접 기입해도 무방할 것이다.

 

2) Parameter Store : Key를 기입하면 Value는 Parameter Store에 저장되어 있기 때문에 코드에 직접적으로 값이 노출될 일이 없고, Secrets manager에 비해 가격이 저렴하고 사용이 간편하다는 장점이 있다.

 

3) Secrets manager : Lambda와 연동하여 주기적으로 값을 변경해줄 수 있다는 장점이 있으며, Parameter store와 거의 유사하다. 가격은 Parameter Store에 비해 조금 더 비싸다.

30일 주기로 Database의 Password를 변경하고 싶다면 Rotation 기능을 활성화한 뒤 특정 Lambda와 연동하여 패스워드를 랜덤한 값으로 수정한 뒤 관련 담당자들에게 이메일 혹은 Slack으로 발송할 수 있을 것으로 본다.

 

 

 

 

 

참고 사항

1. Endpoint 서비스를 사용하여 VPC 내부에서 외부로 API 접근을 하는 것이 아닌 내부에서 API 접근을 하게 된다면 Traffic 손실을 줄일 수 있을 것이다. (ECR, CodeBuild, S3, .. Endpoint or Gateway interface)


2. CodeBuild는 VPC에 종속되었을 때 Public Subnet에 있을 경우 ENI가 ElasticIP 주소를 할당 받지 못하기 때문Private Subnet에 지정해준 뒤 NAT GW를 타고 S3 등 각종 리소스에 접근하거나 VPC 내부에서 사설 Endpoint로 접근해야 한다.
    REF : https://docs.aws.amazon.com/ko_kr/codebuild/latest/userguide/vpc-support.html

3. CodeDeploy에서 appspec.yml을 참고하여 배포를 하고자 할 경우 TASK_DEFINITION은 별도로 REVISION을 지정하지 않고 <TASK_DEFINITION> 을 지정하면 알아서 코드 파이프라인에서 소스 아티팩트로 주었던 taskdef.json이 자동으로 업데이트된 후 appspec.yml에 치환된다.

    REF : https://docs.aws.amazon.com/ko_kr/codepipeline/latest/userguide/tutorials-ecs-ecr-codedeploy.html

 

반응형