CI/CD(지속적 통합 및 지속적 배포)는 빠르고 신뢰할 수 있는 소프트웨어 전달을 달성하기 위해 애플리케이션의 빌드, 테스트 및 배포를 자동화하는 소프트웨어 개발 프로세스입니다.

CI/CD 과정은 지속적 통합(CI)에서 시작됩니다. 개발자들은 코드를 공유 저장소에 자주 병합하며, 이러한 변경 사항은 즉시 자동화된 빌드 및 테스트 프로세스를 트리거합니다. 통합 테스트를 통해 잠재적인 문제를 조기에 발견함으로써 코드 품질을 보장합니다.
다음으로 지속적 배포(CD)는 테스트가 완료된 애플리케이션을 자동으로 운영 환경에 배포합니다. 이 자동화된 프로세스는 인적 오류를 줄이고 배포 속도를 획기적으로 높입니다. 배포 파이프라인을 통해 테스트 및 검토 후 언제든지 대상 환경에 애플리케이션을 안전하게 출시할 수 있습니다.
현대 CI/CD 프로세스에서 컨테이너화는 매우 중요한 역할을 합니다. Docker와 같은 컨테이너 기술은 애플리케이션과 그 의존성을 격리된 환경에서 패키징하여, 서로 다른 환경에서도 일관된 작동을 보장합니다. 이는 배포 과정을 단순화할 뿐만 아니라 애플리케이션의 이동성과 확장성을 향상시킵니다.

Blue-Green 배포는 컨테이너 환경에 특히 적합한 전략입니다. 이 전략에서는 'Blue'와 'Green'이라는 두 개의 동일하지만 독립적인 생산 환경을 유지합니다.



이 섹션에서는 Node.js 프로젝트를 컨테이너화하고, 이미지가 정상적으로 작동하는지 확인한 후 AWS ECR에 저장하는 과정을 다룹니다.

일관되고 가벼운 컨테이너 런타임 환경을 위해 빌드된 이미지들을 저장하는 곳이 컨테이너 이미지 레지스트리입니다. 대표적으로 '도커 허브'가 있으며, AWS에서 제공하는 관리형 OCI 표준 이미지 저장소 서비스가 바로 AWS ECR입니다.
AWS Workshop에서 제공하는 샘플 웹사이트 프로젝트를 사용하여 실습을 진행합니다. 개발 환경으로는 AWS CLI와 주요 도구들이 미리 구성된 AWS CloudShell을 사용합니다.
pureweb.zip)을 업로드합니다.unzip -qq pureweb.zip
ls

00 폴더에는 기본 HTTP 서버 코드(index.js)와 의존성 목록(package.json)이 들어있습니다. 루트 경로(/) 방문 시 현재 시간을 반환하는 단순한 서버입니다.
const express = require('express');
const app = express();
const port = 3000;
app.get('/', (req, res) => {
return res.send(`OK - ${new Date()}`)
});
app.listen(port, () => {
return console.log(`Example app listening on port ${port}`)
});
# Node.js 버전 확인
node --version
# 라이브러리 설치
npm install
# 서버 시작
node index.js
서버가 실행되면 Example app listening on port 3000 메시지가 출력됩니다.
다른 탭에서 curl을 통해 응답을 확인합니다.
curl http://localhost:3000

애플리케이션을 실행하기 위해 거쳤던 과정(OS 준비, 환경 설정, 라이브러리 설치, 실행)을 하나의 이미지로 굽는 과정입니다.
01 폴더에는 위 과정을 자동화한 Dockerfile이 포함되어 있습니다.
npm install 실행
먼저 공개 ECR 이미지를 가져오기 위해 로그인을 진행한 후 빌드를 시작합니다.
# Public ECR 로그인
aws ecr-public get-login-password --region us-east-1 | docker login --username AWS --password-stdin public.ecr.aws
# 이미지 빌드
docker build . -t pureweb
docker images

## AWS ECR에 이미지 푸시
빌드된 이미지를 AWS 개인 저장소(ECR)에 업로드하여 관리합니다. 이 과정은 AWS 콘솔에서 리포지토리를 먼저 생성한 뒤 진행합니다.
### 1. AWS 콘솔에서 ECR 리포지토리 생성
캡처 화면은 생략되었지만, 다음 순서로 간단히 생성할 수 있습니다.
1. AWS 관리 콘솔 검색창에 **ECR**을 입력하고 **Elastic Container Registry**로 이동합니다.
2. 왼쪽 메뉴에서 **Repositories**를 선택한 후, 우측 상단의 **Create repository** 버튼을 클릭합니다.
3. **General settings**에서 다음을 설정합니다:
- **Visibility settings**: `Private` 선택
- **Repository name**: `pureweb-repo` 입력
4. 페이지 하단의 **Create repository**를 클릭하여 생성을 완료합니다.
> **Tip: CLI로 생성하고 싶다면?**
> 콘솔이 번거롭다면 다음 명령어로 즉시 생성할 수도 있습니다:
> `aws ecr create-repository --repository-name pureweb-repo --region ap-northeast-2`
### 2. ECR 로그인 및 이미지 태그 설정
리포지토리가 생성되었다면, 이제 CloudShell에서 이미지를 업로드할 차례입니다. 생성된 리포지토리의 **View push commands** 버튼을 누르면 나오는 명령어를 참고해도 좋습니다.
```bash
# 1. ECR 로그인 (계정 ID 확인 및 인증 토큰 가져오기)
AWS_ACCOUNT_ID=$(aws sts get-caller-identity --query Account --output text)
aws ecr get-login-password --region ap-northeast-2 | docker login --username AWS --password-stdin ${AWS_ACCOUNT_ID}.dkr.ecr.ap-northeast-2.amazonaws.com
# 2. 이미지 태그 설정 (로컬 이미지를 ECR 주소와 매칭)
docker tag pureweb:latest ${AWS_ACCOUNT_ID}.dkr.ecr.ap-northeast-2.amazonaws.com/pureweb-repo:latest
# ECR 저장소로 이미지 전송
docker push ${AWS_ACCOUNT_ID}.dkr.ecr.ap-northeast-2.amazonaws.com/pureweb-repo:latest
이제 ECR 리포지토리 목록에서 푸시된 이미지를 확인할 수 있습니다. 저장된 이미지는 이후 ECS 서비스의 새로운 버전으로 배포되어, 실제 Blue-Green 배포 파이프라인의 핵심 리소스로 사용됩니다.

컨테이너 이미지를 ECR에 안전하게 저장했다면, 이제 이 이미지를 사용하여 Amazon ECS(Elastic Container Service) 환경을 구축할 차례입니다. ECS는 작업 정의(Task Definition)를 통해 클러스터 내에서 컨테이너를 실행하고 관리합니다.







ECS와 관련 서비스들이 상호작용하기 위해 필요한 권한을 설정합니다.
role-ecs-pureweb (현재 앱은 외부 서비스를 쓰지 않으므로 정책 연결 없이 생성)AmazonECSTaskExecutionRolePolicy 연결.role-ecs-task-executionrole-ecs-codedeploy
방화벽 규칙을 통해 트래픽 흐름을 제어합니다.
sg_alb-pureweb)0.0.0.0/0 (모든 트래픽 허용)sg_ecs-pureweb)0.0.0.0/0 (테스트용)
Blue-Green 배포를 위해 두 개의 대상 그룹을 생성하고 ALB 리스너를 설정합니다.
Blue-Green 배포 전략을 위해 tg-pureweb-A와 tg-pureweb-B 두 개를 만듭니다.
tg-pureweb-A, tg-pureweb-B

alb-pureweb / 방식: 인터넷 방향sg_alb-pureweb 선택tg-pureweb-A로 전달
지금까지 ECR에 이미지를 등록하고 ECS 및 ALB를 구성하여 초기 배포를 성공적으로 마쳤습니다. 이제 이 과정을 자동화하여 소스 코드가 수정될 때마다 자동으로 빌드와 블루-그린 배포가 진행되도록 CI/CD 파이프라인을 구축해 보겠습니다.
사용될 서비스와 각 단계의 역할은 다음과 같습니다:
버전 관리 시스템을 대신할 S3 버킷을 만듭니다. CI/CD 트리거를 위해서는 반드시 버킷의 버전 관리가 활성화되어 있어야 합니다.
bucket-source-{본인이름}-{날짜}pipeline-ecs-blue-greenrole-codepipeline 입력bucket-source-{yourname}-{date} 버킷 선택Archive.zip (이 파일은 설정이 완료된 후 나중에 업로드합니다.)AWS CodeBuild를 선택하고 프로젝트 생성을 클릭합니다.buildproject-pureweb-ecs1로 설정role-codebuild 지정SourceArtifact를 선택하고 다음으로 넘어갑니다. (자동 재시도 활성화 체크 해제)배포(Deploy) 구성 파일이 아직 준비되지 않았으므로 먼저 파이프라인 생성을 완료합니다.
1. 테스트 단계는 '테스트 단계 건너뛰기'를 클릭합니다.
2. 배포 단계 또한 실패 시 자동 롤백/재시도 체크를 해제하고 '배포 단계 일시적으로 건너뛰기'를 클릭합니다.
3. 파이프라인 설정을 검토하고 파이프라인 생성을 완료합니다.
참고: 파이프라인이 생성되면 바로 실행되지만 소스 단계에서 오류가 발생하는 것이 정상입니다. S3 버킷에 아직
Archive.zip파일을 업로드하지 않았기 때문입니다.
생성한 파이프라인이 CodeDeploy와 ECS 등 다른 리소스에 접근하고 제어할 수 있도록 IAM 역할에 권한을 추가해야 합니다.
role-codepipeline)role-codepipeline을 찾습니다.{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowCodeDeployDeploymentActions",
"Action": [
"codedeploy:CreateDeployment",
"codedeploy:GetDeployment",
"codedeploy:GetApplication",
"codedeploy:GetApplicationRevision",
"codedeploy:RegisterApplicationRevision",
"codedeploy:GetDeploymentConfig",
"ecs:RegisterTaskDefinition"
],
"Resource": [
"*"
],
"Effect": "Allow"
},
{
"Sid": "AllowPassRoleToECS",
"Effect": "Allow",
"Action": "iam:PassRole",
"Resource": [
"*"
],
"Condition": {
"StringEquals": {
"iam:PassedToService": [
"ecs.amazonaws.com",
"ecs-tasks.amazonaws.com"
]
}
}
}
]
}
policy-codeploy-to-ecs를 입력하고 생성합니다.role-codebuild)role-codebuild를 찾습니다.AmazonEC2ContainerRegistryPowerUserAmazonElasticContainerRegistryPublicPowerUserCodeBuild와 CodeDeploy가 참조할 환경 설정 파일을 준비합니다. 컴퓨터의 02 폴더 내 실습 파일을 다음과 같이 수정합니다.
taskdef.yml (ECS 작업 정의):
02/taskdef.yml 파일 내용을 덮어씁니다.containerDefinitions.image의 값(URL)을 <ImageURI> 플레이스홀더 텍스트로 교체합니다.tags 블록은 삭제합니다.buildspec.yml (CodeBuild 실행 스크립트):
{ACCOUNT_ID} 텍스트를 사용 중인 샌드박스 계정 ID로 교체합니다.이제 준비된 설정 파일을 바탕으로 CodePipeline에 최종 배포 단계를 추가합니다. CodePipeline 페이지로 돌아와 pipeline-ecs-blue-green의 편집(Edit)을 클릭합니다.
DefinitionArtifact와 ImageArtifact 두 개를 새로 추가한 뒤 완료를 누릅니다.Deploy로 지정합니다.deploy-blue-green-for-ecsDefinitionArtifact, ImageArtifact 추가DefinitionArtifact 선택, taskdef.json 입력DefinitionArtifact 선택, appspec.yaml 입력ImageArtifact 선택 후, 플레이스홀더 텍스트 <ImageURI>를 매핑합니다.왜 이렇게 설정하나요?
buildspec.yml을 통해 이미지가 생성되면 CodeBuild는 이를 파이프라인을 통해 CodeDeploy(Deploy 단계)로 전달합니다. CodeDeploy는DefinitionArtifact와ImageArtifact의 정보를 받아 ECS에 새로운 구성을 업데이트하며 안전하게 블루-그린 배포를 진행하게 됩니다.
모든 설정이 완료되었습니다! 코드를 S3에 푸시하면 이 파이프라인이 트리거되어 새 이미지를 빌드하고 ECS 블루-그린 배포를 수행합니다. 과정의 흐름은 다음과 같습니다.
02 폴더 내의 모든 파일을 압축하여 Archive.zip을 만듭니다. 이를 S3 소스 버킷에 업로드하면 Source 단계가 신호를 받고 빌드 단계로 전송합니다.buildspec.yml 스크립트를 수행하고 이미지를 컴파일하는 상세 과정을 로그를 통해 확인할 수 있습니다.마치며
단순한 코드 작성에서 끝나지 않고, ECS 컨테이너화부터 CodePipeline을 활용한 무중단 Blue-Green 배포까지 전체 CI/CD 사이클을 직접 구축해 보니 인프라 자동화가 주는 안정성과 효율성을 깊이 체감할 수 있었습니다.