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

cloudflare_tunnel requires secret (unnecessarily for remotely-managed tunnels) #3355

Closed
3 tasks done
alecglassford opened this issue Jun 11, 2024 · 3 comments
Closed
3 tasks done
Labels
kind/bug Categorizes issue or PR as related to a bug. service/tunnel Categorizes issue or PR as related to the Tunnel service. triage/accepted Indicates an issue or PR is ready to be actively worked on. triage/debug-log-attached Indicates an issue or PR has a complete Terraform debug log. workflow/synced

Comments

@alecglassford
Copy link

alecglassford commented Jun 11, 2024

Confirmation

  • This is a bug with an existing resource and is not a feature request or enhancement. Feature requests should be submitted with Cloudflare Support or your account team.
  • I have searched the issue tracker and my issue isn't already found.
  • I have replicated my issue using the latest version of the provider and it is still present.

Terraform and Cloudflare provider version

OpenTofu v1.7.2
registry.opentofu.org/cloudflare/cloudflare v4.34.0

Affected resource(s)

  • cloudflare_tunnel

Terraform configuration files

terraform {
  required_providers {
    cloudflare = {
      source  = "cloudflare/cloudflare"
      version = "~> 4.0"
    }
  }
}

provider "cloudflare" {
  api_token="<API_TOKEN>"
}

resource "cloudflare_tunnel" "my_tunnel" {
  account_id = "<ACCOUNT_ID>"
  name       = "my_tunnel_name"
  config_src = "cloudflare"
}

Link to debug output

https://gist.github.com/alecglassford/b53de65c9b5f84fd6fce3ab87f4d6325

Panic output

No response

Expected output

Receive a plan to create a remotely-managed Cloudflare Tunnel

Actual output

│ Error: Missing required argument
│ 
│   on main.tf line 15, in resource "cloudflare_tunnel" "my_tunnel":
│   15: resource "cloudflare_tunnel" "my_tunnel" {
│ 
│ The argument "secret" is required, but no definition was found.

Steps to reproduce

  1. Create a directory that contains only main.tf with the configuration from a preceding section (⬆️), substituting an appropriate API token and account ID.
  2. Run tofu init (or terraform init).
  3. Run tofu plan (or terraform plan).

Additional factoids

cloudflare_tunnel treats the secret attribute as required, even when config_src is cloudflare:

However, when config_srcis cloudflare, the resource is a remotely-managed tunnel, and secret serves no purpose1 (Please correct me if I'm wrong!)

Indeed, the Cloudflare API does not treat the equivalent tunnel_secret field as required when you create a remotely-managed tunnel using the API: https://developers.cloudflare.com/api/operations/cloudflare-tunnel-create-a-cloudflare-tunnel
This API documentation explicitly notes that the secret is only used for a "locally-managed tunnel," and it is possible to successfully use this API endpoint with config_src set to cloudflare and no tunnel_secret2

Therefore secret should not be required on the cloudflare_tunnel Terraform resource, to be consistent with the Cloudflare API.

References

No response

Footnotes

  1. "A remotely-managed tunnel only requires the tunnel token to run. Anyone with access to the token will be able to run the tunnel. " — https://developers.cloudflare.com/cloudflare-one/connections/connect-networks/configure-tunnels/remote-management/#tunnel-permissions (the tunnel secret is not used in any later context, only the tunnel token)

  2. When you do this, the API result seems to contain an a tunnel secret generated by Cloudflare, but—as mentioned in the preceding footnote—there does not seem to be a reason to ever use this value again for a remotely-managed tunnel.

@alecglassford alecglassford added kind/bug Categorizes issue or PR as related to a bug. needs-triage Indicates an issue or PR lacks a `triage/foo` label and requires one. labels Jun 11, 2024
@jacobbednarz jacobbednarz added triage/accepted Indicates an issue or PR is ready to be actively worked on. service/tunnel Categorizes issue or PR as related to the Tunnel service. and removed needs-triage Indicates an issue or PR lacks a `triage/foo` label and requires one. labels Jun 11, 2024
Copy link
Contributor

Terraform debug log detected ✅

@github-actions github-actions bot added the triage/debug-log-attached Indicates an issue or PR has a complete Terraform debug log. label Jun 11, 2024
@deansundquist
Copy link

@alecglassford,

The secret is necessary for remotely managed tunnels. It is passed through to cloudflared as an argument (--token) at runtime. (In a local configured tunnel it is pulled from the configuration file).

It is presented by cloudflared to the edge in the form of the "token" which includes the account tag, tunnel id, and the secret (base 64 encoded).

A full setup looks like this:

My secret is my-super-secret-password, which base64 encoded is bXktc3VwZXItc2VjcmV0LXBhc3N3b3Jk. Terraform would look like this:

resource "cloudflare_tunnel" "example" {
  account_id = "11111111111111111111111111111111"
  name       = "my-tunnel"
  secret     = "bXktc3VwZXItc2VjcmV0LXBhc3N3b3Jk"
  config_src = "cloudflare"
}

To create the token, we base64 encode this:

{"a":"11111111111111111111111111111111","t":"ad5dffa5-6943-4e33-b308-111111111111","s":"bXktc3VwZXItc2VjcmV0LXBhc3N3b3Jk"}

(Where a = Account Tag (referenced as Account_ID above), T = tunnel Id, and S = the base64 encoded secret.)

To this:

eyJhIjoiMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTEiLCJ0IjoiYWQ1ZGZmYTUtNjk0My00ZTMzLWIzMDgtMTExMTExMTExMTExIiwicyI6ImJYa3RjM1Z3WlhJdGMyVmpjbVYwTFhCaGMzTjNiM0prIn0=

Finally run cloudflared like this:

cloudflared tunnel run --token eyJhIjoiMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTEiLCJ0IjoiYWQ1ZGZmYTUtNjk0My00ZTMzLWIzMDgtMTExMTExMTExMTExIiwicyI6ImJYa3RjM1Z3WlhJdGMyVmpjbVYwTFhCaGMzTjNiM0prIn0=

A secret is necessary, in fact that's how an instance of cloudflared validates against the edge and is allowed to serve this particular tunnel.

The API docs note:

Sets the password required to run a locally-managed tunnel. Must be at least 32 bytes and encoded as a base64 string.

I think the above could be more clear, but I'd argue against that it "explicitly notes that the secret is only used for a 'locally-managed tunnel,'"

In the Terraform Docs, it is clear that is a required parameter: https://registry.terraform.io/providers/cloudflare/cloudflare/latest/docs/resources/tunnel#secret

@xortive
Copy link

xortive commented Sep 10, 2024

secret is not a required field in the API -- the API will generate one if it is not provided.

After creation, the generated secret is available inside the base64-encoded JSON object returned by the /token endpoint of a tunnel.

So, I don't see any reason to require secret when creating a tunnel of any kind -- the API will happily generate one for you and makes it available such that it can be stored in the terraform state.

Fixing this would also make resolving cloudflare/cf-terraforming#573 trivial and would move the privileged tunnel secret to the state file instead of leaving it exposed in the resource definition.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
kind/bug Categorizes issue or PR as related to a bug. service/tunnel Categorizes issue or PR as related to the Tunnel service. triage/accepted Indicates an issue or PR is ready to be actively worked on. triage/debug-log-attached Indicates an issue or PR has a complete Terraform debug log. workflow/synced
Projects
None yet
Development

No branches or pull requests

4 participants