Microsoft AZ-400: 소스 제어 및 리포지토리 관리 — 학습 가이드
다음의 일부입니다: Microsoft DevOps Engineer Expert AZ-400 — 학습 가이드. 검증된 답안으로 연습하기: Microsoft 시험 허브, 또는 다음에서 시간 제한 모의고사 풀기: ExamRoll.io.
개요
현대 DevOps 프랙티스는 예측 가능하고 협업적인 소스 제어와 체계적인 리포지토리 관리에 달려 있습니다. Azure Repos와 GitHub는 버전 제어, 정책 강제, 협업 및 보안을 위한 상호 보완적인 기능을 제공합니다. 브랜칭 전략, pull request 워크플로, 권한, 후크, 대용량 파일 처리, 마이그레이션 패턴, 보안 스캐닝, 버전 관리에 대한 숙달은 복원력 있는 배포 파이프라인과 감사 가능성을 위해 필수적입니다. 목표는 단순히 코드를 저장하는 것을 넘어, 품질을 희생하지 않으면서 팀의 처리량을 확장할 수 있는 강제적이고 자동화된 제어 시스템을 만드는 것입니다.
Azure Repos 및 GitHub의 소스 제어 기본 사항
Azure Repos는 Git과 Team Foundation Version Control (TFVC)을 지원합니다. Git은 분산형 시스템으로, 로컬 커밋, 쉬운 브랜칭, 분산된 워크플로를 가능하게 합니다. TFVC는 중앙 집중식으로 서버 측 버전 관리, 잠금 체크아웃(선택 사항) 기능을 갖추고 있으며, 매우 큰 바이너리 자산이 있는 레거시 솔루션이나 중앙 집중식 워크플로에 익숙한 팀에 적합합니다. 새로운 개발은 기본적으로 Git을 사용해야 합니다. TFVC는 점진적인 변경 제어와 중앙 권한이 가장 중요하고 마이그레이션 비용이 과도할 때 여전히 유효한 선택지입니다.
브랜칭 전략을 신중하게 선택하세요:
- 트렁크 기반 개발은 단일하고 오래 지속되는 main 브랜치와 매우 짧은 수명의 기능 브랜치, 그리고 지속적인 통합을 선호합니다. 이는 흐름을 가속화하고, 병합 부채를 줄이며, 강력한 테스트 자동화를 갖춘 빠른 개발 주기의 팀에 이상적입니다.
- GitFlow는 오래 지속되는 develop 및 main (릴리스) 브랜치를 사용하며, feature, release, hotfix 브랜치를 함께 사용합니다. 이는 공식적인 릴리스 주기가 있고 백포팅이 필요한 제품에 적합하지만, 조정 오버헤드를 추가합니다.
- GitHub Flow는 단일 main 브랜치, 짧은 수명의 토픽 브랜치, 지속적인 배포, 빈번한 릴리스를 특징으로 하는 단순화된 모델입니다. 지속적으로 배포되는 서비스에 효과적입니다.
Monorepo 대 multi-repo는 주로 조직 및 도구의 선택 문제입니다:
- Monorepo는 여러 컴포넌트를 하나의 리포지토리에 통합하여, 원자적인 서비스 간 변경, 통합된 리팩토링, 공유 도구 사용을 용이하게 합니다. 히스토리가 커지면 Git 작업에 부담을 줄 수 있습니다. 완화 기법으로는 sparse checkout, partial clone, 그리고 빌드 및 테스트 범위를 지정하는 CI 경로 필터가 있습니다.
- Multi-repo는 소유권, 히스토리, 권한 경계를 분리하여 독립적인 버전 관리 및 보존을 용이하게 합니다. 리포지토리 간 조정 및 종속성 드리프트가 증가할 수 있으며, 서브모듈이나 종속성 관리자, 릴리스 오케스트레이션이 중요합니다.
코드 소유권 선언을 통해 소유권 및 변경 라우팅을 개선할 수 있습니다. GitHub의 CODEOWNERS 파일은 경로를 필수 검토자에게 자동으로 매핑합니다. Azure Repos에서는 브랜치 정책의 경로 기반 필수 검토자(그리고 활성화된 경우 CODEOWNERS)를 사용하여 컴포넌트 팀으로 리뷰를 라우팅합니다. 브랜치 이름 규칙, 명확한 커밋 메시지(예: Conventional Commits), 리포지토리 템플릿으로 소유권을 보완하여 일관성을 유지하세요.
거버넌스: 정책, 권한 및 Pull Request
Azure Repos의 브랜치 정책은 품질 게이트를 코드화합니다:
- 필수 검토자는 최소 검토자 수를 강제하며, 특정 개인/그룹 또는 경로 기반 자동 검토자를 포함할 수 있습니다. 병합 전에 실질적인 피드백이 처리되도록 댓글 해결을 요구하세요.
- 빌드 유효성 검사는 병합 전에 하나 이상의 CI 파이프라인이 통과해야 합니다. 경로 필터를 사용하여 불필요한 빌드를 피하고 새 업데이트에 대해 자동 트리거를 설정하세요. 상태 정책을 통해 보안 스캔이나 성능 테스트 같은 외부 검사를 통합하세요.
- 병합 전략은 제한될 수 있습니다: Merge (no fast-forward)는 병합 히스토리를 기록합니다. Squash는 변경 사항을 단일 커밋으로 압축하여 히스토리를 선형으로 유지합니다. Rebase and fast-forward는 main 브랜치 위에 토픽 브랜치를 다시 작성하여 직선적인 히스토리를 만듭니다. Rebase and merge는 커밋을 다시 재생하고 병합 커밋 없이 개별 커밋을 보존합니다. 감사 요구 사항 및 다운스트림 도구에 맞춰 전략을 조정하세요.
- 추가 검사에는 필수 연결 작업 항목, 최소 성공 투표 수, 활성 댓글이나 보류 중인 검토자가 있을 경우 차단하는 기능이 포함됩니다.
Pull request는 통합에 대한 논의를 조율합니다:
- **초안 PR(Draft PR)**은 작업 진행 중임을 알리고 준비 완료로 표시될 때까지 완료를 차단합니다. 정책을 조기에 트리거하지 않으면서 빠른 피드백을 장려하세요.
- 자동 완성은 모든 정책이 통과되면 자동으로 병합하여 조정 지연 시간을 줄이고 흐름을 증가시킵니다.
- 정책 우회는 긴급 상황이나 자동화 계정을 위해 존재합니다. “pull request 완료 시 정책 우회” 권한으로 이 기능을 잠그고, 승인 및 변경 관리를 통해 감사하세요.
- PR 템플릿은 컨텍스트를 표준화합니다: 테스트 증거, 위험 메모, 배포 단계, 롤백 계획 등. Azure Repos에서는 pull_request_template.md 파일을 리포지토리 루트나 .azuredevops/ 디렉토리에 배치하세요. 보안, 성능, 문서화에 대한 체크리스트를 제공하세요.
권한 및 보호된 브랜치는 최후의 방어선입니다:
- Azure DevOps RBAC 그룹(Project Administrators, Contributors, Readers)과 세분화된 리포지토리 권한(Create branch, Create tag, Contribute, Force push, Manage permissions, Bypass policies)을 사용하세요. 개별 사용자보다는 그룹에 대해 허용/거부를 설정하는 것을 선호합니다.
- main 및 release 브랜치를 보호하기 위해 Force push와 삭제를 거부하고, Contribute를 PR 병합으로만 제한하며, 빌드와 리뷰를 요구하는 브랜치 정책을 활성화하세요. 변경을 일시적으로 동결하기 위해 “잠금(Lock)“을 고려하세요.
- 브랜치 수준 권한을 사용하여 민감한 브랜치에 대해 PR을 생성하거나 완료할 수 있는 사람을 제한하고, 개발자와 릴리스 관리자 간의 직무를 분리하세요.
자동화, Hook, 대용량 파일 및 보안
Git hook은 개발 초기 단계에서 품질을 확보합니다.
- Pre-commit hook은 개발자가 커밋을 기록하기 전에 로컬에서 린팅, 포맷팅, secret 검사, 단위 테스트를 강제합니다. 빠르고 결정적(deterministic)으로 유지해야 합니다.
- Pre-push hook은 통합 테스트나 정책 검사에 실패한 코드의 push를 차단합니다. 도구(예: JavaScript용 Husky)를 통해 팀 전체에 적용되는 hook 스크립트를 제공하고, 선택적 참여(opt-in) 방식을 문서화하십시오.
- 관리형 서비스의 서버 측 hook은 다릅니다. GitHub는 서버 웹훅과 필수 상태 검사를 지원하지만, Azure DevOps Services는 사용자 지정 서버 측 hook을 허용하지 않고 브랜치 정책, 빌드 유효성 검사, 서비스 hook, 외부 시스템의 상태 검사를 지원합니다. Azure DevOps Server(온프레미스)에서는 서버 hook이 가능합니다.
Large File Storage(Git LFS)는 대용량 바이너리를 Git 객체 데이터베이스 외부에 저장하여 리포지토리 성능을 유지합니다.
undefined
또는 특정 바이너리 파일 유형으로 패턴을 추적합니다. 모든 기여자가 LFS를 일관되게 적용하도록 .gitattributes 파일을 커밋하십시오.
- 경로 필터와 함께
undefined
를 실행하여 대용량 바이너리를 포인터로 다시 작성함으로써 히스토리를 마이그레이션합니다. 팀과 협력하여 push를 일시 중단하고, 신중하게 force-push한 후 클론을 업데이트하십시오.
- 불필요한 smudge를 피해 대역폭을 관리하십시오.
undefined
를 사용하고
undefined
를 선택적으로 실행하십시오. CI에서 LFS를 캐시하고, Git에 저장할 필요가 없는 바이너리는 아티팩트 리포지토리를 사용하는 것을 고려하십시오.
보안 보증은 ‘shift-left’ 방식과 정책 기반으로 이루어져야 합니다.
- GitHub Advanced Security(GHAS)는 secret scanning(push protection 포함), CodeQL을 사용한 코드 스캐닝, dependency review 기능을 제공하여 노출된 자격 증명, 코드 취약점, 공급망 리스크를 탐지합니다. PR에 대한 필수 검사로 강제하십시오. Azure Repos의 경우, Advanced Security for Azure DevOps를 사용하여 유사한 secret scanning, CodeQL을 통한 SAST, 종속성 분석 기능을 구현할 수 있습니다.
- Secret scanning은 신뢰도 높은 secret이 포함된 push를 차단하고 보안 담당자에게 알리도록 구성해야 합니다. 조직별 패턴에 대한 사용자 지정 탐지기를 지원합니다.
- CodeQL 코드 스캐닝은
undefined
및
undefined
트리거에서 실행되어야 하며, SARIF 결과를 상태 검사로 업로드해야 합니다. 노이즈를 줄이고 중요한 경로에 대한 커버리지를 강제하도록 쿼리 팩을 조정하십시오.
- Dependency review는 PR 검토 중에 버전 변경 사항과 알려진 권고 사항을 표시합니다. 이를 해결 조치 SLA 및 라이선스 거버넌스에 활용하십시오.
마이그레이션, 버전 관리 및 릴리스 관리
TFVC에서 Git으로 마이그레이션하려면 리스크 허용 범위에 맞는 전략과 도구가 필요합니다.
- 상세한 기록과 작업 항목 연결을 포함한 완전한 마이그레이션을 위해서는 git-tfs를 사용하여 TFVC 경로를 Git으로 복제하고, 변경 집합을 보존하며 사용자를 매핑합니다. Git 리포지토리를 관리하기 쉬운 크기로 유지하기 위해 애플리케이션이나 브랜치별로 분할합니다. 마이그레이션 중 또는 후에 LFS를 사용하여 대용량 바이너리를 정리합니다.
- 현재 상태만 가볍게 마이그레이션하려면 Azure DevOps 가져오기 도구를 사용하여 TFVC(또는 다른 Git 호스트)에서 새 Git 리포지토리를 생성하고, 선택적으로 기록을 제한합니다. 이 방법은 기간과 리스크를 줄이지만, 상세한 과거 기록은 포기해야 합니다.
- 태그/레이블을 마이그레이션하고, TFVC 브랜치를 Git 브랜치에 매핑하며, 감사를 위해 읽기 전용 TFVC 미러를 유지하여 추적성을 보존합니다. 파일럿 프로젝트로 검증하고, 전환 중에는 소스를 동결하며, 검증 매트릭스(빌드, 테스트, 배포)를 실행합니다.
명확성과 자동화를 위해 시맨틱 버전 관리를 채택합니다.
- SemVer 2.0.0 사용: MAJOR.MINOR.PATCH 형식에 선택적으로 프리릴리스(예: -rc.1) 및 빌드 메타데이터(+build.45)를 추가합니다. 주석 태그(git tag -a v1.4.2 -m “Release 1.4.2”)로 릴리스에 태그를 지정하고, 감사를 위해 태그에 서명합니다.
- CI/CD에서 버전 업데이트 자동화:
- Conventional Commits와 릴리스 도구(예: GitVersion 또는 semantic-release)를 사용하여 커밋에서 버전을 결정하고, 커밋 유형과 범위에 따라 다음 버전을 계산합니다.
- 빌드 번호와 패키지 버전을 자동으로 업데이트하고, 버전 불일치나 태그 충돌이 발생하면 빌드를 실패시킵니다.
- 버전 관리를 브랜칭 전략과 연계:
- 트렁크 기반: main은 항상 릴리스 가능한 상태로 유지하고, main에서 릴리스 태그를 생성하며, 안정화를 위해서만 단기 릴리스 브랜치를 사용합니다.
- GitFlow: release/* 브랜치는 고정된 마이너 버전을 가지며, 긴급 패치를 위해 main에서 hotfix/* 브랜치를 생성하고, develop과 main 양쪽에 다시 병합한 후 병합 완료 시점에 태그를 지정합니다.
- GitHub Flow: 배포 시 main에 태그를 지정하고, 카나리 릴리스를 위해 프리릴리스 태그를 사용합니다.
릴리스 자동화를 리포지토리 정책과 통합합니다. 릴리스 파이프라인의 빌드 성공을 요구하고, 커밋에서 생성된 변경 로그가 업데이트되지 않으면 병합을 차단하며, 규제 환경에서는 서명된 커밋/태그를 요구합니다.
실제 문제 시나리오
Starbucks는 TFVC에서 관리되던 여러 레거시 애플리케이션을 Azure Repos Git으로 통합하면서, 서비스와 모바일 앱 모두에 대해 일관된 거버넌스, 보안 스캐닝, 확장 가능한 워크플로우를 구축해야 합니다.
- 브랜칭 및 리포지토리 토폴로지 선택
- 조치: 공유 라이브러리를 위한 모노리포와 독립적으로 릴리스되는 서비스를 위한 몇 개의 집중된 서비스 리포지토리를 갖춘 트렁크 기반 개발을 채택합니다. 개발자 온보딩 스크립트에서 모노리포에 대해 희소 체크아웃(sparse checkout)을 활성화합니다.
- 이유: 트렁크 기반 개발은 병합 부채를 줄이고 통합을 가속화합니다. 모노리포는 공유 코드를 중앙 집중화하고 원자적 리팩토링을 가능하게 하며, 희소 체크아웃은 일부만 사용하는 팀의 전체 기록 및 워킹 트리 오버헤드를 방지합니다.
- 가치가 있는 경우 기록을 보존하며 TFVC 프로젝트를 Git으로 마이그레이션
- 조치: git-tfs를 사용하여 주요 웹 및 모바일 코드베이스를 전체 기록과 함께 마이그레이션하고, 마이그레이션 중에 대용량 에셋 경로를 Git LFS에 매핑합니다. 작은 유틸리티의 경우, Azure DevOps 가져오기 도구를 사용하여 현재 상태만 가져옵니다.
- 이유: git-tfs는 주력 앱의 중요한 추적성을 보존합니다. 가져오기 도구를 선택적으로 사용하면 리스크가 낮은 마이그레이션을 가속화하고 프로젝트 기간을 단축할 수 있습니다.
- 보호된 브랜치 및 브랜치 정책 설정
- 조치: main 및 release/* 브랜치를 강제 푸시/삭제 거부로 보호하고, 2명의 검토자, 모든 코멘트 해결, 작업 항목 연결, 경로 필터를 사용한 빌드 유효성 검사 통과를 요구합니다. 서비스 리포지토리의 병합은 스쿼시(Squash)로 제한하고, 모노리포는 선형 기록을 유지하기 위해 리베이스 및 빨리 감기(Rebase and fast-forward)로 제한합니다. 소규모 릴리스 엔지니어링 그룹을 제외하고 “정책 우회"를 비활성화합니다.
- 이유: 코드로써의 정책(Policy-as-code)은 품질 게이트와 감사 가능성을 강화합니다. 병합 전략은 팀의 선호도를 반영합니다. 스쿼시는 서비스의 되돌리기(revert)와 체리픽(cherry-pick)을 단순화하고, 모노리포의 선형 기록은 blame 및 bisect 작업을 신속하게 합니다.
- 풀 리퀘스트 관행 표준화
- 조치: .azuredevops/ 아래에 리스크, 테스트 증거, 성능 영향, 롤백 섹션을 포함한 pull_request_template.md를 추가합니다. 초안 PR(Draft PR)을 조기에 사용하도록 장려하고, 모든 PR에 자동 완성(Auto-complete)을 활성화합니다. 코드 소유권을 모방하기 위해 경로 기반 필수 검토자를 구성하고, GitHub 호스팅 리포지토리에는 CODEOWNERS를 추가합니다.
- 이유: 템플릿은 검토 품질의 최소 기준을 높이고, 초안 PR은 조기 협업을 촉진하며, 자동 완성은 유휴 시간을 줄입니다. 소유권 라우팅은 올바른 검토자가 올바른 변경 사항을 검토하게 합니다.
- 훅과 CI 게이트 구현
- 조치: 리포지토리 도구를 통해 pre-commit/pre-push 훅을 배포하여 린팅, 비밀 정보 스캔, 유닛 테스트를 강제하되 실행 속도는 빠르게 유지합니다. Azure Pipelines 빌드 유효성 검사를 표준적인 강제 수단으로 사용하고, 보안 스캐너의 상태 확인을 추가합니다. 사용자 지정 서버 측 훅은 피하고, 서비스 훅을 사용하여 외부 시스템에 알립니다.
- 이유: 로컬 훅은 협업을 방해하지 않으면서 문제를 조기에 발견합니다. Azure DevOps에서의 서버 측 강제 적용은 신뢰성과 감사를 위해 브랜치 정책과 상태 확인을 통해 가장 잘 구현됩니다.
- Git LFS로 대용량 에셋 관리
- 조치: git lfs track으로 바이너리 패턴(이미지, 디자인 에셋, 테스트 미디어)을 추적하고, git lfs migrate import로 레거시 바이너리를 마이그레이션합니다. CI에서 GIT_LFS_SKIP_SMUDGE=1을 설정하고 선택적으로 페치하여 대역폭을 줄이며, 빌드 에이전트에 LFS 아티팩트를 캐시하도록 구성합니다.
- 이유: 리포지토리를 빠르게 유지하고 과도한 네트워크 사용을 피하면서 재현 가능한 빌드를 유지합니다.
- Advanced Security 통합
- 조치: GitHub 리포지토리에서 GitHub Advanced Security를, Azure Repos에서 Advanced Security for Azure DevOps를 활성화합니다. 푸시 보호 기능이 있는 비밀 스캔을 켜고, PR 및 야간 빌드에서 CodeQL을 실행하며, 종속성 검토 확인을 활성화합니다. 심각도가 높은 발견 사항이 있을 경우 PR 완료를 차단합니다.
- 이유: 보안을 왼쪽으로 이동(Shift-left)하여 자격 증명 유출과 악용 가능한 패턴이 main에 유입되는 것을 방지하고, 검토 중에 실행 가능한 통찰력을 제공합니다.
- 시맨틱 버전 관리 및 태깅 자동화
- 조치: Azure Pipelines에서 GitVersion을 사용하여 브랜치 및 커밋 기록에서 SemVer를 계산하고, 릴리스 파이프라인에서 주석이 달린 태그에 서명하고 푸시하며, Conventional Commits에서 릴리스 노트를 생성합니다. release/* 브랜치는 안정화에만 사용하고, 태그가 지정된 main에서 핫픽스를 진행합니다.
- 이유: 결정적이고 자동화된 버전은 추적성과 배포 재현성을 향상시키고, 서명된 태그는 규정 준수를 지원합니다.
이 순서는 마이그레이션 리스크를 낮추고, 일관된 품질과 보안을 강제하며, 전달 과정을 간소화하여 리포지토리 관리를 확장 가능한 DevOps 운영에 정확하게 맞춥니다.
모든 도메인 · Azure Pipelines를 사용한 CI →
이 문제 연습하기 → · ExamRoll.io에서 시간 제한 연습 →
Pass the whole exam — not just this question
You found this answer. Get every verified question and explanation in one place, and save hours of prep. Free to start.
시험 합격하기 →