0

Lab 6 — Ansible Templates với Jinja2

Mục tiêu: Sau Lab này, người học có thể sử dụng Jinja2 Template để sinh file configuration động bằng Ansible, kết hợp Variables + Facts + Conditions + Loops, đồng thời hiểu cách xây dựng configuration có thể tái sử dụng cho Dev / Staging / Production.


1. Bối cảnh

Lab 5 — Variables & Facts, chúng ta đã biết cách:

Variables
    ↓
Configuration data

Facts
    ↓
Server information

Playbook
    ↓
Tasks

Ví dụ:

app_name: todo
app_port: 8080
app_user: deploy

Chúng ta có thể sử dụng:

- name: Create application directory
  ansible.builtin.file:
    path: "/opt/{{ app_name }}"
    state: directory

Nhưng trong thực tế, configuration thường không chỉ có một giá trị.

Ví dụ một file Nginx:

server {
    listen 80;

    server_name todo.example.com;

    location / {
        proxy_pass http://127.0.0.1:8080;
    }
}

Nếu Production dùng:

todo.example.com
8080

nhưng Staging dùng:

staging.todo.example.com
8081

thì không nên tạo:

nginx-dev.conf
nginx-staging.conf
nginx-production.conf

Thay vào đó:

                    Variables
                        │
              ┌─────────┴─────────┐
              ▼                   ▼
          Dev config          Prod config
              │                   │
              └─────────┬─────────┘
                        ▼
                  Jinja2 Template
                        │
                        ▼
                   nginx.conf

Đây chính là nhiệm vụ của Template.


2. Template là gì?

Template là một file mẫu chứa:

  • Static content
  • Variables
  • Conditions
  • Loops
  • Logic của Jinja2

Ví dụ:

server {
    listen {{ nginx_port }};

    server_name {{ server_name }};

    location / {
        proxy_pass http://127.0.0.1:{{ app_port }};
    }
}

Nếu:

nginx_port: 80
server_name: todo.example.com
app_port: 8080

thì Ansible sẽ sinh ra:

server {
    listen 80;

    server_name todo.example.com;

    location / {
        proxy_pass http://127.0.0.1:8080;
    }
}

3. Jinja2 là gì?

Jinja2 là template engine được Ansible sử dụng để tạo nội dung động.

Có thể hình dung:

Template
    +
Variables
    +
Facts
    +
Logic
    │
    ▼
Jinja2
    │
    ▼
Final configuration

Ví dụ:

Hello {{ name }}

với:

name: Thong

sẽ trở thành:

Hello Thong

4. Cú pháp Jinja2 cơ bản

Có 3 loại syntax quan trọng.

4.1. Expression

Dùng:

{{ variable }}

Ví dụ:

server_name {{ domain }}

4.2. Statement

Dùng:

{% ... %}

Thường dùng cho:

  • if
  • for

Ví dụ:

{% if environment == "production" %}
production
{% endif %}

4.3. Comment

Dùng:

{# comment #}

Ví dụ:

{# This is generated by Ansible #}

Comment này sẽ không xuất hiện trong file được generate.


5. {{ }} vs {% %}

Đây là điểm người mới thường nhầm.

In giá trị

{{ app_port }}

Thực hiện logic

{% if environment == "production" %}

Ví dụ:

server {
    listen {{ app_port }};

    {% if environment == "production" %}
    access_log /var/log/nginx/access.log;
    {% endif %}
}

6. Tạo project

Tạo:

mkdir ansible-lab-06
cd ansible-lab-06

Cấu trúc ban đầu:

ansible-lab-06/
├── ansible.cfg
├── inventory.ini
├── group_vars/
│   └── webservers.yml
├── templates/
│   └── nginx.conf.j2
└── playbook.yml

7. ansible.cfg

[defaults]
inventory = ./inventory.ini

8. Inventory

[webservers]
web-01 ansible_host=192.168.56.101
web-02 ansible_host=192.168.56.102

Kiểm tra:

ansible-inventory --graph

9. Variables

Tạo:

group_vars/webservers.yml

Nội dung:

app_name: todo
app_host: 127.0.0.1
app_port: 8080

server_name: todo.example.com
nginx_port: 80

10. Tạo Template đầu tiên

Tạo:

templates/nginx.conf.j2

Nội dung:

server {
    listen {{ nginx_port }};

    server_name {{ server_name }};

    location / {
        proxy_pass http://{{ app_host }}:{{ app_port }};
    }
}

Đây chưa phải file Nginx hoàn chỉnh cho production, nhưng rất phù hợp để hiểu Template.


11. Sử dụng template module

Trong Playbook:

---
- name: Configure nginx
  hosts: webservers
  become: true

  tasks:
    - name: Install nginx
      ansible.builtin.apt:
        name: nginx
        state: present
        update_cache: true

    - name: Deploy nginx configuration
      ansible.builtin.template:
        src: nginx.conf.j2
        dest: /etc/nginx/sites-available/todo.conf
        owner: root
        group: root
        mode: "0644"

Chạy:

ansible-playbook playbook.yml

Ansible sẽ:

templates/nginx.conf.j2
          │
          │ Jinja2
          ▼
/etc/nginx/sites-available/todo.conf

12. Kiểm tra file trên server

SSH vào server:

ssh user@192.168.56.101

Kiểm tra:

cat /etc/nginx/sites-available/todo.conf

Bạn sẽ thấy:

server {
    listen 80;

    server_name todo.example.com;

    location / {
        proxy_pass http://127.0.0.1:8080;
    }
}

Các:

{{ nginx_port }}
{{ server_name }}
{{ app_host }}
{{ app_port }}

đã được thay thế.


13. Template không phải Copy

Đây là điểm rất quan trọng.

Có hai module:

copy
template

copy

Dùng khi file đã hoàn chỉnh:

ansible.builtin.copy:
  src: nginx.conf
  dest: /etc/nginx/nginx.conf

Nó gần như:

Source file
    ↓
Copy
    ↓
Destination

template

Dùng khi file có dữ liệu động:

ansible.builtin.template:
  src: nginx.conf.j2
  dest: /etc/nginx/nginx.conf

Flow:

Jinja2 Template
      +
Variables
      +
Facts
      +
Conditions
      ↓
Rendered file

14. Exercise — thay đổi Variable

Thay:

server_name: todo.example.com

thành:

server_name: api.example.com

Chạy lại:

ansible-playbook playbook.yml

Kiểm tra:

cat /etc/nginx/sites-available/todo.conf

Kết quả:

server_name api.example.com;

Bạn không cần sửa Template.

Đây chính là sức mạnh của Template.


15. Template + Facts

Template không chỉ sử dụng Variables.

Nó cũng có thể sử dụng Facts.

Ví dụ:

# Generated by Ansible

server: {{ ansible_hostname }}
os: {{ ansible_facts.distribution }}
architecture: {{ ansible_facts.architecture }}
ip: {{ ansible_facts.default_ipv4.address }}

Nếu server là:

hostname: web-01
OS: Ubuntu
architecture: x86_64
IP: 192.168.56.101

file sinh ra:

# Generated by Ansible

server: web-01
os: Ubuntu
architecture: x86_64
ip: 192.168.56.101

16. Template + if

Jinja2 hỗ trợ điều kiện.

Ví dụ:

server {
    listen {{ nginx_port }};

    server_name {{ server_name }};

    {% if environment == "production" %}
    access_log /var/log/nginx/access.log;
    error_log /var/log/nginx/error.log;
    {% endif %}

    location / {
        proxy_pass http://{{ app_host }}:{{ app_port }};
    }
}

Variables:

environment: production

thì phần:

{% if environment == "production" %}

được render.


17. if / else

Ví dụ:

{% if environment == "production" %}
worker_processes auto;
{% else %}
worker_processes 1;
{% endif %}

Nếu:

environment: production

kết quả:

worker_processes auto;

Nếu:

environment: development

kết quả:

worker_processes 1;

18. elif

Có thể có nhiều điều kiện:

{% if environment == "production" %}
worker_processes auto;

{% elif environment == "staging" %}
worker_processes 2;

{% else %}
worker_processes 1;

{% endif %}

Flow:

environment
     │
     ├── production → auto
     │
     ├── staging    → 2
     │
     └── other      → 1

19. Loop trong Jinja2

Jinja2 cũng hỗ trợ vòng lặp.

Variables:

upstreams:
  - 127.0.0.1:8080
  - 127.0.0.1:8081
  - 127.0.0.1:8082

Template:

upstream backend {
{% for server in upstreams %}
    server {{ server }};
{% endfor %}
}

Kết quả:

upstream backend {
    server 127.0.0.1:8080;
    server 127.0.0.1:8081;
    server 127.0.0.1:8082;
}

20. Đây là sức mạnh rất lớn

Thay vì viết:

server 127.0.0.1:8080;
server 127.0.0.1:8081;
server 127.0.0.1:8082;

chúng ta chỉ cần:

upstreams:
  - 127.0.0.1:8080
  - 127.0.0.1:8081
  - 127.0.0.1:8082

Template tự sinh.

Nếu thêm:

  - 127.0.0.1:8083

thì Template tự động sinh thêm:

server 127.0.0.1:8083;

21. Loop với Dictionary

Variables:

users:
  - name: deploy
    shell: /bin/bash

  - name: developer
    shell: /bin/bash

  - name: monitoring
    shell: /usr/sbin/nologin

Template:

{% for user in users %}
User: {{ user.name }}
Shell: {{ user.shell }}

{% endfor %}

Kết quả:

User: deploy
Shell: /bin/bash

User: developer
Shell: /bin/bash

User: monitoring
Shell: /usr/sbin/nologin

22. Jinja2 Filters

Một tính năng rất quan trọng của Jinja2 là Filter.

Syntax:

{{ variable | filter }}

Ví dụ:

{{ app_name | upper }}

Nếu:

app_name: todo

kết quả:

TODO

23. Một số Filter cơ bản

upper

{{ app_name | upper }}

lower

{{ app_name | lower }}

default

{{ app_port | default(8080) }}

length

{{ servers | length }}

join

{{ packages | join(', ') }}

24. default

Một tình huống rất thực tế:

Variable có thể không tồn tại.

Thay vì:

{{ app_port }}

có thể:

{{ app_port | default(8080) }}

Nếu app_port không được khai báo:

8080

sẽ được sử dụng.

Tuy nhiên:

Không nên lạm dụng default.

Nếu một variable bắt buộc phải có, tốt hơn nên để Playbook fail sớm thay vì âm thầm dùng giá trị mặc định sai.


25. Template với ansible_facts

Ví dụ tạo:

templates/server-info.txt.j2
Server Information
==================

Hostname: {{ ansible_hostname }}
OS: {{ ansible_facts.distribution }}
OS Version: {{ ansible_facts.distribution_version }}
Architecture: {{ ansible_facts.architecture }}
Memory: {{ ansible_facts.memtotal_mb }} MB
IP Address: {{ ansible_facts.default_ipv4.address }}

Task:

- name: Generate server information
  ansible.builtin.template:
    src: server-info.txt.j2
    dest: /tmp/server-info.txt
    mode: "0644"

26. Template + Environment

Đây là phần cực kỳ quan trọng đối với DevOps.

Tạo:

group_vars/
├── webservers.yml
├── development.yml
└── production.yml

Development:

environment: development
server_name: todo-dev.example.com
app_port: 8080

Production:

environment: production
server_name: todo.example.com
app_port: 8080

Template có thể dùng:

server_name {{ server_name }};

và:

{% if environment == "production" %}
    # Production configuration
{% endif %}

Một Template.

Nhiều Environment.


27. Template + Environment

Kiến trúc:

                  Playbook
                     │
                     ▼
              Jinja2 Template
                     │
          ┌──────────┼──────────┐
          ▼          ▼          ▼
        Dev       Staging      Prod
          │          │          │
          ▼          ▼          ▼
       Variables  Variables  Variables
          │          │          │
          └──────────┼──────────┘
                     ▼
              Rendered Config

Đây là nền tảng cho Lab 13 — Ansible với nhiều Environment.


28. template module quan trọng thế nào?

Một task production thường có dạng:

- name: Deploy configuration
  ansible.builtin.template:
    src: app.conf.j2
    dest: /etc/myapp/app.conf
    owner: root
    group: root
    mode: "0644"

Đây là pattern bạn sẽ gặp rất nhiều:

Template
    ↓
Configuration
    ↓
Service

Ví dụ:

nginx.conf.j2
    ↓
/etc/nginx/nginx.conf
    ↓
nginx

hoặc:

app.conf.j2
    ↓
/etc/myapp/app.conf
    ↓
application

29. Template + Handler

Có một vấn đề:

Nếu configuration thay đổi:

nginx.conf

thì Nginx cần reload.

Không nên:

- name: Deploy config
  template:
    ...

- name: Restart nginx
  service:
    name: nginx
    state: restarted

Vì mỗi lần chạy Playbook đều restart Nginx.

Đây là vấn đề Lab 7 sẽ giải quyết sâu hơn.

Nhưng ở đây chúng ta bắt đầu làm quen:

- name: Deploy nginx configuration
  ansible.builtin.template:
    src: nginx.conf.j2
    dest: /etc/nginx/sites-available/todo.conf
  notify: Reload nginx

Handler:

handlers:
  - name: Reload nginx
    ansible.builtin.service:
      name: nginx
      state: reloaded

Flow:

Template
   │
   ├── Changed
   │      ↓
   │   notify
   │      ↓
   │  Reload nginx
   │
   └── Not changed
          ↓
       No reload

Đây là một pattern cực kỳ quan trọng trong production.


30. Full Example

Cấu trúc:

ansible-lab-06/
├── ansible.cfg
├── inventory.ini
├── group_vars/
│   └── webservers.yml
├── templates/
│   └── nginx.conf.j2
└── playbook.yml

group_vars/webservers.yml

app_name: todo
app_host: 127.0.0.1
app_port: 8080

server_name: todo.example.com
nginx_port: 80

environment: production

templates/nginx.conf.j2

server {
    listen {{ nginx_port }};

    server_name {{ server_name }};

    {% if environment == "production" %}
    access_log /var/log/nginx/{{ app_name }}_access.log;
    error_log /var/log/nginx/{{ app_name }}_error.log;
    {% endif %}

    location / {
        proxy_pass http://{{ app_host }}:{{ app_port }};
        proxy_http_version 1.1;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }
}

playbook.yml

---
- name: Configure web server
  hosts: webservers
  become: true

  tasks:
    - name: Install nginx
      ansible.builtin.apt:
        name: nginx
        state: present
        update_cache: true

    - name: Deploy nginx configuration
      ansible.builtin.template:
        src: nginx.conf.j2
        dest: "/etc/nginx/sites-available/{{ app_name }}.conf"
        owner: root
        group: root
        mode: "0644"
      notify: Reload nginx

  handlers:
    - name: Reload nginx
      ansible.builtin.service:
        name: nginx
        state: reloaded

31. Kiểm tra Template trước khi Apply

Một kỹ năng rất hữu ích là kiểm tra Playbook trước khi thay đổi server.

ansible-playbook playbook.yml --check

Đây gọi là:

Check Mode

Ansible sẽ cố gắng mô phỏng thay đổi thay vì thực hiện thật.


32. Diff Mode

Có thể sử dụng:

ansible-playbook playbook.yml --check --diff

Đây là command rất hữu ích khi làm việc với Template.

Bạn có thể nhìn thấy:

- server_name old.example.com;
+ server_name todo.example.com;

Tư duy production:

Change configuration
        ↓
Check
        ↓
Diff
        ↓
Review
        ↓
Apply

33. Kiểm tra Syntax

Trước khi chạy:

ansible-playbook --syntax-check playbook.yml

Nếu Template có lỗi syntax Jinja2, việc render có thể thất bại khi task chạy.

Workflow tốt:

ansible-playbook --syntax-check playbook.yml
ansible-playbook playbook.yml --check --diff
ansible-playbook playbook.yml

34. Exercise 1 — Template cơ bản

Tạo:

templates/app.conf.j2

Nội dung:

Application: {{ app_name }}
Version: {{ app_version }}
Port: {{ app_port }}
Environment: {{ environment }}

Variables:

app_name: todo
app_version: "1.0.0"
app_port: 8080
environment: development

Generate:

/etc/myapp/app.conf

35. Exercise 2 — Template với Facts

Tạo:

templates/server-info.txt.j2

Sinh:

Hostname:
OS:
OS Version:
Architecture:
Memory:
IP:

Tất cả phải lấy từ Facts.


36. Exercise 3 — Template với if

Tạo:

environment: production

Nếu Production:

DEBUG=false
LOG_LEVEL=INFO

Nếu Development:

DEBUG=true
LOG_LEVEL=DEBUG

Template:

{% if environment == "production" %}
DEBUG=false
LOG_LEVEL=INFO
{% else %}
DEBUG=true
LOG_LEVEL=DEBUG
{% endif %}

37. Exercise 4 — Template với Loop

Variables:

backend_servers:
  - 10.0.0.11:8080
  - 10.0.0.12:8080
  - 10.0.0.13:8080

Generate:

upstream backend {
    server 10.0.0.11:8080;
    server 10.0.0.12:8080;
    server 10.0.0.13:8080;
}

Không được viết thủ công từng server trong Template.


38. Exercise 5 — Dynamic Nginx

Tạo Template:

templates/nginx.conf.j2

Variables:

server_name: todo.example.com
nginx_port: 80
app_host: 127.0.0.1
app_port: 8080

Template phải generate Reverse Proxy:

Client
   │
   ▼
Nginx :80
   │
   ▼
Application :8080

39. Exercise 6 — Multi Environment

Tạo:

group_vars/
├── development.yml
├── staging.yml
└── production.yml

Mỗi Environment có:

environment:
server_name:
app_port:

Template duy nhất:

templates/app.conf.j2

Yêu cầu:

1 Template
   │
   ├── Development
   ├── Staging
   └── Production

Không tạo:

app-dev.conf.j2
app-staging.conf.j2
app-production.conf.j2

40. Exercise 7 — Template + Handler

Khi Template thay đổi:

Reload nginx

Khi Template không thay đổi:

Không reload

Kiểm tra bằng:

ansible-playbook playbook.yml

lần đầu.

Sau đó chạy lại:

ansible-playbook playbook.yml

Lần thứ hai phải có:

changed=0

và handler không chạy.


41. Exercise 8 — Senior Challenge

Xây dựng một hệ thống cấu hình Nginx hoàn chỉnh.

Variables:

app:
  name: todo
  domain: todo.example.com
  port: 8080

nginx:
  port: 80

environment: production

backend_servers:
  - 127.0.0.1:8080
  - 127.0.0.1:8081

Template phải generate:

upstream todo_backend {
    server 127.0.0.1:8080;
    server 127.0.0.1:8081;
}

server {
    listen 80;

    server_name todo.example.com;

    location / {
        proxy_pass http://todo_backend;
    }
}

Thêm:

Production
    ↓
access log
error log

Development:

Development
    ↓
debug configuration

42. Những lỗi người mới thường gặp

Lỗi 1 — Quên .j2

Không bắt buộc về mặt kỹ thuật, nhưng convention nên là:

nginx.conf.j2

thay vì:

nginx.conf

để người khác biết đây là Jinja2 Template.


Lỗi 2 — Sai {{ }}

Sai:

server_name { server_name };

Đúng:

server_name {{ server_name }};

Lỗi 3 — Nhầm {% %}{{ }}

Sai:

{{ if environment == "production" }}

Đúng:

{% if environment == "production" %}

43. Lỗi 4 — Quên đóng if

Sai:

{% if environment == "production" %}

access_log /var/log/nginx/access.log;

Đúng:

{% if environment == "production" %}

access_log /var/log/nginx/access.log;

{% endif %}

44. Lỗi 5 — Template phụ thuộc Variable không tồn tại

Ví dụ:

server_name {{ domain_name }};

nhưng không có:

domain_name:

Có thể dẫn tới lỗi hoặc output không như mong muốn tùy context.

Tốt hơn nên thiết kế Variables rõ ràng và validate input khi cần.


45. Lỗi 6 — Template quá nhiều logic

Không nên biến Template thành một chương trình:

{% if ... %}
{% for ... %}
{% if ... %}
{% for ... %}
{% if ... %}
...

Nếu Template có quá nhiều logic:

Template
   ↓
Khó đọc
Khó test
Khó maintain

Nên đưa configuration data về Variables và giữ Template đơn giản.


46. Lỗi 7 — Hard-code trong Template

Không nên:

proxy_pass http://127.0.0.1:8080;

nếu giá trị có thể thay đổi.

Nên:

proxy_pass http://{{ app_host }}:{{ app_port }};

47. Tư duy Senior #1 — Template là "presentation layer"

Một cách tư duy rất tốt:

Variables
    ↓
Data

Template
    ↓
Presentation

Module
    ↓
Deployment

Ví dụ:

app_port: 8080
       ↓
nginx.conf.j2
       ↓
proxy_pass :8080
       ↓
/etc/nginx/nginx.conf

Template không nên chứa quá nhiều business logic.


48. Tư duy Senior #2 — Data-driven automation

Thay vì:

Nếu server A
    làm A

Nếu server B
    làm B

Nếu server C
    làm C

hãy hướng tới:

Configuration Data
       ↓
Generic Template
       ↓
Generated Configuration

Đây là tư duy data-driven automation.


49. Tư duy Senior #3 — Một Template, nhiều Environment

Không nên:

dev.conf.j2
staging.conf.j2
production.conf.j2

nếu sự khác biệt chỉ nằm ở configuration.

Tốt hơn:

app.conf.j2

và:

Development variables
Staging variables
Production variables

Flow:

               app.conf.j2
                    │
          ┌─────────┼─────────┐
          ▼         ▼         ▼
         Dev     Staging     Prod
          │         │         │
          ▼         ▼         ▼
        config    config    config

50. Tư duy Senior #4 — Configuration phải deterministic

Cùng một:

Template
+
Variables
+
Facts

nên tạo ra cùng một configuration.

Input
  ↓
Template
  ↓
Output

Điều này giúp:

  • Debug.
  • Review.
  • Audit.
  • Reproduce.
  • CI/CD.

51. Tư duy Senior #5 — Template + Idempotency

Đây là nền tảng của Lab 7.

Nếu configuration không thay đổi:

template
    ↓
same content
    ↓
changed = false
    ↓
no handler

Nếu configuration thay đổi:

template
    ↓
different content
    ↓
changed = true
    ↓
notify handler
    ↓
reload service

Đây là automation đúng cách.


52. Tư duy Senior #6 — Check trước khi Apply

Một workflow tốt:

Code
 ↓
Syntax Check
 ↓
Check Mode
 ↓
Diff
 ↓
Review
 ↓
Apply

Commands:

ansible-playbook --syntax-check playbook.yml
ansible-playbook playbook.yml --check --diff

sau đó:

ansible-playbook playbook.yml

Đây là thói quen rất nên hình thành ngay từ đầu.


53. Template trong Production

Template được sử dụng rất nhiều để generate:

Nginx
Apache
HAProxy
Systemd
Docker Compose
Application config
Environment files
Prometheus
Alertmanager
Fluent Bit
Loki
SSH
Database

Ví dụ trong DevOps:

Ansible
   │
   ├── nginx.conf.j2
   ├── docker-compose.yml.j2
   ├── application.yml.j2
   ├── prometheus.yml.j2
   └── systemd.service.j2

Sau đó:

Variables
    ↓
Templates
    ↓
Configuration
    ↓
Services

54. Một ví dụ gần với Kubernetes/DevOps

Giả sử application có:

app:
  name: todo
  port: 8080

database:
  host: postgres.internal
  port: 5432

redis:
  host: redis.internal
  port: 6379

Template:

server:
  port: {{ app.port }}

database:
  host: {{ database.host }}
  port: {{ database.port }}

redis:
  host: {{ redis.host }}
  port: {{ redis.port }}

Ansible có thể generate:

application.yml

cho từng Environment.

Đây là một pattern rất phổ biến trong infrastructure automation.


55. Lab Challenge — Production Configuration Generator

Đây là bài tập cuối Lab 6.

Xây dựng:

ansible-lab-06/
├── ansible.cfg
├── inventory.ini
├── group_vars/
│   └── webservers.yml
├── templates/
│   ├── nginx.conf.j2
│   └── server-info.txt.j2
└── playbook.yml

Variables

app:
  name: todo
  host: 127.0.0.1
  port: 8080

nginx:
  port: 80

environment: production

backend_servers:
  - 127.0.0.1:8080
  - 127.0.0.1:8081

Template phải có

Nginx

upstream
server
proxy_pass
server_name
access log
error log

Environment

Production:

access log
error log

Development:

debug

Backend

Loop qua:

backend_servers

để generate upstream.

Server Info

Sử dụng Facts:

hostname
OS
version
architecture
memory
IP

Handler

Nếu Nginx configuration thay đổi:

Reload nginx

Nếu không:

Không reload

56. Checklist hoàn thành Lab 6

Người học cần nắm được:

  • [ ] Template là gì.
  • [ ] Jinja2 là gì.
  • [ ] {{ }}.
  • [ ] {% %}.
  • [ ] {# #}.
  • [ ] template module.
  • [ ] Template + Variables.
  • [ ] Template + Facts.
  • [ ] if.
  • [ ] elif.
  • [ ] else.
  • [ ] for.
  • [ ] Jinja2 Filters.
  • [ ] default.
  • [ ] upper.
  • [ ] lower.
  • [ ] join.
  • [ ] Template + group_vars.
  • [ ] Template + Environment.
  • [ ] Template + Handler.
  • [ ] Check Mode.
  • [ ] Diff Mode.
  • [ ] Syntax Check.
  • [ ] Hiểu Template và Copy khác nhau thế nào.
  • [ ] Hiểu Template nên chứa presentation logic, không nên chứa quá nhiều business logic.
  • [ ] Có thể tạo một Template dùng cho nhiều Environment.
  • [ ] Có thể generate Nginx configuration động.

57. Tổng kết

Sau Lab 5:

Variables
Facts
     ↓
Playbook

Sau Lab 6:

                Variables
                    │
                    │
                  Facts
                    │
                    ▼
              Jinja2 Template
                    │
          ┌─────────┼─────────┐
          ▼         ▼         ▼
        Dev      Staging     Prod
          │         │         │
          ▼         ▼         ▼
       Config     Config     Config

Người học đã chuyển từ:

"Ansible chạy task như thế nào?"

sang:

"Ansible có thể tự động sinh configuration phù hợp với từng server/environment như thế nào?"

Đây là một bước tiến rất quan trọng trên con đường lên DevOps/Senior.

Và Lab tiếp theo sẽ ghép hai kiến thức quan trọng lại với nhau:

Lab 6
Templates
    │
    ▼
Configuration changes
    │
    ▼
Lab 7
Handlers & Idempotency
    │
    ├── Nếu config đổi
    │       ↓
    │    Reload/Restart
    │
    └── Nếu config không đổi
            ↓
         Không làm gì

Lab 7 — Ansible Handlers & Idempotency sẽ là bài đặc biệt quan trọng vì đây là lúc người học bắt đầu hiểu sâu hơn về tư duy Desired State, Idempotent Automation và cách tránh gây downtime không cần thiết trong production.


All rights reserved

Viblo
Hãy đăng ký một tài khoản Viblo để nhận được nhiều bài viết thú vị hơn.
Đăng kí