JonasProgrammer / docker-machine-driver-hetzner

Docker machine driver for the new hetzner cloud API
https://jonasprogrammer.github.io/docker-machine-driver-hetzner/
MIT License
431 stars 53 forks source link

How to inject hcloud_ssh_keys via Terraform in hetzner_config definitions? ? #85

Closed KittlitzMichael closed 2 years ago

KittlitzMichael commented 2 years ago

Error: Unsupported argument │ │ on 07-init-rancher-with-hetzner-node.tf line 35, in resource "rancher2_node_template" "hetzner_create_template": │ 35: additionalkeys = data.hcloud_ssh_keys.ssh_keys_master.ssh_keys.*.name │ │ An argument named "additionalkeys" is not expected here.

Different approach, inspired by https://github.com/rancher/terraform-provider-rancher2/issues/936

│ │ An argument named "additional_keys" is not expected here.

So I've tried several different approaches as I did not find any working example or documentation so far:

`resource "rancher2_node_template" "hetzner_create_template" { provider = rancher2.admin name = "hetzner-node-default-template" description = "Default template to acquire Hetzner Cloud Nodes" driver_id = rancher2_node_driver.hetzner_node_driver.id hetzner_config { api_token = var.hcloud_api_token image = var.base_image server_type = var.worker_type server_location = var.location networks = hcloud_network.kubenet.ip_range

None of the Approaches works:

#cachedadditionalkeys = data.hcloud_ssh_keys.ssh_keys_master.ssh_keys.*.name
#additionalkeyids         = data.hcloud_ssh_keys.ssh_keys_master.ssh_keys.*.name
additionalkeys         = data.hcloud_ssh_keys.ssh_keys_master.ssh_keys.*.name
additional_keys         = data.hcloud_ssh_keys.ssh_keys_master.ssh_keys.*.name
#cachedKey                = data.hcloud_ssh_keys.ssh_keys_master.ssh_keys.*.name
#keylabels       = "terraform=rancher"

`

Reading the source-code https://github.com/JonasProgrammer/docker-machine-driver-hetzner/blob/master/driver.go shows in line 203 the usage. In Line 263 they are added. In the function makeCreateServerOptions() on Line 481 it's added at the end (532) too. In Line 608 the for-loop should upload them.

I don't see though where the arguments for terraform are defined yet.

By the way: Reloading the Template via Rancher UI does not show the marked SSH-Keys either. So as a User I don't know which SSH-Keys where set up before hand and I'm not sure, wheather this informaiton is acutally stored.

JonasProgrammer commented 2 years ago

Hi,

sorry this is causing you inconvenience. Unfortunately I'm not familiar with what Terraform does when calling into a docker-machine driver binary -- when used with docker-machine, the program does not even parse real command line arguments, but rather gets has them passed down via RPC from the docker-machine command. All I can say is that, when called from the command line, the option does indeed work (or at least did so at the time of implementation).

One thing you could give a shot though: Have you tried spelling variants of additional_key (i.e. singular). While the flag constant, environment variable and variable references use plural spelling, the option is actually --hetzner-additional-key -- which may or may not be what Terraform uses internally to derive option names.

IIRC the original intention was to have the option say 'please add key x and then please add key y' when called like --hetzner-additional-key path/to/x --hetzner-additional-key path/to/y, but nowadays I see that I should have just sticked with a consistent naming, especially since networks and volumes use plural naming. This inconsistency is there for most 'newer' features, this one just takes the crown as the flag variable name is also misleading. But again: I'm not even sure this is the actual cause of your problem.

KittlitzMichael commented 2 years ago

Thank you for your fast Answer Jonas.

In the meantime I've checked this sources: https://github.com/rancher/terraform-provider-rancher2/blob/master/rancher2/data_source_rancher2_node_driver.go and https://github.com/rancher/terraform-provider-rancher2/blob/master/rancher2/data_source_rancher2_node_template.go

on the the Template - Source-File in Lines 97-99 it seems to iterate through the interface:

filters := map[string]interface{}{ "name": name, }

so I would expect, that your exported variables should be accessible. I still don't know why it's not working yet though.

JonasProgrammer commented 2 years ago

The 'argument' part is what's throwing me off. I would not expect such an error message, if it were about accessing fields via reflection or something like that.

The code fragment you found merely sets up some filter options (as a map of string to interface, i.e. an arbitrary type -- this is what you would to build dynamic JSON-esque objects) to be passed to the driver when listing machines, so I think that is unrelated to the current problems.

Could you maybe try the singular naming approach? I'm still unsure, but at least it is a straw to grab.

KittlitzMichael commented 2 years ago

// Sorry for the edit, I missed the 'quote reply button'

Hi Jonas,

another though, I've read on line 330 ff your code:

func (d *Driver) PreCreateCheck() error {

within this function you don't check all the other attributes. Maybe the behaviour of terraform has changed, so that the PreCreateCheck needs to make sure, that everything is correctly set?

As requested I've tried the following:

PS C:\Daten\GIT\axc\iac> terraform plan ╷ │ Error: Unsupported argument │ │ on 07-init-rancher-with-hetzner-node.tf line 30, in resource "rancher2_node_template" "hetzner_create_template": │ 30: image_id = data.hcloud_image.image_1.id │ │ An argument named "image_id" is not expected here. ╵ PS C:\Daten\GIT\axc\iac> terraform plan ╷ │ Error: Unsupported argument │ │ on 07-init-rancher-with-hetzner-node.tf line 30, in resource "rancher2_node_template" "hetzner_create_template": │ 30: image_id = data.hcloud_image.image_1.id │ │ An argument named "image_id" is not expected here. ╵ ╷ │ Error: Unsupported argument │ │ on 07-init-rancher-with-hetzner-node.tf line 56, in resource "rancher2_node_template" "hetzner_create_template": │ 56: additional_keys = data.hcloud_ssh_keys.ssh_keys_master.ssh_keys..name │ │ An argument named "additional_keys" is not expected here. ╵ ╷ │ Error: Unsupported argument │ │ on 07-init-rancher-with-hetzner-node.tf line 57, in resource "rancher2_node_template" "hetzner_create_template": │ 57: additional_key = data.hcloud_ssh_keys.ssh_keys_master.ssh_keys..name │ │ An argument named "additional_key" is not expected here. ╵ ╷ │ Error: Unsupported argument │ │ on 07-init-rancher-with-hetzner-node.tf line 58, in resource "rancher2_node_template" "hetzner_create_template": │ 58: additionalkeys = data.hcloud_ssh_keys.ssh_keys_master.ssh_keys..name │ │ An argument named "additionalkeys" is not expected here. ╵ ╷ │ Error: Unsupported argument │ │ on 07-init-rancher-with-hetzner-node.tf line 59, in resource "rancher2_node_template" "hetzner_create_template": │ 59: additionalkey = data.hcloud_ssh_keys.ssh_keys_master.ssh_keys..name │ │ An argument named "additionalkey" is not expected here. ╵ ╷ │ Error: Unsupported argument │ │ on 07-init-rancher-with-hetzner-node.tf line 60, in resource "rancher2_node_template" "hetzner_create_template": │ 60: additionalkeyids = data.hcloud_ssh_keys.ssh_keys_master.ssh_keys..name │ │ An argument named "additionalkeyids" is not expected here. ╵ ╷ │ Error: Unsupported argument │ │ on 07-init-rancher-with-hetzner-node.tf line 61, in resource "rancher2_node_template" "hetzner_create_template": │ 61: additionalkeyid = data.hcloud_ssh_keys.ssh_keys_master.ssh_keys..name │ │ An argument named "additionalkeyid" is not expected here. ╵ ╷ │ Error: Unsupported argument │ │ on 07-init-rancher-with-hetzner-node.tf line 62, in resource "rancher2_node_template" "hetzner_create_template": │ 62: cachedadditionalkeys = data.hcloud_ssh_keys.ssh_keys_master.ssh_keys..name │ │ An argument named "cachedadditionalkeys" is not expected here. ╵ ╷ │ Error: Unsupported argument │ │ on 07-init-rancher-with-hetzner-node.tf line 63, in resource "rancher2_node_template" "hetzner_create_template": │ 63: cachedadditionalkey = data.hcloud_ssh_keys.ssh_keys_master.ssh_keys..name │ │ An argument named "cachedadditionalkey" is not expected here.

KittlitzMichael commented 2 years ago

I'm still analysing this.

I turned on TRACE on Terraform-logging:

2022-08-08T13:00:42.684+0200 [TRACE] BuiltinEvalContext: Initialized "provider[\"registry.terraform.io/rancher/rancher2\"].admin" provider for provider["registry.terraform.io/rancher/rancher2"].admin 2022-08-08T13:00:42.684+0200 [TRACE] NodeApplyableProvider: validating configuration for provider["registry.terraform.io/rancher/rancher2"].admin 2022-08-08T13:00:42.684+0200 [TRACE] GRPCProvider: Close 2022-08-08T13:00:42.695+0200 [TRACE] vertex "provider[\"registry.terraform.io/rancher/rancher2\"] (close)": visit complete 2022-08-08T13:00:42.695+0200 [TRACE] GRPCProvider: Close 2022-08-08T13:00:42.710+0200 [TRACE] vertex "provider[\"registry.terraform.io/hetznercloud/hcloud\"] (close)": visit complete 2022-08-08T13:00:42.710+0200 [TRACE] buildProviderConfig for provider["registry.terraform.io/rancher/rancher2"].admin: using explicit config only 2022-08-08T13:00:42.710+0200 [TRACE] GRPCProvider: GetProviderSchema 2022-08-08T13:00:42.727+0200 [DEBUG] No provider meta schema returned 2022-08-08T13:00:42.736+0200 [TRACE] GRPCProvider: ValidateProviderConfig 2022-08-08T13:00:42.750+0200 [TRACE] vertex "provider[\"registry.terraform.io/rancher/rancher2\"].admin": visit complete 2022-08-08T13:00:42.750+0200 [TRACE] vertex "rancher2_node_driver.hetzner_node_driver": starting visit (*terraform.NodeValidatableResource) 2022-08-08T13:00:42.751+0200 [TRACE] GRPCProvider: ValidateResourceConfig 2022-08-08T13:00:42.751+0200 [TRACE] vertex "rancher2_node_driver.hetzner_node_driver": visit complete 2022-08-08T13:00:42.751+0200 [TRACE] vertex "output.hetzner_driver_id": starting visit (*terraform.NodeApplyableOutput) 2022-08-08T13:00:42.751+0200 [TRACE] vertex "rancher2_node_template.hetzner_create_template": starting visit (*terraform.NodeValidatableResource) 2022-08-08T13:00:42.751+0200 [TRACE] setValue: Saving Create change for output.hetzner_driver_id in changeset 2022-08-08T13:00:42.751+0200 [TRACE] setValue: Removing output.hetzner_driver_id from state (it is now null) 2022-08-08T13:00:42.751+0200 [TRACE] vertex "output.hetzner_driver_id": visit complete 2022-08-08T13:00:42.751+0200 [ERROR] vertex "rancher2_node_template.hetzner_create_template" error: Unsupported argument 2022-08-08T13:00:42.751+0200 [TRACE] vertex "rancher2_node_template.hetzner_create_template": visit complete, with errors

Searching for "rancher2_node_template unsupported argument" leads via this https://www.reddit.com/r/Terraform/comments/sr0d06/terraform_unsupported_arguments/ to https://www.reddit.com/r/Terraform/comments/wf6sdg/i_wrote_an_article_on_terraform_validations/ to https://betterprogramming.pub/design-by-contracts-in-terraform-63467a749c1a

Maybe this readings are helpfull?

KittlitzMichael commented 2 years ago

By the way: I've tried the latest three different versions of Terraform, just to make sure beforehand. v1.2.6 v1.1.9 v.1.0.11 -> same result

JonasProgrammer commented 2 years ago

Hi Michael,

within this function you don't check all the other attributes. Maybe the behaviour of terraform has changed, so that the PreCreateCheck needs to make sure, that everything is correctly set?

Well, I originally modeled the driver after an existing one in Cloud beta times (IIRC it was the existing Digital Ocean driver, but don't quote me on that) -- so while I never read the official docker-machine driver interface specification, I think the gist of what the driver does is correct. SetConfigurationFromFlags is the actual place where any driver configuration should be retrieved. It can return an error, so contradictory options can be reported immediately. PreCreateCheck is just for verifying the state of the configured driver and its environment is ready to go -- i.e. for checks that require interaction with things other than the driver state itself.

If this were the reason, then Terraform would be the culprit violating the protocol that docker-machine would follow. But from the strange nature of the error message, I still think this is something else.

JonasProgrammer commented 2 years ago

As for the trace, I'll have a look into this tomorrow

JonasProgrammer commented 2 years ago

Hi Michael,

today I have had some more spare time on my hands. First of all, thank you so much for going into depth with all of this -- when I replied yesterday I had looked at the issue comments here, but had not followed any of the links or references.

I have skimmed over their repo and indeed, this seems to be the place where options are being restricted: https://github.com/rancher/terraform-provider-rancher2/blob/b5b1f4c1a94fa05742bcc034e191c4ea39b13dcd/rancher2/schema_node_template_hetzner.go

While this approach is somewhat cumbersome (the docker-machine driver protocol retrieves flags on-the fly rather than relying on declarations for the very reason of more easily supporting new features), I do get the intention behind a more conservative configuration support approach in a tool like terraform. I will see if I do something there to at least cover your use cases.

JonasProgrammer commented 2 years ago

@KittlitzMichael Quick update: I just now wanted to start working on the config over at terraform-provider-rancher2. While I understood the basic structure of the node_template*.go and structure_node*.go files, I could not really figure out what naming convetion/argument mapping they use (and, to be frank, I still don't get it as of now, as it neither seems wholly consistent with the public config fields from the driver nor its arguments), so I did some more poking around the repo.

Long story short, I found this: https://github.com/rancher/terraform-provider-rancher2/pull/894

It may actually cover the majority of use cases, perhaps including #86. Unfortunately, the PR looks stale so far.

JonasProgrammer commented 2 years ago

@KittlitzMichael Given that this is an upstream problem and we were able to work around the problems in today's session, would you be ok with closing this as out-of-scope?

KittlitzMichael commented 2 years ago

Dear Jonas,

thank you for your time and support! And of course, after figuring out the different layers and the depencies, please close the ticket!

Best regards

Michael

Please excuse my brevity and typos due to iPhone. Ich bitte darum die kurze Antwort und evtl. Tippfehler aufgrund der Nutzung eines iPhones zu verzeihen.

Am 16.08.2022 um 22:07 schrieb Jonas Stoehr @.***>:

 @KittlitzMichael Given that this is an upstream problem and we were able to work around the problems in today's session, would you be ok with closing this as out-of-scope?

— Reply to this email directly, view it on GitHub, or unsubscribe. You are receiving this because you were mentioned.