Skip to main content

VCS Integration

Connect HCP Terraform กับ Git provider — auto plan ตอน PR, auto apply ตอน merge

Supported VCS

  • GitHub (cloud + enterprise)
  • GitLab (cloud + self-managed)
  • Bitbucket (cloud + server)
  • Azure DevOps (services + server)

Setup VCS Connection

GitHub

HCP → Organization Settings → VCS Providers → GitHub
└── Token: github_pat_xxx (from GitHub OAuth or Personal Access Token)
Connect

หรือใช้ GitHub App (recommended):

Add VCS Provider → GitHub.com (OAuth or App)
└── Install GitHub App on org/repo

GitHub App เด่นกว่า:

  • Fine-grained permissions
  • Per-repo access
  • ไม่ต้องผูกกับ user account

GitLab

GitLab → User Settings → Applications → Add new application
└── Name: HCP Terraform
Redirect URI: https://app.terraform.io/auth/<provider-id>/callback
Scopes: api

Copy Application ID + Secret → HCP

Bitbucket Cloud

Bitbucket → Settings → OAuth consumers → Add consumer
└── Permissions: Repositories (read/admin), Webhooks (read/write)

Connect Workspace to VCS

Workspace → Settings → Version Control
└── VCS Provider: GitHub
Repository: myorg/infra
Branch: main
Working directory: ./prod/network
Trigger patterns: prod/network/**
Apply method: Auto / Manual

Triggers

Trigger on Push to Branch

ทุกครั้งที่ push ไป main (ที่มี file ใน working directory)

Trigger Patterns

trigger_patterns:
- prod/network/**
- shared/iam/**
- "!**.md" # exclude markdown

→ Push ที่แก้แค่ *.md → ไม่ trigger

Trigger on Pull Request

Workspace → Settings → Version Control
└── ☑ Automatic speculative plans

→ PR เปิด → speculative plan run → comment ใน PR

Speculative Plan

= "what if" plan โดยไม่ apply

PR opened → HCP runs `terraform plan` → comment:
"Plan: 3 to add, 0 to change, 0 to destroy"
"View run: https://app.terraform.io/..."

→ Reviewer เห็น diff ก่อน approve

Auto Apply Setup

Workspace → Settings → General
└── Apply method:
- Manual apply (default) ← prod
- Auto apply ← dev
Auto apply trigger:
- On successful plan
- On VCS push to main

Manual Apply Workflow

1. PR opened → speculative plan
2. Review plan in PR
3. Merge PR → main
4. HCP queues run with full plan
5. Reviewer clicks "Confirm & Apply"
6. Apply runs

Webhook Setup (Auto)

HCP จะ create webhook ใน VCS อัตโนมัติเมื่อ connect workspace

URL pattern:

https://app.terraform.io/webhooks/vcs/<workspace-id>

VCS push event → HCP receives webhook → triggers run

Multi-Workspace per Repo

infra/                                       # 1 repo
├── prod/
│ ├── network/ # workspace: prod-network
│ │ └── trigger_patterns: ["prod/network/**"]
│ ├── data/ # workspace: prod-data
│ │ └── trigger_patterns: ["prod/data/**"]
│ └── compute/ # workspace: prod-compute
│ └── trigger_patterns: ["prod/compute/**"]
└── staging/
└── ... (same)

→ แก้ prod/network/main.tf → trigger เฉพาะ prod-network workspace

Branch Strategy

Main-Only

Workspace 1: branch=main

→ Only main triggers

Feature Branch (Speculative)

Workspace 1: branch=main
└── Auto plan on PR (speculative)

→ PR creates speculative plan, merge triggers real run

Per-Branch Workspace

Workspace 1: branch=main → prod
Workspace 2: branch=develop → staging
Workspace 3: branch=feature/* → dev

→ Each branch deploys to different env

VCS-Driven Workflow

Working with Modules

Public Modules

ปกติใน workspace สามารถใช้ได้:

module "vpc" {
source = "terraform-aws-modules/vpc/aws"
version = "5.13.0"
}

Private Modules (HCP Registry)

module "vpc" {
source = "app.terraform.io/my-org/vpc/aws"
version = "1.0.0"
}

→ Module repo ก็ต้อง connect VCS เพื่อ publish

Publish Module

Module Registry → Publish → Connect VCS
└── Repository: myorg/terraform-aws-vpc
Tags become versions: v1.0.0 → 1.0.0

→ Push tag v1.1.0 → auto publish module version 1.1.0

Status Checks

GitHub PR shows:

✓ Terraform Cloud / prod-network — Plan finished
✗ Terraform Cloud / prod-data — Plan errored

→ Block merge if plan fails (require status checks ใน branch protection)

Branch Protection (GitHub)

Repo → Settings → Branches → Add Rule
└── Branch pattern: main
Require status checks to pass:
- Terraform Cloud / prod-network
- Terraform Cloud / prod-data
Require approvals: 1
Restrict who can push: platform-team

→ ป้องกัน merge ที่ plan fail

Conditional Run on Files Changed

Workspace → Settings → Version Control → Trigger Patterns:
- "prod/network/**"
- "modules/network/**" ← include shared module
- "!docs/**" ← exclude docs

→ Only run when relevant files change

VCS-Driven vs CLI-Driven

AspectVCS-DrivenCLI-Driven
TriggerGit pushterraform apply
Best forProductionDev / debugging
Audit trailGit history + HCP logsHCP logs only
Code reviewBuilt-in (PR)Manual
SpeedSlower (queue)Faster (immediate)

→ Production ใช้ VCS-driven, dev ใช้ CLI-driven

ตัวอย่าง: Setup with TFE Provider

provider "tfe" {
organization = "my-org"
}

data "tfe_oauth_client" "github" {
service_provider = "github"
}

resource "tfe_workspace" "prod_network" {
name = "prod-network"
organization = "my-org"
working_directory = "prod/network"
auto_apply = false # require manual approve

vcs_repo {
identifier = "myorg/infra"
branch = "main"
oauth_token_id = data.tfe_oauth_client.github.oauth_token_id
ingress_submodules = false
}

trigger_patterns = [
"prod/network/**",
"modules/network/**"
]

tag_names = ["prod", "network"]
}

Disconnect VCS

Workspace → Settings → Version Control → Disconnect

→ Workspace ใน CLI-driven mode

Best Practices

✅ DO:
- ใช้ VCS-driven สำหรับ production
- Use GitHub App แทน OAuth user (per-repo permissions)
- Branch protection + required status checks
- Trigger patterns specific (`prod/network/**`)
- Speculative plans on PR
- Manual approve for prod

❌ DON'T:
- ห้าม auto-apply ใน prod
- ห้าม connect VCS โดยใช้ user OAuth ของ admin
- ห้ามให้ workspace trigger ทุก path (run จะเยอะมาก)
- ห้าม skip status checks

ทางเลือก: GitOps Tools

ถ้าไม่ใช้ HCP:

  • Atlantis — open-source, VCS-driven
  • GitHub Actions — DIY
  • GitLab CI — DIY
  • Argo CD (สำหรับ K8s manifests)

สรุป

  • VCS Integration = Git provider connect to HCP
  • Triggers: push to branch, PR (speculative)
  • Trigger patterns ระบุ files ที่จะ trigger
  • Status checks + branch protection ใน VCS
  • GitHub App > OAuth user (recommended)
  • Production: VCS-driven + manual apply

ต่อไป → Run Tasks