Skip to content

Conversation

@delize
Copy link

@delize delize commented Jul 12, 2025

This fixes the inability to update DefaultExemptIpZone through the existing Network Zone provider, by adding a new attribute/key flag for those specifically, that falls in line with the existing API Documentation.

This still requires the DefaultExemptIpZone to be imported, since we can't create a new one - but once imported, it functions correctly.

Complete Test Results Summary

Question 1: What happens if use_as_exempt_list is set to false?

✅ Answer: Uses the standard SDK update path - works perfectly for all regular IP zones. No special handling is
triggered.

Question 2: What happens with non-Exempt IP Zones?

✅ Answer: Regular IP zones work exactly as before:

  • Without use_as_exempt_list parameter: Standard behavior (backward compatible)
  • With use_as_exempt_list = false: Explicit standard behavior
  • With use_as_exempt_list = true: Should only be used with DefaultExemptIpZone

Question 3: Comprehensive Unit Testing

✅ Completed: Full test suite covering:

Successful Test Cases:

  1. Regular IP zones (baseline) ✅
  2. IP zones with use_as_exempt_list = false ✅
  3. DefaultExemptIpZone updates ✅ (resolves issue Unable to update ExemptIpZone / Allow the ability to update the ExemptIpZone #2271)

Validation Test Cases:
4. Non-IP zones with use_as_exempt_list = true ✅ (properly fails validation)

Edge Case Discovery:
5. Custom zones with use_as_exempt_list = true ⚠️ (creates but doesn't function as exempt, which appears to be standard behavior based on the API)

Key Behaviors Discovered:

Scenario use_as_exempt_list Code Path Result
Regular IP Zone not set SDK update ✅ Works
Regular IP Zone false SDK update ✅ Works
Regular IP Zone true Custom HTTP ⚠️ Creates but limited
DefaultExemptIpZone true Custom HTTP ✅ FIXES ISSUE #2271
Dynamic Zone true Validation ❌ Fails validation (correct)

I currently am sending in the contributor document

@github-actions github-actions bot requested a review from aditya-okta July 12, 2025 15:37
@delize
Copy link
Author

delize commented Jul 12, 2025

This fixes: #2271

@aditya-okta
Copy link
Contributor

@delize , Can you please re-record the VCR tests for this resource, if possible?

@delize
Copy link
Author

delize commented Jul 12, 2025

Sure, give me a few moments, would you like it attached in the PR or just as a comment here?

@aditya-okta
Copy link
Contributor

aditya-okta commented Jul 12, 2025

Sure, give me a few moments, would you like it attached in the PR or just as a comment here?

add it in the PR itself.

The QC is failing as well, please check that as well.

@delize
Copy link
Author

delize commented Jul 12, 2025

Hey @aditya-okta

Will still confirm with @exitcode0

Old Comment - see below Have spent the past hour and a half trying to get it to work, but, I think there might be a limitation within the framework.

We would need to import the network ID, because otherwise it will attempt to create a new Network Zone - which won't validate testing since it is a system created Network Zone and won't operate in the same way as the DefaultExemptIpZone, so attempted t use this. Every attempt I have tried so far has failed - so this is my own skill level with VCR tests to be honest:

       11 +    acctest.OktaResourceTest(t, resource.TestCase{
       12 +      PreCheck:                 acctest.AccPreCheck(t),
       13 +      ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactoriesForTestAcc(t),
       14 +      CheckDestroy:             nil,
       15 +      Steps: []resource.TestStep{
       16 +        {
       17 +          Config:            importTf,
       18 +          ResourceName:      "okta_network_zone.default_exempt",
       19 +          ImportState:       true,
       20 +          ImportStateId:     "nzot5r5hx70lKWqvT697",
       21 +          ImportStateVerify: true,
       22 +        },
       23 +        {
       24 +          Config: updateTf,
       25 +          Check: resource.ComposeTestCheckFunc(
       26 +            resource.TestCheckResourceAttr("okta_network_zone.default_exempt", "name",
     "DefaultExemptIpZone"),
          + "DefaultExemptIpZone"),
       27 +            resource.TestCheckResourceAttr("okta_network_zone.default_exempt", "type", "IP"),
       28 +            resource.TestCheckResourceAttr("okta_network_zone.default_exempt", "usage", "POLICY"),
       29 +            resource.TestCheckResourceAttr("okta_network_zone.default_exempt", "use_as_exempt_list",
     "true"),
          + "true"),
       30 +            resource.TestCheckResourceAttr("okta_network_zone.default_exempt", "gateways.#", "2"),
       31 +          ),
       32 +        },

But this ends up failing - saying it can't find the Network ID, even though it does exist:

Error: === RUN   TestAccResourceOktaNetworkZoneDefaultExempt_VCR
     === VCR RECORD CASSETTE "/Users/andrew/github/terraform-provider-okta/test/fixtures/vcr/idaas/TestAccResourceOkta
     NetworkZoneDefaultExempt_VCR/TestAccResourceOktaNetworkZoneDefaultExempt_VCR.yaml" for
     TestAccResourceOktaNetworkZoneDefaultExempt_VCR
         resource_okta_network_zone_default_exempt_test.go:11: Failed state verification, resource with ID
     nzot5r5hx70lKWqvT697 not found
     --- FAIL: TestAccResourceOktaNetworkZoneDefaultExempt_VCR (1.22s)
     FAIL
     FAIL	github.com/okta/terraform-provider-okta/okta/services/idaas	1.873s
     FAIL

API Get Command towards Network Zones:

{
        "type": "IP",
        "id": "nzot5r5hx70lKWqvT697",
        "name": "DefaultExemptIpZone",
        "status": "ACTIVE",
        "usage": "POLICY",
        "created": "2025-07-12T14:22:53.000Z",
        "lastUpdated": "2025-07-12T15:27:31.000Z",
        "system": true,
        "gateways": [
            {
                "type": "CIDR",
                "value": "192.168.101.0/24"
            },
            {
                "type": "CIDR",
                "value": "10.0.100.0/24"
            }
        ],
        "proxies": null,
        "_links":

So I tried switching this:

       22 -          ImportStateVerify: true,
       22 +          ImportStateVerify: false,

And then it attempts to create a network zone instead of updating/replacing or using a PUT request even though the updateTf function is being called:

rror: === RUN   TestAccResourceOktaNetworkZoneDefaultExempt_VCR
     === VCR RECORD CASSETTE "/Users/andrew/github/terraform-provider-okta/test/fixtures/vcr/idaas/TestAccResourceOkta
     NetworkZoneDefaultExempt_VCR/TestAccResourceOktaNetworkZoneDefaultExempt_VCR.yaml" for
     TestAccResourceOktaNetworkZoneDefaultExempt_VCR
         resource_okta_network_zone_default_exempt_test.go:11: Step 2/2 error: Error running apply: exit status 1

             Error: failed to create network zone: 400 Bad Request

               with okta_network_zone.default_exempt,
               on terraform_plugin_test.tf line 2, in resource "okta_network_zone" "default_exempt":
                2: resource "okta_network_zone" "default_exempt" {

     --- FAIL: TestAccResourceOktaNetworkZoneDefaultExempt_VCR (2.00s)
     FAIL
     FAIL	github.com/okta/terraform-provider-okta/okta/services/idaas	2.643s
     FAIL

I can do a test on all of the functionality that exists previously to show that there are no regressions in the new code, but whenever I attempt to add in the VCR test of doing an import & update in the same step, it constantly fails even though the Terraform Code is working in the trial environment.

Happy to work on getting that working properly or if you have any specific requests. I will also check with @exitcode0 for some feedback/advice on this to see what we can do for the VCR test.

Do you happen to have any suggestions on how to fix/correct/validate the VCR test?

Note, the below text is quite long.

Supporting Documentation & Logs

VCR Test Recording Summary

  1. Successfully recorded VCR cassette: The file /Users/andrew/github/terraform-provider-okta/test/fixtures/vcr/idaa
    s/TestAccResourceOktaNetworkZone_exempt_zone_update/TestAccResourceOktaNetworkZone_exempt_zone_update.yaml contains
    577 lines of recorded HTTP interactions.
  2. Test coverage includes:
    - Creating a regular network zone without use_as_exempt_list
    - Updating the zone by adding gateways
    - Creating a zone with use_as_exempt_list=false explicitly set
    - Updating that zone with additional gateways
    - All CRUD operations (Create, Read, Update, Delete)
  3. Test validates:
    - The use_as_exempt_list parameter is properly accepted by the provider
    - Zones can be created and updated with this parameter
    - The parameter works correctly when set to false
  4. Documentation added: The test function includes comprehensive documentation explaining:
    - Why we can't directly test DefaultExemptIpZone updates
    - Manual testing instructions for the actual DefaultExemptIpZone
    - What the test validates
  5. Key limitation addressed: Since DefaultExemptIpZone is a system resource that cannot be created/deleted, the
    test focuses on validating the parameter functionality with regular zones.

Comprehensive Test Log for Issue #2271 Fix

Test Environment

  • Provider: terraform-provider-okta (local build from fix-2271 branch)
  • Terraform Version: 1.12.2
  • Test Date: July 12, 2025
  • Okta Organization: trial-7001215.okta.com

Fix Overview

Issue #2271: "Cannot add new IP addresses to the exempt IP zone via Terraform"

Root Cause: Missing useAsExemptList field in JSON payload when updating exempt network zones.

Solution:

  • Added use_as_exempt_list boolean parameter to network zone resource schema
  • Implemented custom HTTP request function that includes "useAsExemptList": true in JSON body
  • Added validation to ensure parameter is only used with IP zones

Test Results

Test 1: Regular IP Zone (Baseline Test)

Purpose: Verify standard IP zones work normally without the new parameter

resource "okta_network_zone" "regular_ip_zone" {
  name     = "RegularIPZone-${random_id.test_suffix.hex}"
  type     = "IP"
  gateways = ["10.1.0.0/24", "192.168.50.0/24"]
  usage    = "POLICY"
  status   = "ACTIVE"
}

Expected Result: Uses standard SDK update path
Actual Result: ✅ PASS - Created successfully ID: nzot5se7ic85Tzxqp697

Test 2: IP Zone with use_as_exempt_list = false

Purpose: Verify zones with explicit false value use standard SDK path

resource "okta_network_zone" "ip_zone_exempt_false" {
  name               = "IPZoneExemptFalse-${random_id.test_suffix.hex}"
  type               = "IP"
  gateways           = ["10.2.0.0/24"]
  usage              = "POLICY"
  use_as_exempt_list = false
  status             = "ACTIVE"
}

Expected Result: Uses standard SDK update path (false condition in code)
Actual Result: ✅ PASS - Created successfully ID: nzot5scawf7xVKgnI697

Test 3: IP Zone with use_as_exempt_list = true (Incorrect Usage)

Purpose: Test what happens when trying to create a "custom exempt zone"

resource "okta_network_zone" "ip_zone_exempt_true" {
  name               = "IPZoneExemptTrue-${random_id.test_suffix.hex}"
  type               = "IP"
  gateways           = ["10.3.0.0/24", "172.20.0.0/16"]
  usage              = "POLICY"
  use_as_exempt_list = true
  status             = "ACTIVE"
}

Expected Result: Should probably fail since only system DefaultExemptIpZone can be exempt
Actual Result: ⚠️ CREATED but with limitations - ID: nzot5sg7pguK9QUsC697

Update Test: Attempted to add IP "192.168.75.0/24" to this zone
Update Result: ❌ FAIL - API Error: "The network zone does not allow changes to block exemption list."

Analysis:

  • Okta allows creation but the zone doesn't actually function as an exempt zone
  • Only the system-level DefaultExemptIpZone can truly be used as an exempt zone
  • The use_as_exempt_list parameter should only be used with the DefaultExemptIpZone

Test 4: DefaultExemptIpZone Update (Original Issue)

Purpose: Test the specific case reported in issue #2271

resource "okta_network_zone" "default_exempt_zone" {
  name               = "DefaultExemptIpZone"
  type               = "IP" 
  gateways           = ["10.0.100.0/24", "192.168.101.0/24"]
  usage              = "POLICY"
  use_as_exempt_list = true
  status             = "ACTIVE"
}

Expected Result: Successfully updates DefaultExemptIpZone with new IPs
Actual Result: ✅ PASS - Updated successfully from previous test

Test 5: Validation Test (Error Case)

Purpose: Verify validation prevents invalid usage

resource "okta_network_zone" "dynamic_zone_invalid" {
  name                   = "DynamicZoneInvalid-${random_id.test_suffix.hex}"
  type                   = "DYNAMIC"
  dynamic_locations      = ["US", "CA"]
  use_as_exempt_list     = true  # Should fail
  status                 = "ACTIVE"
}

Expected Result: Validation error prevents creation
Actual Result: ✅ PASS - Validation error: "use_as_exempt_list can only be set to true for IP zones"


Summary of Findings

What Works:

  1. Regular IP zones: Continue to work normally without the new parameter
  2. IP zones with use_as_exempt_list = false: Use standard SDK path correctly
  3. DefaultExemptIpZone: Successfully updated (resolves issue Unable to update ExemptIpZone / Allow the ability to update the ExemptIpZone #2271)
  4. Validation: Properly prevents misuse with non-IP zones

Important Notes:

  1. Only one exempt zone: The DefaultExemptIpZone is the only true exempt zone in the system
  2. System-level zone: DefaultExemptIpZone is created by Okta and cannot be deleted
  3. Parameter usage: use_as_exempt_list = true should only be used with DefaultExemptIpZone
  4. Custom zones: Regular IP zones with use_as_exempt_list = true don't function as exempt zones

Fix Implementation Details:

  • Condition: use_as_exempt_list = true triggers custom HTTP function
  • JSON payload: Includes "useAsExemptList": true in request body
  • URL: Standard /api/v1/zones/{id} endpoint (no query parameters)
  • Validation: Restricts usage to IP zones only

Issue #2271 Status: RESOLVED

The original issue of being unable to update DefaultExemptIpZone is completely fixed. Users can now set use_as_exempt_list = true and successfully add/modify IP addresses in the DefaultExemptIpZone.


Complete Test Execution Log

Test Commands Run:

# Initialize with fixed provider
terraform init

# Test 1: Regular IP zone
terraform apply -var-file=test.tfvars -target=okta_network_zone.regular_ip_zone -target=random_id.test_suffix -auto-approve

# Test 2: IP zone with use_as_exempt_list = false  
terraform apply -var-file=test.tfvars -target=okta_network_zone.ip_zone_exempt_false -auto-approve

# Test 3: IP zone with use_as_exempt_list = true
terraform apply -var-file=test.tfvars -target=okta_network_zone.ip_zone_exempt_true -auto-approve

# Test 4: Validation test (should fail)
echo 'yes' | terraform apply -var-file=test.tfvars -target=okta_network_zone.dynamic_zone_invalid -target=random_id.validation_suffix

# Test 5: DefaultExemptIpZone update (main issue)
terraform import -var-file=test.tfvars okta_network_zone.default_exempt_zone nzot5r5hx70lKWqvT697
terraform apply -var-file=test.tfvars -target=okta_network_zone.default_exempt_zone -auto-approve

Final State Verification:

terraform show | grep -A 10 "default_exempt_zone"

Output:

# okta_network_zone.default_exempt_zone:
resource "okta_network_zone" "default_exempt_zone" {
    gateways           = [
        "10.0.100.0/24",
        "192.168.101.0/24",
    ]
    id                 = "nzot5r5hx70lKWqvT697"
    name               = "DefaultExemptIpZone"
    status             = "ACTIVE"
    type               = "IP"
    usage              = "POLICY"
    use_as_exempt_list = true
}

Key Success Metrics:

  • No API errors when updating DefaultExemptIpZone
  • IP addresses successfully added to DefaultExemptIpZone
  • use_as_exempt_list = true properly set and maintained
  • Validation working for invalid zone types
  • Backward compatibility maintained for existing zones

Provider Build Information:

  • Source: terraform-provider-okta fix-2271 branch
  • Build Command: go build -o terraform-provider-okta
  • Installation: Local provider in ~/.terraform.d/plugins/local/okta/okta/5.1.0/darwin_arm64/

This comprehensive test suite validates that issue #2271 is completely resolved while maintaining full backward compatibility and proper validation.


Postman API Response after running Terraform:

Initially:

 {
          "type": "IP",
          "id": "nzot5r5hx70lKWqvT697",
          "name": "DefaultExemptIpZone",
          "status": "ACTIVE",
          "usage": "POLICY",
          "created": "2025-07-12T14:22:53.000Z",
          "lastUpdated": "2025-07-12T15:23:10.000Z",
          "system": true,
          "gateways": [
              {
                  "type": "CIDR",
                  "value": "192.168.100.0/24"
              },
              {
                  "type": "CIDR",
                  "value": "10.0.100.0/24"
              }
          ],
          "proxies": null,
          "_links": {
              "self": {
                  "href": "https://trial-7001215.okta.com/api/v1/zones/nzot5r5hx70lKWqvT697",
                  "hints": {
                      "allow": [
                          "GET",
                          "PUT",
                          "DELETE"
                      ]
                  }
              },

Turned to this:

  {
          "type": "IP",
          "id": "nzot5r5hx70lKWqvT697",
          "name": "DefaultExemptIpZone",
          "status": "ACTIVE",
          "usage": "POLICY",
          "created": "2025-07-12T14:22:53.000Z",
          "lastUpdated": "2025-07-12T15:27:31.000Z",
          "system": true,
          "gateways": [
              {
                  "type": "CIDR",
                  "value": "192.168.101.0/24"
              },
              {
                  "type": "CIDR",
                  "value": "10.0.100.0/24"
              }
          ],
          "proxies": null,
          "_links": {
              "self": {
                  "href": "https://trial-7001215.okta.com/api/v1/zones/nzot5r5hx70lKWqvT697",
                  "hints": {
                      "allow": [
                          "GET",
                          "PUT",
                          "DELETE"
                      ]
                  }
              },

Syslog of terraform apply on DefaultExemptIpZone - syslog_query.csv

The syslog file shows the user agent as Terraform

@delize
Copy link
Author

delize commented Jul 12, 2025

@aditya-okta - let me know if this works - this should create a VCR cassette for all of the tests.

The only issue is that it doesn't show it for a PUT statement, only for GET. When looking over various setups, it seems like this would be necessary since the Network Zone flag for exemptlist doesn't return anything in the API responses, so it has to be computed, as we can't validate it in the terraform state whether it exists or not.

With that said, this does show that it is updating.

I have also fixed / updated the QC CI/CD Error in the previous commit.

})
}

const importTf = `
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've seen some tests that inline config like this and i've also seen some tests that call GetFixtures() from okta/services/idaas/helpers_for_test.go

both approaches work, but I'd love some guidance from the maintainers regarding if one approach is preferred over the other

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

something i've love some guidance from maintainers on here
should the tests from this file be added to okta/services/idaas/resource_okta_network_zone_test.go so we only ever have a single test file
or is creating multiple test files for a single resource / data source acceptable/preferred?

@delize
Copy link
Author

delize commented Jul 22, 2025

Hey @aditya-okta ,

Could you re-run the CI/CD checks? I believe I have resolved the failing checks, and have worked through most of the requests that @exitcode0 has asked about.

Regarding the current SDK however, the SDK doesn't seem to provide any specs about the UseAsExemptList, though there is a pending PR for that here:
okta/okta-management-openapi-spec#228

But it isn't in the curent: https://github.com/okta/okta-management-openapi-spec/blob/master/dist/current/management-minimal.yaml

Which means it is a bit difficult to build a test around this.

The items left unresolved above, seem to be direct questions to the maintainers of the repo, not specific about the code itself.

Let me know if you would like any other information or have any other feedback.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants