CloudFormation
고친 사람 github-actions[bot]
CloudFormation 은 글로 적어 둔 아마존 클라우드 자원 목록을 읽고 그 자원들을 대신 만들어 주는 서비스입니다. 서버나 저장소를 아마존 클라우드의 웹 관리 화면인 콘솔에서 하나씩 누르는 대신 파일 하나로 한꺼번에 세웁니다. 고칠 때도 파일을 고쳐 다시 넘기면 달라진 것만 바뀝니다. 지울 때는 그 파일로 만든 것이 전부 함께 지워집니다.
쉽고 빠른 이해
아마존 클라우드에 무엇을 만들지 파일에 적어 넘기면, 적힌 대로 만들어 주는 서비스입니다. 가상 서버 한 대와 파일 저장소 하나를 적어 넘기면 둘이 함께 생깁니다.
콘솔에서 손으로 만들면 무엇을 어떻게 눌렀는지가 남지 않습니다. 같은 구성을 한 벌 더 세우거나, 누가 무엇을 바꿨는지 찾을 때 기억에 기대야 합니다.
돌아가는 방식은 이렇습니다.
- 만들 자원과 설정값을 파일에 적습니다
- 그 파일을 넘기면 CloudFormation 이 순서를 정해 자원을 만듭니다
- 도중에 하나라도 실패하면 이번에 한 일을 되돌립니다
대가가 있습니다. 아마존 클라우드의 자원만 다룹니다. 파일 밖에서 손으로 바꾼 것은 파일에 반영되지 않아서, 파일과 실물이 조용히 어긋날 수 있습니다.
상세
CloudFormation 은 AWS(Amazon Web Services, 아마존 웹 서비스)가 내놓은 서비스입니다. 앞에서 말한 아마존 클라우드가 AWS 입니다. 받아서 설치하는 프로그램이 아니라, AWS 안에서 이미 돌고 있는 기능을 불러 쓰는 물건입니다. 인프라를 코드로 적어 관리하는 방식을 코드형 인프라라고 합니다. CloudFormation 은 AWS 가 그 방식을 자기 자원에 맞춰 내놓은 도구입니다.
이 절은 파일 하나가 자원 묶음이 되기까지를 따라갑니다. 웹 서버 한 대와 그 서버가 파일을 올려 둘 저장소 하나를 만드는 구성을 줄곧 예로 씁니다.
콘솔에서 누르던 일
AWS 에서 서버를 하나 띄우려면 콘솔 화면에서 여러 단계를 거칩니다. 서버 종류 · 네트워크 · 접속을 허용할 포트를 차례로 고릅니다. 저장소도 따로 만들고 이름을 붙입니다.
이 과정은 한 번은 할 만합니다. 곤란한 것은 두 번째부터입니다. 개발용과 운영용을 똑같이 세우려면 같은 클릭을 기억해서 다시 해야 합니다. 몇 달 뒤 누군가 설정 하나를 바꿔 두면 무엇이 언제 바뀌었는지 남는 기록이 없습니다.
CloudFormation 은 이 클릭들을 글로 바꿉니다. 글은 버전 관리에 넣을 수 있습니다. 두 번 넘기면 같은 구성이 두 벌 생깁니다. 바뀐 내용은 파일의 차이로 남습니다.
템플릿에 적는 것
CloudFormation 에 넘기는 파일을 템플릿이라고 부릅니다. YAML(YAML Ain't Markup Language) 이나 JSON(JavaScript Object Notation)으로 씁니다. 둘 다 이름과 값을 계층으로 적는 텍스트 형식입니다.
템플릿의 중심은 Resources 입니다. 만들 자원을 하나씩 적는 구역입니다. 자원마다 템플릿 안에서
부를 이름을 붙이고, 무슨 종류인지와 설정값을 적습니다. 템플릿 안에서 붙인 이 이름이 논리 ID 입니다.
Resources:
UploadBucket:
Type: AWS::S3::Bucket
WebServer:
Type: AWS::EC2::Instance
Properties:
InstanceType: t3.micro
ImageId: ami-0123456789abcdef0
위 템플릿은 자원 둘을 적었습니다. UploadBucket 은 Amazon S3(Simple Storage Service)의 파일 저장소입니다.
WebServer 는 Amazon EC2(Elastic Compute Cloud)의 가상 서버입니다. InstanceType 은 서버의 크기를,
ImageId 는 서버에 깔 운영체제 이미지의 번호를 적습니다. 위 번호는 예시로 지어 넣은 값입니다.
Type 줄의 AWS::S3::Bucket 처럼 종류 이름은 「AWS · 서비스 · 자원」 세 토막으로 적습니다.
Resources 말고도 두 구역을 자주 씁니다. Parameters 는 넘길 때마다 바꿔 넣을 값을 받습니다.
개발용이면 작은 서버, 운영용이면 큰 서버를 같은 템플릿으로 세울 때 씁니다. Outputs 는 만든 뒤
밖으로 알려 줄 값을 적습니다. 새로 생긴 서버의 주소 같은 것입니다.
템플릿은 「어떻게 만들어라」가 아니라 「이것이 있어야 한다」를 적습니다. 순서나 명령을 적지 않고 끝난 모습만 적습니다. 이런 방식이 선언적 설정입니다.
스택 — 한 템플릿으로 만든 묶음
템플릿을 CloudFormation 에 넘기면 스택이 하나 생깁니다. 스택은 그 템플릿 하나로 만든 자원들을 한 묶음으로 다루는 단위입니다. 위 예로 보면 저장소 하나와 서버 한 대가 스택 하나에 들어 있습니다.
만들기 · 고치기 · 지우기를 스택 단위로 합니다. 스택을 지우면 그 안의 자원이 모두 지워집니다. 손으로 만들었다면 하나씩 찾아 지워야 했을 것을 한 번에 치웁니다.
같은 템플릿을 이름만 달리해 두 번 넘기면 스택이 둘 생깁니다. 개발용 스택과 운영용 스택이 같은 템플릿에서 나오는 것입니다. 이때 자원의 이름을 템플릿에 고정해 두면 두 번째 스택이 이름 충돌로 실패합니다. 그래서 이름은 비워 두고 CloudFormation 이 지어 붙이게 하는 경우가 많습니다.
AWS 가 실물에 붙인 이름은 물리 ID 입니다. 저장소라면 스택 이름 뒤에 논리 ID 와 무작위 글자를 이어
붙인 이름이 됩니다. 서버라면 i- 로 시작하는 번호가 됩니다. 템플릿 안에서는 논리 ID 로 부릅니다.
AWS 안에서는 물리 ID 로 존재합니다. 둘을 잇는 표를 CloudFormation 이 스택마다 들고 있습니다.
flowchart TD
T["템플릿 한 벌"]
T --> D
T --> P
subgraph D["개발 스택"]
D1["UploadBucket"] --> D2["dev-uploadbucket-a1b2"]
D3["WebServer"] --> D4["i-0aaa…"]
end
subgraph P["운영 스택"]
P1["UploadBucket"] --> P2["prod-uploadbucket-c3d4"]
P3["WebServer"] --> P4["i-0bbb…"]
end
그림은 두 스택의 이름을 dev 와 prod 로 넘긴 경우입니다. 스택 칸마다 화살표 앞이 논리 ID, 화살표 끝이 물리 ID 입니다.
논리 ID 는 두 스택에서 같습니다.
물리 ID 는 스택마다 달라서 이름이 부딪히지 않습니다. 저장소 이름을 템플릿에 고정했다면 두 스택의
물리 ID 가 같아야 해서 두 번째 스택이 실패합니다.
만드는 순서
자원 사이에는 앞뒤가 있습니다. 서버가 저장소 이름을 알아야 한다면 저장소가 먼저 있어야 합니다. 템플릿에는 순서를 적지 않습니다. 앞뒤는 CloudFormation 이 알아냅니다.
앞뒤를 알아내는 단서는 참조입니다. 참조란 한 자원의 설정값에 다른 자원의 값을 끌어다 쓰는 것입니다. 참조가 있으면 가리켜진 쪽을 먼저 만듭니다.
참조는 CloudFormation 이 미리 마련해 둔 함수로 적습니다. 이런 함수를 내장 함수라고 합니다.
자주 쓰는 것은 둘입니다. !Ref 는 자원의 대표 값을 돌려줍니다. 저장소라면 저장소 이름입니다.
!GetAtt 는 자원이 가진 값 가운데 이름을 대어 하나를 골라 돌려줍니다. 서버의 공인 IP(Internet Protocol) 주소
(PublicIp)처럼 대표 값이 아닌 것을 꺼낼 때 씁니다.
앞의 예제에 참조를 더하면 이렇게 됩니다.
WebServer:
Type: AWS::EC2::Instance
Properties:
InstanceType: t3.micro
ImageId: ami-0123456789abcdef0
Tags:
- Key: UploadTo
Value: !Ref UploadBucket
Outputs:
ServerAddress:
Value: !GetAtt WebServer.PublicIp
서버의 태그 값이 저장소 이름을 가리킵니다. 그래서 저장소가 먼저 만들어지고 서버는 그 뒤에 만들어집니다.
Outputs 의 서버 주소는 서버가 다 만들어진 뒤에야 채워집니다. 서로 가리키지 않는 자원끼리는
기다릴 것이 없어서 함께 만들어집니다.
서로가 서로를 가리키면 앞뒤가 정해지지 않습니다. CloudFormation 은 이런 템플릿을 만들기 전에 거절합니다.
실패하면 되돌린다
스택을 만들다 자원 하나가 실패할 수 있습니다. 권한이 모자라거나, 설정값이 틀렸거나, 같은 이름이 이미 있는 경우입니다. 그러면 CloudFormation 은 이번에 만든 자원을 거꾸로 지워 나갑니다. 이 되돌림이 롤백입니다.
고칠 때도 롤백이 있습니다. 고치다 실패하면 이번에 바꾼 자원을 고치기 전 설정으로 돌려놓습니다. 만들 때의 롤백은 지우는 것입니다. 고칠 때의 롤백은 옛 설정으로 돌려놓는 것입니다.
stateDiagram-v2
[*] --> 만드는중
만드는중 --> 완료: 전부 성공
만드는중 --> 만들기되돌림: 하나라도 실패
만들기되돌림 --> 시작전: 만든 것을 지움
완료 --> 고치는중: 새 템플릿을 넘김
고치는중 --> 완료: 전부 성공
고치는중 --> 고치기되돌림: 하나라도 실패
고치기되돌림 --> 완료: 고치기 전 설정으로 돌림
만들기되돌림 --> 멈춤: 되돌리기 실패
고치기되돌림 --> 멈춤: 되돌리기 실패
그림처럼 스택은 반쯤 만들어진 채로 머물지 않는 쪽으로 움직입니다. 만들 때는 다 되거나 시작 전으로 돌아갑니다. 고칠 때는 다 고쳐지거나 고치기 전의 완료 상태로 돌아갑니다.
되돌림이 늘 깔끔하지는 않습니다. 되돌리는 도중에도 지우기나 되돌리기가 실패할 수 있습니다. 그러면 스택은 그림의 「멈춤」, 곧 사람이 들여다봐야 하는 상태에 머뭅니다. 자원 안에 이미 쌓인 데이터는 되돌림으로 살아나지 않습니다.
고칠 때는 차이만 바뀐다
스택을 고치려면 고친 템플릿을 다시 넘깁니다. CloudFormation 은 스택이 지금 들고 있는 템플릿과 새 템플릿을 견줍니다. 바뀐 자원만 손대고 나머지는 두고 갑니다.
바뀐 자원을 손대는 방식은 설정값마다 다릅니다. 태그 같은 값은 자원을 둔 채 값만 고칩니다. 저장소 이름 같은 값은 고칠 수 없어서, 새 자원을 만들고 옛 자원을 지웁니다. 이것이 교체입니다. 교체되는 자원이 데이터베이스라면 안에 든 데이터도 함께 사라질 수 있습니다.
그래서 넘기기 전에 무엇이 바뀔지 먼저 볼 수 있게 해 둡니다. 새 템플릿으로 변경 세트를 만들면, 어느 자원이 고쳐지고 어느 자원이 교체되는지가 목록으로 나옵니다. 목록을 보고 괜찮으면 그 변경 세트를 실행합니다. 아니면 버립니다.
파일과 실물이 어긋날 때
스택으로 만든 자원도 콘솔에서 손으로 고칠 수 있습니다. 그렇게 고치면 템플릿에 적힌 것과 AWS 에 있는 것이 달라집니다. 이 어긋남을 드리프트라고 부릅니다.
CloudFormation 은 드리프트를 찾아 주는 기능을 둡니다. 스택의 자원마다 템플릿이 기대하는 값과 지금 값을 견줘 다른 것을 알려 줍니다. 알려 줄 뿐 스스로 고치지는 않습니다.
어긋난 채로 템플릿을 다시 넘기면 결과를 짐작하기 어려워집니다. 손으로 바꾼 값이 템플릿 값으로 덮이기도 하고, 고치기 자체가 실패하기도 합니다. 그래서 스택으로 만든 자원은 템플릿으로만 고친다는 약속을 팀 안에 두는 경우가 많습니다.
상태를 AWS 가 들고 있다
코드형 인프라 도구는 「지금 무엇이 있는가」를 어딘가에 기록해 둬야 합니다. 그래야 다음에 무엇을 바꿀지 셈할 수 있습니다. 이 기록을 상태 파일로 사용자가 들고 있는 도구도 있습니다. 테라폼이 그렇습니다.
CloudFormation 에서는 이 기록을 AWS 가 스택 안에 들고 있습니다. 사용자는 기록을 어디에 둘지, 여러 사람이 동시에 고치다 기록이 깨지지 않게 할지를 신경 쓰지 않습니다. 대신 그 기록을 직접 열어 고칠 수도 없습니다.
CloudFormation 을 고르지 않는 때
CloudFormation 은 AWS 자원만 다룹니다. 다른 클라우드나 AWS 밖의 서비스까지 한 파일로 세우고 싶다면 테라폼처럼 여러 곳을 다루는 도구를 고릅니다.
YAML 로 모든 자원을 적다 보면 템플릿이 금방 길어집니다. 비슷한 자원을 되풀이해 적어야 합니다. 조건이나 반복을 표현하는 수단도 넉넉하지 않습니다. 이 불편 때문에 일반 프로그래밍 언어로 적은 코드에서 템플릿을 뽑아내는 도구가 따로 나와 있습니다. 아래 「맞물림」에서 봅니다.
맞물림
CloudFormation 은 템플릿을 읽어 다른 AWS 서비스를 부르는 물건이라 혼자서는 아무것도 만들지 못합니다. 이 절은 그중 넷을 봅니다. 권한을 대는 쪽, 템플릿을 대신 써 주는 쪽, 템플릿으로 못 적는 일을 맡는 쪽, 큰 파일을 받아 두는 쪽입니다.
AWS IAM 에서 권한을 받는다
CloudFormation 이 서버를 만든다는 것은, 누군가의 권한으로 EC2 에 「서버를 만들어라」를 부른다는 뜻입니다. 권한은 AWS IAM(Identity and Access Management, 신원과 접근 관리)이 정합니다. 기본으로는 스택을 넘긴 사람의 권한을 빌려 씁니다.
따로 역할 하나를 만들어 CloudFormation 에 맡길 수도 있습니다. 그러면 사람에게는 스택을 넘길 권한만 주고, 서버를 만들 권한은 그 역할에만 줍니다. 대가는 역할의 권한이 모자라면 스택이 중간에 실패하고 롤백된다는 것입니다. 무엇이 모자랐는지는 스택의 이벤트 기록을 뒤져야 나옵니다. 이벤트 기록은 스택의 자원마다 언제 만들기 시작했고 성공했는지 실패했는지를 적어 둔 목록입니다.
AWS CDK 와 AWS SAM 이 템플릿을 써 준다
템플릿이 길어지는 불편 때문에 AWS 는 템플릿을 대신 써 주는 도구를 둡니다. AWS CDK(Cloud Development Kit, 클라우드 개발 키트)는 TypeScript 나 Python 같은 언어로 자원을 적게 합니다. 그 코드를 돌리면 CloudFormation 템플릿이 나옵니다. 그 템플릿이 CloudFormation 에 넘어갑니다.
AWS SAM(Serverless Application Model, 서버리스 애플리케이션 모델)은 서버리스 자원을 짧게 적는 표기입니다. 서버리스 자원은 Lambda 함수처럼 서버를 직접 띄우고 관리하지 않아도 되는 자원입니다. 몇 줄로 적은 SAM 템플릿을 CloudFormation 이 받아 긴 템플릿으로 펼친 뒤 만듭니다.
두 도구 모두 결국 스택을 만듭니다. 그래서 롤백 · 변경 세트 · 드리프트가 그대로 따라옵니다. 대신 오류는 CloudFormation 의 말로 나옵니다. 자기가 쓴 코드와 나온 템플릿 사이를 한 번 더 오가며 원인을 찾아야 합니다.
AWS Lambda 가 템플릿으로 못 적는 일을 맡는다
CloudFormation 이 모르는 일도 있습니다. 만든 저장소에 초기 파일을 넣는 일 같은 것입니다. 이런 일은 템플릿에 AWS Lambda 함수를 하나 걸어 둡니다.
스택을 만들 때 CloudFormation 이 그 함수를 부르고, 함수가 일을 마친 뒤 성공인지 실패인지를 돌려줍니다. 이렇게 함수로 채운 자원이 커스텀 리소스입니다. 대가는 함수가 답을 안 돌려주면 스택이 한참 멈춘다는 것입니다. 지울 때와 고칠 때 할 일도 그 함수에 사람이 직접 짜 넣어야 합니다.
Amazon S3 에 템플릿과 코드를 올려 둔다
템플릿은 보통 파일 내용을 CloudFormation 에 바로 넘깁니다. 템플릿이 커지면 한 번에 넘길 수 있는 크기를 넘어서므로, S3 에 올린 뒤 그 주소를 넘깁니다. Lambda 함수 코드처럼 템플릿에 못 담는 파일도 S3 에 먼저 올리고, 템플릿에는 그 위치만 적습니다.
템플릿 하나 안에서 다른 템플릿을 불러 쓰는 중첩 스택도 S3 에 올린 템플릿을 가리킵니다. 그래서 스택을 넘기기 전에 S3 에 올리는 단계가 하나 늘어납니다. 올린 파일을 지우거나 바꾸면 다음 고치기가 엉뚱한 템플릿을 읽게 됩니다.
관련 항목
CloudFormation 이 속하는 상위 분류
코드형 인프라 · 선언적 설정 · 프로비저닝 · AWS · 클라우드
CloudFormation 스택을 이루는 구성 요소
템플릿 · 스택 · 변경 세트 · 중첩 스택 · StackSets · 내장 함수 · 커스텀 리소스 · YAML · JSON
CloudFormation 이 만들고 부르는 AWS 서비스
AWS IAM · AWS Lambda · Amazon S3 · Amazon EC2 · Amazon VPC · Amazon RDS
CloudFormation 템플릿을 대신 써 주는 도구
AWS CDK · AWS SAM · Serverless Framework
CloudFormation 을 대신할 수 있는 다른 수단
테라폼 · OpenTofu · Pulumi · 앤서블 · Azure Resource Manager · Google Cloud Deployment Manager
CloudFormation 을 굴릴 때 부딪히는 문제
CloudFormation 스택과 맞세워지는 테라폼의 구성 요소
다른 이름: AWS CloudFormation · 클라우드포메이션 · 클라우드 포메이션