cloudflare / terraform-provider-cloudflare

Cloudflare Terraform Provider
https://registry.terraform.io/providers/cloudflare/cloudflare
Mozilla Public License 2.0
770 stars 596 forks source link

Any token or key results in "403: Authentication error" for cloudflare_record. #913

Closed robertdebock closed 3 years ago

robertdebock commented 3 years ago

Terraform version

Even with a token that can write anywhere, I'm getting 403's when trying to create a record in an existing domain. I am able to read (using data "cloudflare_zones" "example_com" {.

This also happens with the 'Global API Key'.

I've tried multiple domain in my account.

$ terraform -v
Terraform v0.14.4
+ provider registry.terraform.io/cloudflare/cloudflare v2.17.0
+ provider registry.terraform.io/digitalocean/digitalocean v2.3.0

Affected resource(s)

Terraform configuration files

# Lookup a zone.
data "cloudflare_zones" "example_com" {
  filter {
    name = "example.com"
  }
}

# Add a record to the zone.
resource "cloudflare_record" "www_example_com" {
  zone_id = data.cloudflare_zones.example_com.id
  name    = "www"
  value   = "123.45.67.89"
  type    = "A"
  ttl     = 3600
}

Debug output

2021/01/15 14:06:40 [INFO] backend/local: apply calling Apply
2021/01/15 14:06:40 [INFO] terraform: building graph: GraphTypeApply
2021/01/15 14:06:40 [DEBUG] Resource state not found for node "cloudflare_record.www_example_com", instance cloudflare_record.www_example_com
2021/01/15 14:06:40 [DEBUG] ProviderTransformer: "data.cloudflare_zones.example_com (expand)" (*terraform.nodeExpandApplyableResource) needs provider["registry.terraform.io/cloudflare/cloudflare"]
2021/01/15 14:06:40 [DEBUG] ProviderTransformer: "cloudflare_record.www_example_com" (*terraform.NodeApplyableResourceInstance) needs provider["registry.terraform.io/cloudflare/cloudflare"]
2021/01/15 14:06:40 [DEBUG] ProviderTransformer: "cloudflare_record.www_example_com (expand)" (*terraform.nodeExpandApplyableResource) needs provider["registry.terraform.io/cloudflare/cloudflare"]
2021/01/15 14:06:40 [DEBUG] ReferenceTransformer: "var.webservervolumesize" references: []
2021/01/15 14:06:40 [DEBUG] ReferenceTransformer: "var.databaseserverimage" references: []
2021/01/15 14:06:40 [DEBUG] ReferenceTransformer: "var.databaseservervolumesize" references: []
2021/01/15 14:06:40 [DEBUG] ReferenceTransformer: "provider[\"registry.terraform.io/cloudflare/cloudflare\"]" references: []
2021/01/15 14:06:40 [DEBUG] ReferenceTransformer: "cloudflare_record.www_example_com (expand)" references: []
2021/01/15 14:06:40 [DEBUG] ReferenceTransformer: "var.webserverimage" references: []
2021/01/15 14:06:40 [DEBUG] ReferenceTransformer: "var.region" references: []
2021/01/15 14:06:40 [DEBUG] ReferenceTransformer: "var.webserverscount" references: []
2021/01/15 14:06:40 [DEBUG] ReferenceTransformer: "var.webserversize" references: []
2021/01/15 14:06:40 [DEBUG] ReferenceTransformer: "cloudflare_record.www_example_com" references: [data.cloudflare_zones.example_com (expand)]
2021/01/15 14:06:40 [DEBUG] ReferenceTransformer: "data.cloudflare_zones.example_com (expand)" references: []
2021/01/15 14:06:40 [DEBUG] ReferenceTransformer: "var.databaseserversize" references: []
2021/01/15 14:06:40 [DEBUG] Starting graph walk: walkApply
2021-01-15T14:06:40.966+0100 [INFO]  plugin: configuring client automatic mTLS
2021-01-15T14:06:41.009+0100 [DEBUG] plugin: starting plugin: path=.terraform/providers/registry.terraform.io/cloudflare/cloudflare/2.17.0/linux_amd64/terraform-provider-cloudflare_v2.17.0 args=[.terraform/providers/registry.terraform.io/cloudflare/cloudflare/2.17.0/linux_amd64/terraform-provider-cloudflare_v2.17.0]
2021-01-15T14:06:41.009+0100 [DEBUG] plugin: plugin started: path=.terraform/providers/registry.terraform.io/cloudflare/cloudflare/2.17.0/linux_amd64/terraform-provider-cloudflare_v2.17.0 pid=111554
2021-01-15T14:06:41.009+0100 [DEBUG] plugin: waiting for RPC address: path=.terraform/providers/registry.terraform.io/cloudflare/cloudflare/2.17.0/linux_amd64/terraform-provider-cloudflare_v2.17.0
2021-01-15T14:06:41.022+0100 [INFO]  plugin.terraform-provider-cloudflare_v2.17.0: configuring server automatic mTLS: timestamp=2021-01-15T14:06:41.022+0100
2021-01-15T14:06:41.066+0100 [DEBUG] plugin.terraform-provider-cloudflare_v2.17.0: plugin address: address=/tmp/plugin943612231 network=unix timestamp=2021-01-15T14:06:41.066+0100
2021-01-15T14:06:41.066+0100 [DEBUG] plugin: using plugin: version=5
2021-01-15T14:06:41.151+0100 [DEBUG] plugin.terraform-provider-cloudflare_v2.17.0: 2021/01/15 14:06:41 [INFO] Cloudflare Client configured for user: 
2021/01/15 14:06:41 [WARN] Provider "registry.terraform.io/cloudflare/cloudflare" produced an invalid plan for cloudflare_record.www_example_com, but we are tolerating it because it is using the legacy plugin SDK.
    The following problems may be the cause of any confusing errors from downstream operations:
      - .proxied: planned value cty.False does not match config value cty.NullVal(cty.Bool)
cloudflare_record.www_example_com: Creating...
2021/01/15 14:06:41 [DEBUG] EvalApply: ProviderMeta config value set
2021/01/15 14:06:41 [DEBUG] cloudflare_record.www_example_com: applying the planned Create change
2021-01-15T14:06:41.155+0100 [DEBUG] plugin.terraform-provider-cloudflare_v2.17.0: 2021/01/15 14:06:41 [DEBUG] setting computed for "metadata" from ComputedKeys
2021-01-15T14:06:41.155+0100 [DEBUG] plugin.terraform-provider-cloudflare_v2.17.0: 2021/01/15 14:06:41 [DEBUG] Data found in config: map[string]interface {}{}
2021-01-15T14:06:41.155+0100 [DEBUG] plugin.terraform-provider-cloudflare_v2.17.0: 2021/01/15 14:06:41 [DEBUG] Cloudflare Record create configuration: cloudflare.DNSRecord{ID:"", Type:"A", Name:"www", Content:"123.45.67.89", Proxiable:false, Proxied:false, TTL:3600, Locked:false, ZoneID:"d17dec8ccdc37e7adfa98d5bbb26de6d", ZoneName:"", CreatedOn:time.Time{wall:0x0, ext:0, loc:(*time.Location)(nil)}, ModifiedOn:time.Time{wall:0x0, ext:0, loc:(*time.Location)(nil)}, Data:interface {}(nil), Meta:interface {}(nil), Priority:0}
2021-01-15T14:06:41.155+0100 [DEBUG] plugin.terraform-provider-cloudflare_v2.17.0: 2021/01/15 14:06:41 [DEBUG] Waiting for state to become: [success]
2021-01-15T14:06:41.155+0100 [DEBUG] plugin.terraform-provider-cloudflare_v2.17.0: 2021/01/15 14:06:41 [DEBUG] Cloudflare API Request Details:
2021-01-15T14:06:41.155+0100 [DEBUG] plugin.terraform-provider-cloudflare_v2.17.0: ---[ REQUEST ]---------------------------------------
2021-01-15T14:06:41.155+0100 [DEBUG] plugin.terraform-provider-cloudflare_v2.17.0: POST /client/v4/zones/d17dec8ccdc37e7adfa98d5bbb26de6d/dns_records HTTP/1.1
2021-01-15T14:06:41.155+0100 [DEBUG] plugin.terraform-provider-cloudflare_v2.17.0: Host: api.cloudflare.com
2021-01-15T14:06:41.155+0100 [DEBUG] plugin.terraform-provider-cloudflare_v2.17.0: User-Agent: HashiCorp Terraform/0.14.4 (+https://www.terraform.io) Terraform Plugin SDK/1.16.0 terraform-provider-cloudflare/2.17.0
2021-01-15T14:06:41.155+0100 [DEBUG] plugin.terraform-provider-cloudflare_v2.17.0: Content-Length: 186
2021-01-15T14:06:41.155+0100 [DEBUG] plugin.terraform-provider-cloudflare_v2.17.0: Authorization: Bearer e4CTkRPHdyoBklqhPzbb1B9ctqE1eoeySJ5oD1Ei
2021-01-15T14:06:41.155+0100 [DEBUG] plugin.terraform-provider-cloudflare_v2.17.0: Content-Type: application/json
2021-01-15T14:06:41.155+0100 [DEBUG] plugin.terraform-provider-cloudflare_v2.17.0: Accept-Encoding: gzip
2021-01-15T14:06:41.155+0100 [DEBUG] plugin.terraform-provider-cloudflare_v2.17.0: 
2021-01-15T14:06:41.155+0100 [DEBUG] plugin.terraform-provider-cloudflare_v2.17.0: {
2021-01-15T14:06:41.155+0100 [DEBUG] plugin.terraform-provider-cloudflare_v2.17.0:  "type": "A",
2021-01-15T14:06:41.155+0100 [DEBUG] plugin.terraform-provider-cloudflare_v2.17.0:  "name": "www",
2021-01-15T14:06:41.155+0100 [DEBUG] plugin.terraform-provider-cloudflare_v2.17.0:  "content": "123.45.67.89",
2021-01-15T14:06:41.155+0100 [DEBUG] plugin.terraform-provider-cloudflare_v2.17.0:  "ttl": 3600,
2021-01-15T14:06:41.155+0100 [DEBUG] plugin.terraform-provider-cloudflare_v2.17.0:  "zone_id": "d17dec8ccdc37e7adfa98d5bbb26de6d",
2021-01-15T14:06:41.155+0100 [DEBUG] plugin.terraform-provider-cloudflare_v2.17.0:  "created_on": "0001-01-01T00:00:00Z",
2021-01-15T14:06:41.155+0100 [DEBUG] plugin.terraform-provider-cloudflare_v2.17.0:  "modified_on": "0001-01-01T00:00:00Z"
2021-01-15T14:06:41.155+0100 [DEBUG] plugin.terraform-provider-cloudflare_v2.17.0: }
2021-01-15T14:06:41.155+0100 [DEBUG] plugin.terraform-provider-cloudflare_v2.17.0: -----------------------------------------------------
2021-01-15T14:06:41.551+0100 [DEBUG] plugin.terraform-provider-cloudflare_v2.17.0: 2021/01/15 14:06:41 [DEBUG] Cloudflare API Response Details:
2021-01-15T14:06:41.551+0100 [DEBUG] plugin.terraform-provider-cloudflare_v2.17.0: ---[ RESPONSE ]--------------------------------------
2021-01-15T14:06:41.551+0100 [DEBUG] plugin.terraform-provider-cloudflare_v2.17.0: HTTP/1.1 403 Forbidden
2021-01-15T14:06:41.551+0100 [DEBUG] plugin.terraform-provider-cloudflare_v2.17.0: Connection: close
2021-01-15T14:06:41.551+0100 [DEBUG] plugin.terraform-provider-cloudflare_v2.17.0: Transfer-Encoding: chunked
2021-01-15T14:06:41.551+0100 [DEBUG] plugin.terraform-provider-cloudflare_v2.17.0: Cf-Cache-Status: DYNAMIC
2021-01-15T14:06:41.551+0100 [DEBUG] plugin.terraform-provider-cloudflare_v2.17.0: Cf-Ray: 611fd0bfaed2c857-AMS
2021-01-15T14:06:41.551+0100 [DEBUG] plugin.terraform-provider-cloudflare_v2.17.0: Cf-Request-Id: 07a7c0cbc60000c857dc979000000001
2021-01-15T14:06:41.551+0100 [DEBUG] plugin.terraform-provider-cloudflare_v2.17.0: Content-Type: application/json
2021-01-15T14:06:41.551+0100 [DEBUG] plugin.terraform-provider-cloudflare_v2.17.0: Date: Fri, 15 Jan 2021 13:06:41 GMT
2021-01-15T14:06:41.551+0100 [DEBUG] plugin.terraform-provider-cloudflare_v2.17.0: Expect-Ct: max-age=604800, report-uri="https://report-uri.cloudflare.com/cdn-cgi/beacon/expect-ct"
2021-01-15T14:06:41.551+0100 [DEBUG] plugin.terraform-provider-cloudflare_v2.17.0: Server: cloudflare
2021-01-15T14:06:41.551+0100 [DEBUG] plugin.terraform-provider-cloudflare_v2.17.0: Set-Cookie: __cfduid=d148c0f1dcaba2b9ef863a1ef168eac401610716001; expires=Sun, 14-Feb-21 13:06:41 GMT; path=/; domain=.api.cloudflare.com; HttpOnly; SameSite=Lax; Secure
2021-01-15T14:06:41.551+0100 [DEBUG] plugin.terraform-provider-cloudflare_v2.17.0: Set-Cookie: __cflb=0H28vgHxwvgAQtjUGU56Rb8iNWZVUvXhb5tX6rgdo4q; SameSite=Lax; path=/; expires=Fri, 15-Jan-21 15:36:42 GMT; HttpOnly
2021-01-15T14:06:41.551+0100 [DEBUG] plugin.terraform-provider-cloudflare_v2.17.0: Vary: Accept-Encoding
2021-01-15T14:06:41.551+0100 [DEBUG] plugin.terraform-provider-cloudflare_v2.17.0: 
2021-01-15T14:06:41.551+0100 [DEBUG] plugin.terraform-provider-cloudflare_v2.17.0: 4d
2021-01-15T14:06:41.551+0100 [DEBUG] plugin.terraform-provider-cloudflare_v2.17.0: {
2021-01-15T14:06:41.551+0100 [DEBUG] plugin.terraform-provider-cloudflare_v2.17.0:  "success": false,
2021-01-15T14:06:41.551+0100 [DEBUG] plugin.terraform-provider-cloudflare_v2.17.0:  "errors": [
2021-01-15T14:06:41.551+0100 [DEBUG] plugin.terraform-provider-cloudflare_v2.17.0:   {
2021-01-15T14:06:41.551+0100 [DEBUG] plugin.terraform-provider-cloudflare_v2.17.0:    "code": 10000,
2021-01-15T14:06:41.551+0100 [DEBUG] plugin.terraform-provider-cloudflare_v2.17.0:    "message": "Authentication error"
2021-01-15T14:06:41.551+0100 [DEBUG] plugin.terraform-provider-cloudflare_v2.17.0:   }
2021-01-15T14:06:41.551+0100 [DEBUG] plugin.terraform-provider-cloudflare_v2.17.0:  ]
2021-01-15T14:06:41.552+0100 [DEBUG] plugin.terraform-provider-cloudflare_v2.17.0: }
2021-01-15T14:06:41.552+0100 [DEBUG] plugin.terraform-provider-cloudflare_v2.17.0: 
2021-01-15T14:06:41.552+0100 [DEBUG] plugin.terraform-provider-cloudflare_v2.17.0: 0
2021-01-15T14:06:41.552+0100 [DEBUG] plugin.terraform-provider-cloudflare_v2.17.0: 
2021-01-15T14:06:41.552+0100 [DEBUG] plugin.terraform-provider-cloudflare_v2.17.0: 
2021-01-15T14:06:41.552+0100 [DEBUG] plugin.terraform-provider-cloudflare_v2.17.0: -----------------------------------------------------
2021/01/15 14:06:41 [DEBUG] cloudflare_record.www_example_com: apply errored, but we're indicating that via the Error pointer rather than returning it: failed to create DNS record: error from makeRequest: HTTP status 403: Authentication error

Error: failed to create DNS record: error from makeRequest: HTTP status 403: Authentication error

  on main.tf line 119, in resource "cloudflare_record" "www_example_com":
 119: resource "cloudflare_record" "www_example_com" {

2021-01-15T14:06:41.567+0100 [WARN]  plugin.stdio: received EOF, stopping recv loop: err="rpc error: code = Unavailable desc = transport is closing"
2021-01-15T14:06:41.573+0100 [DEBUG] plugin: plugin process exited: path=.terraform/providers/registry.terraform.io/cloudflare/cloudflare/2.17.0/linux_amd64/terraform-provider-cloudflare_v2.17.0 pid=111554
2021-01-15T14:06:41.573+0100 [DEBUG] plugin: plugin exited

Expected behavior

The record should have been created.

Actual behavior

A 403 is returned:

Error: failed to create DNS record: error from makeRequest: HTTP status 403: Authentication error

Steps to reproduce

In Cloudflare, create a new token (My profile -> API Tokens -> Create Token. Select "Read all resources" and change all occurences of "read" into "write" (where possible).) Save this value under api_key:

provider "cloudflare" {
  email     = "REDACTED"
  api_key   = "REDACTED"
}

I've also tried to use the "Global API Key" and save that value under api_token:

provider "cloudflare" {
  email     = "REDACTED"
  api_token = "REDACTED"
}

Important factoids

none

References

none

Community note

jacobbednarz commented 3 years ago

From the looks of your reproduction case, you've mixed up keys and tokens. API key is your global API key (api_key + email) and tokens are the ones you can select permissions on (api_token).

By the way, if you're using API tokens, you can just use write permissions, you also need to assign read permissions.

Closing as this isn't a bug but confusion with authentication. We can continue the discussion here but there is no action required.

miyurusankalpa commented 3 years ago

I faced the same issue today and the found out that the the id returned by the terraform was incorrect.

When I hard corded the correct zone id, it worked correctly.

@jacobbednarz please reopen this.

jacobbednarz commented 3 years ago

@miyurusankalpa without a reproduction test case, I can't really help you any further. If you're sure you've encountered a bug, please open a new issue following the issue template.

If you're using the cloudflare_zones datasource and seeing an unusable checksum/ID looking string, it's likely you're not using the zones being returned (available under the index [0] on the zones) instead of the resource identifier which is a checksum of all the zones returned.

Not using the correct index resulting in the resource ID being returned.

resource "cloudflare_record" "..." {
  zone_id = data.cloudflare_zones.example_com.id
}

Correct usage accessing all zones available.

resource "cloudflare_record" "..." {
  zone_id = data.cloudflare_zones.example_com[0].id
}

Please see the documentation for full examples.

robertdebock commented 3 years ago

Thanks for your response, I fixed the issue.

My issue was that I was referring to:

  zone_id = data.cloudflare_zones.example_com.id

But needed to refer to:

  zone_id = data.cloudflare_zones.example_com.zones[0].id

Thanks for helping to explain and allow me to fix the mistake!

jacobbednarz commented 3 years ago

Good to know! Glad it's all sorted for you.

danihodovic commented 3 years ago

@jacobbednarz I would guess that 80% of use cases when using the zone data source is to retrieve exactly one domain. Is it possible to add a resource for exactly that use case instead of getting the 403 and googling for this issue?

ethanbayliss commented 3 years ago

@jacobbednarz I would guess that 80% of use cases when using the zone data source is to retrieve exactly one domain. Is it possible to add a resource for exactly that use case instead of getting the 403 and googling for this issue?

I'm here exactly because of this. Would also prefer a single zone data source too.

roseMix commented 3 years ago

Just wondering is it even possible to have more than one zone under a given domain? I've also found this extra zone array confusing.

jacobbednarz commented 3 years ago

@danihodovic no; it's definitely not 80%. the data suggests it's 50/50 for single and multiple lookups 😃 customers are using this across the board for a single and a subset of domains when interacting with other products.

@roseMix it's not restricted to a single account when querying. you can have any number of accounts with the identical zone name or subset of the name. take a look at the test cases if you're curious as to some of the use cases where this can be used.

at this stage, there will not be a single zone resource created when this one works fine however it requires reading the documentation and understanding it's full use case.

tamsky commented 2 years ago

@jacobbednarz wrote

By the way, if you're using API tokens, you can just use write permissions, you also need to assign read permissions.

The statement quoted above does not comport with my experiences using the cloudflare API. More likely, it is in need of some type of correction or further explanation?

One of these is likely true about it: a) it is missing some important words that substantially alter its meaning. b) it is factually incorrect.

The web-based api-token interface does not allow users to assign multiple permission types (READ + EDIT) to the same resource: image

(Note the dimmed item in the selection list. Selecting the dimmed item would create a potential duplicate permission.)

So I'm left wondering: what were you trying to clarify?

marcelloromani commented 2 years ago

@tamsky I have been able (after a short fight with the UI) to assign both DNS read and edit permissions to an API token Screenshot 2022-05-04 at 18 07 36

danihodovic commented 2 years ago

@marcelloromani I believe Edit includes the Read permission.

marcelloromani commented 2 years ago

@danihodovic That's my guess as well. I tried that while debugging a nasty terraform+cloudflare problem. In the end my particular problem was due to a stale resource state in terraform (nothing to do with CloudFlare authentication). So yeah, almost certainly adding Read + Edit permission is superfluous: Edit suffices. Thanks.