lumos_app resource, then version, review, and apply it like any other infrastructure — instead of clicking through the Lumos UI. This guide is the Terraform counterpart to Managing Integrations via API. For an example that configures AppStore requestable permissions with the same provider, see Terraform in the Developers tab.
Overview
Alumos_app resource represents a connection between Lumos and one of your apps (for example Okta or Google Workspace). With it you can declare an integration and its credentials in HCL, create it with terraform apply, read its state, rotate credentials by re-applying, import an integration that already exists, and remove it with terraform destroy. Managing integrations this way provides repeatable, reviewable, and auditable change control.
Before you start
You need:- Terraform 1.0 or later.
- The
teamlumos/lumosprovider (configured in the next section). - A Lumos API token. Create one in the Lumos UI under Settings → API Tokens. It’s shown once — copy it somewhere safe. The provider reads it from the
LUMOS_ACCESS_TOKENenvironment variable. - Permission to manage integrations. The token acts as the user who created it, so that user must be an admin with permission to connect and remove integrations. Otherwise applies fail with
HTTP 403.
apply starts the connection and you finish authorizing it in the Lumos UI. See step 6.
Concept-to-operation map
Configure the provider
Declare the provider and authenticate. The token comes from theLUMOS_ACCESS_TOKEN environment variable, so you don’t commit it to your configuration:
http_bearer argument: provider "lumos" { http_bearer = var.lumos_token }.
Core workflow
1. Discover the integration and its connection schema
Before writing the resource, find the integration’sapp_class_id and check its connection schema — the definitive list of which credential keys go in auth and which configuration keys go in settings. Both are read from the REST API with the same token the provider uses:
api_key credential in auth and the tenant domain as app_instance_identifier in settings. Other integrations use different keys — some name the tenant differently, some derive it from the credentials and need no setting at all. See the discovery section of Managing Integrations via API for how to read the schema in detail.
2. Declare an integration resource
Precondition: the provider is configured (previous section). Give the resource the app’s identifier inapp_class_id:
3. Set its fields
Put all credentials insideauth, encoded with jsonencode({...}), and non-secret configuration inside settings — shaped exactly as the connection schema from step 1 describes. Keep secrets in sensitive variables, not in the resource literally:
4. Initialize, plan, and apply
Precondition:LUMOS_ACCESS_TOKEN is exported.
apply connects the integration and Lumos starts the first sync automatically.
5. Trigger a sync
Lumos starts a sync automatically whenever anapply connects or reconnects an integration, so your first apply (step 4) already triggered one.
The provider manages connect/reconnect/disconnect — it does not manage syncs. To run a sync on demand afterwards (for example from a CI step after apply), call the REST sync endpoint directly with the resource’s id. Read the id from state with terraform state show lumos_app.okta, or expose it with an output, then POST to /v1/apps/{id}/sync:
202 Accepted confirms the sync was launched (it runs asynchronously). Only one sync runs at a time — if a sync is already in progress the call returns 409; wait for the running sync to finish, then retry. See the REST API guide for the full contract.
6. Read its state
The resource’s computed attributes are managed by Lumos — read them from state rather than setting them. The two most useful aredisconnected (whether the integration’s credentials have been removed) and instance_id (the tenant/instance Lumos resolved for the connection). Expose them with an output:
apply starts the connection but the authorization is finished in the Lumos UI — until you complete it there, the integration isn’t syncing yet. Complete the consent in the Lumos UI, and manage the resource from Terraform as usual afterwards:
7. Update an integration
Precondition: the integration already exists in state. Changeauth (for example to rotate an API key) or settings, then apply:
app_class_id replaces the integration (Terraform destroys and recreates it). If a sync is already running for the integration, the update is throttled with HTTP 429 and a Retry-After hint — wait and re-apply.
8. Import an existing integration
Precondition: declare a matchinglumos_app resource block first. You need the integration’s id (the UUID returned when you connect it via the Integrations API, or listed by GET /v1/apps?connection_source=API).
terraform plan to confirm your HCL matches the imported state, and fill in auth/settings as needed.
9. Destroy it
Removing the resource (or runningterraform destroy) disconnects the integration and removes its stored credentials. The app remains available to reconnect later.
Argument reference
These are the arguments you set when declaring an integration. Their meanings match the field reference in Managing Integrations via API; discover the exact keys each integration accepts via its connection schema (step 1).Read-only attributes
Lumos computes these; reference them but don’t set them:id— the integration’s UUID (use it withterraform importand the REST sync endpoint).instance_id— the tenant/instance Lumos resolved for the connection (either the value you configured insettingsor one derived from the credentials).disconnected—falsewhile the integration’s credentials are stored (connected);trueafter a disconnect.
Handling errors
The provider surfaces API failures as Terraform diagnostics duringplan or apply, formatted HTTP <code>: <detail>. Common ones:
Next steps
- Expose
disconnected(and other attributes) as outputs to monitor your integrations. - Rotate credentials on a schedule by updating
authand re-applying — ideally from CI. - For the underlying field semantics and the discovery endpoints, see Managing Integrations via API and the full reference at API reference.