
1. ECS 인프라 구축하기
1) IAM 생성
- ecs ec2 인스턴스 프로파일 Role
- 이름 : prod-ecs-instance-role
- 권한 : AmazonEC2ContainerServiceforEC2Role

- codedeploy role
- 이름 : prod-ecs-codedeploy-role
- 권한 : AWSCodeDeployRoleForECS

2) S3 생성
이름 : prod-ecs-cluster-s3

3) ECS 생성
https://monta010.tistory.com/171
AWS ECS 콘솔 구축하기
AWS ECS컨테이너 애플리케이션을 쉽게 배포, 관리 및 확대할 수 있도록 도와주는 완전 관리형 컨테이너 오케스트레이션 서비스 AWS ECS용어ECS Cluster : 컨테이너를 실행할 리소스 그룹ECS Task : 작업
monta010.tistory.com
- ECS Cluster
- Name : prod-ecs
- ASG EC2 구성 : 최소 2개 , 최대 4대


- Task
- 이름 : prod-ecs-backend
- 개수 : 기본 1개
- 컨테이너 이름 : prod-backend
- 호스트포트 : 8080
- 컨테이너 포트 : 8080
- 네트워크 모드 : brige -> fargate는 awsvpc 사용됨
- 리소스 스펙
- CPU : 512
- Memory : 1024

- Service
- 이름 : prod-ecs-cluster
- 로드 밸런서 유형 : Application Load Balancer
- 프러덕션 리스너 : 8080
- 테스트 리스너 : 8081
- 배포 유형 : 블루/그린 배포
- 베포 구성 : CodeDeployDefault.ECSAllAtOnce


4) Application Load Balancer
- 이름 : prod-ecs-backend-alb
- 리스너 : 8080(프로덕션용) , 8081(테스트용)

5) TargetGroup
- 이름 : prod-ecs-backend-alb-tg1 , prod-ecs-backend-alb-tg2
- 리스너 : 8080 , 8080


6) Codedeploy
- 어플리케이션 이름 : prod-ecs-backend-svc
- 배포 그룹 : prod-ecs-backend-svc-deployment-group


- 새로운 배포에 문제가 있는지 모니터링하기 위한 지정된 시간(이 경우 5분) 동안 유지
- 만약 해당 시간동안 문제가 생길 경우 롤백이 가능
- 시스템 상황에 맞도록 구성하자

2. CICD 구성
- 사전 조건(kubernetes환경) : gitalb + gitlab runner
https://monta010.tistory.com/139
GITLAB Runner 설치 가이드
GITLAB CICD를 활용하기 위해서는 GITLAB Runner가 필요Runner를 통하여 Build . Deploy등을 진행 공식 문서 참고https://docs.gitlab.com/runner/install/kubernetes.html GitLab Runner Helm Chart | GitLabGitLab product documentation.d
monta010.tistory.com
https://docs.gitlab.com/ee/install/docker/configuration.html
Configure GitLab running in a Docker container | GitLab
GitLab product documentation.
docs.gitlab.com
https://docs.gitlab.com/runner/install/docker.html
Run GitLab Runner in a container | GitLab
GitLab product documentation.
docs.gitlab.com
1) GITLAB CI yml
- 테스트용이므로 variable는 하드코딩하여 테스트
- 실제 운영시에는 gitlab variable에 넣어서 변수로 사용 추천
variables:
ECR_REPOSITORY: backend
ECS_CLUSTER: prod-ecs-cluster
ECS_SERVICE: prod-ecs-backend-svc
TASK_DEFINITION: prod-ecs-backend
AWS_REGION: "Region
AWS_ACCOUNT: "Account"
AWS_ACCESS_KEY_ID: "Accesskey"
AWS_SECRET_ACCESS_KEY: "secret_key"
S3_BUCKET: prod-ecs-cluster-s3
stages:
- configure
- build
- ecs-task
- deploy
configure:
stage: configure
image:
name: gcr.io/kaniko-project/executor:debug
entrypoint: [""]
only:
- main
script:
- mkdir -p /kaniko/.docker
- echo "{\"auths\":{\"${AWS_ACCOUNT}.dkr.ecr.${AWS_REGION}.amazonaws.com\":{\"auth\":\"$(echo -n \"AWS:$(aws ecr get-login-password --region ${AWS_REGION})\" | base64)\"}}}" > /kaniko/.docker/config.json
build:
stage: build
image:
name: gcr.io/kaniko-project/executor:debug
entrypoint: [""]
variables:
AWS_SDK_LOAD_CONFIG: "true"
only:
- main
script:
- mkdir -p /kaniko/.docker
- echo "{\"credsStore\":\"ecr-login\"}" > /kaniko/.docker/config.json
- /kaniko/executor
--context "${CI_PROJECT_DIR}"
--dockerfile "${CI_PROJECT_DIR}/Dockerfile"
--destination "${AWS_ACCOUNT}.dkr.ecr.${AWS_REGION}.amazonaws.com/${ECR_REPOSITORY}:latest"
--destination "${AWS_ACCOUNT}.dkr.ecr.${AWS_REGION}.amazonaws.com/${ECR_REPOSITORY}:${CI_COMMIT_SHA}"
ecs-task:
stage: ecs-task
image:
name: amazon/aws-cli
entrypoint: [""]
before_script:
- yum install -y jq
script:
# 현재 작업 정의 가져오기
- TASK_DEFINITION=$(aws ecs describe-task-definition --task-definition ${TASK_DEFINITION} --region ${AWS_REGION})
- NEW_TASK_DEFINITION=$(echo $TASK_DEFINITION | jq --arg IMAGE "${AWS_ACCOUNT}.dkr.ecr.${AWS_REGION}.amazonaws.com/${ECR_REPOSITORY}:${CI_COMMIT_SHA}" '.taskDefinition | .containerDefinitions[0].image = $IMAGE | del(.taskDefinitionArn) | del(.revision) | del(.status) | del(.requiresAttributes) | del(.compatibilities) | del(.registeredAt) | del(.registeredBy)')
# 새 작업 정의 등록 및 ARN 추출
- aws ecs register-task-definition --region ${AWS_REGION} --cli-input-json "${NEW_TASK_DEFINITION}" | jq -r '.taskDefinition.taskDefinitionArn' > task-definition-arn.txt
only:
- main
artifacts:
paths:
- task-definition-arn.txt
deploy:
stage: deploy
image:
name: amazon/aws-cli
entrypoint: [""]
before_script:
- yum install -y zip
script:
# 이전 stage에서 생성된 Task Definition ARN 읽기
- NEW_TASK_DEF_ARN=$(cat task-definition-arn.txt)
# appspec.yml 파일 복사 및 업데이트
- sed -i "s|<TASK_DEFINITION>|${NEW_TASK_DEF_ARN}|g" appspec.yml
# appsepc.yml 확인
- cat appspec.yml
# scripts와 appspec.yaml을 포함한 배포 패키지 생성
- zip -r deploy.zip appspec.yml scripts/
# 배포 패키지를 S3에 업로드
- aws s3 cp deploy.zip s3://${S3_BUCKET}/deploy.zip
# CodeDeploy 배포 시작
- |
aws deploy create-deployment \
--application-name "${ECS_SERVICE}" \
--deployment-group-name ${ECS_SERVICE}-deployment-group \
--s3-location bucket=${S3_BUCKET},key=deploy.zip,bundleType=zip \
--region "${AWS_REGION}"
only:
- main
2) codedeploy appspec.yml
- TASK_DEFINITION 정보는 gitalb ci 에서 업데이트
version: 0.0
Resources:
- TargetService:
Type: AWS::ECS::Service
Properties:
TaskDefinition: <TASK_DEFINITION>
LoadBalancerInfo:
ContainerName: "prod-backend"
ContainerPort: 8080
PlatformVersion: "EC2"
3) 파이프라인


4) S3 - Codedeploy 파일
- gitlab ci가 완료되면 appspec.yml을 압축해서 s3 업로드(추후에 codedeploy에서 참고하여 배포 진행)

5) CodeDeploy
- gitlab ci가 완료되면 s3 deploy.zip 파일을 참고하여 deploy를 진행
- 블루/그린 배포로 진행하므로 원본 트래픽 -> 대체 트래픽으로 완전히 전환 후 다시 원본으로 전환처리

- 배포 진행 중..

- 배포 완료 (약 8분)

- TargetGroup 상태
- 기존 테스트 리스너에는 ecs ec2 인스턴스가 존재하지 않았지만, 블루/그린으로 배포하면서 트래픽 전환으로 인하여 targetGroup 추가됨
- 배포 전상태

- 배포 후

'AWS > CICD' 카테고리의 다른 글
AWS EC2 Gitlab CI Codedeploy (0) | 2025.01.24 |
---|
댓글