---
id: config-chef
title: "Chef"
shortTitle: "Chef"
track: config
trackTitle: "Configuration Management"
order: 4
level: important
status: published
estimatedMinutes: 25
prerequisites:
  - config-puppet
next: config-salt
reviewedAgainst: 2026-10-12
sources:
  - title: "About recipes"
    url: https://docs.chef.io/recipes/
  - title: "About cookbooks"
    url: https://docs.chef.io/cookbooks/
---

# Chef

Chef viết cấu hình bằng Ruby. Recipe là file thực thi resource. Cookbook là thư mục chứa recipe và file kèm. Bài Ruby phía trước đủ để đọc cú pháp. Bài này đọc resource của Chef.

## Để làm gì

Bạn đọc một recipe tạo file, và biết `chef-client` trên node sẽ kéo cookbook từ server nếu máy đang được Chef quản lý.

## Gồm những gì

- Recipe, cookbook, resource `file`.
- `chef-client` là lần hội tụ trên node.
- Khác Puppet ở ngôn ngữ. Cùng mục tiêu: đưa máy về trạng thái đã khai báo.

Đừng dựng Chef Infra Server, và đừng cài workstation trong bài này.

## Dùng khi nào

Repo có `cookbooks/` hoặc một node còn chạy `chef-client`. Đừng đưa Chef vào máy mới nếu chưa có server. Ansible playbook đã làm việc tạo file trong lab.

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

Một recipe là Ruby gọi resource. Resource `file` có `path` và `content`. Chạy recipe lần hai, file đã đúng nội dung thì Chef không ghi lại. Đó là hội tụ.

Cookbook có `metadata.rb`, thư mục `recipes`, và có thể có `templates`. Recipe mặc định là `recipes/default.rb`. Node chạy `chef-client` theo lịch hoặc theo tay. Nó lấy danh sách cookbook mà node được gán, rồi áp.

Ohai thu thập thông tin máy và đưa vào object `node`. Recipe có thể đọc `node['platform']`. Đừng dựa vào một attribute chưa ai set. Nó ra nil và resource nhận giá trị rỗng.

## Lệnh và code mẫu

`recipes/default.rb`:

```ruby
file '/tmp/devops-lab-chef.txt' do
  content "ok\n"
  action :create
end
```

Không chạy `chef-client`. Máy không có Chef thì file này chỉ để đọc.

## Thực hành

1. Chỉ path file resource sẽ tạo.
2. Chỉ action.
3. Không cài Chef và không đăng ký node.

## Kết quả mong đợi

Path `/tmp/devops-lab-chef.txt`, action `:create`, nội dung `ok`.

## Checklist

- [ ] Sửa cookbook trong Git, không sửa chỉ trên một node.
- [ ] Không thêm Chef server cho một task Ansible đã làm được.
- [ ] Đọc `action` trước khi chạy, `:delete` không phải `:create`.

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

**Recipe Ruby đúng cú pháp nhưng resource sai path.** `ruby -c` không hiểu Chef. Lỗi nằm ở path `/etc` trên node thật. Chạy trên một node lab, hoặc dùng chế độ why-run nếu workstation đã có.

**Gán cookbook lên mọi node trong organization.** Một recipe cài package sẽ đụng cả máy không liên quan. Gán theo role hoặc policy của nhóm máy đó.

## Nguồn

1. [About recipes](https://docs.chef.io/recipes/) — resource và lần chạy.
2. [About cookbooks](https://docs.chef.io/cookbooks/) — cấu trúc thư mục.

## Tiếp theo

[Salt](./05-salt.md)
