サーバー設定やDocker、Kubernetesなどの構成管理をしていると、よく目にする「YAML(ヤムル)」というファイル。
こんな経験はありませんか?
- 「YAMLファイルを編集してって言われたけど、何これ?」
- 「インデントがずれただけでエラーになる…」
- 「JSONと何が違うの?」
- 「書き方のルールがよくわからない」
実は、YAMLはとてもシンプルで読みやすい形式です。
この記事でわかること:
- YAMLの基本概念と特徴
- JSONやXMLとの違い
- 実際に使える書き方の基本
- よくあるエラーと対処法
- 実際のプロジェクトでの活用例
この記事を読めば、YAMLを恐れることなく、自信を持って編集・作成できるようになります!
YAMLとは何か?【基礎知識編】

YAMLの定義と由来
YAMLは**「YAML Ain’t Markup Language」**(YAMLはマークアップ言語じゃない)の再帰的頭字語です。
歴史と発展:
- 2001年:Clark Evans、Ingy döt Net、Oren Ben-Kikiによって開発開始
- 設計目標:人間が読みやすく、すべてのプログラミング言語でアクセス可能
- 現在のバージョン:YAML 1.2(2009年リリース、現在も標準)
YAMLの主な特徴
特徴 | 説明 | メリット |
---|---|---|
人間可読性 | インデントで構造を表現 | 直感的に理解しやすい |
軽量 | 余計な記号が少ない | ファイルサイズが小さい |
コメント対応 | # でコメント記述可能 | ドキュメント化しやすい |
データタイプ豊富 | 文字列、数値、配列、オブジェクトなど | 複雑なデータ構造も表現可能 |
言語非依存 | 多くのプログラミング言語でサポート | 汎用性が高い |
YAMLが使われる主な場面
1. 設定ファイル
# アプリケーション設定例
app:
name: "MyApplication"
version: "1.2.3"
debug: true
database:
host: "localhost"
port: 5432
name: "mydb"
2. インフラ構成管理
# Docker Compose例
version: '3.8'
services:
web:
image: nginx:latest
ports:
- "80:80"
db:
image: postgres:13
environment:
POSTGRES_DB: mydb
3. CI/CDパイプライン
# GitHub Actions例
name: CI
on: [push, pull_request]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Run tests
run: npm test
YAMLと他の形式の比較
YAML vs JSON vs XML
同じデータの表現比較
YAML:
person:
name: "田中太郎"
age: 30
skills:
- "JavaScript"
- "Python"
- "Docker"
contact:
email: "tanaka@example.com"
phone: "090-1234-5678"
JSON:
{
"person": {
"name": "田中太郎",
"age": 30,
"skills": [
"JavaScript",
"Python",
"Docker"
],
"contact": {
"email": "tanaka@example.com",
"phone": "090-1234-5678"
}
}
}
XML:
<person>
<name>田中太郎</name>
<age>30</age>
<skills>
<skill>JavaScript</skill>
<skill>Python</skill>
<skill>Docker</skill>
</skills>
<contact>
<email>tanaka@example.com</email>
<phone>090-1234-5678</phone>
</contact>
</person>
比較表
項目 | YAML | JSON | XML |
---|---|---|---|
可読性 | ★★★ | ★★☆ | ★☆☆ |
記述量 | ★★★ | ★★☆ | ★☆☆ |
コメント | ✅ | ❌ | ✅ |
パース速度 | ★☆☆ | ★★★ | ★☆☆ |
Web API | ★☆☆ | ★★★ | ★★☆ |
設定ファイル | ★★★ | ★★☆ | ★☆☆ |
使い分けの指針
YAMLを選ぶべき場面
- 設定ファイル:アプリケーション、インフラ設定
- ドキュメント:APIドキュメント、仕様書
- 人間が編集:手動で変更する可能性が高い
JSONを選ぶべき場面
- API通信:REST APIのリクエスト/レスポンス
- Webアプリ:JavaScript との親和性
- パフォーマンス重視:高速なパースが必要
XMLを選ぶべき場面
- レガシーシステム:既存システムとの互換性
- 厳密な検証:XML Schemaによる厳密なバリデーション
- 複雑な構造:名前空間、属性が必要
YAMLの基本文法【詳細解説】

1. 基本的なデータ型
スカラー値(単一の値)
# 文字列
name: "田中太郎"
title: プロジェクトマネージャー # 引用符なしでもOK
# 数値
age: 30
price: 1299.99
scientific: 1.23e10
# 真偽値
active: true
completed: false
enabled: yes # true と同じ
disabled: no # false と同じ
# null値
middle_name: null
nickname: ~ # null と同じ
# 日付
birth_date: 1990-12-25
timestamp: 2023-01-01T10:00:00Z
複数行文字列
# 改行を保持(|記号)
description: |
これは複数行の
説明文です。
改行が保持されます。
# 改行を空白に変換(>記号)
summary: >
これは長い文章を
複数行に分けて書いた場合、
実際は一行になります。
# インデントを制御
code: |2
def hello():
print("Hello, World!")
2. コレクション(配列とオブジェクト)
配列(リスト)
# 基本的な配列
fruits:
- apple
- orange
- banana
# インライン形式
colors: [red, green, blue]
# 複雑なオブジェクトの配列
users:
- name: "Alice"
role: "admin"
active: true
- name: "Bob"
role: "user"
active: false
# 入れ子の配列
matrix:
- [1, 2, 3]
- [4, 5, 6]
- [7, 8, 9]
オブジェクト(辞書)
# 基本的なオブジェクト
person:
name: "田中太郎"
age: 30
city: "東京"
# インライン形式
coordinates: {x: 10, y: 20}
# 入れ子のオブジェクト
company:
name: "サンプル株式会社"
address:
zip: "100-0001"
prefecture: "東京都"
city: "千代田区"
street: "千代田1-1-1"
departments:
- name: "開発部"
members: 15
- name: "営業部"
members: 10
3. 高度な機能
アンカーとエイリアス(参照)
# アンカーの定義(&記号)
defaults: &default_settings
timeout: 30
retry_count: 3
debug: false
# エイリアスで参照(*記号)
development:
<<: *default_settings
debug: true
production:
<<: *default_settings
timeout: 60
# 結果的に以下と同じ:
# development:
# timeout: 30
# retry_count: 3
# debug: true
# production:
# timeout: 60
# retry_count: 3
# debug: false
マージキー
# 複数の設定をマージ
server_defaults: &server
memory: "512MB"
cpu: 1
database_defaults: &database
engine: "postgresql"
version: "13"
app_server:
<<: [*server, *database]
name: "app-server"
port: 8080
明示的なデータ型指定
# 文字列として明示
version: !!str 1.2
quote: !!str "true"
# 整数として明示
count: !!int "42"
# 浮動小数点として明示
price: !!float 19.99
# バイナリデータ
image: !!binary |
R0lGODlhPQBEAPeoAJosM//AwO/AwHVYZ/z595kzAP/s7P+goOXMv8+fhw/v739/f+8PD98fH/8mJl+fn/9ZWb8/PzWlwv///6wWGbImAPgTEMImIN9gUFCEm/gDALULDN8PAD6atYdCTX
実践的なYAMLの書き方
1. Docker Compose の実例
# docker-compose.yml
version: '3.8'
services:
# Webアプリケーション
web:
build: .
ports:
- "3000:3000"
environment:
- NODE_ENV=production
- DATABASE_URL=postgresql://user:password@db:5432/myapp
depends_on:
- db
- redis
volumes:
- ./logs:/app/logs
networks:
- app-network
# データベース
db:
image: postgres:13
environment:
POSTGRES_DB: myapp
POSTGRES_USER: user
POSTGRES_PASSWORD: password
volumes:
- postgres_data:/var/lib/postgresql/data
networks:
- app-network
# Redis
redis:
image: redis:6-alpine
networks:
- app-network
# リバースプロキシ
nginx:
image: nginx:alpine
ports:
- "80:80"
- "443:443"
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf:ro
- ./ssl:/etc/ssl:ro
depends_on:
- web
networks:
- app-network
volumes:
postgres_data:
networks:
app-network:
driver: bridge
2. Kubernetes の実例
# kubernetes-deployment.yml
apiVersion: apps/v1
kind: Deployment
metadata:
name: web-app
labels:
app: web-app
spec:
replicas: 3
selector:
matchLabels:
app: web-app
template:
metadata:
labels:
app: web-app
spec:
containers:
- name: web
image: myapp:latest
ports:
- containerPort: 3000
env:
- name: NODE_ENV
value: "production"
- name: DATABASE_URL
valueFrom:
secretKeyRef:
name: app-secrets
key: database-url
resources:
requests:
memory: "128Mi"
cpu: "100m"
limits:
memory: "256Mi"
cpu: "200m"
livenessProbe:
httpGet:
path: /health
port: 3000
initialDelaySeconds: 30
periodSeconds: 10
readinessProbe:
httpGet:
path: /ready
port: 3000
initialDelaySeconds: 5
periodSeconds: 5
---
apiVersion: v1
kind: Service
metadata:
name: web-app-service
spec:
selector:
app: web-app
ports:
- protocol: TCP
port: 80
targetPort: 3000
type: ClusterIP
3. GitHub Actions の実例
# .github/workflows/ci.yml
name: CI/CD Pipeline
on:
push:
branches: [main, develop]
pull_request:
branches: [main]
env:
NODE_VERSION: '16'
REGISTRY: ghcr.io
IMAGE_NAME: ${{ github.repository }}
jobs:
test:
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [14, 16, 18]
steps:
- name: Checkout code
uses: actions/checkout@v3
- name: Setup Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v3
with:
node-version: ${{ matrix.node-version }}
cache: 'npm'
- name: Install dependencies
run: npm ci
- name: Run linting
run: npm run lint
- name: Run tests
run: npm test
- name: Run coverage
run: npm run coverage
- name: Upload coverage reports
uses: codecov/codecov-action@v3
with:
token: ${{ secrets.CODECOV_TOKEN }}
build:
needs: test
runs-on: ubuntu-latest
if: github.ref == 'refs/heads/main'
steps:
- name: Checkout code
uses: actions/checkout@v3
- name: Log in to Container Registry
uses: docker/login-action@v2
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Extract metadata
id: meta
uses: docker/metadata-action@v4
with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
tags: |
type=ref,event=branch
type=ref,event=pr
type=sha
- name: Build and push Docker image
uses: docker/build-push-action@v4
with:
context: .
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
deploy:
needs: build
runs-on: ubuntu-latest
if: github.ref == 'refs/heads/main'
environment: production
steps:
- name: Deploy to production
run: |
echo "Deploying to production..."
# デプロイスクリプトの実行
よくあるエラーと対処法

1. インデント関連のエラー
問題:インデントの不一致
❌ 間違った例:
person:
name: "田中"
age: 30 # インデントが深すぎる
city: "東京"
✅ 正しい例:
person:
name: "田中"
age: 30
city: "東京"
問題:タブとスペースの混在
❌ 間違った例:
config:
database: # スペース2個
host: localhost # タブ文字(見た目は同じだがエラー)
✅ 正しい例:
config:
database:
host: localhost # すべてスペース
2. データ型関連のエラー
問題:意図しない型変換
❌ 問題のある例:
version: 1.2.0 # 数値として解釈される
port: 008080 # 8進数として解釈される可能性
enabled: yes # 真偽値として解釈される
✅ 明示的な型指定:
version: "1.2.0" # 文字列として明示
port: "008080" # 文字列として明示
enabled: "yes" # 文字列として明示
# または
version: !!str 1.2.0
port: !!str 008080
enabled: !!str yes
3. 文字列関連のエラー
問題:特殊文字のエスケープ
❌ 問題のある例:
message: Hello "World"! # 引用符が混在
path: C:\Users\name # バックスラッシュの問題
✅ 正しいエスケープ:
message: 'Hello "World"!' # シングルクォートで囲む
# または
message: "Hello \"World\"!" # エスケープ
path: "C:\\Users\\name" # バックスラッシュをエスケープ
# または
path: 'C:\Users\name' # シングルクォートで囲む
4. 構造関連のエラー
問題:重複キー
❌ 問題のある例:
config:
host: localhost
port: 3000
host: example.com # 重複キー(上書きされる)
✅ 正しい構造:
config:
primary_host: localhost
backup_host: example.com
port: 3000
YAMLの検証とツール
1. オンライン検証ツール
主要なYAML検証サイト
- YAML Lint(yamllint.com):基本的な構文チェック
- YAML Validator:詳細なエラー表示
- JSON to YAML:形式変換
2. エディタとIDE
Visual Studio Code
// settings.json での設定
{
"yaml.validate": true,
"yaml.hover": true,
"yaml.completion": true,
"yaml.schemas": {
"https://json.schemastore.org/docker-compose.json": "docker-compose*.yml",
"kubernetes": "*.k8s.yml"
}
}
推奨拡張機能:
- YAML Language Support
- Kubernetes Support
- Docker Compose Support
3. コマンドラインツール
yamllint のインストールと使用
# インストール
pip install yamllint
# 基本的な検証
yamllint myfile.yml
# 設定ファイルを使用
yamllint -c .yamllint myfile.yml
# 設定ファイル例(.yamllint)
extends: default
rules:
line-length:
max: 120
indentation:
spaces: 2
comments:
min-spaces-from-content: 1
yq(YAML processor)
# インストール
brew install yq # macOS
# または
wget https://github.com/mikefarah/yq/releases/latest/download/yq_linux_amd64
# 基本的な使用例
yq eval '.services.web.ports' docker-compose.yml
yq eval '.spec.replicas = 5' deployment.yml
yq eval 'select(.kind == "Service")' k8s-manifest.yml
実際のプロジェクトでの活用例

1. アプリケーション設定管理
# config/app.yml
app:
name: "MyApplication"
version: "2.1.0"
environment: "production"
server:
host: "0.0.0.0"
port: 8080
timeout: 30
database:
primary:
host: "${DB_HOST:-localhost}"
port: "${DB_PORT:-5432}"
database: "${DB_NAME:-myapp}"
username: "${DB_USER:-user}"
password: "${DB_PASSWORD}"
readonly:
host: "${DB_READONLY_HOST}"
port: "${DB_READONLY_PORT:-5432}"
database: "${DB_NAME:-myapp}"
username: "${DB_READONLY_USER}"
password: "${DB_READONLY_PASSWORD}"
cache:
redis:
host: "${REDIS_HOST:-localhost}"
port: "${REDIS_PORT:-6379}"
password: "${REDIS_PASSWORD}"
db: 0
logging:
level: "${LOG_LEVEL:-info}"
format: "json"
outputs:
- type: "console"
- type: "file"
path: "/var/log/app.log"
max_size: "100MB"
max_age: "7d"
features:
user_registration: true
email_verification: true
two_factor_auth: false
analytics: true
external_services:
email:
provider: "sendgrid"
api_key: "${SENDGRID_API_KEY}"
payment:
provider: "stripe"
public_key: "${STRIPE_PUBLIC_KEY}"
secret_key: "${STRIPE_SECRET_KEY}"
webhook_secret: "${STRIPE_WEBHOOK_SECRET}"
2. CI/CDパイプライン設定
# .gitlab-ci.yml
stages:
- validate
- test
- build
- deploy
variables:
DOCKER_REGISTRY: registry.gitlab.com
DOCKER_IMAGE: $DOCKER_REGISTRY/$CI_PROJECT_PATH
KUBECONFIG: /tmp/kubeconfig
# 共通設定をアンカーで定義
.docker_template: &docker_template
image: docker:20.10.16
services:
- docker:20.10.16-dind
before_script:
- echo $CI_REGISTRY_PASSWORD | docker login -u $CI_REGISTRY_USER --password-stdin $CI_REGISTRY
.kubectl_template: &kubectl_template
image: bitnami/kubectl:latest
before_script:
- echo "$KUBE_CONFIG" | base64 -d > $KUBECONFIG
# バリデーション
yaml_lint:
stage: validate
image: python:3.9-alpine
before_script:
- pip install yamllint
script:
- yamllint .
only:
- merge_requests
- main
dockerfile_lint:
stage: validate
image: hadolint/hadolint:latest-debian
script:
- hadolint Dockerfile
only:
- merge_requests
- main
# テスト
unit_test:
stage: test
image: node:16-alpine
cache:
paths:
- node_modules/
script:
- npm ci
- npm run test:unit
coverage: '/Lines\s*:\s*(\d+\.\d+)%/'
artifacts:
reports:
coverage_report:
coverage_format: cobertura
path: coverage/cobertura-coverage.xml
integration_test:
stage: test
image: node:16-alpine
services:
- postgres:13
- redis:6-alpine
variables:
DATABASE_URL: "postgresql://postgres:postgres@postgres:5432/test"
REDIS_URL: "redis://redis:6379"
script:
- npm ci
- npm run test:integration
# ビルド
build_image:
<<: *docker_template
stage: build
script:
- docker build -t $DOCKER_IMAGE:$CI_COMMIT_SHA .
- docker tag $DOCKER_IMAGE:$CI_COMMIT_SHA $DOCKER_IMAGE:latest
- docker push $DOCKER_IMAGE:$CI_COMMIT_SHA
- docker push $DOCKER_IMAGE:latest
only:
- main
# デプロイ
deploy_staging:
<<: *kubectl_template
stage: deploy
script:
- kubectl set image deployment/myapp myapp=$DOCKER_IMAGE:$CI_COMMIT_SHA -n staging
- kubectl rollout status deployment/myapp -n staging
environment:
name: staging
url: https://staging.example.com
only:
- main
deploy_production:
<<: *kubectl_template
stage: deploy
script:
- kubectl set image deployment/myapp myapp=$DOCKER_IMAGE:$CI_COMMIT_SHA -n production
- kubectl rollout status deployment/myapp -n production
environment:
name: production
url: https://example.com
when: manual
only:
- main
3. Infrastructure as Code(Ansible)
# playbook.yml
---
- name: Web Server Setup
hosts: webservers
become: true
vars:
app_name: myapp
app_user: deploy
app_port: 3000
nginx_port: 80
ssl_enabled: true
tasks:
- name: Update system packages
apt:
update_cache: true
upgrade: safe
tags: [system]
- name: Install required packages
apt:
name:
- nginx
- nodejs
- npm
- certbot
- python3-certbot-nginx
state: present
tags: [packages]
- name: Create application user
user:
name: "{{ app_user }}"
system: true
shell: /bin/bash
home: "/var/www/{{ app_name }}"
create_home: true
tags: [user]
- name: Create application directories
file:
path: "{{ item }}"
state: directory
owner: "{{ app_user }}"
group: "{{ app_user }}"
mode: '0755'
loop:
- "/var/www/{{ app_name }}"
- "/var/www/{{ app_name }}/logs"
- "/var/www/{{ app_name }}/shared"
tags: [directories]
- name: Deploy application
unarchive:
src: "{{ app_archive_url }}"
dest: "/var/www/{{ app_name }}"
remote_src: true
owner: "{{ app_user }}"
group: "{{ app_user }}"
notify: restart app
tags: [deploy]
- name: Install Node.js dependencies
npm:
path: "/var/www/{{ app_name }}"
production: true
become_user: "{{ app_user }}"
tags: [deploy]
- name: Configure systemd service
template:
src: systemd.service.j2
dest: "/etc/systemd/system/{{ app_name }}.service"
notify:
- reload systemd
- restart app
tags: [service]
- name: Configure Nginx
template:
src: nginx.conf.j2
dest: "/etc/nginx/sites-available/{{ app_name }}"
notify: restart nginx
tags: [nginx]
- name: Enable Nginx site
file:
src: "/etc/nginx/sites-available/{{ app_name }}"
dest: "/etc/nginx/sites-enabled/{{ app_name }}"
state: link
notify: restart nginx
tags: [nginx]
- name: Obtain SSL certificate
command: >
certbot --nginx
--non-interactive
--agree-tos
--email "{{ ssl_email }}"
-d "{{ domain_name }}"
when: ssl_enabled
tags: [ssl]
handlers:
- name: reload systemd
systemd:
daemon_reload: true
- name: restart app
systemd:
name: "{{ app_name }}"
state: restarted
enabled: true
- name: restart nginx
systemd:
name: nginx
state: restarted
enabled: true
ベストプラクティス
1. 読みやすさの向上
適切なコメント
# 良い例:目的と注意事項を記載
# データベース接続設定
# 注意: パスワードは環境変数から取得
database:
host: "${DB_HOST}"
port: 5432
# 本番環境では読み書き分離
read_replicas:
- "${DB_READ_REPLICA_1}"
- "${DB_READ_REPLICA_2}"
# 悪い例:自明なコメント
database:
host: localhost # ホスト名
port: 5432 # ポート番号
一貫したインデント
# 推奨:2スペースで統一
services:
web:
image: nginx
ports:
- "80:80"
app:
build: .
environment:
- NODE_ENV=production
# 避ける:インデント幅の混在
services:
web: # 4スペース
image: nginx
app: # 2スペース
build: .
2. 保守性の向上
環境変数の活用
# config.yml
app:
name: "${APP_NAME:-MyApp}"
version: "${APP_VERSION:-1.0.0}"
debug: "${DEBUG:-false}"
database:
url: "${DATABASE_URL}"
pool_size: "${DB_POOL_SIZE:-10}"
timeout: "${DB_TIMEOUT:-30}"
# デフォルト値の設定例
defaults: &defaults
timeout: 30
retry_count: 3
log_level: "info"
development:
<<: *defaults
debug: true
log_level: "debug"
production:
<<: *defaults
timeout: 60
retry_count: 5
バリデーション用スキーマ
# JSON Schema for validation
# config-schema.yml
$schema: "http://json-schema.org/draft-07/schema#"
type: object
required:
- app
- database
properties:
app:
type: object
required:
- name
- version
properties:
name:
type: string
minLength: 1
version:
type: string
pattern: "^\\d+\\.\\d+\\.\\d+$"
debug:
type: boolean
default: false
database:
type: object
required:
- url
properties:
url:
type: string
format: uri
pool_size:
type: integer
minimum: 1
maximum: 100
default: 10
3. セキュリティ考慮事項
機密情報の管理
# ❌ 悪い例:機密情報をハードコード
database:
host: "prod-db.example.com"
username: "admin"
password: "super_secret_password123" # 危険!
# ✅ 良い例:環境変数や外部シークレット管理
database:
host: "${DB_HOST}"
username: "${DB_USERNAME}"
password: "${DB_PASSWORD}"
# Kubernetes Secretsを使用
apiVersion: v1
kind: Secret
metadata:
name: db-secret
type: Opaque
data:
username: YWRtaW4= # base64エンコード
password: cGFzc3dvcmQ=
ファイル権限の設定
# 設定ファイルの適切な権限設定
chmod 600 config.yml # 所有者のみ読み書き可能
chmod 644 docker-compose.yml # 一般的な設定ファイル
chmod 400 secrets.yml # 所有者のみ読み取り可能
高度なYAMLテクニック

1. 動的設定の生成
テンプレートエンジンとの組み合わせ
# Jinja2テンプレート例
# config.yml.j2
app:
name: "{{ app_name }}"
replicas: {{ replicas | default(3) }}
{% if environment == "production" %}
resources:
limits:
cpu: "1000m"
memory: "1Gi"
requests:
cpu: "500m"
memory: "512Mi"
{% else %}
resources:
limits:
cpu: "500m"
memory: "512Mi"
requests:
cpu: "100m"
memory: "128Mi"
{% endif %}
{% for service in services %}
{{ service.name }}:
image: "{{ service.image }}"
port: {{ service.port }}
{% endfor %}
2. 条件分岐とループの実現
Helm Chart での条件分岐
# values.yml
replicaCount: 3
autoscaling:
enabled: false
minReplicas: 1
maxReplicas: 100
ingress:
enabled: true
className: "nginx"
annotations:
cert-manager.io/cluster-issuer: "letsencrypt-prod"
# deployment.yml
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ include "myapp.fullname" . }}
spec:
{{- if not .Values.autoscaling.enabled }}
replicas: {{ .Values.replicaCount }}
{{- end }}
template:
spec:
containers:
- name: {{ .Chart.Name }}
image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
{{- if .Values.ingress.enabled }}
ports:
- name: http
containerPort: 80
protocol: TCP
{{- end }}
3. 大規模プロジェクトでの分割管理
ファイル分割パターン
# docker-compose.yml (メインファイル)
version: '3.8'
include:
- compose.services.yml
- compose.networks.yml
- compose.volumes.yml
# compose.services.yml
services:
web:
extends:
file: common-services.yml
service: web-base
environment:
- NODE_ENV=production
# common-services.yml
version: '3.8'
services:
web-base:
build: .
ports:
- "3000"
volumes:
- ./logs:/app/logs
Kustomize での設定管理
# base/kustomization.yml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- deployment.yml
- service.yml
- configmap.yml
# overlays/production/kustomization.yml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
bases:
- ../../base
patchesStrategicMerge:
- deployment-patch.yml
images:
- name: myapp
newTag: v1.2.3
replicas:
- name: myapp
count: 5
トラブルシューティング
1. パフォーマンス問題
大きなYAMLファイルの最適化
# ❌ 非効率な例
users:
- name: "user1"
permissions:
- read
- write
- name: "user2"
permissions:
- read
- write
# 数千のユーザー...
# ✅ 効率的な例(アンカー使用)
permissions: &default_permissions
- read
- write
users:
- name: "user1"
permissions: *default_permissions
- name: "user2"
permissions: *default_permissions
ストリーミング処理
# Python でのストリーミング YAML パース
import yaml
def process_large_yaml(file_path):
with open(file_path, 'r') as file:
# ストリーミングで処理
for document in yaml.safe_load_all(file):
process_document(document)
def process_document(doc):
# 各ドキュメントを個別に処理
print(f"Processing: {doc.get('name', 'Unknown')}")
2. 互換性問題
YAML バージョン間の差異
# YAML 1.1 と 1.2 の違い
yes_value: yes # 1.1: true, 1.2: "yes"
no_value: no # 1.1: false, 1.2: "no"
octal_value: 0123 # 1.1: 83, 1.2: 123
# 明示的な型指定で回避
boolean_yes: !!bool "yes"
boolean_no: !!bool "no"
string_yes: !!str "yes"
integer_octal: !!int "0o123" # 8進数の正しい書き方
3. デバッグテクニック
YAML構造の可視化
# yq を使った構造確認
yq eval '.' config.yml
# 特定のパスの確認
yq eval '.services.web.environment' docker-compose.yml
# 型情報を含む出力
yq eval -j '.' config.yml | jq '.'
段階的な確認
# デバッグ用の段階的設定
debug:
level: 1 # 1=basic, 2=detailed, 3=verbose
# レベル1: 基本情報のみ
basic_config:
app_name: "myapp"
version: "1.0"
# レベル2: 詳細設定追加
detailed_config:
<<: *basic_config
database:
host: "localhost"
port: 5432
# レベル3: 全設定
verbose_config:
<<: *detailed_config
logging:
level: "debug"
output: "file"
まとめ:YAMLを効果的に活用しよう
YAMLは、適切に使用することで、設定管理やインフラ構成を大幅に改善できる強力なツールです。
重要なポイントのおさらい
YAML の特徴:
- 人間可読性:直感的で理解しやすい
- 構造化データ:複雑な設定も表現可能
- コメント対応:ドキュメント化が容易
- 環境変数対応:動的な設定管理
書き方のポイント:
- 一貫したインデント(2スペース推奨)
- 適切なコメント(目的と注意事項)
- アンカーとエイリアスで重複を削減
- 環境変数で柔軟性を確保
エラー回避のコツ:
- yamllintでの事前チェック
- エディタの支援機能を活用
- 型の明示的指定で予期しない変換を防止
- 段階的なテストで問題を早期発見
実際の業務での活用
DevOps エンジニア:
- Docker Compose、Kubernetes マニフェスト
- CI/CDパイプライン設定
- Infrastructure as Code
開発者:
- アプリケーション設定
- API仕様書(OpenAPI)
- テストデータ定義
システム管理者:
- サーバー設定管理
- 監視設定
- バックアップスクリプト設定
コメント