09 · Schematics (Terraform-based IaC)¶
Every resource in Modules 3-8 was created with one-off CLI commands. Schematics is IBM Cloud's managed Terraform service: you describe infrastructure declaratively, and Schematics plans and applies it for you (no local Terraform install or state file management required, though you can also run the same templates with your own Terraform CLI). This module introduces the workflow that Level 2 builds on heavily.
Why declarative IaC over CLI one-liners¶
CLI commands like the ones in earlier modules are easy to run once, but have no memory of what you already created — re-running them either fails (name already exists) or duplicates resources, and there's no single file describing "this is what our infrastructure should look like." A Terraform configuration fixes that: it's a versionable description of desired state, and Terraform (via Schematics or locally) computes and applies the diff.
A minimal configuration¶
# main.tf
terraform {
required_providers {
ibm = {
source = "IBM-Cloud/ibm"
version = "~> 1.60"
}
}
}
variable "ibmcloud_api_key" {
type = string
sensitive = true
}
provider "ibm" {
ibmcloud_api_key = var.ibmcloud_api_key
region = "us-south"
}
data "ibm_resource_group" "group" {
name = "mastery-path"
}
resource "ibm_is_vpc" "vpc" {
name = "schematics-vpc"
resource_group = data.ibm_resource_group.group.id
}
resource "ibm_is_subnet" "subnet" {
name = "schematics-subnet"
vpc = ibm_is_vpc.vpc.id
zone = "us-south-1"
total_ipv4_address_count = 256
resource_group = data.ibm_resource_group.group.id
}
output "vpc_id" {
value = ibm_is_vpc.vpc.id
}
Push this to a Git repo (Schematics pulls templates from a repo URL, not local files) — a public repo is fine for this exercise since it contains no secrets (the API key comes in as a variable, never hardcoded).
Create a Schematics workspace¶
ibmcloud schematics workspace new \
--name mastery-schematics \
--template-repo https://github.com/<you>/mastery-schematics-demo \
--template-type terraform_v1.5 \
--resource-group mastery-path
Set the sensitive ibmcloud_api_key variable through the workspace, not
in the repo:
ibmcloud schematics workspace update --id <workspace-id> \
--var "ibmcloud_api_key=$(cat ~/.ibmcloud/apikey.json | jq -r .apikey)" \
--var-type sensitive
Plan and apply¶
# Generates an execution plan without changing anything
ibmcloud schematics plan --id <workspace-id>
ibmcloud schematics apply --id <workspace-id>
# Watch it run
ibmcloud schematics logs --id <workspace-id> --latest
Inspecting and destroying¶
# See what Terraform believes exists right now
ibmcloud schematics state pull --id <workspace-id>
ibmcloud schematics output --id <workspace-id>
# Tear everything the workspace created back down
ibmcloud schematics destroy --id <workspace-id>
How It Actually Works¶
- Schematics is a managed Terraform runner, not a separate IaC
engine — a workspace packages your
.tffiles plus a chosen Terraform version, and every plan/apply runs an actualterraform plan/applyinside an IBM-managed container, against a state file IBM stores and locks on your behalf. That's the real reason you never seeterraform.tfstatesitting in your repo when using Schematics: it lives server-side, and the workspace ID is effectively a pointer to that remote state plus its execution history. terraform plan's diff isn't guesswork — it refreshes the state file by querying the real IBM Cloud API for each resource's current attributes, then does a structural diff against your.tfconfiguration to compute exactly which resources would be created, changed in place, or destroyed-and-recreated; a "recreate" appears specifically when you change an attribute that provider knows can't be updated on the live resource (e.g. a VSI's zone), forcing delete-then-create instead of an in-place PATCH.- State locking prevents two concurrent applies from corrupting each
other by having the first apply take an exclusive lock on the state
file before it starts — a second
applytargeting the same workspace blocks (or errors) until the first releases it, which is the actual mechanism that keeps Schematics safe for team or CI use against a shared workspace, not a UI-level "someone's editing this" warning. destroywalks the state file's dependency graph in reverse topological order — the same graph Terraform built to know that a VPC must exist before a subnet, so it necessarily deletes the subnet before the VPC — which is why destroy failures usually mean a resource outside Terraform's knowledge (a manually created dependency) is blocking deletion of something the graph expected to be free.
Cheat sheet¶
| Command | Purpose |
|---|---|
ibmcloud schematics workspace new --name <n> --template-repo <url> --template-type <t> |
Create a workspace from a Git-hosted Terraform template |
ibmcloud schematics workspace update --id <id> --var "<k>=<v>" --var-type sensitive |
Set a sensitive input variable |
ibmcloud schematics plan --id <id> |
Preview changes |
ibmcloud schematics apply --id <id> |
Apply changes |
ibmcloud schematics logs --id <id> --latest |
Stream the latest job's logs |
ibmcloud schematics output --id <id> |
Show Terraform outputs |
ibmcloud schematics destroy --id <id> |
Tear down everything the workspace manages |
Exercise¶
Push the main.tf above to a Git repo of your own, create a Schematics
workspace pointing at it, set ibmcloud_api_key as a sensitive variable,
and run plan then apply. Confirm the VPC and subnet appear via
ibmcloud is vpc-list, then run ibmcloud schematics destroy and confirm
they're gone — the same plan/apply/destroy loop you'll use for every
project in Level 2 and beyond.