---
id: iac-cloudformation
title: "CloudFormation"
shortTitle: "CloudFormation"
track: iac
trackTitle: "Infrastructure as Code"
order: 3
level: important
status: published
estimatedMinutes: 30
prerequisites:
  - iac-bicep
next: iac-deployment-manager
reviewedAgainst: 2026-10-12
sources:
  - title: "What is AWS CloudFormation?"
    url: https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/Welcome.html
  - title: "Template anatomy"
    url: https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/template-anatomy.html
---

# CloudFormation

CloudFormation là IaC của AWS. Một stack là một nhóm resource tạo từ template. Terraform quản lý state riêng. CloudFormation giữ stack trên AWS.

## Để làm gì

Bạn đọc một template S3 có mã hóa, và biết `create-stack` sẽ tạo resource thật nên lab không gọi lệnh đó.

## Gồm những gì

- `AWSTemplateFormatVersion`, `Resources`, logical id.
- Stack và change set: đủ để gọi đúng tên.
- Khác Bicep: type là `AWS::...`, không phải ARM.

Bài này không nói nested stack, cũng không tạo bucket.

## Dùng khi nào

Tài khoản AWS đã dùng stack, hoặc một bài viết nội bộ đưa template YAML. Đừng thêm CloudFormation vào hệ Terraform đang giữ, trên cùng một bucket.

## Kiến thức cốt lõi

Template có `Resources`. Mỗi khóa dưới đó là logical id, ví dụ `Bucket`. Type là `AWS::S3::Bucket`. Tên vật lý do AWS đặt, hoặc bạn đưa trong `Properties`. Đổi logical id thì CloudFormation coi resource cũ bị xóa và tạo resource mới. Dữ liệu trong bucket có thể mất nếu DeletionPolicy cho phép xóa.

Change set là bản xem trước của lần update. `create-stack` và `update-stack` ghi thật. `validate-template` chỉ kiểm tra cú pháp, nhưng vẫn cần quyền gọi API, nên lab không chạy lệnh đó.

Xóa stack xóa resource trong stack, trừ resource đặt `DeletionPolicy: Retain`. Database production thường Retain. Lab thì để mặc định và đừng tạo stack.

## Lệnh và code mẫu

`template.yaml`:

```yaml
AWSTemplateFormatVersion: "2010-09-09"
Resources:
  Bucket:
    Type: AWS::S3::Bucket
    Properties:
      BucketEncryption:
        ServerSideEncryptionConfiguration:
          - ServerSideEncryptionByDefault:
              SSEAlgorithm: AES256
      PublicAccessBlockConfiguration:
        BlockPublicAcls: true
        BlockPublicPolicy: true
        IgnorePublicAcls: true
        RestrictPublicBuckets: true
```

Lệnh dưới đây không chạy trong lab:

```bash
aws cloudformation create-stack --stack-name lab --template-body file://template.yaml
```

## Thực hành

1. Chỉ logical id và type.
2. Chỉ bốn cờ chặn public access.
3. Không gọi AWS.

## Kết quả mong đợi

Logical id `Bucket`, type `AWS::S3::Bucket`. Bốn cờ public đều `true`, nghĩa là chặn.

## Checklist

- [ ] Change set trước update stack đang giữ dữ liệu.
- [ ] Không đổi logical id của database chỉ để tên trong YAML đẹp hơn.
- [ ] Bucket lab không public.

## Lỗi thường gặp

**Sửa template bằng tay trên console rồi sửa file.** Lần update sau, stack drift. Sửa file, update stack, đừng vá resource ngoài template.

**`create-stack` từ máy học vì muốn thấy cho biết.** Stack tính phí và để lại bucket. Dừng ở đọc file.

## Nguồn

1. [What is AWS CloudFormation?](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/Welcome.html) — stack và template.
2. [Template anatomy](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/template-anatomy.html) — `Resources` và version.

## Tiếp theo

[Deployment Manager](./13-deployment-manager.md)
