Git Push로 CloudFormation 드리프트(Drift) 해결하기 (feat. AWS CodePipeline)
시작하며
CloudFormation을 사용하여 인프라를 코드(IaC)로 관리할 때, 코드와 실제 리소스 상태 간의 불일치가 발생하는 드리프트(Drift) 는 흔한 문제입니다. 긴급한 장애 대응이나 테스트를 위해 콘솔에서 임시로 설정을 변경하는 경우, 이러한 변경 사항이 코드에 반영되지 않아 드리프트가 발생하곤 합니다.
물론 가장 좋은 방법은 SCP(서비스 제어 정책)나 IAM 권한을 통해 애초에 드리프트 발생을 원천적으로 차단하는 것이지만, 운영 환경의 현실적인 제약이나 긴급 대응 등으로 인해 발생하는 드리프트를 효과적으로 관리하는 것도 중요합니다. 이 글은 바로 그런 상황을 대비하기 위해 작성되었습니다.
자동화 아키텍처
우리가 구축할 파이프라인의 흐름은 매우 간단합니다.
- Source (소스): 사용자가 수정된 CloudFormation 템플릿(
template.yaml
)을 Git Repository(AWS CodeCommit, GitHub 등)에 Push 합니다. - Deploy (배포): Git Push 이벤트가 AWS CodePipeline을 자동으로 트리거합니다.
- CloudFormation Action: CodePipeline은 CloudFormation 배포 액션을 실행하여, Git에 있는 최신 템플릿과 현재 배포된 스택의 상태를 비교합니다.
- 자동 업데이트: CloudFormation은 변경된 부분(사용자가 임의로 수정한 부분 포함)을 감지하고, 코드를 기준으로 인프라를 올바른 상태로 자동 업데이트하여 드리프트를 해결합니다.
구축 과정
1단계: 소스 코드 리포지토리 준비
먼저 CloudFormation 템플릿 파일을 관리할 Git 리포지토리를 준비합니다. GitHub, Bitbucket 등을 사용할 수 있습니다. 이 예제에서는 관리하려는 실제 리소스(Security Group, VPC 등)의 현재 상태와 정확히 일치하는 CloudFormation 템플릿(template.yaml
)을 리포지토리의 루트에 위치시킨다고 가정합니다.
※이전 주제에서 다룬 'IaC 생성기'를 사용하면 이 템플릿의 초안을 손쉽게 만들 수 있습니다.
2단계: 기존 리소스를 CloudFormation으로 가져오기
이제 Git 리포지토리에 준비된 템플릿을 사용하여, 이미 존재하는 Security Group을 CloudFormation의 관리 하에 둡니다. 이 작업을 **'리소스 가져오기(Import)'**라고 합니다.
- 가져오기 실행:
- CloudFormation 콘솔에서
스택
>스택 생성
> **기존 리소스 사용(리소스 가져오기)
*을 선택합니다. - 준비한
template.yaml
파일을 업로드합니다. - 리소스 식별: 다음 화면에서 템플릿에 정의된 논리적 ID(
EC2SecurityGroup
,EC2VPC
) 옆에, 관리할 실제 리소스의 물리적 ID를 입력합니다.EC2SecurityGroup
:sg-0123abcdxxxxxx
형식의 ID 입력EC2VPC
:vpc-0987zyxwxxxxxx
형식의 ID 입력
- 다음 단계를 진행하여 스택 이름(예:
managed-existing-sg-stack
)을 지정하고 생성을 완료합니다.
- CloudFormation 콘솔에서
이 과정이 성공적으로 끝나면, 새로운 리소스가 생성되는 대신 기존 Security Group이 managed-existing-sg-stack
이라는 이름의 스택에 포함되어 CloudFormation으로 관리되기 시작합니다.
3단계: AWS CodePipeline 생성
- AWS Management Console에서 CodePipeline 서비스로 이동하여
파이프라인 생성
을 클릭합니다. - 생성 옵션 선택: 'Category'에서
Deployment
를 선택하고, 'Template'에서 **CloudFormation으로 배포
**를 선택한 후다음
을 클릭합니다.
- 소스 선택:
- 소스 공급자로 1단계에서 준비한 리포지토리(예: GitHub)를 선택합니다.
- 리포지토리와 브랜치(예:
main
)를 선택합니다. CodePipeline은 이 브랜치에 코드가 Push 될 때마다 자동으로 실행됩니다.
- 템플릿 구성(Configure template)
-
이 화면은 파이프라인과 CloudFormation 배포에 필요한 모든 파라미터를 한 번에 입력하는 폼입니다.
-
ConnectionArn
,FullRepositoryId
,BranchName
은 이전 단계에서 선택한 정보로 자동 채워집니다. -
CodePipelineName: 파이프라인의 이름(예:
cfn-sg-sync-pipeline
)을 입력합니다. -
StackName: 배포할 CloudFormation 스택의 이름(예:
my-test-server-stack
)을 입력합니다. (필수) -
TemplatePath: 리포지토리 내의 템플릿 파일 경로(예:
template.yaml
)를 정확히 입력합니다. (필수) -
CloudFormationResourcePermissions: CloudFormation이 리소스를 배포하는 데 필요한 IAM 권한을 JSON 형식으로 입력합니다. 아래는 테스트를 위한 EC2 관련 모든 범위의 권한 예시입니다. (필수)
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "ec2:*" ], "Resource": "*" } ] }
-
나머지 필드는 기본값을 사용하거나 필요에 따라 수정합니다.
-
- 설정을 검토하고
Create pipeline from template
을 클릭하여 완료합니다.
4단계: 파이프라인 실행 및 자동 업데이트 확인
이제 모든 준비가 끝났습니다.
- 테스트를 위해 AWS 콘솔에서 해당 Security Group의 설명을 임의로 수정하여 드리프트를 발생시킵니다.
- 로컬 PC에서
template.yaml
파일의 내용을 올바른 상태로 유지하거나, 혹은 다른 부분을 수정합니다. - 수정된 파일을 Git 리포토리로 Push 합니다.
- CodePipeline 콘솔로 이동하면, Git Push에 의해 파이프라인이 자동으로 실행되는 것을 볼 수 있습니다.
- 배포 스테이지가 성공적으로 완료된 후, CloudFormation 콘솔에서 스택의 이벤트를 확인하거나 EC2 콘솔에서 Security Group의 설명을 확인하면, 코드가 정의한 대로 다시 원복된 것을 확인할 수 있습니다.
결론
AWS CodePipeline을 이용해 CloudFormation 배포를 자동화함으로써, 더 이상 수동으로 드리프트를 확인하고 바로잡는 번거로운 작업을 할 필요가 없어졌습니다.
- GitOps 기반 관리: Git을 '신뢰할 수 있는 단일 소스(Single Source of Truth)'로 사용하여 모든 인프라 변경을 코드로 관리하고 추적할 수 있습니다.
- 드리프트 자동 해결: 파이프라인이 커밋 혹은 주기적으로 실행 하도록 설정 시 코드와 다른 상태를 자동으로 교정해줍니다.
- 작업 효율성 향상: 수동 배포와 관련된 시간을 절약하고, CloudFormation 재배포시 사람의 실수 가능성을 예방합니다.
アノテーション株式会社について
アノテーション株式会社はクラスメソッドグループのオペレーション専門特化企業です。サポート・運用・開発保守・情シス・バックオフィスの専門チームが、最新 IT テクノロジー、高い技術力、蓄積されたノウハウをフル活用し、お客様の課題解決を行っています。当社は様々な職種でメンバーを募集しています。「オペレーション・エクセレンス」と「らしく働く、らしく生きる」を共に実現するカルチャー・しくみ・働き方にご興味がある方は、アノテーション株式会社 採用サイトをぜひご覧ください。