Code Quality #
Kualitas kode Ansible tidak hanya tentang “apakah ia berjalan” — tapi tentang apakah ia bisa dipahami, di-maintain, dan dipercaya oleh semua orang di tim. Kode yang hanya dipahami oleh penulisnya adalah hutang teknis yang menunggu waktu untuk jadi masalah. Investasi dalam code quality — linting, review yang struktural, dokumentasi yang tepat — adalah investasi yang membayar diri sendiri berkali-kali lipat saat tim tumbuh dan infrastruktur menjadi lebih kompleks.
Konfigurasi ansible-lint yang Ketat #
# .ansible-lint
profile: production # Profil paling ketat — rekomendasikan untuk semua project
# Aturan yang di-skip hanya jika ada alasan yang sangat kuat
skip_list:
- yaml[line-length] # Baris panjang kadang tidak terhindarkan untuk command
# Aturan yang jadi warning, bukan error (untuk migrasi bertahap)
warn_list:
- no-changed-when # Sebaiknya diperbaiki, tapi belum blocking
# Path yang dikecualikan dari linting
exclude_paths:
- .cache/
- molecule/
- vendor/
# Aktifkan aturan experimental
use_default_rules: true
rulesdir:
- .ansible-lint-rules/ # Custom rules (lihat di bawah)
# Format output
verbosity: 1
Custom Lint Rules #
Untuk aturan spesifik organisasi yang tidak ada di ansible-lint bawaan:
# .ansible-lint-rules/NoPlaintextSecrets.py
"""Aturan custom: cegah variabel yang terlihat seperti secret tanpa vault."""
from ansiblelint.rules import AnsibleLintRule
import re
SECRET_PATTERNS = [
r'password\s*:\s*["\']?[^{][^"\']+["\']?$',
r'api_key\s*:\s*["\']?[^{][^"\']+["\']?$',
r'secret\s*:\s*["\']?[^{][^"\']+["\']?$',
r'token\s*:\s*["\']?[^{][^"\']+["\']?$',
]
class NoPlaintextSecrets(AnsibleLintRule):
id = 'COMPANY001'
shortdesc = 'Jangan menyimpan secret dalam plaintext'
description = (
'Variabel yang terlihat seperti secret (password, api_key, token) '
'tidak boleh berisi nilai plaintext. Gunakan Ansible Vault.'
)
severity = 'VERY_HIGH'
tags = ['security', 'company-policy']
def matchplay(self, file, data):
errors = []
if 'vars' in data:
for key, value in data.get('vars', {}).items():
if isinstance(value, str):
for pattern in SECRET_PATTERNS:
if re.search(pattern, f"{key}: {value}", re.IGNORECASE):
errors.append(({}, f"Kemungkinan secret plaintext: {key}"))
return errors
Pre-commit Hooks #
Cegah commit yang tidak memenuhi standar sebelum masuk ke repository:
# .pre-commit-config.yaml
repos:
- repo: https://github.com/ansible/ansible-lint
rev: v24.2.0
hooks:
- id: ansible-lint
args: ['--profile=production']
files: \.(yml|yaml)$
exclude: ^(molecule|vendor)/
- repo: https://github.com/adrienverge/yamllint
rev: v1.35.1
hooks:
- id: yamllint
args: [-c=.yamllint]
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.5.0
hooks:
- id: check-yaml
- id: check-merge-conflict
- id: trailing-whitespace
- id: end-of-file-fixer
- id: detect-private-key # Cegah private key masuk Git
- id: check-added-large-files
args: ['--maxkb=500']
# Cegah secret masuk ke Git
- repo: https://github.com/gitleaks/gitleaks
rev: v8.18.0
hooks:
- id: gitleaks
# Setup pre-commit di environment lokal
pip install pre-commit
pre-commit install
# Jalankan manual terhadap semua file (sekali pertama kali)
pre-commit run --all-files
yamllint: Format YAML yang Konsisten #
# .yamllint
---
extends: default
rules:
line-length:
max: 160 # Lebih longgar dari default 80
level: warning
truthy:
allowed-values: ['true', 'false']
check-keys: false # Jangan paksa boolean di keys
comments:
min-spaces-before-comment: 1
require-starting-space: true
braces:
min-spaces-inside: 0
max-spaces-inside: 1
indentation:
spaces: 2
indent-sequences: consistent
Code Review Checklist untuk Ansible #
## Checklist Review Playbook/Role
### Kebenaran
- [ ] Task menggunakan module yang tepat (bukan command/shell jika ada module)
- [ ] Semua task idempoten — aman dijalankan berulang kali
- [ ] Handler digunakan untuk restart service, bukan task langsung
- [ ] Error handling ada untuk operasi yang bisa gagal
### Keamanan
- [ ] Tidak ada secret plaintext (password, key, token)
- [ ] `no_log: true` untuk task yang melibatkan credential
- [ ] `become: true` hanya di task yang benar-benar butuh privilege
- [ ] Tidak ada `host_key_checking: false` tanpa justifikasi
### Kualitas
- [ ] Semua nilai melalui variabel, tidak ada hardcode
- [ ] Variabel punya nama yang deskriptif dan namespaced
- [ ] `defaults/main.yml` lengkap dengan nilai default yang masuk akal
- [ ] Dokumen variabel wajib di `meta/argument_specs.yml` atau README role
### Readability
- [ ] Setiap task punya nama yang menjelaskan tujuannya (bukan perintahnya)
- [ ] Komentar ada untuk logika yang tidak obvious
- [ ] Tidak ada kode yang sudah di-comment-out (hapus atau commit alasannya)
- [ ] Nama file dan direktori mengikuti konvensi project
Dokumentasi Inline yang Efektif #
# ANTI-PATTERN: nama task yang mendeskripsikan perintah, bukan tujuan
- name: Run systemctl restart nginx
systemd:
name: nginx
state: restarted
- name: apt-get install nginx
apt:
name: nginx
state: present
# BENAR: nama task yang menjelaskan MENGAPA, bukan APA
- name: Restart nginx untuk menerapkan konfigurasi SSL baru
systemd:
name: nginx
state: restarted
- name: Install nginx sebagai reverse proxy untuk aplikasi
apt:
name: nginx
state: present
# Komentar untuk logika yang tidak obvious:
- name: Tunggu 30 detik sebelum health check
pause:
seconds: 30
# Aplikasi butuh waktu untuk load semua konfigurasi dari environment
# sebelum health endpoint siap merespons. Nilai ini ditentukan dari
# observasi bahwa p99 startup time adalah 25 detik.
Ringkasan #
- Gunakan
profile: productiondi.ansible-lint— profil paling ketat sebagai standar, bukan sebagai tujuan yang akan dicapai nanti.- Pre-commit hooks adalah cara paling efektif mencegah masalah masuk ke repository — deteksi saat commit, bukan saat code review atau pipeline.
- Custom lint rules untuk aturan spesifik organisasi yang tidak ada di ansible-lint bawaan — misalnya, deteksi secret plaintext atau naming convention.
- Nama task yang menjelaskan tujuan (MENGAPA), bukan perintah (APA) —
systemctl restart nginxtidak informatif,Restart nginx setelah update SSLsangat informatif.- Code review checklist yang konkret lebih efektif dari guideline umum — reviewer tahu persis apa yang harus dicek, bukan mengandalkan intuisi.
yamllintuntuk konsistensi format YAML — style yang konsisten mengurangi cognitive load saat membaca kode orang lain.
← Sebelumnya: Project Structure Berikutnya: Testing Strategy →