gravitational/teleport-plugins

Terraform "Error reading App"

michaelkoetter opened this issue · 2 comments

I tried the "teleport_app" example (app.tf.example) and get the following error:

Terraform will perform the following actions:

  # teleport_app.example will be created
  + resource "teleport_app" "example" {
      + id       = (known after apply)
      + kind     = (known after apply)
      + metadata = {
          + description = "Test app"
          + labels      = {
              + "teleport.dev/origin" = "dynamic"
            }
          + name        = "example"
          + namespace   = (known after apply)
        }
      + spec     = {
          + uri = "localhost:3000"
        }
      + version  = (known after apply)
    }

Plan: 1 to add, 0 to change, 0 to destroy.


Do you want to perform these actions in workspace "terraform-fsn1"?
  Terraform will perform the actions described above.
  Only 'yes' will be accepted to approve.

  Enter a value: yes

teleport_app.example: Creating...
╷
│ Error: Error reading App
│
│   with teleport_app.example,
│   on teleport.tf line 1, in resource "teleport_app" "example":
│    1: resource "teleport_app" "example" {
│
│ Terraform user has no rights to perform this action. Check that Terraform
│ user role has ['list','create','read','update','delete'] verbs for 'app'
│ resource.
│ 	application "example" doesn't exist
╵

The terraform role certainly has the correct verbs (also took that straight from the example):

kind: role
metadata:
  id: 1650840248224075652
  name: terraform
spec:
  allow:
    app_labels:
      '*': '*'
    db_labels:
      '*': '*'
    db_names:
    - '*'
    db_users:
    - '*'
    rules:
    - resources:
      - user
      - role
      - token
      - trusted_cluster
      - github
      - oidc
      - saml
      - cluster_auth_preference
      - cluster_networking_config
      - session_recording_config
      - app
      - db
      verbs:
      - list
      - create
      - read
      - update
      - delete
  deny: {}
  options:
    cert_format: standard
    desktop_clipboard: true
    enhanced_recording:
    - command
    - network
    forward_agent: false
    max_session_ttl: 30h0m0s
    port_forwarding: true
    record_session:
      desktop: true
version: v5

Also, the app seems to be created nonetheless. But it isn't "visible" to the terraform provider on subsequent runs (it always wants to re-create the app, but fails because it exists)

$ tctl get app
kind: app
metadata:
  description: Test app
  id: 1650841107014304941
  labels:
    teleport.dev/origin: dynamic
  name: example
spec:
  insecure_skip_verify: false
  uri: localhost:3000
version: v3

Terraform Version: 1.1.9 (Terraform Cloud / linux_amd64)
Provider Version: 9.1.0

gz#5009

Hey @michaelkoetter 👋
Thank you for opening this issue and for the detailed debugging

I was able to reproduce using the Teleport API client:

  • create an app
  • immediately request that same app <- this returns app not found

Also, the app seems to be created nonetheless. But it isn't "visible" to the terraform provider on subsequent runs (it always wants to re-create the app, but fails because it exists)

As a workaround, you can follow the suggestion from that error message:

App exists in Teleport. Either remove it (tctl rm app/example) or import it to the existing state (terraform import teleport_app.example example)

terraform import teleport_app.<app_name> <app_name>

I'll try to understand what's going on and get back to you when we fix this

We ended up finding the root cause: cache on the teleport server
You can disable cache while we work on a proper fix
To do so, add the following to your teleport.yaml configuration:

teleport:
  cache:
    enabled: false

Please bear in mind that disabling cache will have performance impact

It happens here:

err = r.p.Client.CreateApp(ctx, app)
if err != nil {
resp.Diagnostics.Append(diagFromWrappedErr("Error creating App", trace.Wrap(err), "app"))
return
}
id := app.Metadata.Name
appI, err := r.p.Client.GetApp(ctx, id)

When we try to get the app info, the app is yet to be populated in the cache, so the system returns not found