본 콘텐츠의 이미지 및 내용은 AI로 생성되었습니다.
본 콘텐츠의 이미지 및 내용을 무단으로 복제, 배포, 수정하여 사용할 경우 저작권법에 의해 법적 제재를 받을 수 있습니다.
이미지 로딩 중...
AI Generated
2025. 12. 20. · 7 Views
AWS CodePipeline 구성 완벽 가이드
AWS CodePipeline을 처음 접하는 개발자를 위한 실전 가이드입니다. 파이프라인 생성부터 소스, 빌드, 배포 스테이지 구성까지 단계별로 배워봅니다. 자동화된 CI/CD 파이프라인을 직접 만들어보세요.
목차
1. CodePipeline이란?
어느 날 김개발 씨는 코드를 수정할 때마다 직접 서버에 접속해 배포하는 일이 너무 번거롭다고 느꼈습니다. "매번 이렇게 해야 하나요?" 선배 박시니어 씨가 웃으며 말했습니다.
"CodePipeline을 사용하면 이 모든 과정이 자동화됩니다."
CodePipeline은 AWS에서 제공하는 완전관리형 지속적 전달 서비스입니다. 마치 공장의 컨베이어 벨트처럼 코드가 자동으로 빌드되고 테스트되어 배포되는 과정을 관리합니다.
이를 통해 개발자는 코드 작성에만 집중할 수 있습니다.
다음 코드를 살펴봅시다.
// CodePipeline 기본 구조 예시 (AWS SDK v3)
import { CodePipelineClient, GetPipelineCommand } from "@aws-sdk/client-codepipeline";
// CodePipeline 클라이언트 생성
const client = new CodePipelineClient({ region: "ap-northeast-2" });
// 파이프라인 정보 조회
const command = new GetPipelineCommand({
name: "my-web-app-pipeline"
});
try {
const response = await client.send(command);
// 파이프라인의 각 스테이지 정보를 확인할 수 있습니다
console.log(response.pipeline.stages);
} catch (error) {
console.error("파이프라인 조회 실패:", error);
}
김개발 씨는 입사 6개월 차 백엔드 개발자입니다. 오늘도 열심히 새로운 기능을 개발했고, 이제 서버에 배포할 시간입니다.
하지만 배포 과정이 만만치 않습니다. 먼저 코드를 Git에 푸시하고, EC2 서버에 SSH로 접속합니다.
그다음 코드를 pull 받고, npm install로 의존성을 설치합니다. 빌드를 실행하고, 프로세스를 재시작합니다.
매번 이런 과정을 반복하다 보니 실수도 잦고, 시간도 많이 걸립니다. 선배 박시니어 씨가 김개발 씨의 모니터를 보며 말했습니다.
"아직도 수동으로 배포하고 있어요? CodePipeline을 쓰면 이 모든 게 자동화됩니다." 그렇다면 CodePipeline이란 정확히 무엇일까요?
쉽게 비유하자면, CodePipeline은 마치 자동차 공장의 조립 라인과 같습니다. 자동차 부품이 컨베이어 벨트를 따라 이동하면서 조립, 검사, 도색 과정을 거치듯이, 코드도 파이프라인을 따라 이동하면서 빌드, 테스트, 배포 과정을 자동으로 거칩니다.
개발자는 코드만 푸시하면 나머지는 알아서 처리됩니다. CodePipeline이 없던 시절에는 어땠을까요?
개발자들은 모든 배포 과정을 수동으로 처리해야 했습니다. 코드를 수정할 때마다 서버에 접속하고, 명령어를 하나하나 입력했습니다.
실수로 빌드를 깜빡하거나, 잘못된 브랜치를 배포하는 일도 빈번했습니다. 더 큰 문제는 배포 과정이 사람마다 달랐다는 것입니다.
같은 서비스인데도 누가 배포하느냐에 따라 절차가 달라졌습니다. 바로 이런 문제를 해결하기 위해 CodePipeline이 등장했습니다.
CodePipeline을 사용하면 배포 프로세스를 표준화할 수 있습니다. 누가 배포하든 같은 과정을 거치게 됩니다.
또한 자동화를 통해 사람의 실수를 줄일 수 있습니다. 무엇보다 개발자가 반복적인 배포 작업에서 벗어나 본연의 업무에 집중할 수 있다는 큰 이점이 있습니다.
CodePipeline은 여러 개의 스테이지로 구성됩니다. 각 스테이지는 특정한 역할을 담당합니다.
가장 기본적인 구조는 소스 스테이지, 빌드 스테이지, 배포 스테이지로 이루어집니다. 소스 스테이지는 코드 저장소를 모니터링합니다.
GitHub이나 CodeCommit에 새로운 커밋이 푸시되면 자동으로 감지합니다. 빌드 스테이지는 CodeBuild를 사용해 코드를 컴파일하고 테스트합니다.
배포 스테이지는 빌드된 애플리케이션을 실제 서버에 배포합니다. 실제 현업에서는 어떻게 활용할까요?
예를 들어 쇼핑몰 서비스를 개발한다고 가정해봅시다. 개발자가 새로운 결제 기능을 개발해 GitHub의 main 브랜치에 푸시합니다.
CodePipeline이 이를 자동으로 감지하고, CodeBuild에서 빌드와 테스트를 실행합니다. 모든 테스트가 통과하면 자동으로 스테이징 환경에 배포됩니다.
검증 후 승인 단계를 거쳐 프로덕션 환경에도 배포됩니다. 이 모든 과정이 개발자의 개입 없이 자동으로 진행됩니다.
하지만 주의할 점도 있습니다. 초보 개발자들이 흔히 하는 실수 중 하나는 테스트 없이 바로 프로덕션에 배포하는 파이프라인을 만드는 것입니다.
이렇게 하면 버그가 있는 코드가 그대로 배포될 수 있습니다. 따라서 반드시 빌드 스테이지에 테스트를 포함시키고, 필요하다면 수동 승인 단계를 추가해야 합니다.
다시 김개발 씨의 이야기로 돌아가 봅시다. 박시니어 씨의 설명을 들은 김개발 씨는 눈이 반짝였습니다.
"이제 더 이상 수동으로 배포하지 않아도 되겠네요!" CodePipeline을 제대로 이해하면 배포 프로세스를 자동화하고 안정적으로 관리할 수 있습니다. 여러분도 오늘 배운 내용을 실제 프로젝트에 적용해 보세요.
실전 팁
💡 - 처음에는 간단한 3단계 파이프라인(소스-빌드-배포)으로 시작하세요
- 각 스테이지마다 실패 시 알림을 설정하면 문제를 빠르게 파악할 수 있습니다
- 스테이징 환경을 거쳐 프로덕션에 배포하는 다단계 구조를 추천합니다
2. 파이프라인 생성
이론은 충분히 들었으니 이제 직접 파이프라인을 만들어볼 차례입니다. 김개발 씨는 AWS 콘솔을 열고 CodePipeline 서비스를 찾았습니다.
"생각보다 간단하네요?" 하지만 설정 항목들을 보니 어디서부터 시작해야 할지 막막했습니다.
파이프라인 생성은 CodePipeline 사용의 첫 단계입니다. 파이프라인의 이름을 정하고, 서비스 역할을 설정하며, 아티팩트 저장소를 지정하는 과정입니다.
이 설정들이 전체 파이프라인의 기반이 됩니다.
다음 코드를 살펴봅시다.
// AWS SDK를 사용한 파이프라인 생성
import { CodePipelineClient, CreatePipelineCommand } from "@aws-sdk/client-codepipeline";
const client = new CodePipelineClient({ region: "ap-northeast-2" });
const params = {
pipeline: {
name: "my-first-pipeline",
// 파이프라인이 사용할 IAM 역할
roleArn: "arn:aws:iam::123456789012:role/CodePipelineServiceRole",
// 아티팩트를 저장할 S3 버킷
artifactStore: {
type: "S3",
location: "my-pipeline-artifacts-bucket"
},
stages: [] // 스테이지는 나중에 추가합니다
}
};
const command = new CreatePipelineCommand(params);
const response = await client.send(command);
console.log("파이프라인 생성 완료:", response.pipeline.name);
김개발 씨는 AWS 콘솔에서 CodePipeline 메뉴를 클릭했습니다. 화면 중앙에 큰 버튼이 보입니다.
"파이프라인 생성"이라고 적혀 있습니다. 버튼을 클릭하자 설정 화면이 나타났습니다.
첫 번째 단계는 "파이프라인 설정"입니다. 여기서 파이프라인의 기본적인 정보를 입력해야 합니다.
가장 먼저 파이프라인 이름을 입력해야 합니다. 이름은 파이프라인을 식별하는 중요한 요소입니다.
마치 프로젝트 폴더에 이름을 붙이는 것과 같습니다. "my-app-pipeline"이나 "backend-deploy-pipeline"처럼 무엇을 위한 파이프라인인지 명확하게 알 수 있는 이름을 사용하는 것이 좋습니다.
팀원들이 나중에 봤을 때도 쉽게 이해할 수 있어야 합니다. 다음은 서비스 역할 설정입니다.
CodePipeline이 다른 AWS 서비스를 사용하려면 권한이 필요합니다. 예를 들어 S3에 아티팩트를 저장하거나, CodeBuild를 실행하거나, EC2에 배포하려면 그에 맞는 권한이 있어야 합니다.
이런 권한을 부여하는 것이 바로 IAM 역할입니다. 처음 파이프라인을 만들 때는 "새 서비스 역할"을 선택하면 됩니다.
AWS가 자동으로 필요한 권한을 가진 역할을 생성해줍니다. 역할 이름은 자동으로 생성되지만, 원한다면 직접 지정할 수도 있습니다.
세 번째는 아티팩트 저장소 설정입니다. 아티팩트란 무엇일까요?
쉽게 말하면 파이프라인의 각 단계에서 생성되는 파일들입니다. 소스 코드, 빌드된 파일, 테스트 결과 등이 모두 아티팩트입니다.
이런 파일들을 어딘가에 저장해야 다음 단계에서 사용할 수 있습니다. CodePipeline은 기본적으로 S3를 아티팩트 저장소로 사용합니다.
"기본 위치"를 선택하면 AWS가 자동으로 S3 버킷을 생성해줍니다. 버킷 이름은 "codepipeline-ap-northeast-2-123456789"처럼 자동으로 생성됩니다.
고급 설정에서는 암호화 옵션도 선택할 수 있습니다. 보안이 중요한 프로젝트라면 아티팩트를 암호화하는 것이 좋습니다.
AWS KMS(Key Management Service)를 사용해 데이터를 암호화할 수 있습니다. 기본 AWS 관리형 키를 사용하거나, 직접 만든 고객 관리형 키를 사용할 수 있습니다.
실제 현업에서는 어떻게 설정할까요? 대부분의 팀은 프로젝트마다 별도의 파이프라인을 만듭니다.
예를 들어 "frontend-production-pipeline", "backend-staging-pipeline"처럼 환경과 목적을 명확히 구분합니다. 또한 아티팩트 저장소는 별도의 S3 버킷을 만들어 사용하는 경우가 많습니다.
이렇게 하면 아티팩트 관리가 더 명확해집니다. 주의할 점이 있습니다.
파이프라인 이름은 한번 정하면 변경할 수 없습니다. 나중에 이름을 바꾸려면 파이프라인을 삭제하고 다시 만들어야 합니다.
따라서 처음부터 명확하고 일관된 이름 규칙을 정하는 것이 중요합니다. 김개발 씨는 신중하게 설정을 완료했습니다.
파이프라인 이름은 "web-app-deploy-pipeline"으로, 서비스 역할은 자동 생성으로, 아티팩트 저장소는 기본 위치로 선택했습니다. "다음" 버튼을 클릭하자 소스 스테이지 설정 화면으로 넘어갔습니다.
파이프라인의 기본 설정은 건물의 기초를 다지는 것과 같습니다. 튼튼한 기초 위에서 각 스테이지를 쌓아올릴 수 있습니다.
실전 팁
💡 - 파이프라인 이름은 변경할 수 없으니 처음부터 명확하게 정하세요
- 처음에는 자동 생성되는 서비스 역할을 사용하는 것이 안전합니다
- 아티팩트 저장소는 기본 위치로 시작하고, 나중에 필요하면 별도 버킷을 사용하세요
3. 소스 스테이지
파이프라인의 기본 설정을 마친 김개발 씨는 이제 소스 스테이지를 설정해야 합니다. "소스 스테이지가 뭐죠?" 박시니어 씨가 설명했습니다.
"코드가 어디에 있는지, 어떤 변화를 감지할지 정하는 단계입니다."
소스 스테이지는 파이프라인의 시작점입니다. GitHub, CodeCommit, S3 같은 소스 저장소를 연결하고, 코드 변경을 자동으로 감지하도록 설정합니다.
새로운 커밋이 푸시되면 파이프라인이 자동으로 시작됩니다.
다음 코드를 살펴봅시다.
// 소스 스테이지 설정 (GitHub 연결)
const sourceStage = {
name: "Source",
actions: [
{
name: "SourceAction",
actionTypeId: {
category: "Source",
owner: "AWS",
provider: "CodeStarSourceConnection", // GitHub 연결용
version: "1"
},
configuration: {
// GitHub 연결 ARN
ConnectionArn: "arn:aws:codestar-connections:ap-northeast-2:123456789012:connection/abc123",
FullRepositoryId: "mycompany/web-app", // 리포지토리 경로
BranchName: "main", // 모니터링할 브랜치
OutputArtifactFormat: "CODE_ZIP" // 출력 형식
},
outputArtifacts: [{ name: "SourceOutput" }]
}
]
};
소스 스테이지 설정 화면을 본 김개발 씨는 여러 옵션이 있다는 것을 알았습니다. CodeCommit, GitHub, Bitbucket, S3 등 다양한 소스 제공자가 보입니다.
김개발 씨의 팀은 GitHub을 사용하고 있습니다. 따라서 소스 제공자로 "GitHub(버전 2)"를 선택했습니다.
버전 2는 CodeStar Connections를 사용하는 최신 방식입니다. 소스 제공자를 선택하는 것이 첫 번째 단계입니다.
각 제공자마다 특징이 있습니다. CodeCommit은 AWS의 완전관리형 Git 저장소입니다.
AWS 환경과 가장 잘 통합됩니다. GitHub은 전 세계에서 가장 많이 사용되는 코드 저장소입니다.
오픈소스 프로젝트나 협업에 유리합니다. Bitbucket은 Atlassian 제품군과 잘 연동됩니다.
S3는 정적 파일이나 미리 빌드된 아티팩트를 소스로 사용할 때 선택합니다. GitHub을 선택하면 연결을 설정해야 합니다.
처음 GitHub을 연결할 때는 "GitHub에 연결"버튼을 클릭합니다. 새 창이 열리면서 GitHub 로그인을 요청합니다.
로그인 후 CodePipeline이 리포지토리에 접근할 수 있도록 권한을 부여합니다. 이 과정을 통해 CodeStar Connection이 생성됩니다.
연결이 완료되면 리포지토리를 선택합니다. 드롭다운 메뉴에서 자신의 GitHub 리포지토리 목록이 나타납니다.
김개발 씨는 "mycompany/web-app"을 선택했습니다. 이것이 파이프라인이 모니터링할 리포지토리입니다.
다음은 브랜치 선택입니다. 어떤 브랜치의 변경사항을 감지할지 정해야 합니다.
대부분의 팀은 "main"이나 "master" 브랜치를 선택합니다. 하지만 개발 환경을 위한 파이프라인이라면 "develop" 브랜치를 선택할 수도 있습니다.
김개발 씨는 프로덕션 배포를 위한 파이프라인이므로 "main" 브랜치를 선택했습니다. 변경 감지 옵션도 중요합니다.
기본적으로 CodePipeline은 CloudWatch Events를 사용해 변경을 감지합니다. 누군가 main 브랜치에 커밋을 푸시하면 GitHub이 웹훅으로 AWS에 알립니다.
CodePipeline이 이를 감지하고 자동으로 실행됩니다. 이것이 가장 빠르고 효율적인 방식입니다.
또 다른 옵션은 폴링 방식입니다. CodePipeline이 주기적으로 리포지토리를 확인해 변경사항이 있는지 검사합니다.
하지만 이 방식은 느리고 비효율적이어서 권장하지 않습니다. 출력 아티팩트는 자동으로 설정됩니다.
소스 스테이지는 리포지토리의 코드를 ZIP 파일로 압축합니다. 이 파일이 바로 출력 아티팩트입니다.
기본 이름은 "SourceArtifact"지만, 원한다면 "SourceOutput"처럼 다른 이름을 사용할 수 있습니다. 이 아티팩트는 S3에 저장되고, 다음 스테이지에서 입력으로 사용됩니다.
실제 현업에서는 여러 전략을 사용합니다. 어떤 팀은 브랜치마다 별도의 파이프라인을 만듭니다.
main 브랜치는 프로덕션 배포 파이프라인으로, develop 브랜치는 스테이징 배포 파이프라인으로 연결하는 식입니다. 또 어떤 팀은 태그 기반 배포를 사용합니다.
v1.0.0 같은 태그를 푸시하면 파이프라인이 실행되도록 설정합니다. 주의할 점이 있습니다.
GitHub 연결은 처음 한 번만 설정하면 됩니다. 같은 조직의 다른 리포지토리를 추가할 때는 기존 연결을 재사용할 수 있습니다.
하지만 연결을 삭제하면 그 연결을 사용하는 모든 파이프라인이 작동하지 않습니다. 김개발 씨는 설정을 완료하고 "다음" 버튼을 눌렀습니다.
이제 main 브랜치에 새로운 커밋이 푸시될 때마다 파이프라인이 자동으로 시작될 것입니다. 소스 스테이지는 파이프라인의 눈과 귀입니다.
코드의 변화를 감지하고, 전체 자동화 프로세스를 시작하는 출발점입니다.
실전 팁
💡 - GitHub 버전 2(CodeStar Connections)를 사용하면 더 안정적입니다
- main 브랜치는 프로덕션, develop 브랜치는 스테이징으로 분리하는 것을 추천합니다
- 출력 아티팩트 이름은 명확하게 지정하면 나중에 디버깅할 때 편리합니다
4. 빌드 스테이지
소스 스테이지 설정을 마친 김개발 씨는 다음 단계로 넘어갔습니다. "이제 빌드 스테이지를 설정해야 합니다." 박시니어 씨가 말했습니다.
"여기서 코드를 컴파일하고 테스트하는 것이죠?"
빌드 스테이지는 소스 코드를 실행 가능한 형태로 변환하는 단계입니다. CodeBuild를 사용해 의존성을 설치하고, 코드를 컴파일하며, 테스트를 실행합니다.
빌드가 성공해야 다음 단계로 진행됩니다.
다음 코드를 살펴봅시다.
// buildspec.yml - CodeBuild 빌드 명세 파일
version: 0.2
phases:
install:
runtime-versions:
nodejs: 18
commands:
# 의존성 설치
- npm install
pre_build:
commands:
# 테스트 실행
- npm run test
- echo "테스트 완료"
build:
commands:
# 프로덕션 빌드
- npm run build
- echo "빌드 완료"
artifacts:
files:
# 배포할 파일들
- '**/*'
base-directory: dist
빌드 스테이지 설정 화면에서 김개발 씨는 "빌드 제공자" 선택 메뉴를 봤습니다. 여러 옵션이 있지만, AWS CodeBuild가 가장 일반적입니다.
CodeBuild는 AWS의 완전관리형 빌드 서비스입니다. 마치 클라우드에 있는 빌드 서버라고 생각하면 됩니다.
로컬 컴퓨터에서 "npm run build"를 실행하는 것처럼, CodeBuild가 클라우드에서 같은 작업을 수행합니다. 차이점은 항상 깨끗한 환경에서 시작한다는 것입니다.
매번 새로운 컨테이너에서 빌드가 실행되므로 일관성이 보장됩니다. 빌드 스테이지를 설정하려면 먼저 CodeBuild 프로젝트를 만들어야 합니다.
"프로젝트 생성" 버튼을 클릭하면 새 화면이 열립니다. 프로젝트 이름을 입력합니다.
"web-app-build"처럼 무엇을 빌드하는지 알 수 있는 이름이 좋습니다. 다음은 환경 설정입니다.
빌드를 실행할 환경을 선택해야 합니다. 운영 체제는 Ubuntu Linux가 일반적입니다.
런타임은 프로젝트에 따라 다릅니다. Node.js 프로젝트라면 "Standard" 이미지에서 Node.js 버전을 선택합니다.
Python이라면 Python 런타임을, Java라면 Java 런타임을 선택합니다. 컴퓨팅 성능도 선택할 수 있습니다.
3GB 메모리와 2 vCPU를 가진 기본 인스턴스면 대부분의 경우 충분합니다. 더 큰 프로젝트라면 7GB나 15GB 인스턴스를 선택할 수 있습니다.
가장 중요한 것은 buildspec.yml 파일입니다. 이 파일은 빌드 과정을 정의합니다.
마치 레시피와 같습니다. 어떤 명령어를 어떤 순서로 실행할지 YAML 형식으로 작성합니다.
프로젝트의 루트 디렉토리에 buildspec.yml 파일을 만들어야 합니다. buildspec.yml은 여러 단계로 구성됩니다.
install 단계에서는 필요한 런타임과 도구를 설치합니다. Node.js 18을 사용한다고 명시하고, npm install로 의존성을 설치합니다.
pre_build 단계에서는 빌드 전에 할 작업을 정의합니다. 보통 테스트를 실행합니다.
"npm run test"로 단위 테스트를 돌려 코드에 문제가 없는지 확인합니다. build 단계에서는 실제 빌드를 수행합니다.
"npm run build"로 프로덕션 빌드를 생성합니다. React나 Vue 프로젝트라면 최적화된 정적 파일들이 dist 폴더에 만들어집니다.
마지막으로 artifacts 섹션에서 출력 파일을 지정합니다. 빌드가 완료되면 어떤 파일들을 다음 스테이지로 넘길지 정해야 합니다.
"files" 항목에 파일 패턴을 지정합니다. '**/*'는 모든 파일을 의미합니다.
base-directory를 "dist"로 지정하면 dist 폴더의 내용이 아티팩트로 저장됩니다. 환경 변수도 설정할 수 있습니다.
빌드 시 필요한 환경 변수를 CodeBuild 프로젝트 설정에서 추가할 수 있습니다. API 키나 비밀번호 같은 민감한 정보는 AWS Systems Manager Parameter Store나 Secrets Manager에 저장하고, CodeBuild에서 참조하는 것이 안전합니다.
실제 현업에서는 빌드 단계가 매우 중요합니다. 많은 팀이 빌드 단계에 린터와 정적 분석 도구를 포함시킵니다.
ESLint로 코드 스타일을 검사하고, SonarQube로 코드 품질을 분석합니다. 또한 단위 테스트뿐 아니라 통합 테스트도 실행합니다.
빌드가 실패하면 배포가 중단되므로, 문제를 조기에 발견할 수 있습니다. 주의할 점이 있습니다.
buildspec.yml 파일의 문법 오류는 빌드 실패의 주요 원인입니다. YAML은 들여쓰기에 민감합니다.
탭 대신 스페이스를 사용해야 하고, 들여쓰기 레벨이 정확해야 합니다. 로컬에서 YAML 검증기로 미리 확인하는 것이 좋습니다.
김개발 씨는 buildspec.yml 파일을 프로젝트에 추가하고, CodeBuild 프로젝트를 생성했습니다. 파이프라인 설정에서 방금 만든 빌드 프로젝트를 선택하고 "다음" 버튼을 눌렀습니다.
빌드 스테이지는 파이프라인의 품질 관문입니다. 문제가 있는 코드가 프로덕션에 배포되는 것을 막아줍니다.
실전 팁
💡 - buildspec.yml은 반드시 프로젝트 루트에 위치해야 합니다
- 테스트는 pre_build 단계에서 실행하면 빌드 전에 문제를 발견할 수 있습니다
- 환경 변수로 민감한 정보를 관리할 때는 Secrets Manager를 사용하세요
5. 배포 스테이지
빌드가 성공했으니 이제 마지막 단계입니다. "배포 스테이지에서는 어디에 배포할지 정하는 거죠?" 김개발 씨가 물었습니다.
박시니어 씨가 고개를 끄덕였습니다. "맞아요.
EC2, ECS, Lambda 등 다양한 대상에 배포할 수 있습니다."
배포 스테이지는 빌드된 애플리케이션을 실제 서버에 배포하는 마지막 단계입니다. CodeDeploy, ECS, S3 등 다양한 배포 대상을 선택할 수 있습니다.
이 단계를 통해 사용자가 새로운 버전을 사용할 수 있게 됩니다.
다음 코드를 살펴봅시다.
// appspec.yml - CodeDeploy 배포 명세 파일
version: 0.0
os: linux
files:
# 빌드된 파일을 서버 경로로 복사
- source: /
destination: /var/www/html
hooks:
ApplicationStop:
# 배포 전 애플리케이션 중지
- location: scripts/stop_application.sh
timeout: 300
AfterInstall:
# 파일 복사 후 의존성 설치
- location: scripts/install_dependencies.sh
timeout: 600
ApplicationStart:
# 애플리케이션 시작
- location: scripts/start_application.sh
timeout: 300
배포 스테이지 설정 화면에서 김개발 씨는 여러 배포 제공자 옵션을 봤습니다. CodeDeploy, ECS, S3, CloudFormation 등 선택지가 많습니다.
김개발 씨의 팀은 EC2 인스턴스에서 웹 애플리케이션을 실행하고 있습니다. 따라서 CodeDeploy를 선택했습니다.
CodeDeploy는 EC2 인스턴스나 온프레미스 서버에 애플리케이션을 배포하는 서비스입니다. 마치 택배 배송 시스템과 비슷합니다.
빌드된 애플리케이션이라는 "상품"을 EC2 인스턴스라는 "목적지"에 안전하게 전달합니다. 중요한 것은 무중단 배포가 가능하다는 점입니다.
서비스를 중단하지 않고도 새 버전을 배포할 수 있습니다. CodeDeploy를 사용하려면 먼저 애플리케이션과 배포 그룹을 만들어야 합니다.
CodeDeploy 콘솔로 이동해 "애플리케이션 생성" 버튼을 클릭합니다. 애플리케이션 이름은 "web-app-deploy"처럼 명확하게 지정합니다.
컴퓨팅 플랫폼은 "EC2/온프레미스"를 선택합니다. 다음은 배포 그룹 생성입니다.
배포 그룹은 어떤 서버들에 배포할지 정의합니다. 서비스 역할을 지정하고, 배포 유형을 선택합니다.
현재 위치 배포는 기존 인스턴스를 업데이트하는 방식입니다. 블루/그린 배포는 새 인스턴스를 만들어 트래픽을 전환하는 방식입니다.
환경 구성에서 대상 인스턴스를 지정합니다. EC2 태그를 사용하면 편리합니다.
예를 들어 "Environment: Production" 태그가 붙은 모든 인스턴스에 배포하도록 설정할 수 있습니다. Auto Scaling 그룹을 사용한다면 그룹 이름으로 지정할 수도 있습니다.
배포 설정도 중요합니다. 한 번에 모든 인스턴스를 업데이트할지, 아니면 단계적으로 업데이트할지 선택합니다.
"CodeDeployDefault.OneAtATime"은 인스턴스를 하나씩 업데이트합니다. "CodeDeployDefault.HalfAtATime"은 절반씩 업데이트합니다.
"CodeDeployDefault.AllAtOnce"는 모든 인스턴스를 동시에 업데이트합니다. 프로덕션 환경에서는 OneAtATime이나 HalfAtATime을 권장합니다.
문제가 발생해도 일부 서버는 정상 작동하므로 서비스가 완전히 중단되지 않습니다. 배포 과정을 정의하는 appspec.yml 파일이 필요합니다.
이 파일은 빌드 아티팩트에 포함되어야 합니다. 소스 코드 저장소의 루트에 appspec.yml을 만듭니다.
파일에는 어떤 파일을 어디에 복사할지, 어떤 스크립트를 언제 실행할지 정의합니다. files 섹션에서 소스와 목적지를 지정합니다.
빌드된 모든 파일을 /var/www/html 디렉토리로 복사하라고 명시합니다. **훅(Hooks)**은 배포의 각 단계에서 실행할 스크립트를 정의합니다.
ApplicationStop 훅에서는 기존 애플리케이션을 중지합니다. PM2나 systemd로 실행 중인 프로세스를 정리합니다.
AfterInstall 훅에서는 새 파일이 복사된 후 필요한 작업을 합니다. npm install로 의존성을 설치하거나, 환경 설정 파일을 복사합니다.
ApplicationStart 훅에서는 새 버전의 애플리케이션을 시작합니다. "pm2 restart app"이나 "systemctl start myapp" 같은 명령어를 실행합니다.
로드 밸런서 통합도 가능합니다. Application Load Balancer를 사용한다면 배포 그룹 설정에서 연결할 수 있습니다.
CodeDeploy가 자동으로 인스턴스를 로드 밸런서에서 제거하고, 배포 후 다시 추가합니다. 이렇게 하면 사용자는 배포 과정을 전혀 느끼지 못합니다.
실제 현업에서는 다양한 배포 전략을 사용합니다. 블루/그린 배포는 위험을 최소화합니다.
새 버전을 완전히 별도의 환경에 배포하고, 검증 후 트래픽을 전환합니다. 문제가 있으면 즉시 이전 버전으로 롤백할 수 있습니다.
카나리 배포는 소수의 사용자에게만 먼저 배포합니다. 예를 들어 트래픽의 10%만 새 버전으로 보냅니다.
문제가 없으면 점진적으로 비율을 늘립니다. 주의할 점이 있습니다.
EC2 인스턴스에는 CodeDeploy 에이전트가 설치되어 있어야 합니다. 에이전트가 없으면 배포 명령을 받을 수 없습니다.
또한 인스턴스의 IAM 역할에 CodeDeploy와 S3 접근 권한이 있어야 합니다. 김개발 씨는 모든 설정을 완료했습니다.
CodeDeploy 애플리케이션과 배포 그룹을 만들고, appspec.yml 파일을 프로젝트에 추가했습니다. 파이프라인 설정에서 방금 만든 배포 구성을 선택했습니다.
"파이프라인 생성" 버튼을 클릭하자 모든 설정이 완료되었습니다. 이제 파이프라인이 생성되고, 첫 실행이 자동으로 시작됩니다.
배포 스테이지는 파이프라인의 목적지입니다. 모든 노력의 결실이 사용자에게 전달되는 순간입니다.
실전 팁
💡 - EC2 인스턴스에 CodeDeploy 에이전트를 미리 설치해두세요
- 프로덕션에서는 OneAtATime 배포로 위험을 최소화하세요
- appspec.yml의 스크립트는 실행 권한(chmod +x)이 필요합니다
6. 파이프라인 실행
파이프라인 생성이 완료되자 화면에 "실행 중"이라는 표시가 나타났습니다. 김개발 씨는 긴장하며 화면을 지켜봤습니다.
"이제 자동으로 배포가 되는 건가요?" 박시니어 씨가 미소 지으며 말했습니다. "네, 이제 지켜보기만 하면 됩니다."
파이프라인 실행은 전체 자동화 프로세스가 작동하는 것을 의미합니다. 각 스테이지가 순차적으로 실행되며, 실시간으로 진행 상황을 확인할 수 있습니다.
실패 시 자동으로 중단되고, 성공 시 새 버전이 배포됩니다.
다음 코드를 살펴봅시다.
// 파이프라인 실행 상태 모니터링
import { CodePipelineClient, GetPipelineExecutionCommand } from "@aws-sdk/client-codepipeline";
const client = new CodePipelineClient({ region: "ap-northeast-2" });
async function checkPipelineStatus(pipelineName, executionId) {
const command = new GetPipelineExecutionCommand({
pipelineName: pipelineName,
pipelineExecutionId: executionId
});
const response = await client.send(command);
// 실행 상태 확인: InProgress, Succeeded, Failed
console.log("파이프라인 상태:", response.pipelineExecution.status);
console.log("각 스테이지 상태:", response.pipelineExecution.artifactRevisions);
return response.pipelineExecution.status;
}
파이프라인이 생성되자마자 첫 실행이 시작되었습니다. 김개발 씨는 CodePipeline 콘솔에서 실시간으로 진행 상황을 볼 수 있었습니다.
화면 상단에 파이프라인의 전체 구조가 시각적으로 표시됩니다. 소스, 빌드, 배포 스테이지가 왼쪽에서 오른쪽으로 나열되어 있습니다.
소스 스테이지가 가장 먼저 실행됩니다. 파란색 진행 바가 움직이면서 "진행 중"이라고 표시됩니다.
CodePipeline이 GitHub에서 최신 코드를 가져오고 있습니다. main 브랜치의 최신 커밋이 다운로드되고, ZIP 파일로 압축되어 S3에 저장됩니다.
몇 초 후 소스 스테이지가 녹색으로 바뀌면서 "성공"으로 변합니다. 체크 마크 아이콘이 나타납니다.
클릭하면 어떤 커밋이 사용되었는지, 누가 커밋했는지 상세 정보를 볼 수 있습니다. 자동으로 빌드 스테이지가 시작됩니다.
파란색 진행 바가 빌드 박스에 나타납니다. "세부 정보" 링크를 클릭하면 CodeBuild 콘솔로 이동합니다.
실시간 로그를 볼 수 있습니다. 로그 화면에서는 buildspec.yml의 각 단계가 실행되는 것을 볼 수 있습니다.
"npm install" 명령어가 실행되고, 수많은 패키지가 설치됩니다. "npm run test"가 실행되면서 테스트 결과가 출력됩니다.
모든 테스트가 통과하면 "npm run build"가 실행됩니다. 빌드가 완료되면 아티팩트가 생성됩니다.
dist 폴더의 내용이 ZIP 파일로 압축되어 S3에 업로드됩니다. 이 파일이 다음 배포 스테이지의 입력이 됩니다.
빌드 스테이지도 녹색으로 바뀌면서 성공 표시가 나타납니다. 마지막으로 배포 스테이지가 실행됩니다.
CodeDeploy가 빌드 아티팩트를 다운로드하고, EC2 인스턴스에 배포를 시작합니다. "세부 정보"를 클릭하면 CodeDeploy 콘솔로 이동합니다.
배포 세부 정보 화면에서는 각 인스턴스의 상태를 볼 수 있습니다. ApplicationStop 훅이 실행되면서 기존 애플리케이션이 중지됩니다.
새 파일이 복사되고, AfterInstall 훅에서 의존성을 설치합니다. ApplicationStart 훅에서 애플리케이션이 다시 시작됩니다.
모든 인스턴스에서 배포가 성공하면 배포 스테이지도 녹색으로 바뀝니다. 전체 파이프라인이 성공했습니다.
화면 상단에 "성공" 배지가 표시됩니다. 처음 코드를 가져온 시점부터 배포가 완료된 시점까지 걸린 시간도 표시됩니다.
보통 5분에서 15분 정도 소요됩니다. 자동 재실행도 이해해야 합니다.
이제부터 누군가 main 브랜치에 새 커밋을 푸시할 때마다 파이프라인이 자동으로 실행됩니다. 개발자는 코드를 푸시하기만 하면 됩니다.
나머지는 파이프라인이 알아서 처리합니다. 실패 처리도 중요합니다.
만약 빌드 단계에서 테스트가 실패하면 어떻게 될까요? 빌드 스테이지가 빨간색으로 바뀌면서 "실패"로 표시됩니다.
파이프라인은 즉시 중단됩니다. 배포 스테이지는 실행되지 않습니다.
문제가 있는 코드가 프로덕션에 배포되는 것을 막아줍니다. CloudWatch Events를 설정하면 알림을 받을 수 있습니다.
파이프라인이 실패하면 SNS로 이메일이나 슬랙 메시지를 보낼 수 있습니다. "빌드가 실패했습니다"라는 알림을 받으면 즉시 로그를 확인해 문제를 해결할 수 있습니다.
수동 실행도 가능합니다. 파이프라인 화면에서 "변경 사항 릴리스" 버튼을 클릭하면 언제든지 수동으로 파이프라인을 실행할 수 있습니다.
코드 변경이 없어도 다시 배포하고 싶을 때 유용합니다. 실제 현업에서는 파이프라인 모니터링이 중요합니다.
많은 팀이 파이프라인 실행 히스토리를 주기적으로 검토합니다. 어떤 변경이 문제를 일으켰는지, 빌드 시간이 너무 길지 않은지 확인합니다.
파이프라인 성능을 최적화하면 피드백 시간이 짧아져 개발 속도가 빨라집니다. 김개발 씨는 파이프라인이 성공적으로 완료된 것을 확인했습니다.
웹 브라우저를 열고 서비스 URL에 접속하자 새로 배포된 버전이 정상적으로 작동하고 있었습니다. "이제 코드만 푸시하면 자동으로 배포되는군요!" 김개발 씨가 감탄하며 말했습니다.
박시니어 씨가 웃으며 대답했습니다. "맞아요.
이제 배포는 파이프라인에 맡기고, 우리는 좋은 코드를 작성하는 데 집중하면 됩니다." 파이프라인 실행은 자동화의 완성입니다. 한 번 설정해두면 계속해서 일관되고 안정적인 배포를 제공합니다.
실전 팁
💡 - CloudWatch Events로 파이프라인 실패 알림을 설정하세요
- 각 스테이지의 로그를 정기적으로 검토해 최적화 포인트를 찾으세요
- 배포 히스토리를 기록하면 문제 발생 시 빠르게 원인을 파악할 수 있습니다
이상으로 학습을 마칩니다. 위 내용을 직접 코드로 작성해보면서 익혀보세요!
댓글 (0)
함께 보면 좋은 카드 뉴스
서비스 메시 완벽 가이드
마이크로서비스 간 통신을 안전하고 효율적으로 관리하는 서비스 메시의 핵심 개념부터 실전 도입까지, 초급 개발자를 위한 완벽한 입문서입니다. Istio와 Linkerd 비교, 사이드카 패턴, 실무 적용 노하우를 담았습니다.
EFK 스택 로깅 완벽 가이드
마이크로서비스 환경에서 로그를 효과적으로 수집하고 분석하는 EFK 스택(Elasticsearch, Fluentd, Kibana)의 핵심 개념과 실전 활용법을 초급 개발자도 쉽게 이해할 수 있도록 정리한 가이드입니다.
Grafana 대시보드 완벽 가이드
실시간 모니터링의 핵심, Grafana 대시보드를 처음부터 끝까지 배워봅니다. Prometheus 연동부터 알람 설정까지, 초급 개발자도 쉽게 따라할 수 있는 실전 가이드입니다.
분산 추적 완벽 가이드
마이크로서비스 환경에서 요청의 전체 흐름을 추적하는 분산 추적 시스템의 핵심 개념을 배웁니다. Trace, Span, Trace ID 전파, 샘플링 전략까지 실무에 필요한 모든 것을 다룹니다.
보안 아키텍처 구성 완벽 가이드
프로젝트의 보안을 처음부터 설계하는 방법을 배웁니다. AWS 환경에서 VPC부터 WAF, 암호화, 접근 제어까지 실무에서 바로 적용할 수 있는 보안 아키텍처를 단계별로 구성해봅니다.