AWS DOP - CloudFormation (3)

2025. 4. 19. 18:06·Web

CFN 연동 도구

  • cfn-init: CloudFormation이 EC2 인스턴스에서 리소스를 초기화할 때 사용하는 헬퍼 스크립트입니다.
  • cfn-signal: EC2 인스턴스가 성공적으로 프로비저닝되었는지를 CloudFormation에 알릴 때 사용됩니다.
  • cfn-hup: EC2 인스턴스에서 메타데이터 변경을 감지하고 재적용하는 데 사용하는 데몬입니다.
  • cfn-response: Lambda 함수에서 CloudFormation 커스텀 리소스에 대한 응답을 보낼 때 사용하는 모듈입니다.

 


사용자 데이터

EC2 인스턴스가 부팅될 때 실행되는 초기 스크립트
보통 웹 서버 설치, 설정 스크립트, 초기 파일 구성 등에 사용

CloudFormation에서 사용자 데이터 전달하는 법
필수: CloudFormation 템플릿에서 UserData는 Base64로 인코딩되어야 하므로 !Base64 사용.

 

예제 (YAML 형식)

  MyEC2Instance:
    Type: AWS::EC2::Instance
    Properties:
      InstanceType: t2.micro
      ImageId: ami-0abcdef1234567890  # 지역에 맞는 AMI로 변경
      SecurityGroupIds:
        - !Ref MySecurityGroup
      UserData: 
        Fn::Base64: !Sub |
          #!/bin/bash
          dnf update -y
          dnf install -y httpd
          systemctl enable httpd
          systemctl start httpd
          echo "Hello World from CloudFormation" > /var/www/html/index.html

 

사용자 데이터의 한계와 문제점

문제 설명
가독성 사용자 데이터에 쉘 스크립트를 직접 작성하면 길어지고 복잡해짐
유지보수 어려움 변경이나 상태 유지가 어려움
상태 비저장 인스턴스를 중지하고 다시 시작하면 사용자 데이터가 다시 실행되지 않음
상태 확인 어려움 성공 여부 확인이 불편하며, 로그는 직접 봐야 함 (/var/log/cloud-init-output.log)

 

 

해결책: CloudFormation + cfn-init

  MyInstance:
    Type: AWS::EC2::Instance
    Metadata:
      AWS::CloudFormation::Init:
        config:
          packages:
            yum:
              httpd: []
          files:
            /var/www/html/index.html:
              content: |
                <h1>Hello from cfn-init</h1>
              mode: '000644'
              owner: root
              group: root
          services:
            sysvinit:
              httpd:
                enabled: true
                ensureRunning: true
    Properties:
      ImageId: ami-0abcdef1234567890
      InstanceType: t2.micro
      SecurityGroupIds:
        - !Ref MySecurityGroup
      UserData:
        Fn::Base64: !Sub |
          #!/bin/bash
          yum update -y
          yum install -y aws-cfn-bootstrap
          /opt/aws/bin/cfn-init -v --stack ${AWS::StackName} \
            --resource MyInstance --region ${AWS::Region}

 

Metadata에 선언된 이 부분이 cfn-init의 실행 대상 구성

 

장점 설명
💡 가독성 향상 구성 요소를 구조적으로 YAML로 작성 가능
🔧 복잡한 설정 관리 패키지 설치, 사용자 생성, 파일 배포, 서비스 실행 등 다양한 작업을 분리 가능
🧩 유연한 상태 구성 cfn-hup과 연계하면 상태 변화 감지도 가능
📋 로그 추적 /var/log/cfn-init.log, /var/log/cfn-init-cmd.log 등으로 명확한 로그 추적 가능

 

 

예시 코드: cfn-signal 포함된 템플릿

Resources:
  MyInstance:
    Type: AWS::EC2::Instance
    Metadata:
      AWS::CloudFormation::Init:
        config:
          packages:
            yum:
              httpd: []
          files:
            /var/www/html/index.html:
              content: |
                <h1>Hello from cfn-signal!</h1>
          services:
            sysvinit:
              httpd:
                enabled: true
                ensureRunning: true
    CreationPolicy:
      ResourceSignal:
        Timeout: PT2M
        Count: 1
    Properties:
      ImageId: ami-0abcdef1234567890
      InstanceType: t2.micro
      UserData:
        Fn::Base64: !Sub |
          #!/bin/bash
          yum install -y aws-cfn-bootstrap
          /opt/aws/bin/cfn-init -v --stack ${AWS::StackName} \
            --resource MyInstance --region ${AWS::Region}
          INIT_STATUS=$?
          /opt/aws/bin/cfn-signal -e $INIT_STATUS \
            --stack ${AWS::StackName} \
            --resource MyInstance \
            --region ${AWS::Region}

전체 프로세스

  1. CloudFormation 스택 생성 시작
  2. EC2 인스턴스가 생성되며 UserData에서 cfn-init 실행
  3. cfn-init 실행 결과를 변수에 저장
  4. cfn-signal로 CloudFormation의 WaitCondition에 신호 전송
  5. CloudFormation은 신호를 받아 스택 생성을 계속 진행하거나 실패로 처리

 

실패 원인

원인 설명
AMI 문제 사용하는 AMI에 cfn-init, cfn-signal 등 부트스트랩 도구가 포함되지 않았을 수 있음
인터넷 연결 인스턴스가 사설 서브넷에 있고, NAT 게이트웨이 없이 외부 인터넷 접근 불가하면 cfn-signal 전송 실패
사용자 스크립트 오류 UserData 스크립트나 cfn-init 설정 중 exit 1 등 오류 코드 반환 시 실패
롤백 설정 디폴트 설정은 실패 시 자동으로 인스턴스를 삭제함 → 디버깅 어려움

디버깅 팁: 롤백 방지

CloudFormation 스택 생성 시 “스택 실패 옵션”에서 스택 롤백 비활성화 를 반드시 체크해야 EC2 인스턴스가 삭제되지 않고 남아있어 SSH 접속 후 로그를 확인하고 문제를 추적할 수 있음.

 


 

중첩 스택(Nested Stack) vs 크로스 스택(Cross-Stack)

항목 중첩 스택 (Nested Stack) 크로스 스택 (Cross-Stack Reference)
📘 정의 하나의 템플릿 안에서 또 다른 스택을 포함 서로 다른 스택이 출력값을 공유
📦 구성 방식 AWS::CloudFormation::Stack 리소스를 이용해 템플릿을 포함 Export, ImportValue를 통해 출력값을 참조
♻️ 재사용성 높은 수준의 구성 요소를 재사용 공통 리소스를 여러 스택에서 참조
🔄 업데이트 부모 스택을 업데이트하면 하위 스택도 자동 갱신 값 참조만 하므로 독립적인 업데이트 가능
🧹 삭제 시 부모 스택 삭제 시 함께 삭제됨 서로 독립적으로 삭제 가능
🧠 예시 RDS 구성, 웹 서버 구성 등 하나의 기능 단위로 분리 공용 VPC, 공용 보안 그룹 등 공유 자원 구성

중첩 스택은 코드 재사용성과 구성 관리 측면에서 강력
크로스 스택은 자원 공유에 효과적
적절한 모듈화 전략을 사용하면 스택 유지보수가 쉬워지고 확장성도 높아짐
실습에서는 실제 웹 서버를 구성하고, 그 결과를 웹사이트로 확인함 (PHP + MySQL + httpd)

 


 

StackSet

StackSet은 하나의 CloudFormation 템플릿을 여러 계정과 여러 리전에 동시에 배포할 수 있는 기능
예를 들어, VPC 스택을 조직 전체에 동일하게 배포

항목 내용
🎯 목적 여러 계정/리전에 공통된 인프라 배포
🔐 권한 서비스 관리형 (AWS 자동 IAM 구성) 추천
조직 기반 StackSet은 서비스 관리형 권한을 사용하는 게 일반적
🧩 사용 조건 AWS Organizations + 신뢰할 수 있는 액세스 활성화
🔁 자동성 OU에 새 계정 추가 시 스택 자동 배포
👥 위임 관리 특정 OU 또는 계정에게 StackSet 관리 권한 위임 가능

 


 

CloudFormation 문제 해결

DELETE_FAILED

삭제 실패는 특정 리소스가 삭제되지 못해 스택 전체 삭제가 실패하는 경우

 

주요 원인:

  • S3 버킷: 버킷이 비워지지 않음 → 수동 비우기 또는 Lambda + Custom Resource로 자동 비우기
  • 보안 그룹: 아직 다른 리소스 (예: EC2 인스턴스)가 사용 중이라 삭제 불가
  • 종속성 있는 리소스가 삭제되지 않음
  • DeletionPolicy: Retain 설정된 리소스는 삭제되지 않음

ROLLBACK_FAILED

스택 업데이트 도중 오류가 발생했고, 롤백도 실패한 경우

 

주요 원인:

  • 외부에서 수동 변경된 리소스
  • 권한 부족
  • Auto Scaling Group이 새 인스턴스를 띄우기 위한 리소스를 찾지 못함
  • 외부 시스템 또는 리소스 의존성 문제

해결 팁:

  1. CloudFormation 콘솔에서 이벤트 로그 확인 → 오류 원인 찾기
  2. 수동으로 리소스를 수정하여 상태를 정상화
  3. CLI 또는 콘솔에서 ContinueUpdateRollback 호출

 

StackSet 문제 해결

StackSet은 다수의 계정+리전에 동시에 배포되므로 더 복잡하고 예외 처리가 많음

 

주요 원인:

  • IAM 권한 부족: 대상 계정에 충분한 권한이 없음
  • 신뢰 관계 문제: StackSet 관리 역할과 실행 역할의 trust relationship 누락
  • 리소스 이름 중복: 예: S3 버킷 이름은 글로벌 고유 → bucket-${AWS::AccountId} 같은 변수 사용
  • 서비스 할당량 초과: 예: EC2 인스턴스 제한
  • 스택 인스턴스 상태 불일치 → 구식(Outdated), 실패 상태

해결 팁:

  • 실패한 스택 인스턴스만 다시 재배포 (retry-stack-operation)
  • S3 버킷, IAM Role 등 고유해야 하는 리소스에 변수 사용
  • CloudFormation StackSet 콘솔 → 인스턴스 상세 상태 확인
  • StackSet 작업 시 로그 필수 확인 (실패한 지역/계정 식별)

 


 

AWS Service Catalog

조직 내 승인된 리소스 템플릿(CloudFormation)을 사용자들이 셀프서비스로 배포할 수 있도록 하는 서비스

 

구성 요소 설명
제품 (Product) CloudFormation 템플릿으로 정의된 실제 리소스 (예: EC2, RDS 등)
포트폴리오 (Portfolio) 여러 제품들을 묶은 묶음. IAM 권한을 통해 액세스를 제어
프로비저닝된 제품 (Provisioned Product) 사용자가 실제로 배포한 제품 인스턴스
관리자 템플릿 작성 및 포트폴리오 구성. IAM 역할로 통제 권한 부여
사용자 카탈로그에 정의된 승인된 제품만 선택 및 배포 가능

 

동작 흐름

  1. 관리자
    • CloudFormation 템플릿 작성
    • 제품 생성 (Product)
    • 포트폴리오 생성 + 제품 포함
    • IAM을 통해 어떤 사용자가 어떤 포트폴리오에 접근 가능한지 설정
  2. 사용자
    • AWS 콘솔 또는 포털에서 포트폴리오 접근
    • 승인된 제품 중 선택
    • 파라미터 입력하고 배포
    • Service Catalog는 CloudFormation 기반으로 리소스를 배포

 

사용 이유

이유 설명
표준화 조직에서 승인된 리소스, 네이밍, 태깅 전략 강제
보안 사용자는 최소한의 권한만 갖고 작업 가능
컴플라이언스 유지 모든 리소스는 미리 정의된 템플릿을 통해서만 생성 가능
셀프 서비스 사용자는 별도 교육 없이도 승인된 리소스를 배포 가능
중앙 집중식 관리 모든 배포 현황은 Service Catalog에서 추적 가능

 

추가 기능

StackSet 제약 조건 (StackSet Constraint)

개념:

  • 제품이 CloudFormation StackSet을 통해 배포되도록 구성
  • 배포 가능 지역 및 타겟 계정을 제한
  • 어떤 IAM 역할을 통해 배포할지도 지정
    특징:
  • CloudFormation 자체는 지역이나 계정에 대한 제한 기능이 없음
  • Service Catalog에서 StackSet 제약 조건을 추가해야 가드레일을 설정할 수 있음

 

런칭 제약 조건 (Launch Constraint)

개념:

  • 사용자 대신 제품을 런칭할 IAM 역할을 정의
  • 사용자가 리소스(EC2, RDS 등)를 직접 생성할 권한이 없어도 제품을 실행 가능하게 해줌
    특징:
  • IAM 역할이 제품과 연결되어 있고,
  • 사용자는 그 역할로 제품만 런칭할 수 있음
  • 템플릿 내부 리소스 생성 권한은 역할이 책임짐

 

버전 제어 및 Git 연동

개념:

  • 제품 정의를 코드로 관리
  • AWS CodeCommit 또는 Git 리포지토리와 동기화
  • Lambda 함수를 사용해 자동 업데이트 가능
    구현 방법:
  1. 템플릿 버전을 관리하는 YAML 파일 사용 (템플릿 ↔ 제품 매핑)
  2. 새 템플릿을 커밋할 때 Lambda 트리거
  3. Lambda가 Service Catalog API 호출하여 제품 생성 또는 업데이트

-> 제품 템플릿 표준화 + DevOps 파이프라인 통합

'Web' 카테고리의 다른 글

대용량 트래픽이란 몇건일까  (0) 2025.05.01
EKS 사용해보기  (1) 2025.04.24
Route53에서 구입한 도메인 ACM발급 실패  (0) 2025.04.19
AWS DOP - CloudFormation (2)  (0) 2025.04.17
AWS DOP - CloudFormation (1)  (0) 2025.04.16
'Web' 카테고리의 다른 글
  • 대용량 트래픽이란 몇건일까
  • EKS 사용해보기
  • Route53에서 구입한 도메인 ACM발급 실패
  • AWS DOP - CloudFormation (2)
마술사의 수습생
마술사의 수습생
언젠간 당신처럼 되고 싶어요.
  • 마술사의 수습생
    개발 기록 블로그
    마술사의 수습생
  • 전체
    오늘
    어제
    • 분류 전체보기 (53)
      • Web (50)
      • 일기 (2)
      • 잡담 (0)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
마술사의 수습생
AWS DOP - CloudFormation (3)
상단으로

티스토리툴바