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_access_policy always detects changes when both group and email are included #1215

Closed
2 tasks done
bootswithdefer opened this issue Sep 22, 2021 · 9 comments · Fixed by #1983
Closed
2 tasks done
Labels
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.

Comments

@bootswithdefer
Copy link

bootswithdefer commented Sep 22, 2021

Confirmation

  • My issue isn't already found on the issue tracker.
  • I have replicated my issue using the latest version of the provider and it is still present.

Terraform and Cloudflare provider version

Terraform v1.1.2
on linux_amd64
+ provider registry.terraform.io/cloudflare/cloudflare v3.5.0

Affected resource(s)

cloudflare_access_policy

Terraform configuration files

resource "cloudflare_access_policy" "users" {
  application_id = cloudflare_access_application.application.id
  zone_id        = data.vault_generic_secret.cloudflare.data["zone_id"]
  name           = "Allowed Users"
  precedence     = "2"
  decision       = "allow"

  include {
    group = ["uuid-of-group"]
    email = ["email@local"]
  }
}

Debug output

Not including

Panic output

No response

Expected output

No changes on second apply.

Actual output

  ~ resource "cloudflare_access_policy" "users" {
        id                             = "uuid"
        name                           = "Allowed Users"
        # (6 unchanged attributes hidden)

      ~ include {
          ~ group                   = [
              + "uuid-of-group",
            ]
            # (10 unchanged attributes hidden)
        }
      - include {
          - any_valid_service_token = false -> null
          - certificate             = false -> null
          - device_posture          = [] -> null
          - email                   = [] -> null
          - email_domain            = [] -> null
          - everyone                = false -> null
          - geo                     = [] -> null
          - group                   = [
              - "uuid-of-group",
            ] -> null
          - ip                      = [] -> null
          - login_method            = [] -> null
          - service_token           = [] -> null
        }
    }

Steps to reproduce

Apply, approve changes
Apply again, changes detected

Additional factoids

The policy is created correct and the terraform state show the following. Adding two include{} blocks in the resource also causes changes to be detected on every run and does not create the policy correctly.

resource "cloudflare_access_policy" "users" {
    application_id                 = "uuid"
    decision                       = "allow"
    id                             = "uuid"
    name                           = "Allowed Users"
    precedence                     = 2
    purpose_justification_prompt   = ""
    purpose_justification_required = false
    zone_id                        = (sensitive)

    include {
        any_valid_service_token = false
        certificate             = false
        device_posture          = []
        email                   = [
            "email@local",
        ]
        email_domain            = []
        everyone                = false
        geo                     = []
        group                   = []
        ip                      = []
        login_method            = []
        service_token           = []
    }
    include {
        any_valid_service_token = false
        certificate             = false
        device_posture          = []
        email                   = []
        email_domain            = []
        everyone                = false
        geo                     = []
        group                   = [
            "uuid-of-group",
        ]
        ip                      = []
        login_method            = []
        service_token           = []
    }
}

References

No response

@bootswithdefer bootswithdefer 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 Sep 22, 2021
@danie1sullivan
Copy link

I'm experiencing the same issue when trying to include Azure.

      ~ include {
            # (11 unchanged attributes hidden)

          + azure {
              + id                   = ["$grp_uuid"]
              + identity_provider_id = "$idp_uuid"
            }
        }

It doesn't matter if the Azure block is added to a cloudflare_access_policy resource or to a cloudflare_access_group resourced and referenced, both ways always show a change.

@bootswithdefer bootswithdefer changed the title cloudflare_access_policy always detects changes when bot group and email are included cloudflare_access_policy always detects changes when both group and email are included Sep 23, 2021
@ondrejsika
Copy link

I have the same problem

  ~ resource "cloudflare_access_policy" "main" {
        id                             = "d647dd11-130b-4670-a560-90498e465ec0"
        name                           = "allow"
        # (6 unchanged attributes hidden)

      ~ include {
          ~ ip                      = [
              + "1.1.1.1/32",
              + "2.2.2.2/32",
            ]
            # (10 unchanged attributes hidden)
        }
      - include {
          - any_valid_service_token = false -> null
          - certificate             = false -> null
          - device_posture          = [] -> null
          - email                   = [] -> null
          - email_domain            = [] -> null
          - everyone                = false -> null
          - geo                     = [] -> null
          - group                   = [] -> null
          - ip                      = [
              - "1.1.1.1/32",
              - "2.2.2.2/32",
            ] -> null
          - login_method            = [] -> null
          - service_token           = [] -> null
        }
    }

@eidam
Copy link

eidam commented Nov 13, 2021

I am having the same issue, when both email and email_domain are set.

 ~ resource "cloudflare_access_group" "this" {
        id         = "dd8a4299-ad4d-410b-b4ae-14d621a92694"
        name       = "allow-me"
        # (1 unchanged attribute hidden)

      ~ include {
          ~ email                   = [
              + "[email protected]",
              + "[email protected]",
            ]
          ~ email_domain            = [
              - "example.com",
            ]
            # (9 unchanged attributes hidden)
        }
      + include {
          + email_domain = [
              + "example.com",
            ]
        }
    }

@rogersd
Copy link

rogersd commented Feb 9, 2022

I'm still seeing this in 3.8.0

Any chance this can get fixed?

@rnt
Copy link

rnt commented Feb 17, 2022

Still seeing this in 3.9.1 💔

@bas-papegaaij
Copy link
Contributor

I've spent some time looking into this issue and this seems to be due to the way the require, include and exclude blocks are handled internally in the provider.

There seem to be a couple of different bugs interacting here leading to the unwanted behaviour:

  1. When reading data back from the API, the provider reads each field (or set of related fields in the case of e.g. Azure config) and puts it in its own entry in the slice, effectively representing multiple blocks, regardless of how many blocks were defined in Terraform. Terraform emits a warning to this effect:
Provider "provider[\"registry.terraform.io/cloudflare/cloudflare\"]" produced an unexpected new value for cloudflare_access_policy.example, 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:
     - .require: block count changed from 1 to 2

See

if len(emails) > 0 {
data = append(data, map[string]interface{}{
"email": emails,
})
}
where each entry in the data slice effectively represents a block of require, include or exclude.

  1. When writing data to the API, if multiple blocks are configured, only the last one takes effect. See:
    for _, value := range exclude {
    if value != nil {
    group.Exclude = BuildAccessGroupCondition(value.(map[string]interface{}))
    }
    }

These 2 bugs means that you're currently stuck with config that applies outright incorrectly or diffs perpetually.

I've attempted to fix this with a local version of the provider by replacing the code in the latter sample with

for _, value := range exclude {
	if value != nil {
		policy.Exclude = append(policy.Exclude, BuildAccessGroupCondition(value.(map[string]interface{})))
	}
}

but this leads to the following error response from the API when configuring multiple blocks error creating Access Policy for ID "": HTTP status 400: access.api.error.failed_to_load_group (11020), I've yet to find the time to investigate this further.

Hopefully this can be of some help. I'm hesitant to raise a PR for potential fixes because it seems like the most "correct" solution based on Cloudflare's API would require breaking changes to the provider.

@perosb
Copy link

perosb commented Jun 1, 2022

This seem to be not just for email but other things as well.

It doesn't really matter if I specify as:

  include {
    group = var.dev_groups_allow
  }
  include {
    any_valid_service_token = true
  }

which always comes back as:

  ~ resource "cloudflare_access_policy" "allow" {
        id             = "80c1...e629"
        name           = "rule-dev"
        # (4 unchanged attributes hidden)

      ~ include {
          - any_valid_service_token = true -> null
          ~ group                   = [
              + "9310...454",
            ]
            # (9 unchanged attributes hidden)
        }
      + include {
          + any_valid_service_token = true
        }
    }

or

  include {
    group = var.dev_groups_allow
    any_valid_service_token = true
  }

which always comes back as:

  ~ resource "cloudflare_access_policy" "allow" {
        id             = "80c199...f6de629"
        name           = "rule-dev"
        # (4 unchanged attributes hidden)

      ~ include {
          ~ group                   = [
              + "9310e...5a454",
            ]
            # (10 unchanged attributes hidden)
        }
      - include {
          - any_valid_service_token = false -> null
          - certificate             = false -> null
          - device_posture          = [] -> null
          - email                   = [] -> null
          - email_domain            = [] -> null
          - everyone                = false -> null
          - geo                     = [] -> null
          - group                   = [
              - "9310e...a454",
            ] -> null
          - ip                      = [] -> null
          - login_method            = [] -> null
          - service_token           = [] -> null
        }
    }

@dhalturin
Copy link

I have the same problem, does it make sense to wait for a fix?

@esalter
Copy link

esalter commented Sep 30, 2022

We're running into this when both email and email_domain are specified. We're interested in a fix.

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. needs-triage Indicates an issue or PR lacks a `triage/foo` label and requires one.
Projects
None yet
10 participants