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

Defining provider in module with its parameters as variables does not work #19532

Closed
walterdolce opened this issue Dec 2, 2018 · 5 comments
Labels

Comments

@walterdolce
Copy link
Contributor

@walterdolce walterdolce commented Dec 2, 2018

When a Terraform provider has one of its parameters marked as required, it seems that even if the said parameter is injected via modules this doesn't seem to work.

For example, with a module "implementing" the Cloudflare provider and exposing the ability to create DNS records, like so:

# module/cloudflare-dns-record/main.tf
variable "cloudflare_account_email" {
  type = "string"
  description = "The Cloudflare account email"
}

variable "cloudflare_account_token" {
  type = "string"
  description = "The Cloudflare account token"
}

variable "cloudflare_record_domain" {
  type = "string"
  description = "The Cloudflare record domain name"
}

variable "cloudflare_record_name" {
  type = "string"
  description = "The Cloudflare record name"
}

variable "cloudflare_record_value" {
  type = "string"
  description = "The Cloudflare record value"
}

variable "cloudflare_record_type" {
  type = "string"
  description = "The Cloudflare record type"
}

variable "cloudflare_record_ttl" {
  type = "string"
  description = "The Cloudflare record TTL (defaults to 300)."
  default = "300"
}



provider "cloudflare" {
  email = "${var.cloudflare_account_email}"
  token = "${var.cloudflare_account_token}"
  version = "1.2.0"  # Note this is not parameterised on purpose as there is no ability to do so at the moment...
}

resource "cloudflare_record" "record" {
  domain = "${var.cloudflare_record_domain}"
  name = "${var.cloudflare_record_name}"
  value = "${var.cloudflare_record_value}"
  type = "${var.cloudflare_record_type}"
  ttl = "${var.cloudflare_record_ttl}"
}

And then a module which implements that:

# dns-records.tf
variable "cloudflare_account_email" {
  type = "string"
  description = "The Cloudflare account email"
}

variable "cloudflare_account_token" {
  type = "string"
  description = "The Cloudflare account token"
}

module "dns_record_application_entrypoint" {
  source = "./modules/cloudflare-dns-record"

  cloudflare_account_email = "${var.cloudflare_account_email}"
  cloudflare_account_token = "${var.cloudflare_account_token}"

  cloudflare_record_domain = "example.com"
  cloudflare_record_name = "subdomain"
  cloudflare_record_type = "A"
  cloudflare_record_value = "some_ip_address"
}

And a tfvars which define the vars' value:

# vars.tfvars
cloudflare_account_email = "some_email_address"
cloudflare_account_token = "a_token"

When running terraform plan -var-file=vars.tfvars, Terraform/the provider prompts for the email address, but this has been specified in vars.tfvars 🤔

terraform plan -var-file=vars.tfvars

provider.cloudflare.email
  A registered Cloudflare email address.

  Enter a value: ^C

Why is that?

I noticed that with other Terraform providers whose parameters are optional (such as i.e. the Google or K8s providers) this doesn't happen.

Is it a case that this is not working at all and the fact that the other providers have the parameters optional is masking this making me believe this is working when in reality it's not?

Thank you.

Terraform Version

0.11.1

@mildwonkey

This comment has been minimized.

Copy link
Member

@mildwonkey mildwonkey commented Dec 3, 2018

Hi @walterdolce !

I'm sorry you are experiencing an issue here. I copied the files you provided and was not able to reproduce your issue. Do my environment and directory structure match yours?

$ terraform version
Terraform v0.11.1
+ provider.cloudflare v1.2.0

$ tree
.
├── dns-records.tf
├── modules
│   └── cloudflare-dns-record
│       └── main.tf
└── vars.tfvars

At the moment there are two things I can think of that might cause an issue like what you're seeing:

  • Invalid syntax somewhere in your vars.tfvars file, which tends to get swallowed instead of reported as an error.
  • A terraform overrides file that's clobbering what you have set in vars.tfvars

Is there anything else in the directory that contains your dns-records.tf and vars.tfvars? If so, it might be worthwhile for you to test out only the configuration you've shared here in case there's something else.

If none of this applies, perhaps you could run TF_LOG=TRACE terraform plan -var-file=vars.tfvars and share the output (as a gist, with any sensitive information removed) here?

@apparentlymart

This comment has been minimized.

Copy link
Member

@apparentlymart apparentlymart commented Dec 3, 2018

Since the input prompt is talking about provider.cloudflare.email rather than module.dns_record_application_entrypoint.provider.cloudflare.email this suggests that there's a Cloudfront resource in the root module and so the provider needs to be configured there instead of in the child module.

Our general recommendation for most cases is for only root modules to contain provider blocks and for child modules to be passed them either implicitly (by making no declarations at all and letting the default configurations inherit automatically) or explicitly (using the providers meta-argument in the module block). This keeps all of the provider declarations together at the root and thus ensures that all modules can get the providers they need without needing to create a separate provider instance for each module.

@walterdolce

This comment has been minimized.

Copy link
Contributor Author

@walterdolce walterdolce commented Dec 4, 2018

Hi guys @apparentlymart @mildwonkey, thank you for coming back to me on this.

Do my environment and directory structure match yours?

Yep. That matches it. The only difference is I have a few more modules and tf files at the root level (please see below for what these are for).

Is there anything else in the directory that contains your dns-records.tf and vars.tfvars?

Nope. That's it. Those are the only Cloudflare records. Everything else is about GCP and K8s stuff.

Invalid syntax somewhere in your vars.tfvars file, which tends to get swallowed instead of reported as an error.

Hmm I checked and double checked. No invalid syntax anywhere and no overrides (which I wasn't even aware of them until now!!).

this suggests that there's a Cloudfront resource in the root module and so the provider needs to be configured there instead of in the child module.

Nope. There isn't. And to make it work, I have to declare the provider block at the root level, actually. Which brings me to...

Our general recommendation for most cases is for only root modules to contain provider blocks and for child modules to be passed them either implicitly (by making no declarations at all and letting the default configurations inherit automatically) or explicitly (using the providers meta-argument in the module block). This keeps all of the provider declarations together at the root and thus ensures that all modules can get the providers they need without needing to create a separate provider instance for each module.

And this makes perfect sense to me. And it also relieves me from the "burden" of having to expose the provider-specific variables via variables within the modules. This was also something I wasn't aware of and I'll definitely start advocating for/using. I'll give this a go ASAP and let you know.

As far as I'm concerned, this is no longer an issue for me but I'll leave it to you to decide whether this is still worth investigating and so keep this open or close it.

Thank you both!

@hashibot hashibot bot removed the waiting-response label Dec 4, 2018
ameyp pushed a commit to ameyp/terraform-aws-cloudflare-static that referenced this issue May 20, 2019
Apparently the general terraform recommendation is for only root modules to contain provider blocks. hashicorp/terraform#19532
ameyp pushed a commit to ameyp/terraform-aws-cloudflare-static that referenced this issue May 20, 2019
Apparently the general terraform recommendation is for only root modules to contain provider blocks. hashicorp/terraform#19532
@apparentlymart

This comment has been minimized.

Copy link
Member

@apparentlymart apparentlymart commented Jun 6, 2019

Thanks for following up @walterdolce, and sorry we didn't respond here sooner.

From re-reading the discussion here, I think Terraform was working as expected but wasn't explaining itself well. The relevant messaging has changed somewhat in Terraform 0.12, so hopefully things are slightly better now. If not, we'll wait to see feedback about the new 0.12-style messages and work from there, and so I'm going to close this one out now. Thanks again!

@hashibot

This comment has been minimized.

Copy link

@hashibot hashibot bot commented Jul 25, 2019

I'm going to lock this issue because it has been closed for 30 days . This helps our maintainers find and focus on the active issues.

If you have found a problem that seems similar to this, please open a new issue and complete the issue template so we can capture all the details necessary to investigate further.

@hashibot hashibot bot locked and limited conversation to collaborators Jul 25, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
3 participants
You can’t perform that action at this time.