Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

import: fall-back to namespace from provider #375

Closed

Conversation

Chive
Copy link

@Chive Chive commented Aug 18, 2023

Summary

Resolves an issue with importing resources from non-default namespaces. It was impossible to import resources from namespaces other than default, because opts.Namespace would always be "", discarding any environment variable set for NOMAD_NAMESPACE.

Reproducing the issue

Prerequisites

  • Running Nomad agent
  • Created Nomad namespace (i.e. foo)

Files

Expand

main.tf

terraform {
  required_providers {
    nomad = {
      source = "hashicorp/nomad"
      version = "2.0.0-rc.2"
    }
  }
}

resource "nomad_job" "redis" {
  jobspec               = file("redis.nomad")
  detach                = false
  deregister_on_destroy = false
}

redis.nomad

job "redis" {
  type  = "service"
  namespace = "foo"
  region = "region"

  group "redis" {
    count = 1
    
    task "redis" {
      driver = "docker"

      config {
        image = "redis"
      }
    }
  }
}

Environment

Expand

Env Vars

$ env | grep NOMAD_
NOMAD_TOKEN=token
NOMAD_ADDR=http://nomad:4646
NOMAD_REGION=region
NOMAD_NAMESPACE=foo

Nomad job status

$ nomad job status -short redis
ID            = redis
Name          = redis
Type          = service
Namespace     = foo
Status        = running
[...]

Running terraform import on version 2.0.0-rc.2

Expand
$ terraform import nomad_job.redis redis
2023-08-18T11:15:19.937+0200 [INFO]  Terraform version: 1.5.5
2023-08-18T11:15:19.937+0200 [DEBUG] using github.com/hashicorp/go-tfe v1.26.0
2023-08-18T11:15:19.937+0200 [DEBUG] using github.com/hashicorp/hcl/v2 v2.16.2
2023-08-18T11:15:19.937+0200 [DEBUG] using github.com/hashicorp/terraform-svchost v0.1.0
2023-08-18T11:15:19.937+0200 [DEBUG] using github.com/zclconf/go-cty v1.12.2
2023-08-18T11:15:19.937+0200 [INFO]  Go runtime version: go1.20.7
2023-08-18T11:15:19.937+0200 [INFO]  CLI args: []string{"terraform", "import", "nomad_job.redis", "redis"}
2023-08-18T11:15:19.937+0200 [DEBUG] Attempting to open CLI config file: /Users/me/.terraformrc
2023-08-18T11:15:19.938+0200 [INFO]  Loading CLI configuration from /Users/me/.terraformrc
2023-08-18T11:15:19.938+0200 [DEBUG] checking for credentials in "/Users/me/.terraform.d/plugins"
2023-08-18T11:15:19.938+0200 [DEBUG] ignoring non-existing provider search directory terraform.d/plugins
2023-08-18T11:15:19.938+0200 [DEBUG] will search for provider plugins in /Users/me/.terraform.d/plugins
2023-08-18T11:15:19.938+0200 [DEBUG] ignoring non-existing provider search directory /Users/me/Library/Application Support/io.terraform/plugins
2023-08-18T11:15:19.938+0200 [DEBUG] ignoring non-existing provider search directory /Library/Application Support/io.terraform/plugins
2023-08-18T11:15:19.939+0200 [INFO]  CLI command args: []string{"import", "nomad_job.redis", "redis"}
2023-08-18T11:15:19.940+0200 [DEBUG] New state was assigned lineage "5bccfdab-95eb-cac4-f899-3733f3daa0d1"
2023-08-18T11:15:19.993+0200 [DEBUG] checking for provisioner in "."
2023-08-18T11:15:20.000+0200 [DEBUG] checking for provisioner in "/usr/local/bin"
2023-08-18T11:15:20.000+0200 [DEBUG] checking for provisioner in "/Users/me/.terraform.d/plugins"
2023-08-18T11:15:20.001+0200 [DEBUG] Building and walking import graph
2023-08-18T11:15:20.001+0200 [DEBUG] Not attaching any node states: overall state is nil
2023-08-18T11:15:20.001+0200 [DEBUG] No state, no orphan outputs
2023-08-18T11:15:20.002+0200 [DEBUG] ProviderTransformer: "nomad_job.redis (expand)" (*terraform.nodeExpandPlannableResource) needs provider["registry.terraform.io/hashicorp/nomad"]
2023-08-18T11:15:20.002+0200 [DEBUG] created provider logger: level=debug
2023-08-18T11:15:20.019+0200 [DEBUG] provider: starting plugin: path=.terraform/providers/registry.terraform.io/hashicorp/nomad/2.0.0-rc.2/darwin_amd64/terraform-provider-nomad_v2.0.0-rc.2_x5 args=[.terraform/providers/registry.terraform.io/hashicorp/nomad/2.0.0-rc.2/darwin_amd64/terraform-provider-nomad_v2.0.0-rc.2_x5]
2023-08-18T11:15:20.023+0200 [DEBUG] provider: plugin started: path=.terraform/providers/registry.terraform.io/hashicorp/nomad/2.0.0-rc.2/darwin_amd64/terraform-provider-nomad_v2.0.0-rc.2_x5 pid=11667
2023-08-18T11:15:20.023+0200 [DEBUG] provider: waiting for RPC address: path=.terraform/providers/registry.terraform.io/hashicorp/nomad/2.0.0-rc.2/darwin_amd64/terraform-provider-nomad_v2.0.0-rc.2_x5
2023-08-18T11:15:20.048+0200 [DEBUG] provider: using plugin: version=5
2023-08-18T11:15:20.048+0200 [DEBUG] provider.terraform-provider-nomad_v2.0.0-rc.2_x5: plugin address: network=unix address=/var/folders/q4/j8wp984517ng76_sswqfjhhh0000gn/T/plugin1846681391 timestamp=2023-08-18T11:15:20.048+0200
2023-08-18T11:15:20.069+0200 [DEBUG] provider.stdio: received EOF, stopping recv loop: err="rpc error: code = Unavailable desc = error reading from server: EOF"
2023-08-18T11:15:20.070+0200 [DEBUG] provider: plugin process exited: path=.terraform/providers/registry.terraform.io/hashicorp/nomad/2.0.0-rc.2/darwin_amd64/terraform-provider-nomad_v2.0.0-rc.2_x5 pid=11667
2023-08-18T11:15:20.070+0200 [DEBUG] provider: plugin exited
2023-08-18T11:15:20.071+0200 [DEBUG] ReferenceTransformer: "nomad_job.redis (expand)" references: []
2023-08-18T11:15:20.071+0200 [DEBUG] ReferenceTransformer: "provider[\"registry.terraform.io/hashicorp/nomad\"]" references: []
2023-08-18T11:15:20.071+0200 [DEBUG] Starting graph walk: walkImport
2023-08-18T11:15:20.071+0200 [DEBUG] created provider logger: level=debug
2023-08-18T11:15:20.078+0200 [DEBUG] provider: starting plugin: path=.terraform/providers/registry.terraform.io/hashicorp/nomad/2.0.0-rc.2/darwin_amd64/terraform-provider-nomad_v2.0.0-rc.2_x5 args=[.terraform/providers/registry.terraform.io/hashicorp/nomad/2.0.0-rc.2/darwin_amd64/terraform-provider-nomad_v2.0.0-rc.2_x5]
2023-08-18T11:15:20.082+0200 [DEBUG] provider: plugin started: path=.terraform/providers/registry.terraform.io/hashicorp/nomad/2.0.0-rc.2/darwin_amd64/terraform-provider-nomad_v2.0.0-rc.2_x5 pid=11668
2023-08-18T11:15:20.082+0200 [DEBUG] provider: waiting for RPC address: path=.terraform/providers/registry.terraform.io/hashicorp/nomad/2.0.0-rc.2/darwin_amd64/terraform-provider-nomad_v2.0.0-rc.2_x5
2023-08-18T11:15:20.106+0200 [DEBUG] provider: using plugin: version=5
2023-08-18T11:15:20.106+0200 [DEBUG] provider.terraform-provider-nomad_v2.0.0-rc.2_x5: plugin address: address=/var/folders/q4/j8wp984517ng76_sswqfjhhh0000gn/T/plugin1172689847 network=unix timestamp=2023-08-18T11:15:20.105+0200
2023-08-18T11:15:20.121+0200 [WARN]  ValidateProviderConfig from "provider[\"registry.terraform.io/hashicorp/nomad\"]" changed the config value, but that value is unused
2023-08-18T11:15:20.123+0200 [DEBUG] ReferenceTransformer: "nomad_job.redis (import id \"redis\")" references: []
nomad_job.redis: Importing from ID "redis"...
nomad_job.redis: Import prepared!
  Prepared nomad_job for import
nomad_job.redis: Refreshing state... [id=redis]
2023-08-18T11:15:20.125+0200 [INFO]  provider.terraform-provider-nomad_v2.0.0-rc.2_x5: 2023/08/18 11:15:20 [DEBUG] reading information for job "redis" in namespace "default": timestamp=2023-08-18T11:15:20.125+0200
2023-08-18T11:15:20.906+0200 [INFO]  provider.terraform-provider-nomad_v2.0.0-rc.2_x5: 2023/08/18 11:15:20 [DEBUG] job "redis" does not exist, so removing: timestamp=2023-08-18T11:15:20.906+0200
2023-08-18T11:15:20.906+0200 [WARN]  Provider "registry.terraform.io/hashicorp/nomad" produced an unexpected new value for nomad_job.redis during refresh.
      - Root resource was present, but now absent
2023-08-18T11:15:20.906+0200 [ERROR] vertex "import nomad_job.redis result" error: Cannot import non-existent remote object
2023-08-18T11:15:20.906+0200 [ERROR] vertex "nomad_job.redis (import id \"redis\")" error: Cannot import non-existent remote object
2023-08-18T11:15:20.906+0200 [ERROR] vertex "nomad_job.redis (expand)" error: Cannot import non-existent remote object
╷
│ Error: Cannot import non-existent remote object
│
│ While attempting to import an existing object to "nomad_job.redis", the provider detected that no object exists with the given id. Only pre-existing objects can be imported; check that the id is correct and that it is associated with the
│ provider's configured region or endpoint, or use "terraform apply" to create a new remote object for this resource.


2023-08-18T11:15:20.908+0200 [DEBUG] provider.stdio: received EOF, stopping recv loop: err="rpc error: code = Unavailable desc = error reading from server: EOF"
2023-08-18T11:15:20.909+0200 [DEBUG] provider: plugin process exited: path=.terraform/providers/registry.terraform.io/hashicorp/nomad/2.0.0-rc.2/darwin_amd64/terraform-provider-nomad_v2.0.0-rc.2_x5 pid=11668
2023-08-18T11:15:20.909+0200 [DEBUG] provider: plugin exited

The fix

Running terraform import on this branch

Expand
❯ terraform import nomad_job.redis redis
2023-08-18T11:15:40.918+0200 [INFO]  Terraform version: 1.5.5
2023-08-18T11:15:40.918+0200 [DEBUG] using github.com/hashicorp/go-tfe v1.26.0
2023-08-18T11:15:40.918+0200 [DEBUG] using github.com/hashicorp/hcl/v2 v2.16.2
2023-08-18T11:15:40.918+0200 [DEBUG] using github.com/hashicorp/terraform-svchost v0.1.0
2023-08-18T11:15:40.919+0200 [DEBUG] using github.com/zclconf/go-cty v1.12.2
2023-08-18T11:15:40.919+0200 [INFO]  Go runtime version: go1.20.7
2023-08-18T11:15:40.919+0200 [INFO]  CLI args: []string{"terraform", "import", "nomad_job.redis", "redis"}
2023-08-18T11:15:40.919+0200 [DEBUG] Attempting to open CLI config file: /Users/me/.terraformrc
2023-08-18T11:15:40.919+0200 [INFO]  Loading CLI configuration from /Users/me/.terraformrc
2023-08-18T11:15:40.919+0200 [DEBUG] checking for credentials in "/Users/me/.terraform.d/plugins"
2023-08-18T11:15:40.919+0200 [DEBUG] Explicit provider installation configuration is set
2023-08-18T11:15:40.920+0200 [INFO]  CLI command args: []string{"import", "nomad_job.redis", "redis"}
2023-08-18T11:15:40.922+0200 [DEBUG] New state was assigned lineage "df54c4ba-c2de-82af-5dd6-a83ef6b60628"
2023-08-18T11:15:40.922+0200 [DEBUG] Provider registry.terraform.io/hashicorp/nomad is overridden by dev_overrides
2023-08-18T11:15:40.922+0200 [DEBUG] Provider registry.terraform.io/hashicorp/nomad is overridden to load from /Users/me/go/bin
2023-08-18T11:15:40.922+0200 [DEBUG] checking for provisioner in "."
2023-08-18T11:15:40.931+0200 [DEBUG] checking for provisioner in "/usr/local/bin"
2023-08-18T11:15:40.931+0200 [DEBUG] checking for provisioner in "/Users/me/.terraform.d/plugins"
2023-08-18T11:15:40.932+0200 [DEBUG] Provider registry.terraform.io/hashicorp/nomad is overridden by dev_overrides
2023-08-18T11:15:40.933+0200 [DEBUG] Config.VerifyDependencySelections: skipping registry.terraform.io/hashicorp/nomad because it's overridden by a special configuration setting
2023-08-18T11:15:40.933+0200 [DEBUG] Building and walking import graph
2023-08-18T11:15:40.933+0200 [DEBUG] Not attaching any node states: overall state is nil
2023-08-18T11:15:40.933+0200 [DEBUG] No state, no orphan outputs
2023-08-18T11:15:40.933+0200 [DEBUG] ProviderTransformer: "nomad_job.redis (expand)" (*terraform.nodeExpandPlannableResource) needs provider["registry.terraform.io/hashicorp/nomad"]
2023-08-18T11:15:40.933+0200 [DEBUG] created provider logger: level=debug
2023-08-18T11:15:40.952+0200 [DEBUG] provider: starting plugin: path=/Users/me/go/bin/terraform-provider-nomad args=[/Users/me/go/bin/terraform-provider-nomad]
2023-08-18T11:15:40.955+0200 [DEBUG] provider: plugin started: path=/Users/me/go/bin/terraform-provider-nomad pid=11683
2023-08-18T11:15:40.955+0200 [DEBUG] provider: waiting for RPC address: path=/Users/me/go/bin/terraform-provider-nomad
2023-08-18T11:15:40.977+0200 [DEBUG] provider.terraform-provider-nomad: plugin address: address=/var/folders/q4/j8wp984517ng76_sswqfjhhh0000gn/T/plugin620373180 network=unix timestamp=2023-08-18T11:15:40.977+0200
2023-08-18T11:15:40.977+0200 [DEBUG] provider: using plugin: version=5
2023-08-18T11:15:40.995+0200 [DEBUG] provider.stdio: received EOF, stopping recv loop: err="rpc error: code = Unavailable desc = error reading from server: EOF"
2023-08-18T11:15:40.995+0200 [DEBUG] provider: plugin process exited: path=/Users/me/go/bin/terraform-provider-nomad pid=11683
2023-08-18T11:15:40.995+0200 [DEBUG] provider: plugin exited
2023-08-18T11:15:40.996+0200 [DEBUG] ReferenceTransformer: "nomad_job.redis (expand)" references: []
2023-08-18T11:15:40.996+0200 [DEBUG] ReferenceTransformer: "provider[\"registry.terraform.io/hashicorp/nomad\"]" references: []
2023-08-18T11:15:40.996+0200 [DEBUG] Starting graph walk: walkImport
2023-08-18T11:15:40.996+0200 [DEBUG] created provider logger: level=debug
2023-08-18T11:15:41.003+0200 [DEBUG] provider: starting plugin: path=/Users/me/go/bin/terraform-provider-nomad args=[/Users/me/go/bin/terraform-provider-nomad]
2023-08-18T11:15:41.007+0200 [DEBUG] provider: plugin started: path=/Users/me/go/bin/terraform-provider-nomad pid=11684
2023-08-18T11:15:41.007+0200 [DEBUG] provider: waiting for RPC address: path=/Users/me/go/bin/terraform-provider-nomad
2023-08-18T11:15:41.028+0200 [DEBUG] provider: using plugin: version=5
2023-08-18T11:15:41.028+0200 [DEBUG] provider.terraform-provider-nomad: plugin address: address=/var/folders/q4/j8wp984517ng76_sswqfjhhh0000gn/T/plugin1593627099 network=unix timestamp=2023-08-18T11:15:41.028+0200
2023-08-18T11:15:41.045+0200 [WARN]  ValidateProviderConfig from "provider[\"registry.terraform.io/hashicorp/nomad\"]" changed the config value, but that value is unused
2023-08-18T11:15:41.046+0200 [DEBUG] ReferenceTransformer: "nomad_job.redis (import id \"redis\")" references: []
nomad_job.redis: Importing from ID "redis"...
nomad_job.redis: Import prepared!
  Prepared nomad_job for import
nomad_job.redis: Refreshing state... [id=redis]
2023-08-18T11:15:41.048+0200 [INFO]  provider.terraform-provider-nomad: 2023/08/18 11:15:41 [DEBUG] reading information for job "redis" in namespace "foo": timestamp=2023-08-18T11:15:41.048+0200
2023-08-18T11:15:41.853+0200 [INFO]  provider.terraform-provider-nomad: 2023/08/18 11:15:41 [DEBUG] found job "redis" in namespace "foo": timestamp=2023-08-18T11:15:41.853+0200
2023-08-18T11:15:41.855+0200 [WARN]  Provider "registry.terraform.io/hashicorp/nomad" produced an unexpected new value for nomad_job.redis during refresh.
      - .modify_index: was null, but now cty.StringVal("916149557")
      - .namespace: was null, but now cty.StringVal("foo")
      - .allocation_ids: was null, but now cty.ListValEmpty(cty.String)
      - .name: was null, but now cty.StringVal("redis")
      - .task_groups: was null, but now cty.ListVal([]cty.Value{cty.ObjectVal(map[string]cty.Value{[..]}))
      - .region: was null, but now cty.StringVal("region")
      - .type: was null, but now cty.StringVal("service")
2023-08-18T11:15:41.856+0200 [DEBUG] provider.stdio: received EOF, stopping recv loop: err="rpc error: code = Unavailable desc = error reading from server: EOF"
2023-08-18T11:15:41.857+0200 [DEBUG] provider: plugin process exited: path=/Users/me/go/bin/terraform-provider-nomad pid=11684
2023-08-18T11:15:41.857+0200 [DEBUG] provider: plugin exited
2023-08-18T11:15:41.857+0200 [INFO]  Writing state output to:

Import successful!

The resources that were imported are shown above. These resources are now in
your Terraform state and will henceforth be managed by Terraform.

Resolves an issue with importing resources from non-default namespaces.

It was impossible to import resources from namespaces other than default, because opts.Namespace would always be "".
@hashicorp-cla
Copy link

hashicorp-cla commented Aug 18, 2023

CLA assistant check
All committers have signed the CLA.

@lgfa29
Copy link
Contributor

lgfa29 commented Aug 21, 2023

Thanks for the PR @Chive, that's a great catch!

The problem is that we have avoided using the provider config for namespace information, as it allows you to manage resource across namespaces.

Reading the NOMAD_NAMESPACE env var can also cause unexpected problems, such as when running terraform inside a job allocation (as is the case for TFC) because the allocation will automatically have this env var set to its namespace.

Maybe a better option would be have the namespace in the import ID, and then extract that information on import. Unfortunately Nomad is pretty liberal in terms of which characters are allowed in the job ID so we need to be careful to pick a separator that can't clash with a valid job ID.

Looking at the validation rules for job ID and namespaces the only human-friendly option seems to be a space.

So if we do something like this 6d5a960 we would be write imports like so:

import {
  to = nomad_job.example
  id = "dev test"
}

resource "nomad_job" "example" {
  jobspec = file("${path.module}/test_dev.nomad")
}

import {
  to = nomad_job.example_default
  id = "test"
}

resource "nomad_job" "example_default" {
  jobspec = file("${path.module}/test.nomad")
}

How do you feel about this approach?

@lgfa29 lgfa29 self-requested a review August 21, 2023 20:13
@Chive
Copy link
Author

Chive commented Aug 28, 2023

Hey @lgfa29, thanks for the fast reply. Your proposed solution would work for us as well. Should I update this PR to reflect your suggested method?

@lgfa29
Copy link
Contributor

lgfa29 commented Sep 1, 2023

Hey @lgfa29, thanks for the fast reply. Your proposed solution would work for us as well. Should I update this PR to reflect your suggested method?

Nice! Yeah, feel free to update this PR with the new approach. Thanks!

@lgfa29
Copy link
Contributor

lgfa29 commented Dec 16, 2023

Hi @Chive 👋

I implemented the approach I suggested in #408. I skipped nomad_volume and nomad_external_volume since they're deprecated resources.

I will close this one in favour of #408 but thank you so much for the contribution!

@lgfa29 lgfa29 closed this Dec 16, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants