linuxlab.io
Учебники▾
  • Линукс и сети
    Файловая система, процессы, TCP/IP, BGP и OSPF
    →
  • Terraform и IaC
    HCL, state, plan/apply на sandbox LocalStack
    →
  • Git и GitHub
    Объектная модель, plumbing, ветвление, GitHub Actions
    →
Все учебники →
ЦеныО платформеВойтиСоздать аккаунт
/
Intro
Lessons
Footer
linuxlab-УчебникиЦеныО платформеКонфиденциальность и куки
Copyright © 2026 LinuxLab. Все права защищены.
linuxlab.io
Учебники▾
  • Линукс и сети
    Файловая система, процессы, TCP/IP, BGP и OSPF
    →
  • Terraform и IaC
    HCL, state, plan/apply на sandbox LocalStack
    →
  • Git и GitHub
    Объектная модель, plumbing, ветвление, GitHub Actions
    →
Все учебники →
ЦеныО платформеВойтиСоздать аккаунт
/
  • Введение
  • Уроки
  • How it works
  • База знаний
  • Шпаргалка
  • Capstone
  • Собеседование
home/terraform/lessons/tf-production-08-github-actions

lesson ── terraform-production ── ~18 мин ── 5 шагов

GitHub Actions, полный pipeline через act

Собираем всё в один pipeline. .github/workflows/terraform.yml с тремя jobs: lint (fmt+validate+tflint+checkov), plan (с artifact upload), apply (с download + apply). Локально гоняем через act, он эмулирует GitHub Actions без полёта на github.com. Реальный AWS не используем workflow читает env-переменные провайдера, которые указывают на LocalStack.

▶ интерактивный sandbox

Поднимется пара контейнеров: terraform 1.9 и localstack 3.8 в одной сети. В браузере откроется терминал, можно сразу terraform init. Каждый шаг проверяется автоматически. TTL 45 минут, без регистрации.

запустить sandbox →

stack ── terraform · localstack · 1 GB RAM · самоуничтожается через 45 мин простоя

Шаги

  1. 01

    Напиши .github/workflows/terraform.yml

    bash
    cd /home/student/tf-gha
    cat > main.tf <<'EOF'
    resource "aws_s3_bucket" "gha_demo" {
      bucket = "linuxlab-gha-demo"
      tags = {
        ManagedBy   = "terraform"
        Environment = "dev"
      }
    }
    EOF
    cat > .github/workflows/terraform.yml <<'EOF'
    name: Terraform CI
    on:
      push:
        branches: [main]
      pull_request:
    env:
      TF_IN_AUTOMATION: "true"
      TF_INPUT: "false"
      AWS_ACCESS_KEY_ID: test
      AWS_SECRET_ACCESS_KEY: test
      AWS_DEFAULT_REGION: us-east-1
    jobs:
      lint:
        runs-on: ubuntu-latest
        steps:
          - uses: actions/checkout@v4
          - uses: hashicorp/setup-terraform@v3
            with:
              terraform_version: 1.9.8
          - name: terraform fmt -check
            run: terraform fmt -check -recursive
          - name: terraform validate
            run: |
              terraform init -backend=false -no-color
              terraform validate -no-color
      plan:
        needs: lint
        runs-on: ubuntu-latest
        steps:
          - uses: actions/checkout@v4
          - uses: hashicorp/setup-terraform@v3
            with:
              terraform_version: 1.9.8
          - name: terraform plan
            run: |
              terraform init -no-color
              terraform plan -no-color -out=plan.tfplan
          - name: show plan
            run: terraform show -no-color plan.tfplan > plan.txt
          - uses: actions/upload-artifact@v4
            with:
              name: tf-plan
              path: |
                plan.tfplan
                plan.txt
      apply:
        needs: plan
        if: github.ref == 'refs/heads/main'
        runs-on: ubuntu-latest
        steps:
          - uses: actions/checkout@v4
          - uses: hashicorp/setup-terraform@v3
            with:
              terraform_version: 1.9.8
          - uses: actions/download-artifact@v4
            with:
              name: tf-plan
          - name: terraform apply
            run: |
              terraform init -no-color
              terraform apply -no-color plan.tfplan
    EOF

    Структура, три job'а, sequential через needs:. apply гоняется только на main (через if).

    ✓ Workflow готов. Запустим act.

  2. 02

    act -l, что увидит GitHub

    bash
    act -l -W .github/workflows/terraform.yml

    Должно показать три job'а: lint, plan, apply, с их dependencies.

    act парсит workflow, понимает needs: и conditional if:. Для нашего сэндбокса refs/heads/main подойдёт по defaultу, но проще запускать конкретный job.

    ✓ act парсит workflow корректно.

  3. 03

    Запусти lint job

    bash
    act -j lint \
      -W .github/workflows/terraform.yml \
      --container-architecture linux/amd64 \
      --bind 2>&1 | tail -20

    Что флаги:

    • -j lint, только один job.
    • --container-architecture linux/amd64, нужен на arm64-хостах.
    • --bind, монтирует текущий каталог вместо клонирования (быстрее для локальной dev-петли).

    В первом запуске act скачает Ubuntu runner-образ, может занять минуту. Дальше быстро.

    Должно показать Success - lint (или подробные шаги fmt и validate).

    ✓ Lint-job отработал в эмулированном GHA.

  4. 04

    Запусти весь pipeline

    bash
    act push \
      -W .github/workflows/terraform.yml \
      --container-architecture linux/amd64 \
      --bind 2>&1 | tail -30

    act push, событие push. По умолчанию act гоняет всё, что триггерится этим событием. Job'ы выполнятся sequentially из-за needs:.

    Артефакты act хранит в /tmp/artifact внутри runner-container'а или в .artifacts/ локально (зависит от version'и). Если pipeline успешен, все три job'а зелёные.

    ✓ Полный pipeline отработал. lint → plan → apply.

    То же самое на OpenTofu

    OpenTofu держит CLI и state совместимыми с Terraform по командам этого шага: миграция обычно проходит через mv .terraform .terraform.bak; tofu init -upgrade. Но при первом переходе сделай backup state и прогон на feature-branch - расхождения концентрируются в новых фичах (variables в backend, state-encryption, OCI registry-backed модули). См. tf-opentofu-parity для полной матрицы.

    • → OpenTofu parity
  5. 05

    Добавь policy-gate в pipeline

    Добавим Checkov-job. Положим baseline:

    bash
    cat > policies/check.sh <<'EOF'
    #!/usr/bin/env bash
    set -euo pipefail
    checkov -d . --quiet --no-guide --soft-fail-on CKV_AWS_18
    echo "Checkov gate passed."
    EOF
    chmod +x policies/check.sh
    mkdir -p policies

    Обнови workflow, добавь policy job после lint, до plan:

    bash
    python3 - <<'EOF'
    with open('.github/workflows/terraform.yml') as f:
        wf = f.read()
    injection = """
      policy:
        needs: lint
        runs-on: ubuntu-latest
        steps:
          - uses: actions/checkout@v4
          - name: checkov
            run: checkov -d . --quiet --no-guide --soft-fail-on CKV_AWS_18
    """
    wf = wf.replace("    plan:\n      needs: lint",
                    injection + "\n    plan:\n      needs: [lint, policy]")
    with open('.github/workflows/terraform.yml', 'w') as f:
        f.write(wf)
    EOF
    grep -A2 "needs:" .github/workflows/terraform.yml

    plan теперь требует и lint, и policy. Если бакет в HCL слабый, Checkov ловит, plan не стартует.

    ✓ Policy-gate в pipeline. Pipeline стал production-grade.

    act ≠ GitHub Actions 1:1

    Чего act не делает или делает по-другому:

    1. OIDC. Реальный GHA выдаёт OIDC-token через actions/configure-aws-credentials. act, нет; локально работают только access-keys или mock'и.

    2. Permissions. permissions: id-token: write в act игнорируется.

    3. Environments. GitHub UI «environment: prod» с required reviewers act'ом не моделируется. Job просто стартует.

    4. Secrets. GHA-secrets act берёт из .secrets локально или --secret-file. Защиты как в реальном GitHub, нет.

    5. Cache. actions/cache в act работает, но через локальный путь. Расхождение в content иногда видно при первом запуске.

    Когда act ценен: проверить «workflow вообще запустится». Когда не ценен: продакшен-debug security и OIDC-specifics, это надо проверять в реальном GitHub на feature-branch.

    • → Plan-as-artifact теория
    • → Линтеры в pipeline

Что ты узнал

Workflow, YAML в .github/workflows/. Jobs: lint → plan (uploads artifact) → apply (downloads artifact). act гоняет workflow локально в Docker-контейнере, использует образ Ubuntu похожий на GHA-runner.

команды

  • act --container-architecture linux/amd64 -W .github/workflows/terraform.ymlзапустить workflow.
  • act -lсписок job'ов в workflow.
  • act -j lintзапустить только один job.
  • act -ndry-run, что бы запустилось, без execution.

концепции

  • · act ≠ полноценный GHA, некоторые actions могут вести себя иначе
  • · ubuntu-latest не несёт terraform — в каждом job нужен hashicorp/setup-terraform
  • · Artifact между jobs в act хранится в /tmp/artifact
  • · needs: между jobs, sequential ordering

← предыдущий

Декларативный import: захват существующего ресурса

следующий →

lifecycle: запреты, игнор и пересоздание

Footer
linuxlab-
Copyright © 2026 LinuxLab. Все права защищены.
Учебники
Цены
О платформе
Конфиденциальность и куки