Your first run
This walks through the API flow on a Firstlume you have already installed: a folder, inherited variables, a stack, and an apply that you review and approve. Everything here is also available in the UI.
What you need
A Git repository with a folder that holds a .firstlume/config.yaml. Firstlume runs your code from that folder:
examples/hello/
├── .firstlume/config.yaml
└── main.tf
# .firstlume/config.yaml
version: 1
engine: terraform
engine_version: 1.15.6
# main.tf
terraform {
backend "http" {}
}
variable "greeting" {
type = string
default = "hello"
}
resource "terraform_data" "hello" {
input = var.greeting
}
The empty backend "http" block is required: it keeps the state in Firstlume. See State backend.
Set up your shell
Get the admin token from the release's Secret. The default organization is created when the server starts, and the agent the chart installed belongs to it.
export FIRSTLUME_ADMIN_TOKEN=$(kubectl -n firstlume get secret firstlume-control-plane \
-o jsonpath='{.data.admin-token}' | base64 -d)
H="Authorization: Bearer $FIRSTLUME_ADMIN_TOKEN"
O=https://firstlume.example.com/api/v1/orgs/default
1. Create a folder
Folders are optional: stacks can also sit at the top of the organization.
F=$(curl -s -H "$H" $O/folders -d '{"name": "infra"}' | jq -r .id)
2. Set variables and secrets
The stacks below this folder inherit them.
curl -s -X PUT -H "$H" $O/folders/$F/settings -d '{
"require_approval": true,
"variables": [
{"key": "greeting", "category": "terraform", "value": "hello"},
{"key": "AWS_SECRET_ACCESS_KEY", "category": "env", "sensitive": true, "value": "..."}
]
}'
terraform variables become TF_VAR_greeting. env variables become environment variables. Sensitive values are encrypted, masked in logs and never returned by the API.
3. Create the stack
path is the folder in the repository that contains .firstlume/config.yaml.
ST=$(curl -s -H "$H" $O/stacks -d "{
\"folder_id\": \"$F\", \"name\": \"hello\",
\"repository\": \"https://github.com/your-org/infra.git\", \"path\": \"examples/hello\"
}" | jq -r .id)
For a private repository, also send a git_token. With a Git connection, you can pick repositories from the account instead of typing URLs.
4. Start an apply and follow the logs
The logs arrive live, over server-sent events. The stream ends when the run stops for approval.
RUN=$(curl -s -H "$H" $O/stacks/$ST/runs -d '{"type": "apply"}' | jq -r .id)
curl -N -H "$H" "$O/runs/$RUN/logs?follow=true"
5. Review and approve
See what changes, resource by resource, then approve:
curl -s -H "$H" $O/runs/$RUN/changes | jq .
curl -s -X POST -H "$H" $O/runs/$RUN/approve -d '{"acknowledged": []}'
acknowledged lists the addresses you confirm when the stack requires confirming each deletion or replacement. Here it is empty.
The apply then runs in a new Job and writes the state's first version. Run the same plan again and it shows no changes.
In the UI
Open https://firstlume.example.com and choose "Use admin token". The folder and the stack are in the tree, and the run page shows the steps, the changes and the logs.
Next steps
- Set a drift check on the folder
- Declare files and variables in the repository
- Import the state you already have