Модуль 03 — Программирование для DevOps

DevOps без скриптинга — это «клик-инженер». Senior DevOps пишет кода больше, чем некоторые разработчики. Эта дисциплина — инвестиция, которая окупается каждый день.

Стек для DevOps

ЯзыкУровеньПрименение
BashСвободноСкрипты автоматизации, CI/CD jobs, healthcheck'и
PythonУверенноСложная автоматизация, AWS Lambda, REST API скрипты, тесты
GoЧтениеK8s операторы, контрибуции в Terraform/etcd, CLI-утилиты
YAMLСвободноK8s, Ansible, GitHub Actions, Docker Compose
HCLСвободноTerraform, Vault, Consul
JSONСвободноAPI, IAM-политики, CloudFormation
Jinja2УверенноAnsible templates, Helm-аналоги
SQLБазовоЗапросы, EXPLAIN, бекапы

Bash — must-have ⭐

Скелет «защищённого» скрипта

#!/usr/bin/env bash
set -euo pipefail            # строгий режим: stop on error, undefined var, pipe fail
IFS=$'\n\t'                  # безопасный разделитель

readonly SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
readonly LOG_FILE="/tmp/$(basename "$0").log"

trap 'echo "Error on line $LINENO" >&2' ERR
trap 'rm -f "$tmpfile"' EXIT  # cleanup при выходе

usage() {
  cat <<EOF
Usage: $0 [-h] -e ENV -r REGION
  -e  environment (dev|staging|prod)
  -r  AWS region
EOF
  exit 1
}

main() {
  local env="${1:?Usage: $0 ENV}"
  local region="${2:-eu-west-1}"

  if [[ ! "$env" =~ ^(dev|staging|prod)$ ]]; then
    echo "Invalid env: $env" >&2
    return 1
  fi

  echo "Deploying to $env in $region..."
}

main "$@"

Bash idioms

# Параметр expansion
${var:-default}    # default если пусто
${var:?error}      # exit с ошибкой если пусто
${var/find/replace}# замена
${#var}            # длина
${var^^}           # UPPERCASE

# Условия
[[ -f file ]]      # файл существует
[[ -d dir ]]       # директория
[[ -z "$var" ]]    # пустое
[[ "$a" == "$b" ]] # равенство
[[ "$str" =~ ^prod ]]  # regex
(( x > 5 ))        # арифметика

# Циклы
for f in *.log; do echo "$f"; done
while IFS= read -r line; do
  echo "$line"
done < file.txt

# Process substitution
diff <(cmd1) <(cmd2)

# Heredoc
cat <<EOF > config.yaml
key: $value
EOF

Линтер обязателен: shellcheck script.sh. Проверь свой скрипт перед коммитом.

Bash или Python?

Bash: до 50 строк, простая последовательность shell-команд, glue-код в CI.
Python: парсинг сложного, REST API, JSON/YAML, что-то с тестами, что-то на 100+ строк.

Python — обязательно

Что освоить

Типичный DevOps-скрипт

#!/usr/bin/env python3
"""Деплой Lambda через AWS API."""
from __future__ import annotations

import argparse
import logging
import sys
from pathlib import Path

import boto3
from botocore.exceptions import ClientError

logging.basicConfig(level=logging.INFO, format="%(asctime)s %(levelname)s %(message)s")
log = logging.getLogger(__name__)

def deploy(name: str, zip_path: Path, role_arn: str) -> None:
    client = boto3.client("lambda")
    log.info("Deploying %s from %s", name, zip_path)
    try:
        client.update_function_code(FunctionName=name, ZipFile=zip_path.read_bytes())
    except ClientError as e:
        log.error("AWS error: %s", e)
        sys.exit(1)

def main() -> None:
    p = argparse.ArgumentParser()
    p.add_argument("--name", required=True)
    p.add_argument("--zip", type=Path, required=True)
    p.add_argument("--role", required=True)
    args = p.parse_args()
    deploy(args.name, args.zip, args.role)

if __name__ == "__main__":
    main()

DevOps-библиотеки Python

Go — для роста к Senior

Go — язык DevOps-инструментов: Docker, Kubernetes, Terraform, Prometheus, etcd, Consul, Vault — всё на Go. Знание Go = можешь читать сорцы и контрибьютить.

Учить когда: после уверенного Python и Bash, ближе к Senior уровню.

Минимум: уметь читать чужой Go-код. Понимать goroutines, channels, structs, interfaces. Уметь собрать проект через go build.

// Минимальный пример
package main

import (
    "fmt"
    "os"
)

func main() {
    if len(os.Args) < 2 {
        fmt.Fprintln(os.Stderr, "usage: app NAME")
        os.Exit(1)
    }
    fmt.Printf("Hello, %s!\n", os.Args[1])
}

Регулярные выражения

Без regex ты не парсер логов. Используй regex101.com для отладки — это must.

ПаттернЗначение
.любой символ (кроме \n)
\d \w \sцифра / слово / whitespace
+ * ?1+, 0+, 0 или 1
{n,m}от n до m повторений
^ $начало / конец строки
(...)группа
(?:...)не-захватывающая группа
(?=...)positive lookahead
.*?ленивый (не жадный) квантификатор ⭐

Чек-лист

Лучшие источники

Программирование освоено. Теперь — Git и GitHub.

Модуль 04 → Git