CertNote/ 출퇴근 학습 노트
로드맵
KOEN
CLF-C02 · FoundationalCloud Practitioner - Foundational
DVA-C02 · AssociateDeveloper - Associate
  • Week 1
    • 1.개발자 시점에서 본 AWS: 리전, 인프라, 그리고 책임의 경계
    • 2.IAM의 4대 엔터티: User, Group, Role, Policy
    • 3.STS와 정책 조건: 임시 자격증명의 깊은 세계
    • 4.AWS CLI와 SDK: 자격증명 체이닝부터 SigV4까지
    • 5.Week 1 종합: 인프라와 IAM이 만드는 신뢰의 사슬
  • Week 2
  • Week 3
  • Week 4
  • Week 5
  • Week 6
  • Week 7
  • Week 8
    • 1.CodeCommit과 CodeBuild: AWS가 그린 CI/CD의 첫 두 칸
    • 2.CodeDeploy: 배포라는 가장 위험한 순간을 안전하게
    • 3.CodePipeline: CI/CD 흐름의 지휘자
    • 4.Elastic Beanstalk: AWS가 만든 가장 친절한 PaaS
    • 5.Week 8 종합 복습: CI/CD 파이프라인을 머릿속에서 끝까지 돌려보기
  • Week 9
  • Week 10
  • Week 11
  • Week 12
  • Week 13
SAA-C03 · AssociateSolutions Architect - Associate
SOA-C02 · AssociateCloudOps Engineer - Associate
SAP-C02 · ProfessionalSolutions Architect - Professional
DOP-C02 · ProfessionalDevOps Engineer - Professional
SCS-C03 · SpecialtySecurity - Specialty
MLA-C01 · AssociateMachine Learning Engineer - Associate
AIF-C01 · FoundationalAI Practitioner - Foundational
DEA-C01 · AssociateData Engineer - Associate
MLS-C01 · SpecialtyMachine Learning - Specialty
합격 후기

© CertNote · 주간랩스

  • 소개
  • 수정 기록
  • 문의
  • 이용약관
  • 개인정보처리방침
← DVA-C02/Week 8/Day 3

기준: DVA-C02 시험 가이드·오류 제보

DVA-C02· AssociateWeek 8 · Day 3읽기 약 17분

Day 3 - CodePipeline: CI/CD 흐름의 지휘자

빌드 도구, 테스트 도구, 배포 도구를 따로 만들었으면 그 다음 문제는 "이걸 어떻게 자동으로 이어 붙일까"다. 한 사람이 매번 손으로 "빌드 끝났으니 테스트 시작", "테스트 통과했으니 배포 시작"을 누르는 건 출시 직전 새벽 3시까지 누군가가 깨어 있어야 하는 비극을 만든다. CodePipeline은 그 비극을 끝내는 도구다. "소스 변경 감지 → 빌드 → 테스트 → 승인 → 배포"라는 흐름을 한 번 정의해두면, 그 다음부터는 코드를 push할 때마다 자동으로 production까지 흘러간다.

DVA-C02 시험에서는 CodePipeline 자체의 문법보다 *다른 Code 서비스들과 어떻게 조합되는지**, 수동 승인이 언제 필요한지, artifact가 어떻게 단계 간에 흐르는지, 그리고 2023년 등장한 V2 파이프라인의 변수와 트리거 필터링이 중요하다. 이번 글에서는 CodePipeline의 내부 동작 모델, 아티팩트 시스템의 본질, 그리고 크로스 계정/리전 패턴까지 짚는다.

CodePipeline의 본질: workflow engine, not build tool

CodePipeline은 build tool이 아니다. 빌드 자체는 CodeBuild가 하고, 배포는 CodeDeploy/CloudFormation/ECS가 한다. CodePipeline의 역할은 그것들을 순서대로, 조건부로, 병렬로 실행하는 워크플로우 엔진이다. AWS Step Functions가 일반 비즈니스 워크플로우용이라면, CodePipeline은 CI/CD 워크플로우에 특화된 형태다.

CodePipeline은 Stage(단계) → Action(액션) → Transition(전이)의 3층 구조이고, 각 Action은 외부 서비스 호출이다. GitHub Actions의 jobs → steps, GitLab CI의 stages → jobs, Jenkins의 stages → steps도 같은 추상화다.

CodePipeline의 데이터 모델:

Pipeline (전체 워크플로우)
  └── Stage (논리적 단계: Source, Build, Deploy 등)
        └── Action (구체적 작업: CodeBuild 실행, CodeDeploy 실행, 수동 승인)
              ├── Input Artifacts (이전 단계 산출물)
              ├── Output Artifacts (이 단계 산출물, 다음에 전달)
              ├── Configuration (액션별 파라미터)
              └── Role ARN (이 액션이 사용할 IAM 역할)

한 Stage 안에 여러 Action을 두면 기본적으로 병렬 실행된다. 순차 실행을 강제하려면 runOrder 속성을 다르게 지정한다(runOrder 1 → 2 → 3). "한 stage에서 빌드와 보안 스캔을 동시에 돌리고 둘 다 통과해야 다음 stage" 같은 시나리오에서 정답이 되는 개념이다.

{
  "name": "BuildAndScan",
  "actions": [
    {
      "name": "Build",
      "runOrder": 1,
      "actionTypeId": { "category": "Build", "provider": "CodeBuild" }
    },
    {
      "name": "SecurityScan",
      "runOrder": 1,    // 같은 runOrder = 병렬
      "actionTypeId": { "category": "Test", "provider": "CodeBuild" }
    },
    {
      "name": "UploadResult",
      "runOrder": 2,    // 위 두 개 완료 후
      "actionTypeId": { "category": "Invoke", "provider": "Lambda" }
    }
  ]
}

액션 카테고리 6종: 각각 무엇을 하나

CodePipeline은 액션을 6가지 카테고리로 분류한다. "다음 중 Source 카테고리에 속하지 않는 것은?"처럼 카테고리 분류를 직접 묻는 유형이 있다.

카테고리역할대표 Provider
Source코드/아티팩트 가져오기CodeCommit, GitHub, GitHub Enterprise, BitBucket, S3, ECR, Service Catalog
Build빌드 산출물 생성CodeBuild, Jenkins, TeamCity
Test테스트 실행CodeBuild, Device Farm, BlazeMeter, Ghost Inspector
Approval수동 승인 게이트Manual, ServiceNow Change
Deploy배포 실행CodeDeploy, CloudFormation, Elastic Beanstalk, ECS, S3, AppConfig, Service Catalog, AWS OpsWorks
Invoke임의 함수 호출Lambda, Step Functions

"Invoke" 카테고리는 비교적 새로 추가됐는데(2018년 Lambda, 2022년 Step Functions), "임의 검증 로직을 파이프라인 중간에 넣고 싶다"는 시나리오의 정답은 Lambda Invoke다. 단순한 검증은 Manual Approval로 사람이 누르지만, "외부 API에서 컴플라이언스 체크 가져오기" 같은 자동화된 검증은 Lambda Invoke를 쓴다.

아티팩트: 단계 간 데이터를 어떻게 흘리는가

CodePipeline의 가장 중요한 개념 중 하나가 아티팩트다. Stage A의 출력이 Stage B의 입력이 되는 메커니즘이고, 이것이 S3 기반이라는 점이 시험에서 구분해야 할 포인트다.

[Source Stage]
   Output Artifact: "SourceOutput"
       │ (zip으로 압축돼 S3 artifact bucket에 저장)
       ▼
[Build Stage]
   Input Artifact: "SourceOutput"
       │ (S3에서 다운로드해 CodeBuild 작업 디렉토리에 풀림)
   Output Artifact: "BuildOutput"
       │ (artifacts: 섹션의 파일을 다시 zip해 S3에 저장)
       ▼
[Deploy Stage]
   Input Artifact: "BuildOutput"

아티팩트는 계정·리전당 하나의 S3 bucket에 저장된다(이름: codepipeline-<region>-<random>). 파이프라인을 처음 만들 때 AWS가 자동 생성하지만, 명시적으로 다른 bucket을 지정할 수도 있다. 이 bucket의 access를 제대로 통제하지 않으면 빌드 산출물(소스 코드 zip, Docker 이미지 메타데이터)이 노출될 수 있다.

⚠️ 함정: 아티팩트 bucket은 반드시 파이프라인과 같은 리전에 있어야 한다. Cross-Region 배포를 하려면 각 리전마다 별도의 artifact bucket이 필요하고, CodePipeline이 자동으로 복제한다. 이를 모르고 "us-east-1 artifact를 ap-northeast-2 deploy에 직접 참조"하려고 하면 실패한다.

# Cross-Region 배포의 artifact bucket 설정 (CloudFormation 발췌)
Pipeline:
  Type: AWS::CodePipeline::Pipeline
  Properties:
    ArtifactStores:
      - Region: us-east-1
        ArtifactStore:
          Type: S3
          Location: !Ref PrimaryArtifactBucket
      - Region: ap-northeast-2
        ArtifactStore:
          Type: S3
          Location: !Ref SeoulArtifactBucket   # 서울 리전 별도 bucket

트리거: 파이프라인이 시작되는 4가지 방법

CodePipeline이 어떻게 trigger되는지는 헷갈리기 쉬운 영역이다. 4가지 방식이 있는데, 권장도와 latency가 다르다.

방식Latency권장 사용처시험 키워드
EventBridge (default for AWS sources)수 초CodeCommit, ECR, S3 변경"즉각 자동 시작"
GitHub Webhook수 초GitHub push 시"GitHub 통합"
Polling최대 1분레거시, 비권장"Polling은 비권장"
수동/CLI즉시디버깅, 핫픽스"수동 재시작"

2019년 이전에는 CodePipeline이 기본적으로 polling 모델(매 분마다 S3/GitHub 변경 확인)을 썼다. AWS가 EventBridge 기반 push 모델로 전환한 이유는 ① latency 단축 ② API 호출 비용 절감 ③ GitHub rate limit 회피. Polling은 여전히 가능하지만 비권장으로 명시돼 있고, 시험에서 "가장 효율적인 트리거"가 보이면 EventBridge가 답.

CodePipeline V2: 변수, 트리거 필터, 실행 모드

2023년 10월 출시된 V2는 V1의 한계를 정면 해결했다. V1에서 가장 큰 불편이 ① 단계 간 동적 변수 전달 불가 ② 모든 push마다 파이프라인 실행 ③ 동시 실행 제어 부족이었는데, V2가 모두 풀었다.

1. 변수 (Pipeline Variables)

# 파이프라인 시작 시 변수 정의
variables:
  - name: Environment
    defaultValue: dev
    description: "Target environment"
  - name: ImageTag
    defaultValue: latest
 
# 사용
configuration:
  ProjectName: my-build
  EnvironmentVariables: |
    [{"name":"ENV","value":"#{variables.Environment}","type":"PLAINTEXT"}]

또 stage의 action variable을 다른 stage에서 참조 가능하다:

Source action output: #{SourceVariables.CommitId}
Build action output:  #{BuildVariables.IMAGE_TAG}     (CodeBuild의 exported-variables)

#{SourceVariables.CommitId}는 V1에서도 가능했지만 일부 source에서만 노출됐다. V2는 모든 액션이 일관된 변수 모델을 갖는다. 빌드의 exported-variables가 deploy 단계로 자동으로 흐르는 것이 대표적인 패턴이다. 빌드 시 결정된 image tag를 deploy의 ECS task definition에 동적으로 주입.

2. 트리거 필터링

V1에서는 push만 일어나면 무조건 파이프라인이 실행됐다. V2는 브랜치·파일 패턴으로 필터 가능.

triggers:
  - providerType: CodeStarSourceConnection
    gitConfiguration:
      sourceActionName: Source
      push:
        - branches:
            includes: ["main", "release/**"]
            excludes: ["release/experimental"]
          filePaths:
            includes: ["src/**", "package.json"]
            excludes: ["docs/**", "**/*.md"]
        - tags:
            includes: ["v*.*.*"]

⚠️ 함정: 트리거 필터는 V2 + CodeStar Source Connection(GitHub, BitBucket, GitLab)에서만 동작한다. CodeCommit source에는 적용되지 않는다. "CodeCommit + 특정 브랜치만 트리거" 시나리오의 정답은 파이프라인 트리거 필터가 아니라 EventBridge rule 필터링이다.

3. 실행 모드

executionMode: SUPERSEDED    # 기본. 새 실행이 들어오면 대기 중인 이전 실행 자동 취소
# 또는
executionMode: QUEUED        # 들어온 순서대로 하나씩 실행
# 또는
executionMode: PARALLEL      # 여러 실행 동시 진행

PARALLEL 모드는 2024년 발표된 새 기능이다. 여러 PR을 동시에 검증해야 하는 monorepo 환경에서 유용. 단 deploy 단계가 같은 리소스(예: 동일 ECS service)를 만지면 race condition이 발생한다. 그래서 Source/Build/Test까지만 PARALLEL로 두고, Deploy는 SUPERSEDED나 QUEUED로 별도 파이프라인을 분리하는 것이 안전한 패턴이다.

Manual Approval: 사람이 마지막 게이트가 되는 경우

자동화는 위대하지만, production 배포 직전에는 사람의 눈이 필요할 때가 있다. 컴플라이언스 요구사항이거나, 정책상 변경 관리 위원회 승인이 필요하거나, 단순히 비즈니스 시간에만 배포하고 싶거나.

- name: ProductionApproval
  actions:
    - name: Approve
      actionTypeId:
        category: Approval
        owner: AWS
        provider: Manual
      configuration:
        NotificationArn: arn:aws:sns:ap-northeast-2:111122223333:approvals
        CustomData: "Please review staging environment at https://staging.example.com"
        ExternalEntityLink: "https://staging.example.com"

승인 메커니즘 디테일:

  • 승인하려면 IAM codepipeline:PutApprovalResult 권한 필요
  • SNS 알림에 승인 URL이 포함됨 (콘솔의 specific deep link)
  • 7일 안에 응답 없으면 자동 거부(timeout)
  • 거부되면 그 stage는 Failed로 표시, 다음 stage 실행 안 됨

Manual Approval의 7일 timeout은 변경 불가능한 하드 리밋이다. 더 짧거나 길게 하고 싶으면 EventBridge로 "STARTED" 상태 모니터링 → Lambda로 N시간 후 자동 reject 호출하는 패턴을 쓴다. 또는 Approval action 대신 Lambda Invoke에서 외부 시스템(JIRA, ServiceNow)의 승인 상태를 polling하는 패턴.

Manual Approval에 권한이 있는 IAM 사용자가 본인이 만든 변경을 본인이 승인할 수 있는가? 기본적으로는 가능하지만, IAM Condition aws:userId로 "변경한 사람과 승인자가 달라야 한다"는 분리(separation of duties)를 강제하려면 추가 IAM 정책이 필요하다. 컴플라이언스가 중요한 환경에서는 별도 그룹(release manager)에만 승인 권한을 부여한다.

Cross-Account/Region 패턴: 멀티 계정 조직의 표준

기업이 성장하면 보통 dev/staging/prod 계정을 분리하고, 각 계정의 권한을 분리한다. CodePipeline이 cross-account로 자원을 만지려면 권한 chain을 명시적으로 설정해야 한다.

[Source Account: 111111111111]
  - CodePipeline 실행
  - 아티팩트 bucket
  - KMS CMK (cross-account 사용 허용)

[Target Account: 222222222222 (prod)]
  - CrossAccountDeployRole (Source 계정을 신뢰하는 IAM role)
  - CodeDeploy / CloudFormation으로 실제 배포

[Source 계정 Pipeline] →
   Sts:AssumeRole (CrossAccountDeployRole) →
   [Target 계정에서 배포 실행]

필요한 구성:

  1. Source 계정: Pipeline 서비스 역할에 sts:AssumeRole for Target 계정 role 권한
  2. Target 계정: CrossAccountDeployRole의 trust policy에 Source 계정 명시
  3. KMS CMK: 양쪽 계정에서 사용 가능하도록 Key Policy 설정 (artifact는 KMS로 암호화돼야 cross-account 전달 가능)
  4. S3 Artifact Bucket: Bucket policy에 Target 계정 read 권한

EventBridge 통합: 파이프라인 상태를 외부로 흘리는 표준

CodePipeline의 모든 상태 변경(시작, 단계 진행, 성공, 실패)은 EventBridge로 자동 발행된다. 알림·메트릭·자동화의 표준 hook.

{
  "source": ["aws.codepipeline"],
  "detail-type": [
    "CodePipeline Pipeline Execution State Change",
    "CodePipeline Stage Execution State Change",
    "CodePipeline Action Execution State Change"
  ],
  "detail": {
    "state": ["FAILED"]
  }
}

이걸로 만들 수 있는 패턴:

  • 실패 시 Slack 알림 (→ AWS Chatbot)
  • 실패 시 자동 JIRA 티켓 생성 (→ Lambda → JIRA API)
  • 모든 prod 배포를 보안팀 audit S3 bucket에 기록 (→ Kinesis Firehose)
  • 일별 파이프라인 성공률 메트릭 (→ CloudWatch Custom Metric)

CodeStar Notifications는 EventBridge 위에 더 친화적 UI를 얹은 것이다. "이메일/Slack/Chime으로 알림"이 목적이라면 CodeStar Notifications가 빠르고, "복잡한 자동화 분기"가 필요하면 EventBridge rule을 직접 쓰는 게 유연하다. 시험에서 "Slack 알림 + 최소 구성"이면 CodeStar Notifications, "조건부 자동 응답"이면 EventBridge.

Pipeline-as-Code: CloudFormation/CDK로 관리하기

파이프라인 자체도 코드로 관리하는 게 best practice다. 콘솔로 클릭해 만든 파이프라인은 다른 환경에 복제하기 어렵고, 변경 이력이 안 남는다.

# AWS CDK 예시 (Python)
from aws_cdk import (
    Stack, aws_codepipeline as codepipeline,
    aws_codepipeline_actions as actions,
    aws_codebuild as codebuild,
)
 
class PipelineStack(Stack):
    def __init__(self, scope, id, **kwargs):
        super().__init__(scope, id, **kwargs)
 
        source_output = codepipeline.Artifact()
        build_output = codepipeline.Artifact()
 
        pipeline = codepipeline.Pipeline(self, "MyPipeline",
            pipeline_name="my-app",
            stages=[
                codepipeline.StageProps(
                    stage_name="Source",
                    actions=[actions.CodeCommitSourceAction(
                        action_name="Source",
                        repository=repo,
                        output=source_output,
                        branch="main",
                    )]
                ),
                codepipeline.StageProps(
                    stage_name="Build",
                    actions=[actions.CodeBuildAction(
                        action_name="Build",
                        project=build_project,
                        input=source_output,
                        outputs=[build_output],
                    )]
                ),
                codepipeline.StageProps(
                    stage_name="Deploy",
                    actions=[actions.CloudFormationCreateUpdateStackAction(
                        action_name="DeployInfra",
                        stack_name="my-app-infra",
                        template_path=build_output.at_path("template.yaml"),
                        admin_permissions=False,
                    )]
                ),
            ]
        )

정리

CodePipeline은 빌드도 배포도 직접 하지 않는다. 그저 다른 도구들을 정해진 순서와 조건으로 호출하는 지휘자다. 그 단순한 역할이 중요한 이유는 "수동으로 하던 모든 release 절차를 한 번 정의해두면 그 다음부터는 사람 없이 동작한다"는 약속을 가능하게 하기 때문이다. CodePipeline V2의 변수와 트리거 필터링은 그 약속을 더 정교한 워크플로우까지 확장한다.

다음 글에서는 이 자동 파이프라인의 마지막 안전망 — CloudFormation의 변경 세트(Change Set)와 drift detection — 을 본다. 인프라가 코드와 일치하는지, 그리고 코드 변경이 production에 어떤 영향을 줄지를 어떻게 사전에 검증하는지를 짚는다.

📝 연습 문제

선택지를 클릭하면 정답·해설이 펼쳐집니다.

문제 1

CodePipeline의 한 stage 안에 빌드 액션과 보안 스캔 액션을 두 개 만들었다. 두 액션이 병렬로 실행되게 하려면?

문제 2

CodePipeline의 stage 간 데이터(빌드 산출물) 전달은 어떻게 이뤄지는가?

문제 3

CodePipeline V2에서 추가된 트리거 필터링 기능에 대한 설명으로 옳은 것은?

문제 4

Production CodeDeploy 단계 직전에 사람의 승인을 반드시 받게 하려면?

문제 5

Source 계정의 CodePipeline이 다른 AWS 계정의 ECS 서비스에 배포하려고 한다. 필요한 구성이 아닌 것은?

문제 6

CodePipeline 파이프라인 실패 시 슬랙 채널에 알림을 보내려 한다. 가장 권장되는 구성은?

문제 7

CodePipeline V2의 execution mode 중 새 실행이 들어오면 대기 중이던 이전 실행을 자동 취소하는 모드는?

이전CodeDeploy: 배포라는 가장 위험한 순간을 안전하게Week 8 · Day 2다음 Elastic Beanstalk: AWS가 만든 가장 친절한 PaaSWeek 8 · Day 4

참고 공식 자료

  • DVA-C02 공식 시험 안내(새 탭에서 열림)
  • AWS CodePipeline 공식 문서(새 탭에서 열림)
  • Amazon EventBridge 공식 문서(새 탭에서 열림)
  • Amazon S3 공식 문서(새 탭에서 열림)
  • AWS Lambda 공식 문서(새 탭에서 열림)
  • Amazon ECS · Fargate 공식 문서(새 탭에서 열림)

이 페이지

  • CodePipeline의 본질: workflow engine, not build tool
  • 액션 카테고리 6종: 각각 무엇을 하나
  • 아티팩트: 단계 간 데이터를 어떻게 흘리는가
  • 트리거: 파이프라인이 시작되는 4가지 방법
  • CodePipeline V2: 변수, 트리거 필터, 실행 모드
  • 1. 변수 (Pipeline Variables)
  • 2. 트리거 필터링
  • 3. 실행 모드
  • Manual Approval: 사람이 마지막 게이트가 되는 경우
  • Cross-Account/Region 패턴: 멀티 계정 조직의 표준
  • EventBridge 통합: 파이프라인 상태를 외부로 흘리는 표준
  • Pipeline-as-Code: CloudFormation/CDK로 관리하기
  • 정리
  • 연습 문제