🤖

본 콘텐츠의 이미지 및 내용은 AI로 생성되었습니다.

⚠️

본 콘텐츠의 이미지 및 내용을 무단으로 복제, 배포, 수정하여 사용할 경우 저작권법에 의해 법적 제재를 받을 수 있습니다.

이미지 로딩 중...

CloudFormation 기초 완벽 가이드 - 슬라이드 1/7
A

AI Generated

2025. 12. 20. · 4 Views

CloudFormation 기초 완벽 가이드

AWS 인프라를 코드로 관리하는 CloudFormation의 기초부터 실전까지 다룹니다. 템플릿 작성부터 스택 관리까지, 초급 개발자도 쉽게 따라 할 수 있는 실무 중심 가이드입니다.


목차

  1. IaC란_무엇인가
  2. CloudFormation_개념
  3. 템플릿_구조
  4. 스택_생성하기
  5. 파라미터와_출력
  6. 스택_업데이트와_삭제

1. IaC란 무엇인가

신입 개발자 김개발 씨는 오늘도 AWS 콘솔에서 EC2 인스턴스를 생성하고 있습니다. 보안 그룹 설정하고, 태그 붙이고, 네트워크 설정까지...

30분이 훌쩍 지나갔습니다. 그런데 팀장님이 말씀하십니다.

"개발 환경이랑 똑같은 걸 운영 환경에도 만들어주세요."

IaC(Infrastructure as Code)는 인프라를 코드로 관리하는 방식입니다. 마치 애플리케이션 코드를 Git으로 관리하듯이, 서버와 네트워크 설정도 코드 파일로 작성하고 버전 관리합니다.

클릭 몇 번으로 하던 작업을 코드 한 줄로 자동화할 수 있으며, 같은 환경을 몇 번이든 정확하게 복제할 수 있습니다.

다음 코드를 살펴봅시다.

# CloudFormation 템플릿 예시 (YAML 형식)
Resources:
  MyEC2Instance:
    Type: AWS::EC2::Instance
    Properties:
      # 인스턴스 타입 지정
      InstanceType: t2.micro
      # 리전별 AMI ID
      ImageId: ami-0c55b159cbfafe1f0
      # 태그로 리소스 구분
      Tags:
        - Key: Name
          Value: MyFirstServer
        - Key: Environment
          Value: Development

김개발 씨는 당황했습니다. 아까 만들었던 설정을 정확히 기억할 수 있을까요?

보안 그룹 규칙은 어떻게 설정했더라? 서브넷은 어느 걸 선택했더라?

하나라도 잘못 설정하면 개발 환경과 다른 환경이 만들어질 겁니다. 바로 이때 옆자리 선배 박시니어 씨가 다가왔습니다.

"아직도 콘솔에서 클릭으로 만들어요? IaC를 사용하면 훨씬 편한데." IaC란 정확히 무엇일까요? 쉽게 비유하자면, IaC는 마치 레시피와 같습니다.

요리사가 레시피를 보고 똑같은 음식을 만들 수 있듯이, 인프라 코드를 보고 똑같은 서버 환경을 만들 수 있습니다. 레시피에는 재료의 양과 조리 순서가 정확히 적혀 있습니다.

IaC 코드에도 서버 사양과 설정이 정확히 명시되어 있습니다. IaC가 없던 시절에는 어땠을까요? 예전 개발자들은 서버를 만들 때마다 수십 개의 설정을 직접 클릭해야 했습니다.

엑셀 문서에 "EC2 생성 가이드"를 적어두고, 그걸 보면서 하나하나 따라 했습니다. 실수하기도 쉬웠고, 시간도 오래 걸렸습니다.

더 큰 문제는 일관성이었습니다. 김 과장이 만든 개발 서버와 이 대리가 만든 개발 서버가 미묘하게 달랐습니다.

보안 그룹 규칙 하나가 다르거나, 서브넷이 달라서 버그가 발생했습니다. "제 컴퓨터에서는 되는데요?" 같은 문제가 인프라에서도 똑같이 일어났던 겁니다.

바로 이런 문제를 해결하기 위해 IaC가 등장했습니다. IaC를 사용하면 인프라 설정을 코드 파일로 작성합니다. 이 파일을 실행하면 자동으로 서버가 만들어집니다.

한 번 작성한 코드로 개발 환경, 스테이징 환경, 운영 환경을 모두 똑같이 만들 수 있습니다. 또한 코드이기 때문에 Git으로 버전 관리가 가능합니다.

"지난주에는 어떤 설정이었지?"라는 궁금증을 Git 히스토리로 바로 확인할 수 있습니다. 잘못 수정했다면 이전 버전으로 롤백도 가능합니다.

무엇보다 코드 리뷰가 가능하다는 큰 이점이 있습니다. "이 보안 그룹 규칙, 너무 느슨한 거 아니에요?"라는 피드백을 배포 전에 받을 수 있습니다.

클릭으로 만들었다면 이미 만들어진 후에야 문제를 발견했을 겁니다. 위의 코드를 한 줄씩 살펴보겠습니다. 먼저 Resources 섹션을 보면 생성할 리소스들을 정의한다는 걸 알 수 있습니다.

이 부분이 핵심입니다. MyEC2Instance라는 이름으로 EC2 인스턴스를 하나 정의했습니다.

다음으로 Type 항목에서는 어떤 AWS 리소스를 만들지 지정합니다. AWS::EC2::Instance는 EC2 인스턴스를 의미합니다.

Properties 아래에는 구체적인 설정들이 들어갑니다. 인스턴스 타입은 t2.micro로, AMI ID도 지정했습니다.

마지막으로 Tags를 통해 이 서버가 무엇인지 표시합니다. 나중에 AWS 콘솔에서 수많은 서버 중 이 서버를 쉽게 찾을 수 있습니다.

실제 현업에서는 어떻게 활용할까요? 예를 들어 쇼핑몰 서비스를 개발한다고 가정해봅시다. 웹 서버 2대, 데이터베이스 1대, 로드 밸런서 1개가 필요합니다.

IaC 없이 만든다면 각각 콘솔에서 클릭해서 생성하고, 서로 연결하고, 보안 그룹 설정하는데 1시간은 걸립니다. 하지만 IaC 코드로 작성하면 한 번의 명령어로 전체 환경이 5분 만에 생성됩니다.

더 놀라운 건, 똑같은 환경을 개발용으로 하나, 테스트용으로 하나, 운영용으로 하나 만드는 것도 쉽다는 점입니다. 많은 스타트업과 대기업에서 이런 패턴을 적극적으로 사용하고 있습니다.

하지만 주의할 점도 있습니다. 초보 개발자들이 흔히 하는 실수 중 하나는 IaC 코드를 작성하지 않고 콘솔에서 직접 리소스를 수정하는 것입니다. 이렇게 하면 코드와 실제 인프라가 달라지는 문제가 발생할 수 있습니다.

따라서 모든 변경사항은 반드시 코드를 수정한 후 적용해야 합니다. 다시 김개발 씨의 이야기로 돌아가 봅시다. 박시니어 씨의 설명을 들은 김개발 씨는 고개를 끄덕였습니다.

"아, 그래서 우리 팀이 CloudFormation을 쓰는 거군요!" IaC를 제대로 이해하면 더 빠르고 정확하게 인프라를 관리할 수 있습니다. 여러분도 오늘 배운 내용을 실제 프로젝트에 적용해 보세요.

실전 팁

💡 - IaC 코드는 반드시 Git으로 버전 관리하세요. 언제든 이전 상태로 돌아갈 수 있습니다.

  • 처음에는 작은 리소스(EC2 하나)부터 시작해서 점점 복잡한 구조로 확장하세요.
  • 코드와 실제 인프라가 다르지 않도록, 모든 변경은 코드를 통해서만 하세요.

2. CloudFormation 개념

IaC의 중요성을 깨달은 김개발 씨는 AWS에서 제공하는 IaC 도구를 찾아보기 시작했습니다. Terraform, Ansible, CloudFormation...

여러 도구가 있는데 뭘 써야 할지 고민이 됩니다. 박시니어 씨가 말합니다.

"우리 회사는 AWS만 쓰니까 CloudFormation이 제일 편해요."

'My first CloudFormation template' # 여기에 생성할 리소스들을 정의합니다 Resources: MyS3Bucket: Type: AWS::S3::Bucket Properties: # 버킷 이름은 전 세계에서 유일해야 함 BucketName: my-unique-bucket-20231215 # 퍼블릭 액세스 차단 설정 PublicAccessBlockConfiguration: BlockPublicAcls: true BlockPublicPolicy: true

다음 코드를 살펴봅시다.

# CloudFormation의 기본 구조
AWSTemplateFormatVersion: '2010-09-09'

김개발 씨는 검색을 하다가 의문이 생겼습니다. "Terraform도 유명한데, 왜 CloudFormation을 쓰는 거지?" 박시니어 씨가 커피를 한 모금 마시고 설명하기 시작했습니다.

"CloudFormation은 AWS에서 직접 만든 서비스예요. AWS 콘솔에 이미 내장되어 있어서 별도 설치가 필요 없죠." CloudFormation이란 정확히 무엇일까요? 쉽게 비유하자면, CloudFormation은 마치 건축 설계도와 같습니다.

건축가가 설계도를 그리면 건설 회사가 그대로 건물을 짓습니다. CloudFormation 템플릿에 원하는 인프라를 작성하면, AWS가 그대로 리소스를 만들어줍니다.

설계도에 방 3개, 화장실 2개라고 적으면 정확히 그렇게 지어지듯이, 템플릿에 EC2 2개, RDS 1개라고 적으면 정확히 그렇게 생성됩니다. CloudFormation이 없던 시절에는 어땠을까요? AWS 초창기에는 모든 리소스를 콘솔에서 직접 클릭해서 만들었습니다.

10개의 서버를 만들려면 같은 작업을 10번 반복해야 했습니다. 지루하고, 실수하기 쉬웠으며, 시간도 오래 걸렸습니다.

더 큰 문제는 삭제할 때였습니다. 테스트용으로 만든 리소스 20개를 일일이 찾아서 삭제해야 했습니다.

하나라도 빠뜨리면 요금이 계속 나갔습니다. "이거 누가 만든 거지?" 하면서 주인 없는 리소스가 쌓여갔습니다.

바로 이런 문제를 해결하기 위해 CloudFormation이 등장했습니다. CloudFormation을 사용하면 관련된 리소스들을 하나의 스택으로 묶어서 관리합니다. 웹 서버, 데이터베이스, 로드 밸런서를 하나의 스택으로 만들면, 삭제할 때도 한 번에 전부 삭제됩니다.

더 이상 리소스를 하나씩 찾아 헤맬 필요가 없습니다. 또한 AWS의 최신 기능을 가장 빠르게 지원합니다.

새로운 AWS 서비스가 출시되면 보통 몇 주 안에 CloudFormation에서도 사용할 수 있습니다. AWS가 직접 관리하기 때문에 안정성도 높습니다.

무엇보다 변경 세트(Change Set)라는 강력한 기능이 있습니다. 템플릿을 수정했을 때 실제로 어떤 리소스가 바뀔지 미리 확인할 수 있습니다.

"이 수정을 적용하면 데이터베이스가 재생성됩니다"라는 경고를 보고 적용 전에 판단할 수 있습니다. 위의 코드를 한 줄씩 살펴보겠습니다. 먼저 AWSTemplateFormatVersion을 보면 템플릿 버전을 지정한다는 걸 알 수 있습니다.

현재는 '2010-09-09' 버전이 표준입니다. 오래됐지만 계속 업데이트되고 있습니다.

Description은 이 템플릿이 무엇을 하는지 설명하는 부분입니다. 나중에 AWS 콘솔에서 이 설명을 볼 수 있습니다.

Resources 섹션이 가장 중요합니다. 여기에 실제로 생성할 AWS 리소스들을 정의합니다.

MyS3Bucket이라는 논리적 이름으로 S3 버킷을 하나 정의했습니다. Type은 AWS::S3::Bucket으로 S3 버킷을 의미합니다.

BucketName은 실제 버킷 이름입니다. S3 버킷 이름은 전 세계에서 유일해야 하므로 날짜나 회사명을 포함시키는 것이 좋습니다.

PublicAccessBlockConfiguration은 보안 설정으로, 실수로 버킷이 공개되는 것을 방지합니다. 실제 현업에서는 어떻게 활용할까요? 예를 들어 블로그 서비스를 만든다고 가정해봅시다.

EC2에 웹 서버를 띄우고, RDS에 데이터베이스를 만들고, CloudFront로 CDN을 설정하고, Route53으로 도메인을 연결해야 합니다. 이 모든 걸 CloudFormation 템플릿 하나로 정의합니다.

개발 환경이 필요하면 이 템플릿으로 스택을 하나 만듭니다. 스테이징 환경이 필요하면 또 하나 만듭니다.

똑같은 구조의 환경이 몇 분 만에 생성됩니다. 삭제도 스택 하나만 지우면 관련된 모든 리소스가 깔끔하게 정리됩니다.

많은 스타트업에서 이런 방식으로 여러 환경을 빠르게 생성하고 관리합니다. 하지만 주의할 점도 있습니다. 초보 개발자들이 흔히 하는 실수 중 하나는 템플릿으로 리소스를 만든 후, AWS 콘솔에서 직접 수정하는 것입니다.

이렇게 하면 CloudFormation이 관리하는 상태와 실제 리소스 상태가 달라집니다. 다음에 템플릿을 업데이트할 때 예상치 못한 문제가 발생할 수 있습니다.

따라서 모든 변경은 반드시 템플릿을 수정한 후 CloudFormation을 통해 적용해야 합니다. 다시 김개발 씨의 이야기로 돌아가 봅시다. 박시니어 씨의 설명을 들은 김개발 씨는 이해가 되었습니다.

"그러니까 CloudFormation은 AWS 전용이지만, AWS를 쓴다면 가장 편한 도구네요!" CloudFormation을 제대로 이해하면 AWS 인프라를 코드로 체계적으로 관리할 수 있습니다. 여러분도 오늘 배운 내용을 실제 프로젝트에 적용해 보세요.

실전 팁

💡 - YAML 형식이 JSON보다 읽기 쉬우므로 YAML을 권장합니다.

  • AWS 콘솔의 CloudFormation 디자이너를 사용하면 시각적으로 템플릿을 확인할 수 있습니다.
  • 리소스 이름(논리적 ID)은 의미 있게 지어서 나중에 찾기 쉽게 하세요.

3. 템플릿 구조

CloudFormation의 개념을 이해한 김개발 씨는 본격적으로 템플릿을 작성하기 시작했습니다. 그런데 막상 빈 파일을 열고 보니 어디서부터 시작해야 할지 막막합니다.

박시니어 씨가 화면을 보더니 말합니다. "템플릿에는 정해진 구조가 있어요.

기본 뼈대만 알면 쉽습니다."

Instance ID of the web server Value: !Ref WebServer

다음 코드를 살펴봅시다.

AWSTemplateFormatVersion: '2010-09-09'

김개발 씨는 다른 사람이 작성한 템플릿을 보면서 혼란스러웠습니다. "이 템플릿은 짧은데, 저 템플릿은 왜 이렇게 길지?

뭐가 필수고 뭐가 옵션인지 모르겠어요." 박시니어 씨가 자신이 작성한 템플릿을 보여주며 설명했습니다. "템플릿은 레고 블록처럼 여러 섹션을 조합해서 만드는 거예요." 템플릿 구조란 정확히 무엇일까요? 쉽게 비유하자면, 템플릿은 마치 요리 레시피와 같습니다.

레시피에는 재료 목록(Parameters), 조리 과정(Resources), 완성된 요리 설명(Outputs)이 있습니다. 템플릿도 마찬가지로 입력값, 리소스 정의, 출력값이라는 구조를 가지고 있습니다.

레시피의 각 섹션이 명확한 역할을 하듯이, 템플릿의 각 섹션도 명확한 목적이 있습니다. 템플릿 구조를 모르던 시절에는 어땠을까요? 초기 클라우드 관리 스크립트들은 일관된 구조가 없었습니다.

각자가 자기 방식대로 작성했고, 다른 사람의 스크립트를 이해하기 어려웠습니다. 어디서 입력을 받고, 어디서 리소스를 만들고, 어디서 결과를 보여주는지 찾기 힘들었습니다.

더 큰 문제는 재사용이었습니다. 한 프로젝트에서 작성한 스크립트를 다른 프로젝트에 쓰려면 전체를 다시 분석해야 했습니다.

"이 값은 어디서 설정하지?" 하면서 코드를 위아래로 스크롤하는 시간이 길었습니다. 바로 이런 문제를 해결하기 위해 정형화된 템플릿 구조가 등장했습니다. CloudFormation 템플릿은 정해진 섹션 구조를 따릅니다.

AWSTemplateFormatVersion은 항상 맨 위에 위치하며 템플릿 버전을 나타냅니다. Description은 이 템플릿이 무엇을 하는지 설명합니다.

Parameters 섹션에는 사용자로부터 입력받을 값들을 정의합니다. 인스턴스 타입이나 데이터베이스 비밀번호처럼 환경마다 다를 수 있는 값들을 여기에 둡니다.

Default 값을 지정하면 사용자가 입력하지 않아도 기본값이 사용됩니다. Resources 섹션이 가장 중요하며 유일한 필수 섹션입니다.

여기에 실제로 생성할 AWS 리소스들을 정의합니다. EC2, RDS, S3 등 모든 AWS 리소스를 여기에 작성합니다.

Outputs 섹션에는 스택 생성 후 사용자에게 보여줄 정보를 정의합니다. 생성된 서버의 IP 주소나 데이터베이스 엔드포인트처럼 나중에 필요한 정보를 출력합니다.

위의 코드를 한 줄씩 살펴보겠습니다. 먼저 Parameters 섹션의 InstanceType을 보면 사용자로부터 EC2 인스턴스 타입을 입력받는다는 걸 알 수 있습니다. Type은 String으로 문자열을 의미하며, Default는 t2.micro입니다.

사용자가 값을 입력하지 않으면 자동으로 t2.micro가 사용됩니다. Resources 섹션의 WebServer는 EC2 인스턴스를 정의합니다.

InstanceType 속성에서 !Ref InstanceType을 사용해 위에서 정의한 파라미터를 참조합니다. 이렇게 하면 사용자가 입력한 값이 여기에 들어갑니다.

Outputs 섹션의 InstanceId는 생성된 EC2 인스턴스의 ID를 출력합니다. !Ref WebServer는 WebServer 리소스의 ID를 가져옵니다.

스택 생성이 완료되면 AWS 콘솔에서 이 ID를 확인할 수 있습니다. 실제 현업에서는 어떤 섹션을 주로 사용할까요? 실무에서는 추가로 Mappings, Conditions, Metadata 섹션도 자주 사용합니다.

Mappings는 리전별로 다른 AMI ID를 매핑할 때 유용합니다. Conditions는 특정 조건에서만 리소스를 생성할 때 사용합니다.

예를 들어 개발 환경에서는 작은 인스턴스를, 운영 환경에서는 큰 인스턴스를 생성하고 싶다면 Conditions를 활용합니다. Parameters로 환경을 입력받고, Conditions로 조건을 판단하고, Resources에서 조건에 따라 다른 설정을 적용합니다.

많은 기업에서 이런 패턴으로 하나의 템플릿을 여러 환경에서 재사용합니다. 하지만 주의할 점도 있습니다. 초보 개발자들이 흔히 하는 실수 중 하나는 모든 값을 Parameters로 만드는 것입니다.

너무 많은 파라미터는 오히려 사용하기 어렵게 만듭니다. 환경마다 정말 달라지는 값만 파라미터로 만들고, 나머지는 템플릿에 직접 작성하는 것이 좋습니다.

따라서 "이 값이 정말 변경될까?"를 먼저 생각하고 파라미터를 만들어야 합니다. 다시 김개발 씨의 이야기로 돌아가 봅시다. 박시니어 씨의 설명을 들은 김개발 씨는 템플릿을 보는 눈이 생겼습니다.

"아, 섹션별로 역할이 명확하네요. 이제 어디를 봐야 할지 알겠어요!" 템플릿 구조를 제대로 이해하면 다른 사람의 템플릿도 쉽게 읽을 수 있고, 자신만의 템플릿도 체계적으로 작성할 수 있습니다.

여러분도 오늘 배운 내용을 실제 프로젝트에 적용해 보세요.

실전 팁

💡 - Resources는 필수이고 나머지는 선택입니다. 처음에는 Resources만으로 시작하세요.

  • Parameters는 꼭 필요한 것만 만드세요. 너무 많으면 오히려 복잡합니다.
  • Outputs에 중요한 정보(엔드포인트, ID 등)를 출력하면 나중에 찾기 쉽습니다.

4. 스택 생성하기

템플릿 구조를 이해한 김개발 씨는 드디어 첫 번째 템플릿 파일을 완성했습니다. 파일 이름은 my-first-stack.yaml입니다.

이제 이걸 실제로 실행해서 AWS 리소스를 만들어볼 차례입니다. "템플릿은 만들었는데, 어떻게 실행하죠?"

템플릿을 실행하면 스택이 생성됩니다. 스택은 관련된 AWS 리소스들의 모음으로, 하나의 단위로 관리됩니다.

AWS CLI나 콘솔에서 스택을 생성할 수 있으며, 스택 이름과 템플릿 파일만 지정하면 됩니다.

다음 코드를 살펴봅시다.

# AWS CLI로 스택 생성하기
aws cloudformation create-stack \
  --stack-name my-first-stack \
  --template-body file://my-first-stack.yaml \
  --parameters ParameterKey=InstanceType,ParameterValue=t2.small

# 스택 생성 상태 확인하기
aws cloudformation describe-stacks \
  --stack-name my-first-stack \
  --query 'Stacks[0].StackStatus'

# 스택의 모든 리소스 확인하기
aws cloudformation list-stack-resources \
  --stack-name my-first-stack

김개발 씨는 템플릿 파일을 만들었지만 실행 방법을 몰라 당황했습니다. 터미널에서 yaml 파일을 그냥 실행하면 될까요?

아니면 특별한 명령어가 있을까요? 박시니어 씨가 옆에서 AWS CLI 명령어를 보여주었습니다.

"create-stack 명령어 하나면 끝이에요." 스택 생성이란 정확히 무엇일까요? 쉽게 비유하자면, 스택은 마치 프로젝트 폴더와 같습니다. 개발할 때 관련 파일들을 하나의 폴더에 모아두듯이, CloudFormation도 관련 리소스들을 하나의 스택에 모아둡니다.

폴더를 삭제하면 안의 파일들이 모두 삭제되듯이, 스택을 삭제하면 관련 리소스들이 모두 삭제됩니다. 폴더 이름으로 파일들을 구분하듯이, 스택 이름으로 리소스 그룹을 구분합니다.

스택 개념이 없던 시절에는 어땠을까요? 예전에는 리소스를 개별적으로 생성하고 관리했습니다. EC2 10개, RDS 2개, S3 버킷 5개를 만들면 17개의 독립적인 리소스가 생겼습니다.

이들이 하나의 프로젝트에 속한다는 걸 구분하기 어려웠습니다. 더 큰 문제는 정리할 때였습니다.

프로젝트가 끝나서 모든 리소스를 삭제하려면 17개를 일일이 찾아서 하나씩 지워야 했습니다. 하나라도 놓치면 계속 요금이 청구되었습니다.

"이 RDS는 어느 프로젝트 거였지?" 하면서 찾아 헤매는 일이 많았습니다. 바로 이런 문제를 해결하기 위해 스택이라는 개념이 등장했습니다. 스택을 생성하면 템플릿에 정의된 모든 리소스가 하나의 그룹으로 묶입니다.

my-first-stack이라는 이름으로 스택을 만들면, 이 스택에 속한 모든 리소스에 자동으로 태그가 붙습니다. AWS 콘솔에서 쉽게 찾을 수 있습니다.

또한 스택 단위로 생명주기를 관리합니다. 스택을 생성하면 모든 리소스가 생성되고, 스택을 삭제하면 모든 리소스가 삭제됩니다.

더 이상 개별 리소스를 추적할 필요가 없습니다. 무엇보다 스택은 롤백 기능을 제공합니다.

스택 생성 중 에러가 발생하면 자동으로 이미 만들어진 리소스들을 삭제하고 원래 상태로 돌아갑니다. 반쯤 만들어진 상태로 남아있지 않습니다.

위의 코드를 한 줄씩 살펴보겠습니다. 먼저 create-stack 명령어를 보면 스택을 생성한다는 걸 알 수 있습니다. --stack-name은 스택의 이름을 지정합니다.

이 이름은 나중에 스택을 관리할 때 사용하므로 의미 있게 짓는 것이 좋습니다. --template-body는 템플릿 파일의 위치를 지정합니다.

file://로 시작하면 로컬 파일을 의미합니다. S3에 업로드한 템플릿을 사용하려면 --template-url을 사용할 수도 있습니다.

--parameters는 템플릿의 파라미터에 값을 전달합니다. ParameterKey는 파라미터 이름이고, ParameterValue는 실제 값입니다.

여러 파라미터가 있다면 이 옵션을 여러 번 반복합니다. describe-stacks 명령어는 스택의 상태를 확인합니다.

StackStatus는 CREATE_IN_PROGRESS, CREATE_COMPLETE, CREATE_FAILED 같은 값을 반환합니다. 스택이 제대로 생성되고 있는지 확인할 수 있습니다.

list-stack-resources 명령어는 스택에 속한 모든 리소스를 나열합니다. 어떤 리소스들이 생성되었는지, 각 리소스의 ID는 무엇인지 확인할 수 있습니다.

실제 현업에서는 어떻게 활용할까요? 실무에서는 보통 개발 환경, 스테이징 환경, 운영 환경을 각각 다른 스택으로 만듭니다. dev-web-stack, staging-web-stack, prod-web-stack처럼 환경을 구분해서 이름을 짓습니다.

예를 들어 새로운 기능을 개발할 때는 dev-feature-x-stack처럼 기능별로 스택을 만들기도 합니다. 개발이 끝나면 스택을 삭제하면 모든 리소스가 깔끔하게 정리됩니다.

비용도 절약되고 관리도 쉬워집니다. 많은 스타트업에서 이런 방식으로 여러 환경을 효율적으로 관리합니다.

하지만 주의할 점도 있습니다. 초보 개발자들이 흔히 하는 실수 중 하나는 스택 이름을 대충 짓는 것입니다. test, stack1, my-stack 같은 이름은 나중에 어떤 스택인지 구분하기 어렵습니다.

프로젝트명-환경-용도 형식으로 명확하게 짓는 것이 좋습니다. 따라서 myapp-prod-web처럼 의미 있는 이름을 사용해야 합니다.

또 하나 중요한 점은 스택 생성이 실패했을 때 원인을 확인하는 것입니다. CloudFormation Events 탭에서 어떤 리소스 생성이 실패했는지, 왜 실패했는지 자세한 로그를 볼 수 있습니다.

다시 김개발 씨의 이야기로 돌아가 봅시다. 박시니어 씨의 도움으로 첫 번째 스택을 성공적으로 생성한 김개발 씨는 감격했습니다. "와, AWS 콘솔에서 EC2가 만들어지는 게 보여요!" 스택 생성을 제대로 이해하면 인프라를 체계적으로 관리할 수 있습니다.

여러분도 오늘 배운 내용을 실제 프로젝트에 적용해 보세요.

실전 팁

💡 - 스택 이름은 프로젝트-환경-용도 형식으로 명확하게 짓세요.

  • 스택 생성 후 describe-stacks로 상태를 확인하는 습관을 들이세요.
  • 실패한 스택은 자동으로 롤백되지만, Events에서 실패 원인을 꼭 확인하세요.

5. 파라미터와 출력

첫 번째 스택 생성에 성공한 김개발 씨는 개발 환경과 운영 환경을 만들려고 합니다. 그런데 두 환경에서 인스턴스 타입만 다르고 나머지는 똑같습니다.

템플릿을 두 개 만들어야 할까요? 박시니어 씨가 말합니다.

"파라미터를 쓰면 하나의 템플릿으로 여러 환경을 만들 수 있어요."

Public IP address Value: !GetAtt WebServer.PublicIp

다음 코드를 살펴봅시다.

Parameters:
  Environment:
    Type: String
    Default: dev
    AllowedValues:
      - dev
      - staging
      - prod

김개발 씨는 고민에 빠졌습니다. "개발 환경은 t2.micro로, 운영 환경은 t2.large로 만들고 싶은데, 템플릿을 두 벌 만들어야 하나요?" 박시니어 씨가 웃으며 대답했습니다.

"그럴 필요 없어요. 파라미터를 사용하면 하나의 템플릿으로 모든 환경을 만들 수 있어요." 파라미터란 정확히 무엇일까요? 쉽게 비유하자면, 파라미터는 마치 함수의 매개변수와 같습니다.

함수를 호출할 때 다른 값을 넘겨서 다른 결과를 얻듯이, 스택을 생성할 때 다른 파라미터를 넘겨서 다른 환경을 만듭니다. 같은 함수 코드를 재사용하듯이, 같은 템플릿을 재사용합니다.

calculate(5, 10)과 calculate(20, 30)이 다른 결과를 내듯이, dev 파라미터와 prod 파라미터로 다른 스택을 만듭니다. 파라미터가 없던 시절에는 어땠을까요? 예전에는 환경마다 별도의 템플릿을 만들어야 했습니다.

dev-template.yaml, staging-template.yaml, prod-template.yaml처럼 세 개의 파일을 관리했습니다. 99% 같은 내용인데 인스턴스 타입 하나만 달랐습니다.

더 큰 문제는 유지보수였습니다. 보안 그룹 규칙을 하나 추가하려면 세 개 파일을 모두 수정해야 했습니다.

하나라도 빠뜨리면 환경마다 다른 설정이 되어버렸습니다. "왜 개발 환경에서는 되는데 운영에서는 안 되지?" 하는 문제가 자주 발생했습니다.

바로 이런 문제를 해결하기 위해 파라미터가 등장했습니다. Parameters 섹션에 환경별로 달라지는 값들을 정의합니다. Environment 파라미터는 dev, staging, prod 중 하나를 선택할 수 있습니다.

AllowedValues로 허용 값을 제한하면 사용자가 잘못된 값을 입력하는 걸 방지할 수 있습니다. Default 값을 지정하면 사용자가 값을 입력하지 않았을 때 기본값이 사용됩니다.

개발 환경에서 자주 테스트한다면 dev를 기본값으로 하는 것이 편리합니다. 파라미터를 사용하려면 !Ref 함수를 씁니다.

!Ref InstanceType은 사용자가 입력한 InstanceType 값을 가져옵니다. 이렇게 하면 하나의 템플릿으로 여러 환경을 만들 수 있습니다.

Outputs는 왜 필요할까요? 스택을 생성한 후에 중요한 정보를 확인해야 할 때가 많습니다. 생성된 EC2 인스턴스의 ID는 무엇인지, 퍼블릭 IP는 무엇인지 알아야 SSH로 접속할 수 있습니다.

Outputs 섹션에 이런 정보를 정의하면 스택 생성 후 AWS 콘솔이나 CLI에서 바로 확인할 수 있습니다. 일일이 EC2 콘솔에 가서 인스턴스를 찾을 필요가 없습니다.

더 강력한 기능은 Export입니다. 출력값을 Export하면 다른 스택에서 !ImportValue로 가져갈 수 있습니다.

예를 들어 네트워크 스택에서 VPC ID를 Export하면, 애플리케이션 스택에서 그 VPC ID를 Import해서 사용할 수 있습니다. 스택 간 의존성을 명확하게 관리할 수 있습니다.

위의 코드를 한 줄씩 살펴보겠습니다. 먼저 Parameters 섹션의 Environment를 보면 환경 이름을 입력받는다는 걸 알 수 있습니다. AllowedValues로 dev, staging, prod만 허용합니다.

사용자가 production이라고 잘못 입력하면 에러가 발생해서 실수를 방지합니다. Resources 섹션에서 !Ref Environment를 사용해 태그를 붙입니다.

이렇게 하면 AWS 콘솔에서 어느 환경의 리소스인지 쉽게 구분할 수 있습니다. Outputs 섹션의 InstanceId는 생성된 인스턴스의 ID를 출력합니다.

Export의 Name에서 !Sub 함수를 사용해 스택 이름을 포함시켰습니다. ${AWS::StackName}은 현재 스택의 이름으로 자동 치환됩니다.

PublicIP는 !GetAtt 함수를 사용해 인스턴스의 속성을 가져옵니다. WebServer.PublicIp는 WebServer 리소스의 퍼블릭 IP 주소를 의미합니다.

스택 생성 후 이 IP로 바로 SSH 접속할 수 있습니다. 실제 현업에서는 어떻게 활용할까요? 실무에서는 네트워크 스택과 애플리케이션 스택을 분리해서 만드는 경우가 많습니다.

네트워크 스택에서 VPC, 서브넷, 보안 그룹을 만들고 VPC ID를 Export합니다. 애플리케이션 스택에서는 그 VPC ID를 Import해서 EC2를 생성합니다.

예를 들어 네트워크는 한 번만 만들고, 애플리케이션은 여러 번 배포하는 시나리오입니다. 네트워크 설정은 잘 바뀌지 않지만, 애플리케이션은 자주 업데이트됩니다.

스택을 분리하면 애플리케이션만 업데이트할 때 네트워크는 건드리지 않아도 됩니다. 많은 기업에서 이런 계층형 스택 구조를 사용합니다.

하지만 주의할 점도 있습니다. 초보 개발자들이 흔히 하는 실수 중 하나는 모든 값을 파라미터로 만드는 것입니다. 파라미터가 너무 많으면 스택 생성할 때마다 입력할 게 많아져서 오히려 불편합니다.

정말 환경마다 달라지는 값만 파라미터로 만들고, 고정된 값은 템플릿에 직접 작성하는 것이 좋습니다. 또 하나 주의할 점은 Export된 값은 삭제하기 어렵다는 것입니다.

다른 스택에서 Import하고 있으면 원본 스택을 삭제할 수 없습니다. 먼저 Import하는 스택을 삭제해야 합니다.

따라서 Export는 정말 필요한 경우에만 사용해야 합니다. 다시 김개발 씨의 이야기로 돌아가 봅시다. 박시니어 씨의 설명을 들은 김개발 씨는 파라미터를 추가해서 템플릿을 수정했습니다.

"이제 하나의 템플릿으로 개발, 스테이징, 운영 환경을 모두 만들 수 있겠어요!" 파라미터와 출력을 제대로 이해하면 템플릿의 재사용성이 크게 높아지고, 스택 간 협업도 쉬워집니다. 여러분도 오늘 배운 내용을 실제 프로젝트에 적용해 보세요.

실전 팁

💡 - AllowedValues로 파라미터 값을 제한하면 사용자 실수를 방지할 수 있습니다.

  • 중요한 정보(IP, 엔드포인트 등)는 Outputs에 출력해서 쉽게 확인하세요.
  • Export는 다른 스택과 공유할 값에만 사용하고, 이름 충돌을 피하려면 스택 이름을 포함시키세요.

6. 스택 업데이트와 삭제

며칠 후, 김개발 씨는 운영 중인 스택의 보안 그룹 규칙을 수정해야 하는 상황에 놓였습니다. 스택을 삭제하고 다시 만들어야 할까요?

그러면 데이터가 다 날아가는데... 걱정하는 김개발 씨에게 박시니어 씨가 말합니다.

"스택은 업데이트할 수 있어요. 삭제하지 않아도 됩니다."

생성된 스택은 삭제하지 않고 업데이트할 수 있습니다. 템플릿을 수정한 후 update-stack 명령어로 변경사항을 적용하면 기존 리소스는 유지되고 필요한 부분만 변경됩니다.

변경 세트(Change Set)로 어떤 리소스가 바뀔지 미리 확인할 수 있으며, 더 이상 필요 없는 스택은 delete-stack으로 모든 리소스와 함께 삭제됩니다.

다음 코드를 살펴봅시다.

# 스택 업데이트하기
aws cloudformation update-stack \
  --stack-name my-first-stack \
  --template-body file://my-first-stack-v2.yaml \
  --parameters ParameterKey=InstanceType,ParameterValue=t2.small

# 변경 세트 생성해서 미리 확인하기
aws cloudformation create-change-set \
  --stack-name my-first-stack \
  --change-set-name my-changes \
  --template-body file://my-first-stack-v2.yaml

# 변경 세트 내용 확인
aws cloudformation describe-change-set \
  --change-set-name my-changes \
  --stack-name my-first-stack

# 변경 세트 실행 (확인 후 적용)
aws cloudformation execute-change-set \
  --change-set-name my-changes \
  --stack-name my-first-stack

# 스택 삭제하기
aws cloudformation delete-stack \
  --stack-name my-first-stack

김개발 씨는 당황했습니다. "스택을 만들 때 보안 그룹을 잘못 설정한 것 같아요.

이거 고치려면 전부 삭제하고 다시 만들어야 하나요?" 박시니어 씨가 고개를 저었습니다. "아니에요.

CloudFormation의 강력한 기능 중 하나가 바로 업데이트예요." 스택 업데이트란 정확히 무엇일까요? 쉽게 비유하자면, 스택 업데이트는 마치 소프트웨어 업데이트와 같습니다. 스마트폰 앱을 업데이트할 때 앱을 삭제하고 다시 설치하지 않습니다.

바뀐 부분만 업데이트하고 데이터는 그대로 유지됩니다. 스택도 마찬가지입니다.

템플릿에서 수정한 부분만 반영되고, 변경되지 않은 리소스는 그대로 유지됩니다. 앱 업데이트가 끝나면 새 기능을 쓸 수 있듯이, 스택 업데이트가 끝나면 새 설정이 적용됩니다.

스택 업데이트가 없던 시절에는 어땠을까요? 예전에는 설정을 바꾸려면 AWS 콘솔에서 직접 리소스를 수정했습니다. 보안 그룹 규칙을 콘솔에서 클릭해서 변경하고, 인스턴스 타입을 콘솔에서 변경했습니다.

문제는 템플릿과 실제 환경이 달라진다는 점이었습니다. 더 큰 문제는 추적이었습니다.

"누가 언제 왜 이 설정을 바꿨지?" 하는 질문에 답하기 어려웠습니다. 여러 사람이 각자 콘솔에서 수정하다 보니 누가 뭘 바꿨는지 알 수 없었습니다.

Git 커밋 메시지처럼 변경 이력이 남지 않았습니다. 바로 이런 문제를 해결하기 위해 스택 업데이트가 등장했습니다. update-stack 명령어는 기존 스택을 삭제하지 않고 수정합니다.

템플릿 파일을 수정한 후 이 명령어를 실행하면 CloudFormation이 변경사항을 분석합니다. 어떤 리소스를 업데이트해야 하는지, 어떤 리소스는 삭제하고 재생성해야 하는지, 어떤 리소스는 그대로 둬야 하는지 자동으로 판단합니다.

하지만 여기서 중요한 질문이 생깁니다. "업데이트했는데 데이터베이스가 재생성되면 어떡하지?" 데이터가 날아가는 큰 사고가 발생할 수 있습니다.

바로 이럴 때 변경 세트가 유용합니다. 변경 세트(Change Set)는 실제로 적용하기 전에 어떤 변경이 일어날지 미리 보여줍니다. create-change-set으로 변경 세트를 만들면 CloudFormation이 시뮬레이션을 돌립니다.

"이 리소스는 업데이트됩니다", "이 리소스는 재생성됩니다", "이 리소스는 삭제됩니다" 같은 정보를 보여줍니다. describe-change-set으로 변경 세트의 내용을 확인합니다.

만약 "RDS가 재생성됩니다"라는 메시지를 보면 적용하지 않고 템플릿을 다시 수정할 수 있습니다. 확인 후 괜찮다고 판단되면 execute-change-set으로 실제 적용합니다.

이런 방식은 마치 Git의 pull request와 비슷합니다. 코드 변경을 바로 merge하지 않고 리뷰 후 merge하듯이, 스택 변경도 확인 후 적용합니다.

스택 삭제는 언제 할까요? 개발이 끝났거나, 테스트가 완료되었거나, 더 이상 필요 없는 환경은 삭제해야 합니다. delete-stack 명령어는 스택과 관련된 모든 리소스를 삭제합니다.

EC2, RDS, S3, 로드 밸런서 등 스택에 속한 모든 것이 사라집니다. 하지만 주의할 점이 있습니다.

일부 리소스는 DeletionPolicy를 설정할 수 있습니다. 예를 들어 S3 버킷이나 RDS 데이터베이스는 스택을 삭제해도 보존하고 싶을 수 있습니다.

DeletionPolicy를 Retain으로 설정하면 스택이 삭제되어도 해당 리소스는 남아있습니다. 위의 코드를 한 줄씩 살펴보겠습니다. 먼저 update-stack 명령어를 보면 기존 스택을 업데이트한다는 걸 알 수 있습니다.

--stack-name으로 어떤 스택을 수정할지 지정하고, --template-body로 새 템플릿을 제공합니다. v2.yaml이라는 이름에서 템플릿이 업데이트되었음을 알 수 있습니다.

create-change-set은 실제 적용 전에 변경 내용을 확인하는 명령어입니다. --change-set-name으로 변경 세트에 이름을 붙입니다.

여러 변경 세트를 만들어서 비교할 수도 있습니다. describe-change-set은 변경 세트의 상세 내용을 보여줍니다.

어떤 리소스가 추가되는지, 수정되는지, 삭제되는지, 재생성되는지 모두 확인할 수 있습니다. 특히 Replacement: True라고 표시되면 리소스가 재생성된다는 의미이므로 주의해야 합니다.

execute-change-set은 확인한 변경 세트를 실제로 적용합니다. 이 명령어를 실행하는 순간 리소스들이 변경되기 시작합니다.

신중하게 결정해야 합니다. delete-stack은 스택과 모든 리소스를 삭제합니다.

이 명령어를 실행하면 되돌릴 수 없으므로 정말 삭제해도 되는지 다시 한번 확인해야 합니다. 실제 현업에서는 어떻게 활용할까요? 실무에서는 업데이트 전에 반드시 변경 세트를 확인하는 것이 표준입니다.

특히 운영 환경은 더욱 조심해야 합니다. 데이터베이스가 재생성되면 데이터가 날아가고, 서비스가 중단됩니다.

예를 들어 보안 그룹 규칙을 추가하는 것은 안전합니다. 기존 리소스는 그대로 있고 규칙만 추가됩니다.

하지만 RDS 엔진 버전을 변경하면 재시작이 필요할 수 있고, 인스턴스 타입을 변경하면 다운타임이 발생합니다. 많은 회사에서 변경 세트를 팀원들과 공유하고 리뷰 후에 적용합니다.

"이 변경 세트 확인해주세요"라고 공유하면, 다른 개발자가 리뷰하고 승인합니다. 코드 리뷰처럼 인프라 변경도 리뷰하는 문화가 자리 잡고 있습니다.

하지만 주의할 점도 있습니다. 초보 개발자들이 흔히 하는 실수 중 하나는 운영 환경에서 변경 세트 없이 바로 update-stack을 실행하는 것입니다. 개발 환경에서는 괜찮지만, 운영 환경에서는 반드시 변경 세트로 확인 후 적용해야 합니다.

또 하나 주의할 점은 삭제 보호입니다. 중요한 스택은 EnableTerminationProtection 옵션을 켜서 실수로 삭제되는 것을 방지할 수 있습니다.

삭제 보호가 활성화되면 먼저 보호를 해제해야 삭제할 수 있습니다. 다시 김개발 씨의 이야기로 돌아가 봅시다. 박시니어 씨의 설명을 들은 김개발 씨는 변경 세트를 만들어 확인했습니다.

"아, 보안 그룹만 업데이트되고 EC2는 그대로네요. 안전하게 적용할 수 있겠어요!" 스택 업데이트와 삭제를 제대로 이해하면 안전하게 인프라를 변경하고 관리할 수 있습니다.

여러분도 오늘 배운 내용을 실제 프로젝트에 적용해 보세요.

실전 팁

💡 - 운영 환경에서는 반드시 변경 세트로 확인 후 적용하세요.

  • DeletionPolicy를 Retain으로 설정하면 스택 삭제 시 데이터를 보존할 수 있습니다.
  • 중요한 스택에는 삭제 보호를 활성화해서 실수를 방지하세요.

이상으로 학습을 마칩니다. 위 내용을 직접 코드로 작성해보면서 익혀보세요!

#AWS#CloudFormation#IaC#Infrastructure#DevOps

댓글 (0)

댓글을 작성하려면 로그인이 필요합니다.