release: 5.14.0 (#6481)
Some checks failed
CI / lint (push) Has been cancelled
CI / test (push) Has been cancelled

* codegen metadata

* chore(zone): update migration tests (#6468)

Updates `cloudflare_zone` migration tests to use `tf-migrate` instead of
`cmd/migrate`.

* feat: feat: BOTS-7562 add bot management feedback endpoints to stainless config (prod)

* feat: BOTS-7562 add bot management feedback endpoints to stainless config (prod)

* feat: chore: point Terraform to Go 'next'

* chore: point Terraform to Go 'next'

* chore(api): update composite API spec

* chore(internal): codegen related update

* fix(zone): datasource model schema parity (#6487)

* fix(zone): make datasource's zone ID computed optional

Resolves #6129

* test(zone): fix datasource model/schema parity

Updates the `ZonesAccountDataSourceModel` type be useful for both filters and
decerilization.

* feat: feat(radar): Add origins endpoints to public api docs

* chore(account_tokens): adding a simple CRUD test (#6484)

* adding a simple CRUD test fo account tokens

* add a test file

* feat: chore(api_shield_discovery_operation): Deprecate api_shield_discovery_operation

* chore(cloudflare_api_shield_operation): Add acceptance tests  (#6491)

* test: Add acceptance tests for cloudflare_api_shield_operation

* chore: Add CI acceptance tests for api_shield_operation

* chore(internal): codegen related update

* chore(logpush_job): add v4 to v5 migration tests (#6483)

* codegen metadata

* add migration test for logpush_job

* add zone level logpush jobs to sweeper

* use MigrationV2TestStep, use zone level job for instant-logs test

* handle instant-logs being returned from the API despite not being a valid config value

* rename resource test name to be consistent

---------

Co-authored-by: stainless-app[bot] <142633134+stainless-app[bot]@users.noreply.github.com>

* fix(pages_project): use correct field name in test sweeper

  The Pages API response type uses "Name" instead of "ProjectName". Update
  the test sweeper to access the correct field from "ProjectListResponse".

  Fixes compilation error:
  deployment.ProjectName undefined (type pages.ProjectListResponse has no
  field or method ProjectName)

* fix(zero_trust_device_posture_rule): preserve input.version and other fields (#6500)

not returned by API

  The API doesn't return all configured input fields in Read responses,
  causing
  drift. This preserves input.version (critical), input.enabled cleanup, and
  additional fields (path, sha256, os_distro_*) from current state when API
  omits them.

  Fixes perpetual drift for firewall and os_version posture rules.

* feat: feat(r2_data_catalog): Configure SDKs/Terraform to use R2 Data Catalog routes

* feat(r2_data_catalog): Configure SDKs/Terraform to use R2 Data Catalog routes

* DS-15730: Re-enable logpush_dataset_field data source and add acceptance test (#6499)

Co-authored-by: Henry Clausen <hclausen@cloudflare.com>

* DS-15566: Add logpush_job acceptance test for filter update (#6498)

Co-authored-by: Henry Clausen <hclausen@cloudflare.com>

* chore(internal): codegen related update

* Update Subscription and Subscription.RatePlan schema in order to satisfy terraform to no detect changes on no changes to the config (#6497)

* BILLSUB-247 CUSTESC-57375 fix drift issues after apply causing idempotency issues on subsequent applies

* BILLSUB-247 CUSTESC-57375 fix wrong computed_optional syntax

* Fix zone_subscription Sets field type mismatch

---------

Co-authored-by: Sui Mak <sui@cloudflare.com>

* feat: improve and standardize sweepers (#6501)

* fix(zero_trust_device_posture_rule): preserve input.version and other fields (#6503)

not returned by API

  The API doesn't return all configured input fields in Read responses,
  causing
  drift. This preserves input.version (critical), input.enabled cleanup, and
  additional fields (path, sha256, os_distro_*) from current state when API
  omits them.

  Fixes perpetual drift for firewall and os_version posture rules.

* chore(internal): codegen related update

* chore(zero_trust_device_managed_networks): add tests (#6463)

* chore(zero_trust_device_default_profile_local_domain_fallback): add tests (#6464)

* chore(zero_trust_device_posture_integration): update tests for to test with Crowdstrike (#6470)

* fix(zone_subscription|account_subscription): add partners_ent as valid enum for rate_plan.id (#6505)

* fix: add partners_ent as valid enum for rate_plan.id

* fix: remove partners_enterprise enum from account subscription

---------

Co-authored-by: Sui Mak <sui@cloudflare.com>

* chore(api): update composite API spec

* chore(internal): codegen related update

* chore(internal): codegen related update

* feat: add v4->v5 migration tests for pages_project and adjust schema (#6506)

* fix: update import signature to accept account_id/subscription_id in order to import account subscription (#6510)

Co-authored-by: Sui Mak <sui@cloudflare.com>

* fix: r2 sweeper (#6512)

* chore(internal): codegen related update

* codegen metadata

* chore(internal): codegen related update

* chore(internal): codegen related update

* codegen metadata

* feat: chore: update go sdk to v6.4.0 for provider release

* chore: skip invalid change detection

* chore: update go sdk to v6.4.0

* fix(workers_script):  resource drift when worker has unmanaged secret (#6504)

Co-authored-by: Chris Thorwarth <cthorwarth@cloudflare.com>

* fix(workers_script): No longer treating the migrations attribute as WriteOnly (#6489)

* codegen metadata

* wip: moving migrations to be a write-only attribute

---------

Co-authored-by: stainless-app[bot] <142633134+stainless-app[bot]@users.noreply.github.com>
Co-authored-by: Chris Thorwarth <cthorwarth@cloudflare.com>

* chore(zero_trust_device_default|custom_profile): acceptance test coverage (#6511)

* fix(account_members): making member policies a set (#6488)

* ACCT-11111 making member policies a set

* fixing test resource name

* removing unnecessary

* removing unnecessary

* correct client version

* fixing resource names and sweeping

* manual cleanup of test resources

* making resource groups and perm groups sets

* fix(tests): resolve SDK v6 migration test failures (#6507)

- Change global test resource prefix from cf-tf-test- to cftftest_ to fix
  API name validation errors (fixes list, list_item, snippet)
  - Add certificate_pack hosts order-insensitive comparison in ModifyPlan to
  prevent unnecessary replacements
  - Add UseStateForUnknown() plan modifier to certificate_pack primary_certificate
   field
  - Add UseStateForUnknown() plan modifiers to pages_project deployment_configs
  fields (always_use_latest_compatibility_date, build_image_major_version,
  compatibility_date, fail_open) to prevent state drift

  Fixes test failures in: list, list_item, snippet, certificate_pack,
  pages_domain, pages_project

* chore(tests): cloud connector rules parity tests and add connectivity_directory_service tests (#6513)

* fix(cloud_connector_rules): datasource model schema parity

* fix: rename e2e test for connectivity_directory_service

* fix(account_member): use sdk to setup prereq

* fix(cloud_connector_rules): model and schema

---------

Co-authored-by: Eric Falcao <efalcao@cloudflare.com>

* fix: decoder, build (#6514)

* fix(test_utils): undefined func

* fix(decoder): dont include fields with json tag -

* chore(account_subscription): skip test

* fix: decoder and tests (#6516)

chore(account_member): dont run acceptance with env variable

fix(utils): test assertions

* chore(account_member): fix check for env var (#6517)

* fix(workers_kv): ignore value import state verify (#6521)

* fix(workers_kv): ignore value import state verify

* chore(workers_kv): comment about why we're ignoring value

* chore(account_member): skip until user is dsr enabled (#6522)

* fix(pages_project): non empty refresh plans (#6515)

* chore(docs): update documentation (#6523)

* chore: update changelog (#6525)

* release: 5.14.0

---------

Co-authored-by: stainless-app[bot] <142633134+stainless-app[bot]@users.noreply.github.com>
Co-authored-by: Michael Girouard <206137+mgirouard@users.noreply.github.com>
Co-authored-by: Steve Conrad <sconrad@cloudflare.com>
Co-authored-by: cbertiercloudflare <cbertier@cloudflare.com>
Co-authored-by: Sarah Sicard <18204584+ssicard@users.noreply.github.com>
Co-authored-by: Tamas Jozsa <tamas@cloudflare.com>
Co-authored-by: Henry Clausen <33390934+hc2116@users.noreply.github.com>
Co-authored-by: Henry Clausen <hclausen@cloudflare.com>
Co-authored-by: Sui Mak <smakys501@gmail.com>
Co-authored-by: Sui Mak <sui@cloudflare.com>
Co-authored-by: jlu-cloudflare <124198068+jlu-cloudflare@users.noreply.github.com>
Co-authored-by: Rotem Atzaba <rotem@cloudflare.com>
Co-authored-by: christhorwarth <chris.thorwarth@gmail.com>
Co-authored-by: Chris Thorwarth <cthorwarth@cloudflare.com>
Co-authored-by: Vaishak Dinesh <vaishakpdinesh@gmail.com>
Co-authored-by: Eric Falcao <efalcao@cloudflare.com>
This commit is contained in:
stainless-app[bot] 2025-12-05 16:57:14 -08:00 committed by GitHub
parent cbcb325271
commit 262c3ddc48
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
533 changed files with 14128 additions and 2983 deletions

View file

@ -13,8 +13,8 @@ jobs:
runs-on: ${{ github.repository == 'stainless-sdks/cloudflare-terraform' && 'depot-ubuntu-24.04' || 'lx64' }}
env:
CLOUDFLARE_ACCOUNT_ID: f037e56e89293a057740de681ac9abbe
CLOUDFLARE_ALT_DOMAIN: terraform2.cfapi.net
CLOUDFLARE_ALT_ZONE_ID: b72110c08e3382597095c29ba7e661ea
CLOUDFLARE_ALT_DOMAIN: terraform-alt.cfapi.net
CLOUDFLARE_ALT_ZONE_ID: ed9caae55809bfe3209699f602ce17fc
CLOUDFLARE_DOMAIN: terraform.cfapi.net
CLOUDFLARE_EMAIL: terraform-acceptance-test@cfapi.net
CLOUDFLARE_ZONE_ID: 0da42c8d2132a9ddaf714f9e7c920711

20
.golangci.yml Normal file
View file

@ -0,0 +1,20 @@
# yaml-language-server: schema=https://golangci-lint.run/jsonschema/golangci.jsonschema.json
---
version: '2'
linters:
settings:
staticcheck:
checks:
- all
- -SA1019
- -SA5008
- -ST1000
- -ST1003
- -ST1020
- -ST1022
- -QF1008
govet:
disable:
- structtag

View file

@ -1,3 +1,3 @@
{
".": "5.13.0"
".": "5.14.0"
}

View file

@ -1,4 +1,4 @@
configured_endpoints: 1905
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/cloudflare%2Fcloudflare-cc732ca8d1d7f1c11a1ee579060ddfd8f953a3ad94fd5053056b53370129d040.yml
openapi_spec_hash: a3e1e833dfe13845abd1e2227993a979
config_hash: 9e3a3f3e68822e0dc6f40af202c6c57e
configured_endpoints: 1922
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/cloudflare%2Fcloudflare-6183ef87f1b8eea6ad4bae542bfde2ec23a5526ae2b7bacdf6c6a4c48d990995.yml
openapi_spec_hash: 9c8ac3d56571ebf1e170d993b71ccb4d
config_hash: 56e587ca83a584af152a4bf8a9cfb29e

View file

@ -1,5 +1,138 @@
# Changelog
## 5.14.0 (2025-12-06)
Full Changelog: [v5.13.0...v5.14.0](https://github.com/cloudflare/terraform-provider-cloudflare/compare/v5.13.0...v5.14.0)
### Features
* add v4-&gt;v5 migration tests for pages_project and adjust schema ([#6506](https://github.com/cloudflare/terraform-provider-cloudflare/issues/6506)) ([6de0179](https://github.com/cloudflare/terraform-provider-cloudflare/commit/6de0179a033543e4e63053b9db68185f4e4f2c78))
* chore: point Terraform to Go 'next' ([af9a5f8](https://github.com/cloudflare/terraform-provider-cloudflare/commit/af9a5f896f4e65e9808a2b6458279b9a7ff935fe))
* chore: update go sdk to v6.4.0 for provider release ([63cb021](https://github.com/cloudflare/terraform-provider-cloudflare/commit/63cb021ec8318c4aefaacadc025c90d8ef3e618d))
* chore(api_shield_discovery_operation): Deprecate api_shield_discovery_operation ([7dc0a63](https://github.com/cloudflare/terraform-provider-cloudflare/commit/7dc0a63e0fa3de74d8877788ff787294cb603c07))
* feat: BOTS-7562 add bot management feedback endpoints to stainless config (prod) ([f5112e1](https://github.com/cloudflare/terraform-provider-cloudflare/commit/f5112e1e4d4fe53b9e0ec96aa27f69fb7706099b))
* feat(r2_data_catalog): Configure SDKs/Terraform to use R2 Data Catalog routes ([5beb50b](https://github.com/cloudflare/terraform-provider-cloudflare/commit/5beb50b30d7d012afae92f8f652e005955d4e430))
* feat(radar): Add origins endpoints to public api docs ([ee51e5f](https://github.com/cloudflare/terraform-provider-cloudflare/commit/ee51e5f19c5f1f3cd4d2c07acdcf0f368c635c4d))
* improve and standardize sweepers ([#6501](https://github.com/cloudflare/terraform-provider-cloudflare/issues/6501)) ([03fb2d2](https://github.com/cloudflare/terraform-provider-cloudflare/commit/03fb2d2f4999ca24b9597093f25fd1dbc0f671b7))
### Bug Fixes
* **account_members:** making member policies a set ([#6488](https://github.com/cloudflare/terraform-provider-cloudflare/issues/6488)) ([f3ecaa5](https://github.com/cloudflare/terraform-provider-cloudflare/commit/f3ecaa5938486865698b3956848a8e5f0f6c9054))
* decoder and tests ([#6516](https://github.com/cloudflare/terraform-provider-cloudflare/issues/6516)) ([4c3e2db](https://github.com/cloudflare/terraform-provider-cloudflare/commit/4c3e2db3ec31638d423d0ecc971e5c5ea54298ec))
* decoder, build ([#6514](https://github.com/cloudflare/terraform-provider-cloudflare/issues/6514)) ([1935459](https://github.com/cloudflare/terraform-provider-cloudflare/commit/1935459b88e1ec7d656148d92aee6ea45557ce3c))
* **pages_project:** non empty refresh plans ([#6515](https://github.com/cloudflare/terraform-provider-cloudflare/issues/6515)) ([bc526ff](https://github.com/cloudflare/terraform-provider-cloudflare/commit/bc526ffcf5091195cc143cbf774013b84728296c))
* **pages_project:** use correct field name in test sweeper ([6dc0e53](https://github.com/cloudflare/terraform-provider-cloudflare/commit/6dc0e538754b84e8e31d0c1b7bd8c0e291161811))
* r2 sweeper ([#6512](https://github.com/cloudflare/terraform-provider-cloudflare/issues/6512)) ([fec953c](https://github.com/cloudflare/terraform-provider-cloudflare/commit/fec953c98e8764e5b1ed3dc1906d02206718928e))
* **tests:** resolve SDK v6 migration test failures ([#6507](https://github.com/cloudflare/terraform-provider-cloudflare/issues/6507)) ([bad9716](https://github.com/cloudflare/terraform-provider-cloudflare/commit/bad971609bfb7ddc8d78de6935b747f350f1ae55))
* update import signature to accept account_id/subscription_id in order to import account subscription ([#6510](https://github.com/cloudflare/terraform-provider-cloudflare/issues/6510)) ([c2db582](https://github.com/cloudflare/terraform-provider-cloudflare/commit/c2db582ed27a6e8ac3de6461dba011496b687d05))
* **utils:** test assertions ([4c3e2db](https://github.com/cloudflare/terraform-provider-cloudflare/commit/4c3e2db3ec31638d423d0ecc971e5c5ea54298ec))
* **workers_kv:** ignore value import state verify ([#6521](https://github.com/cloudflare/terraform-provider-cloudflare/issues/6521)) ([c3e3f89](https://github.com/cloudflare/terraform-provider-cloudflare/commit/c3e3f892bcd0d1426eb398688b1f5f8c84144b57))
* **workers_script:** No longer treating the migrations attribute as WriteOnly ([#6489](https://github.com/cloudflare/terraform-provider-cloudflare/issues/6489)) ([dc60e38](https://github.com/cloudflare/terraform-provider-cloudflare/commit/dc60e3883002db7eb9036265aa4000a08a1eb2b6))
* **workers_script:** resource drift when worker has unmanaged secret ([#6504](https://github.com/cloudflare/terraform-provider-cloudflare/issues/6504)) ([505c0fe](https://github.com/cloudflare/terraform-provider-cloudflare/commit/505c0fe78b4f096ed3547f7b564ea5788a64a644))
* **zero_trust_device_posture_rule:** preserve input.version and other fields ([#6500](https://github.com/cloudflare/terraform-provider-cloudflare/issues/6500)) ([4c4e54b](https://github.com/cloudflare/terraform-provider-cloudflare/commit/4c4e54bdfdfa2c6ce584322cd2ae8562269b4a98))
* **zero_trust_device_posture_rule:** preserve input.version and other fields ([#6503](https://github.com/cloudflare/terraform-provider-cloudflare/issues/6503)) ([d45be9a](https://github.com/cloudflare/terraform-provider-cloudflare/commit/d45be9a3b6276bee2c9f4413e141db6d5d1fa596))
* **zero_trust_dlp_custom_profile:** add sweepers for dlp_custom_profile ([cbcb325](https://github.com/cloudflare/terraform-provider-cloudflare/commit/cbcb325271e91d6c3a0bb832eb0c347198d9ce6c))
* **zone_subscription|account_subscription:** add partners_ent as valid enum for rate_plan.id ([#6505](https://github.com/cloudflare/terraform-provider-cloudflare/issues/6505)) ([2a70fb4](https://github.com/cloudflare/terraform-provider-cloudflare/commit/2a70fb49ccc28e5309f7096d1ebc34866c2f07f3))
* **zone:** datasource model schema parity ([#6487](https://github.com/cloudflare/terraform-provider-cloudflare/issues/6487)) ([861c68f](https://github.com/cloudflare/terraform-provider-cloudflare/commit/861c68fcb37627371673e60dfcbc7bf09638e28e))
### Chores
* **account_member:** dont run acceptance with env variable ([4c3e2db](https://github.com/cloudflare/terraform-provider-cloudflare/commit/4c3e2db3ec31638d423d0ecc971e5c5ea54298ec))
* **account_member:** fix check for env var ([#6517](https://github.com/cloudflare/terraform-provider-cloudflare/issues/6517)) ([07e9aa5](https://github.com/cloudflare/terraform-provider-cloudflare/commit/07e9aa5ef6327499731b17ac334f2f9d4cf3f4bf))
* **account_member:** skip until user is dsr enabled ([#6522](https://github.com/cloudflare/terraform-provider-cloudflare/issues/6522)) ([dd7c2fe](https://github.com/cloudflare/terraform-provider-cloudflare/commit/dd7c2fea55e1dc10953b57c2d3792b2e97a8e68e))
* **account_tokens:** adding a simple CRUD test ([#6484](https://github.com/cloudflare/terraform-provider-cloudflare/issues/6484)) ([6869538](https://github.com/cloudflare/terraform-provider-cloudflare/commit/68695382141a2b097c051b38a32fabf5368c2ad9))
* **api:** update composite API spec ([71fc050](https://github.com/cloudflare/terraform-provider-cloudflare/commit/71fc0502fe85faaabd599348b8f46930fa0bd15f))
* **api:** update composite API spec ([68d017a](https://github.com/cloudflare/terraform-provider-cloudflare/commit/68d017a1dd2379d7f4c22b83b9ee31e146971b54))
* **cloudflare_api_shield_operation:** Add acceptance tests ([#6491](https://github.com/cloudflare/terraform-provider-cloudflare/issues/6491)) ([37e1fdf](https://github.com/cloudflare/terraform-provider-cloudflare/commit/37e1fdf9d72b9d853e4ba7b751f2680db5abb9f6))
* **docs:** update documentation ([#6523](https://github.com/cloudflare/terraform-provider-cloudflare/issues/6523)) ([a060e61](https://github.com/cloudflare/terraform-provider-cloudflare/commit/a060e61e9882b706ad6386bc2d1ffc8ac295166d))
* **internal:** codegen related update ([923ea1d](https://github.com/cloudflare/terraform-provider-cloudflare/commit/923ea1db2a8accfd846990947a49f44a1e209ea4))
* **internal:** codegen related update ([a110cbe](https://github.com/cloudflare/terraform-provider-cloudflare/commit/a110cbe76756173711fbc50c6c13c143d53ae625))
* **internal:** codegen related update ([7b36c06](https://github.com/cloudflare/terraform-provider-cloudflare/commit/7b36c06f10f0fee20c5935b20f6817f7f91d2442))
* **internal:** codegen related update ([c789f91](https://github.com/cloudflare/terraform-provider-cloudflare/commit/c789f91d6ba5c773ad152945114ab6b020949616))
* **internal:** codegen related update ([a91faa6](https://github.com/cloudflare/terraform-provider-cloudflare/commit/a91faa61eca4c2cf4ea23aff7f14667e9b042de7))
* **internal:** codegen related update ([dfa745a](https://github.com/cloudflare/terraform-provider-cloudflare/commit/dfa745abb71b94428ff1140f592a48cb7eca8969))
* **internal:** codegen related update ([fb3ef1b](https://github.com/cloudflare/terraform-provider-cloudflare/commit/fb3ef1b5b7fe827753ba82f4f08381bf951f5dbf))
* **internal:** codegen related update ([504e8b6](https://github.com/cloudflare/terraform-provider-cloudflare/commit/504e8b61e19091d8f2e66f37889311256cf6590b))
* **internal:** codegen related update ([550d77c](https://github.com/cloudflare/terraform-provider-cloudflare/commit/550d77c15980feac28e1df2b6fc52473d81f57e6))
* **logpush_job:** add v4 to v5 migration tests ([#6483](https://github.com/cloudflare/terraform-provider-cloudflare/issues/6483)) ([2e4b8a0](https://github.com/cloudflare/terraform-provider-cloudflare/commit/2e4b8a090ca9741cd6f7e5861305f82ac582b63d))
* **tests:** cloud connector rules parity tests and add connectivity_directory_service tests ([#6513](https://github.com/cloudflare/terraform-provider-cloudflare/issues/6513)) ([5341c82](https://github.com/cloudflare/terraform-provider-cloudflare/commit/5341c824679002c0168d3ce8696022aec30ff33e))
* update changelog ([#6480](https://github.com/cloudflare/terraform-provider-cloudflare/issues/6480)) ([adba156](https://github.com/cloudflare/terraform-provider-cloudflare/commit/adba156599c44b43277c7d4b5694f3ccde2408a3))
* update changelog ([#6525](https://github.com/cloudflare/terraform-provider-cloudflare/issues/6525)) ([b026b4d](https://github.com/cloudflare/terraform-provider-cloudflare/commit/b026b4d32a8c394823d91be0a4ed156252ff5fcd))
* **zero_trust_device_default_profile_local_domain_fallback:** add tests ([#6464](https://github.com/cloudflare/terraform-provider-cloudflare/issues/6464)) ([365cb71](https://github.com/cloudflare/terraform-provider-cloudflare/commit/365cb71b906fca75c2be9fedf38f5269eaa0f4dd))
* **zero_trust_device_default|custom_profile:** acceptance test coverage ([#6511](https://github.com/cloudflare/terraform-provider-cloudflare/issues/6511)) ([8e4ec1a](https://github.com/cloudflare/terraform-provider-cloudflare/commit/8e4ec1a9e376ac294707db9fc320a8855be0ba89))
* **zero_trust_device_managed_networks:** add tests ([#6463](https://github.com/cloudflare/terraform-provider-cloudflare/issues/6463)) ([e9b6783](https://github.com/cloudflare/terraform-provider-cloudflare/commit/e9b67835cbf10fb76282b2526f732f13aa13ca06))
* **zero_trust_device_posture_integration:** update tests for to test with Crowdstrike ([#6470](https://github.com/cloudflare/terraform-provider-cloudflare/issues/6470)) ([e360d6f](https://github.com/cloudflare/terraform-provider-cloudflare/commit/e360d6f414799181c76c9eb7b6aaeb51239a2632))
* **zone:** update migration tests ([#6468](https://github.com/cloudflare/terraform-provider-cloudflare/issues/6468)) ([8ff53df](https://github.com/cloudflare/terraform-provider-cloudflare/commit/8ff53dfe672acc0dc3b9538a613de77e96517e0e))
## 5.14.0 (2025-12-05)
Full Changelog: [v5.13.0...v5.14.0](https://github.com/cloudflare/terraform-provider-cloudflare/compare/v5.13.0...v5.14.0)
### Features
* add v4-&gt;v5 migration tests for pages_project and adjust schema ([#6506](https://github.com/cloudflare/terraform-provider-cloudflare/issues/6506)) ([6de0179](https://github.com/cloudflare/terraform-provider-cloudflare/commit/6de0179a033543e4e63053b9db68185f4e4f2c78))
* chore(api_shield_discovery_operation): Deprecate api_shield_discovery_operation ([7dc0a63](https://github.com/cloudflare/terraform-provider-cloudflare/commit/7dc0a63e0fa3de74d8877788ff787294cb603c07))
* feat(bot_management): add bot management feedback endpoints to stainless config (prod) ([f5112e1](https://github.com/cloudflare/terraform-provider-cloudflare/commit/f5112e1e4d4fe53b9e0ec96aa27f69fb7706099b))
* feat(r2_data_catalog): Configure SDKs/Terraform to use R2 Data Catalog routes ([5beb50b](https://github.com/cloudflare/terraform-provider-cloudflare/commit/5beb50b30d7d012afae92f8f652e005955d4e430))
* feat(radar): Add origins endpoints to public api docs ([ee51e5f](https://github.com/cloudflare/terraform-provider-cloudflare/commit/ee51e5f19c5f1f3cd4d2c07acdcf0f368c635c4d))
* improve and standardize sweepers ([#6501](https://github.com/cloudflare/terraform-provider-cloudflare/issues/6501)) ([03fb2d2](https://github.com/cloudflare/terraform-provider-cloudflare/commit/03fb2d2f4999ca24b9597093f25fd1dbc0f671b7))
### Bug Fixes
* **account_members:** making member policies a set ([#6488](https://github.com/cloudflare/terraform-provider-cloudflare/issues/6488)) ([f3ecaa5](https://github.com/cloudflare/terraform-provider-cloudflare/commit/f3ecaa5938486865698b3956848a8e5f0f6c9054))
* **pages_project:** non empty refresh plans ([#6515](https://github.com/cloudflare/terraform-provider-cloudflare/issues/6515)) ([bc526ff](https://github.com/cloudflare/terraform-provider-cloudflare/commit/bc526ffcf5091195cc143cbf774013b84728296c))
* **pages_project:** use correct field name in test sweeper ([6dc0e53](https://github.com/cloudflare/terraform-provider-cloudflare/commit/6dc0e538754b84e8e31d0c1b7bd8c0e291161811))
* **r2** sweeper ([#6512](https://github.com/cloudflare/terraform-provider-cloudflare/issues/6512)) ([fec953c](https://github.com/cloudflare/terraform-provider-cloudflare/commit/fec953c98e8764e5b1ed3dc1906d02206718928e))
* **tests:** resolve SDK v6 migration test failures ([#6507](https://github.com/cloudflare/terraform-provider-cloudflare/issues/6507)) ([bad9716](https://github.com/cloudflare/terraform-provider-cloudflare/commit/bad971609bfb7ddc8d78de6935b747f350f1ae55))
* **utils:** test assertions ([4c3e2db](https://github.com/cloudflare/terraform-provider-cloudflare/commit/4c3e2db3ec31638d423d0ecc971e5c5ea54298ec))
* **workers_kv:** ignore value import state verify ([#6521](https://github.com/cloudflare/terraform-provider-cloudflare/issues/6521)) ([c3e3f89](https://github.com/cloudflare/terraform-provider-cloudflare/commit/c3e3f892bcd0d1426eb398688b1f5f8c84144b57))
* **workers_script:** No longer treating the migrations attribute as WriteOnly ([#6489](https://github.com/cloudflare/terraform-provider-cloudflare/issues/6489)) ([dc60e38](https://github.com/cloudflare/terraform-provider-cloudflare/commit/dc60e3883002db7eb9036265aa4000a08a1eb2b6))
* **workers_script:** resource drift when worker has unmanaged secret ([#6504](https://github.com/cloudflare/terraform-provider-cloudflare/issues/6504)) ([505c0fe](https://github.com/cloudflare/terraform-provider-cloudflare/commit/505c0fe78b4f096ed3547f7b564ea5788a64a644))
* **zero_trust_device_posture_rule:** preserve input.version and other fields ([#6500](https://github.com/cloudflare/terraform-provider-cloudflare/issues/6500)) ([4c4e54b](https://github.com/cloudflare/terraform-provider-cloudflare/commit/4c4e54bdfdfa2c6ce584322cd2ae8562269b4a98))
* **zero_trust_device_posture_rule:** preserve input.version and other fields ([#6503](https://github.com/cloudflare/terraform-provider-cloudflare/issues/6503)) ([d45be9a](https://github.com/cloudflare/terraform-provider-cloudflare/commit/d45be9a3b6276bee2c9f4413e141db6d5d1fa596))
* **zero_trust_dlp_custom_profile:** add sweepers for dlp_custom_profile ([cbcb325](https://github.com/cloudflare/terraform-provider-cloudflare/commit/cbcb325271e91d6c3a0bb832eb0c347198d9ce6c))
* **zone_subscription|account_subscription:** add partners_ent as valid enum for rate_plan.id ([#6505](https://github.com/cloudflare/terraform-provider-cloudflare/issues/6505)) ([2a70fb4](https://github.com/cloudflare/terraform-provider-cloudflare/commit/2a70fb49ccc28e5309f7096d1ebc34866c2f07f3))
* **zone:** datasource model schema parity ([#6487](https://github.com/cloudflare/terraform-provider-cloudflare/issues/6487)) ([861c68f](https://github.com/cloudflare/terraform-provider-cloudflare/commit/861c68fcb37627371673e60dfcbc7bf09638e28e))
* update import signature to accept account_id/subscription_id in order to import account subscription ([#6510](https://github.com/cloudflare/terraform-provider-cloudflare/issues/6510)) ([c2db582](https://github.com/cloudflare/terraform-provider-cloudflare/commit/c2db582ed27a6e8ac3de6461dba011496b687d05))
* json decoder and tests ([#6516](https://github.com/cloudflare/terraform-provider-cloudflare/issues/6516)) ([4c3e2db](https://github.com/cloudflare/terraform-provider-cloudflare/commit/4c3e2db3ec31638d423d0ecc971e5c5ea54298ec))
### Chores
* **api_shield_discovery_operation:** Deprecate api_shield_discovery_operation ([7dc0a63](https://github.com/cloudflare/terraform-provider-cloudflare/commit/7dc0a63e0fa3de74d8877788ff787294cb603c07))
* **account_member:** dont run acceptance with env variable ([4c3e2db](https://github.com/cloudflare/terraform-provider-cloudflare/commit/4c3e2db3ec31638d423d0ecc971e5c5ea54298ec))
* **account_member:** fix check for env var ([#6517](https://github.com/cloudflare/terraform-provider-cloudflare/issues/6517)) ([07e9aa5](https://github.com/cloudflare/terraform-provider-cloudflare/commit/07e9aa5ef6327499731b17ac334f2f9d4cf3f4bf))
* **account_member:** skip until user is dsr enabled ([#6522](https://github.com/cloudflare/terraform-provider-cloudflare/issues/6522)) ([dd7c2fe](https://github.com/cloudflare/terraform-provider-cloudflare/commit/dd7c2fea55e1dc10953b57c2d3792b2e97a8e68e))
* **account_tokens:** adding a simple CRUD test ([#6484](https://github.com/cloudflare/terraform-provider-cloudflare/issues/6484)) ([6869538](https://github.com/cloudflare/terraform-provider-cloudflare/commit/68695382141a2b097c051b38a32fabf5368c2ad9))
* **zero_trust_dlp_entry:** add `profiles` attribute to DLP entry resources ([71fc050](https://github.com/cloudflare/terraform-provider-cloudflare/commit/71fc0502fe85faaabd599348b8f46930fa0bd15f))
* **r2_bucket_sippy:** add S3-compatible provider support with `bucket_url` attribute ([71fc050](https://github.com/cloudflare/terraform-provider-cloudflare/commit/71fc0502fe85faaabd599348b8f46930fa0bd15f))
* **pages_project:** add `source` config block for granular source control settings ([68d017a](https://github.com/cloudflare/terraform-provider-cloudflare/commit/68d017a1dd2379d7f4c22b83b9ee31e146971b54))
* **certificate_pack:** add `certificates` and `primary_certificate` attributes ([68d017a](https://github.com/cloudflare/terraform-provider-cloudflare/commit/68d017a1dd2379d7f4c22b83b9ee31e146971b54))
* **zero_trust_device_posture_rule:** add `antivirus` posture rule type ([68d017a](https://github.com/cloudflare/terraform-provider-cloudflare/commit/68d017a1dd2379d7f4c22b83b9ee31e146971b54))
* **zero_trust_device_settings:** add external emergency signal configuration attributes ([68d017a](https://github.com/cloudflare/terraform-provider-cloudflare/commit/68d017a1dd2379d7f4c22b83b9ee31e146971b54))
* **cloudflare_api_shield_operation:** add acceptance tests ([#6491](https://github.com/cloudflare/terraform-provider-cloudflare/issues/6491)) ([37e1fdf](https://github.com/cloudflare/terraform-provider-cloudflare/commit/37e1fdf9d72b9d853e4ba7b751f2680db5abb9f6))
* **logpush_job:** add v4 to v5 migration tests ([#6483](https://github.com/cloudflare/terraform-provider-cloudflare/issues/6483)) ([2e4b8a0](https://github.com/cloudflare/terraform-provider-cloudflare/commit/2e4b8a090ca9741cd6f7e5861305f82ac582b63d))
* **tests:** cloud connector rules parity tests and add connectivity_directory_service tests ([#6513](https://github.com/cloudflare/terraform-provider-cloudflare/issues/6513)) ([5341c82](https://github.com/cloudflare/terraform-provider-cloudflare/commit/5341c824679002c0168d3ce8696022aec30ff33e))
* **zero_trust_device_default_profile_local_domain_fallback:** add tests ([#6464](https://github.com/cloudflare/terraform-provider-cloudflare/issues/6464)) ([365cb71](https://github.com/cloudflare/terraform-provider-cloudflare/commit/365cb71b906fca75c2be9fedf38f5269eaa0f4dd))
* **zero_trust_device_default|custom_profile:** acceptance test coverage ([#6511](https://github.com/cloudflare/terraform-provider-cloudflare/issues/6511)) ([8e4ec1a](https://github.com/cloudflare/terraform-provider-cloudflare/commit/8e4ec1a9e376ac294707db9fc320a8855be0ba89))
* **zero_trust_device_managed_networks:** add tests ([#6463](https://github.com/cloudflare/terraform-provider-cloudflare/issues/6463)) ([e9b6783](https://github.com/cloudflare/terraform-provider-cloudflare/commit/e9b67835cbf10fb76282b2526f732f13aa13ca06))
* **zero_trust_device_posture_integration:** update tests for to test with Crowdstrike ([#6470](https://github.com/cloudflare/terraform-provider-cloudflare/issues/6470)) ([e360d6f](https://github.com/cloudflare/terraform-provider-cloudflare/commit/e360d6f414799181c76c9eb7b6aaeb51239a2632))
* **zone:** update migration tests ([#6468](https://github.com/cloudflare/terraform-provider-cloudflare/issues/6468)) ([8ff53df](https://github.com/cloudflare/terraform-provider-cloudflare/commit/8ff53dfe672acc0dc3b9538a613de77e96517e0e))
* **internal:** update cloudflare-go SDK dependency ([923ea1d](https://github.com/cloudflare/terraform-provider-cloudflare/commit/923ea1db2a8accfd846990947a49f44a1e209ea4))
* **internal:** update cloudflare-go SDK dependency ([a110cbe](https://github.com/cloudflare/terraform-provider-cloudflare/commit/a110cbe76756173711fbc50c6c13c143d53ae625))
* **internal:** update cloudflare-go SDK dependency ([7b36c06](https://github.com/cloudflare/terraform-provider-cloudflare/commit/7b36c06f10f0fee20c5935b20f6817f7f91d2442))
* **internal:** improve JSON decoder to handle multiple fields with same name ([c789f91](https://github.com/cloudflare/terraform-provider-cloudflare/commit/c789f91d6ba5c773ad152945114ab6b020949616))
* **internal:** update cloudflare-go SDK dependency ([a91faa6](https://github.com/cloudflare/terraform-provider-cloudflare/commit/a91faa61eca4c2cf4ea23aff7f14667e9b042de7))
* **internal:** update cloudflare-go SDK dependency ([dfa745a](https://github.com/cloudflare/terraform-provider-cloudflare/commit/dfa745abb71b94428ff1140f592a48cb7eca8969))
* **internal:** add example files for email security resources ([fb3ef1b](https://github.com/cloudflare/terraform-provider-cloudflare/commit/fb3ef1b5b7fe827753ba82f4f08381bf951f5dbf))
* **internal:** update cloudflare-go SDK dependency ([504e8b6](https://github.com/cloudflare/terraform-provider-cloudflare/commit/504e8b61e19091d8f2e66f37889311256cf6590b))
* **internal:** update cloudflare-go SDK dependency ([550d77c](https://github.com/cloudflare/terraform-provider-cloudflare/commit/550d77c15980feac28e1df2b6fc52473d81f57e6))
### Deprecations
* **api_shield_discovery_operation**
## 5.13.0 (2025-11-21)
Full Changelog: [v5.12.0...v5.13.0](https://github.com/cloudflare/terraform-provider-cloudflare/compare/v5.12.0...v5.13.0)

View file

@ -20,7 +20,7 @@ terraform {
required_providers {
cloudflare = {
source = "cloudflare/cloudflare"
version = "~> 5.13.0"
version = "~> 5.14.0"
}
}
}

View file

@ -45,7 +45,7 @@ Read-Only:
- `currency` (String) The currency applied to the rate plan subscription.
- `externally_managed` (Boolean) Whether this rate plan is managed externally from Cloudflare.
- `id` (String) The ID of the rate plan.
Available values: "free", "lite", "pro", "pro_plus", "business", "enterprise", "partners_free", "partners_pro", "partners_business", "partners_enterprise".
Available values: "free", "lite", "pro", "pro_plus", "business", "enterprise", "partners_free", "partners_pro", "partners_business", "partners_ent".
- `is_contract` (Boolean) Whether a rate plan is enterprise-based (or newly adopted term contract).
- `public_name` (String) The full name of the rate plan.
- `scope` (String) The scope that this rate plan applies to.

View file

@ -23,11 +23,86 @@ data "cloudflare_certificate_pack" "example_certificate_pack" {
### Required
- `certificate_pack_id` (String) Identifier.
- `zone_id` (String) Identifier.
### Optional
- `certificate_pack_id` (String) Identifier.
- `filter` (Attributes) (see [below for nested schema](#nestedatt--filter))
### Read-Only
- `certificate_authority` (String) Certificate Authority selected for the order. For information on any certificate authority specific details or restrictions [see this page for more details.](https://developers.cloudflare.com/ssl/reference/certificate-authorities)
Available values: "google", "lets_encrypt", "ssl_com".
- `certificates` (Attributes List) Array of certificates in this pack. (see [below for nested schema](#nestedatt--certificates))
- `cloudflare_branding` (Boolean) Whether or not to add Cloudflare Branding for the order. This will add a subdomain of sni.cloudflaressl.com as the Common Name if set to true.
- `hosts` (List of String) Comma separated list of valid host names for the certificate packs. Must contain the zone apex, may not contain more than 50 hosts, and may not be empty.
- `id` (String) Identifier.
- `primary_certificate` (String) Identifier of the primary certificate in a pack.
- `status` (String) Status of certificate pack.
Available values: "initializing", "pending_validation", "deleted", "pending_issuance", "pending_deployment", "pending_deletion", "pending_expiration", "expired", "active", "initializing_timed_out", "validation_timed_out", "issuance_timed_out", "deployment_timed_out", "deletion_timed_out", "pending_cleanup", "staging_deployment", "staging_active", "deactivating", "inactive", "backup_issued", "holding_deployment".
- `type` (String) Type of certificate pack.
Available values: "mh_custom", "managed_hostname", "sni_custom", "universal", "advanced", "total_tls", "keyless", "legacy_custom".
- `validation_errors` (Attributes List) Domain validation errors that have been received by the certificate authority (CA). (see [below for nested schema](#nestedatt--validation_errors))
- `validation_method` (String) Validation Method selected for the order.
Available values: "txt", "http", "email".
- `validation_records` (Attributes List) Certificates' validation records. (see [below for nested schema](#nestedatt--validation_records))
- `validity_days` (Number) Validity Days selected for the order.
Available values: 14, 30, 90, 365.
<a id="nestedatt--filter"></a>
### Nested Schema for `filter`
Optional:
- `status` (String) Include Certificate Packs of all statuses, not just active ones.
Available values: "all".
<a id="nestedatt--certificates"></a>
### Nested Schema for `certificates`
Read-Only:
- `bundle_method` (String) Certificate bundle method.
- `expires_on` (String) When the certificate from the authority expires.
- `geo_restrictions` (Attributes) Specify the region where your private key can be held locally. (see [below for nested schema](#nestedatt--certificates--geo_restrictions))
- `hosts` (List of String) Hostnames covered by this certificate.
- `id` (String) Certificate identifier.
- `issuer` (String) The certificate authority that issued the certificate.
- `modified_on` (String) When the certificate was last modified.
- `priority` (Number) The order/priority in which the certificate will be used.
- `signature` (String) The type of hash used for the certificate.
- `status` (String) Certificate status.
- `uploaded_on` (String) When the certificate was uploaded to Cloudflare.
- `zone_id` (String) Identifier.
<a id="nestedatt--certificates--geo_restrictions"></a>
### Nested Schema for `certificates.geo_restrictions`
Read-Only:
- `label` (String) Available values: "us", "eu", "highest_security".
<a id="nestedatt--validation_errors"></a>
### Nested Schema for `validation_errors`
Read-Only:
- `message` (String) A domain validation error.
<a id="nestedatt--validation_records"></a>
### Nested Schema for `validation_records`
Read-Only:
- `emails` (List of String) The set of email addresses that the certificate authority (CA) will use to complete domain validation.
- `http_body` (String) The content that the certificate authority (CA) will expect to find at the http_url during the domain validation.
- `http_url` (String) The url that will be checked during domain validation.
- `txt_name` (String) The hostname that the certificate authority (CA) will check for a TXT record during domain validation .
- `txt_value` (String) The TXT record that the certificate authority (CA) will check during domain validation.

View file

@ -38,4 +38,70 @@ Available values: "all".
<a id="nestedatt--result"></a>
### Nested Schema for `result`
Read-Only:
- `certificate_authority` (String) Certificate Authority selected for the order. For information on any certificate authority specific details or restrictions [see this page for more details.](https://developers.cloudflare.com/ssl/reference/certificate-authorities)
Available values: "google", "lets_encrypt", "ssl_com".
- `certificates` (Attributes List) Array of certificates in this pack. (see [below for nested schema](#nestedatt--result--certificates))
- `cloudflare_branding` (Boolean) Whether or not to add Cloudflare Branding for the order. This will add a subdomain of sni.cloudflaressl.com as the Common Name if set to true.
- `hosts` (List of String) Comma separated list of valid host names for the certificate packs. Must contain the zone apex, may not contain more than 50 hosts, and may not be empty.
- `id` (String) Identifier.
- `primary_certificate` (String) Identifier of the primary certificate in a pack.
- `status` (String) Status of certificate pack.
Available values: "initializing", "pending_validation", "deleted", "pending_issuance", "pending_deployment", "pending_deletion", "pending_expiration", "expired", "active", "initializing_timed_out", "validation_timed_out", "issuance_timed_out", "deployment_timed_out", "deletion_timed_out", "pending_cleanup", "staging_deployment", "staging_active", "deactivating", "inactive", "backup_issued", "holding_deployment".
- `type` (String) Type of certificate pack.
Available values: "mh_custom", "managed_hostname", "sni_custom", "universal", "advanced", "total_tls", "keyless", "legacy_custom".
- `validation_errors` (Attributes List) Domain validation errors that have been received by the certificate authority (CA). (see [below for nested schema](#nestedatt--result--validation_errors))
- `validation_method` (String) Validation Method selected for the order.
Available values: "txt", "http", "email".
- `validation_records` (Attributes List) Certificates' validation records. (see [below for nested schema](#nestedatt--result--validation_records))
- `validity_days` (Number) Validity Days selected for the order.
Available values: 14, 30, 90, 365.
<a id="nestedatt--result--certificates"></a>
### Nested Schema for `result.certificates`
Read-Only:
- `bundle_method` (String) Certificate bundle method.
- `expires_on` (String) When the certificate from the authority expires.
- `geo_restrictions` (Attributes) Specify the region where your private key can be held locally. (see [below for nested schema](#nestedatt--result--certificates--geo_restrictions))
- `hosts` (List of String) Hostnames covered by this certificate.
- `id` (String) Certificate identifier.
- `issuer` (String) The certificate authority that issued the certificate.
- `modified_on` (String) When the certificate was last modified.
- `priority` (Number) The order/priority in which the certificate will be used.
- `signature` (String) The type of hash used for the certificate.
- `status` (String) Certificate status.
- `uploaded_on` (String) When the certificate was uploaded to Cloudflare.
- `zone_id` (String) Identifier.
<a id="nestedatt--result--certificates--geo_restrictions"></a>
### Nested Schema for `result.certificates.geo_restrictions`
Read-Only:
- `label` (String) Available values: "us", "eu", "highest_security".
<a id="nestedatt--result--validation_errors"></a>
### Nested Schema for `result.validation_errors`
Read-Only:
- `message` (String) A domain validation error.
<a id="nestedatt--result--validation_records"></a>
### Nested Schema for `result.validation_records`
Read-Only:
- `emails` (List of String) The set of email addresses that the certificate authority (CA) will use to complete domain validation.
- `http_body` (String) The content that the certificate authority (CA) will expect to find at the http_url during the domain validation.
- `http_url` (String) The url that will be checked during domain validation.
- `txt_name` (String) The hostname that the certificate authority (CA) will check for a TXT record during domain validation .
- `txt_value` (String) The TXT record that the certificate authority (CA) will check during domain validation.

View file

@ -33,6 +33,7 @@ data "cloudflare_cloudforce_one_request_asset" "example_cloudforce_one_request_a
- `created` (String) Defines the asset creation time.
- `description` (String) Asset description.
- `file_type` (String) Asset file type.
- `id` (String) UUID.
- `name` (String) Asset name.

View file

@ -47,6 +47,7 @@ Available values: "asc", "desc".
- `author` (String) Author of message.
- `content` (String) Content of message.
- `created` (String) Defines the message creation time.
- `id` (String) UUID.
- `is_follow_on_request` (Boolean) Whether the message is a follow-on request.
- `updated` (String) Defines the message last updated time.

View file

@ -131,7 +131,7 @@ Available values: "A", "AAAA", "CNAME", "HTTPS", "TXT", "SRV", "LOC", "MX", "NS"
Read-Only:
- `count` (Number) Total number of results for the requested service.
- `email_routing_dns_count` (Number) Total number of results for the requested service.
- `page` (Number) Current page within paginated list of results.
- `per_page` (Number) Number of results per page of results.
- `total_count` (Number) Total results available without any search parameters.

View file

@ -24,8 +24,8 @@ data "cloudflare_pages_domain" "example_pages_domain" {
### Required
- `account_id` (String) Identifier
- `domain_name` (String) Name of the domain.
- `account_id` (String) Identifier.
- `domain_name` (String) The domain name.
- `project_name` (String) Name of the project.
### Read-Only
@ -33,8 +33,8 @@ data "cloudflare_pages_domain" "example_pages_domain" {
- `certificate_authority` (String) Available values: "google", "lets_encrypt".
- `created_on` (String)
- `domain_id` (String)
- `id` (String) Name of the domain.
- `name` (String)
- `id` (String) The domain name.
- `name` (String) The domain name.
- `status` (String) Available values: "initializing", "pending", "active", "deactivated", "blocked", "error".
- `validation_data` (Attributes) (see [below for nested schema](#nestedatt--validation_data))
- `verification_data` (Attributes) (see [below for nested schema](#nestedatt--verification_data))

View file

@ -23,7 +23,7 @@ data "cloudflare_pages_domains" "example_pages_domains" {
### Required
- `account_id` (String) Identifier
- `account_id` (String) Identifier.
- `project_name` (String) Name of the project.
### Optional
@ -43,7 +43,7 @@ Read-Only:
- `created_on` (String)
- `domain_id` (String)
- `id` (String)
- `name` (String)
- `name` (String) The domain name.
- `status` (String) Available values: "initializing", "pending", "active", "deactivated", "blocked", "error".
- `validation_data` (Attributes) (see [below for nested schema](#nestedatt--result--validation_data))
- `verification_data` (Attributes) (see [below for nested schema](#nestedatt--result--verification_data))

View file

@ -23,7 +23,7 @@ data "cloudflare_pages_project" "example_pages_project" {
### Required
- `account_id` (String) Identifier
- `account_id` (String) Identifier.
- `project_name` (String) Name of the project.
### Read-Only
@ -41,7 +41,7 @@ data "cloudflare_pages_project" "example_pages_project" {
- `preview_script_name` (String) Name of the preview script.
- `production_branch` (String) Production branch of the project. Used to identify production deployments.
- `production_script_name` (String) Name of the production script.
- `source` (Attributes) (see [below for nested schema](#nestedatt--source))
- `source` (Attributes) Configs for the project source control. (see [below for nested schema](#nestedatt--source))
- `subdomain` (String) The Cloudflare subdomain associated with the project.
- `uses_functions` (Boolean) Whether the project uses functions.
@ -52,7 +52,7 @@ Read-Only:
- `build_caching` (Boolean) Enable build caching for the project.
- `build_command` (String) Command used to build project.
- `destination_dir` (String) Output directory of the build.
- `destination_dir` (String) Assets output directory of the build.
- `root_dir` (String) Directory to run the command.
- `web_analytics_tag` (String) The classifying tag for analytics.
- `web_analytics_token` (String, Sensitive) The auth token for analytics.
@ -77,9 +77,10 @@ Available values: "preview", "production".
- `project_id` (String) Id of the project.
- `project_name` (String) Name of the project.
- `short_id` (String) Short Id (8 character) of the deployment.
- `source` (Attributes) (see [below for nested schema](#nestedatt--canonical_deployment--source))
- `source` (Attributes) Configs for the project source control. (see [below for nested schema](#nestedatt--canonical_deployment--source))
- `stages` (Attributes List) List of past stages. (see [below for nested schema](#nestedatt--canonical_deployment--stages))
- `url` (String) The live URL to view this deployment.
- `uses_functions` (Boolean) Whether the deployment uses functions.
<a id="nestedatt--canonical_deployment--build_config"></a>
### Nested Schema for `canonical_deployment.build_config`
@ -88,7 +89,7 @@ Read-Only:
- `build_caching` (Boolean) Enable build caching for the project.
- `build_command` (String) Command used to build project.
- `destination_dir` (String) Output directory of the build.
- `destination_dir` (String) Assets output directory of the build.
- `root_dir` (String) Directory to run the command.
- `web_analytics_tag` (String) The classifying tag for analytics.
- `web_analytics_token` (String, Sensitive) The auth token for analytics.
@ -101,7 +102,7 @@ Read-Only:
- `metadata` (Attributes) Additional info about the trigger. (see [below for nested schema](#nestedatt--canonical_deployment--deployment_trigger--metadata))
- `type` (String) What caused the deployment.
Available values: "push", "ad_hoc".
Available values: "github:push", "ad_hoc", "deploy_hook".
<a id="nestedatt--canonical_deployment--deployment_trigger--metadata"></a>
### Nested Schema for `canonical_deployment.deployment_trigger.metadata`
@ -109,6 +110,7 @@ Available values: "push", "ad_hoc".
Read-Only:
- `branch` (String) Where the trigger happened.
- `commit_dirty` (Boolean) Whether the deployment trigger commit was dirty.
- `commit_hash` (String) Hash of the deployment trigger commit.
- `commit_message` (String) Message of the deployment trigger commit.
@ -153,6 +155,7 @@ Read-Only:
- `deployments_enabled` (Boolean, Deprecated) Whether to enable automatic deployments when pushing to the source repository.
When disabled, no deployments (production or preview) will be triggered automatically.
- `owner` (String) The owner of the repository.
- `owner_id` (String) The owner ID of the repository.
- `path_excludes` (List of String) A list of paths that should be excluded from triggering a preview deployment. Wildcard syntax (`*`) is supported.
- `path_includes` (List of String) A list of paths that should be watched to trigger a preview deployment. Wildcard syntax (`*`) is supported.
- `pr_comments_enabled` (Boolean) Whether to enable PR comments.
@ -162,6 +165,7 @@ When disabled, no deployments (production or preview) will be triggered automati
Available values: "all", "none", "custom".
- `production_branch` (String) The production branch of the repository.
- `production_deployments_enabled` (Boolean) Whether to trigger a production deployment on commits to the production branch.
- `repo_id` (String) The ID of the repository.
- `repo_name` (String) The name of the repository.
@ -508,9 +512,10 @@ Available values: "preview", "production".
- `project_id` (String) Id of the project.
- `project_name` (String) Name of the project.
- `short_id` (String) Short Id (8 character) of the deployment.
- `source` (Attributes) (see [below for nested schema](#nestedatt--latest_deployment--source))
- `source` (Attributes) Configs for the project source control. (see [below for nested schema](#nestedatt--latest_deployment--source))
- `stages` (Attributes List) List of past stages. (see [below for nested schema](#nestedatt--latest_deployment--stages))
- `url` (String) The live URL to view this deployment.
- `uses_functions` (Boolean) Whether the deployment uses functions.
<a id="nestedatt--latest_deployment--build_config"></a>
### Nested Schema for `latest_deployment.build_config`
@ -519,7 +524,7 @@ Read-Only:
- `build_caching` (Boolean) Enable build caching for the project.
- `build_command` (String) Command used to build project.
- `destination_dir` (String) Output directory of the build.
- `destination_dir` (String) Assets output directory of the build.
- `root_dir` (String) Directory to run the command.
- `web_analytics_tag` (String) The classifying tag for analytics.
- `web_analytics_token` (String, Sensitive) The auth token for analytics.
@ -532,7 +537,7 @@ Read-Only:
- `metadata` (Attributes) Additional info about the trigger. (see [below for nested schema](#nestedatt--latest_deployment--deployment_trigger--metadata))
- `type` (String) What caused the deployment.
Available values: "push", "ad_hoc".
Available values: "github:push", "ad_hoc", "deploy_hook".
<a id="nestedatt--latest_deployment--deployment_trigger--metadata"></a>
### Nested Schema for `latest_deployment.deployment_trigger.metadata`
@ -540,6 +545,7 @@ Available values: "push", "ad_hoc".
Read-Only:
- `branch` (String) Where the trigger happened.
- `commit_dirty` (Boolean) Whether the deployment trigger commit was dirty.
- `commit_hash` (String) Hash of the deployment trigger commit.
- `commit_message` (String) Message of the deployment trigger commit.
@ -584,6 +590,7 @@ Read-Only:
- `deployments_enabled` (Boolean, Deprecated) Whether to enable automatic deployments when pushing to the source repository.
When disabled, no deployments (production or preview) will be triggered automatically.
- `owner` (String) The owner of the repository.
- `owner_id` (String) The owner ID of the repository.
- `path_excludes` (List of String) A list of paths that should be excluded from triggering a preview deployment. Wildcard syntax (`*`) is supported.
- `path_includes` (List of String) A list of paths that should be watched to trigger a preview deployment. Wildcard syntax (`*`) is supported.
- `pr_comments_enabled` (Boolean) Whether to enable PR comments.
@ -593,6 +600,7 @@ When disabled, no deployments (production or preview) will be triggered automati
Available values: "all", "none", "custom".
- `production_branch` (String) The production branch of the repository.
- `production_deployments_enabled` (Boolean) Whether to trigger a production deployment on commits to the production branch.
- `repo_id` (String) The ID of the repository.
- `repo_name` (String) The name of the repository.
@ -628,6 +636,7 @@ Read-Only:
- `deployments_enabled` (Boolean, Deprecated) Whether to enable automatic deployments when pushing to the source repository.
When disabled, no deployments (production or preview) will be triggered automatically.
- `owner` (String) The owner of the repository.
- `owner_id` (String) The owner ID of the repository.
- `path_excludes` (List of String) A list of paths that should be excluded from triggering a preview deployment. Wildcard syntax (`*`) is supported.
- `path_includes` (List of String) A list of paths that should be watched to trigger a preview deployment. Wildcard syntax (`*`) is supported.
- `pr_comments_enabled` (Boolean) Whether to enable PR comments.
@ -637,6 +646,7 @@ When disabled, no deployments (production or preview) will be triggered automati
Available values: "all", "none", "custom".
- `production_branch` (String) The production branch of the repository.
- `production_deployments_enabled` (Boolean) Whether to trigger a production deployment on commits to the production branch.
- `repo_id` (String) The ID of the repository.
- `repo_name` (String) The name of the repository.

View file

@ -22,7 +22,7 @@ data "cloudflare_pages_projects" "example_pages_projects" {
### Required
- `account_id` (String) Identifier
- `account_id` (String) Identifier.
### Optional
@ -37,23 +37,22 @@ data "cloudflare_pages_projects" "example_pages_projects" {
Read-Only:
- `aliases` (List of String) A list of alias URLs pointing to this deployment.
- `build_config` (Attributes) Configs for the project build process. (see [below for nested schema](#nestedatt--result--build_config))
- `created_on` (String) When the deployment was created.
- `deployment_trigger` (Attributes) Info about what caused the deployment. (see [below for nested schema](#nestedatt--result--deployment_trigger))
- `env_vars` (Attributes Map) Environment variables used for builds and Pages Functions. (see [below for nested schema](#nestedatt--result--env_vars))
- `environment` (String) Type of deploy.
Available values: "preview", "production".
- `id` (String) Id of the deployment.
- `is_skipped` (Boolean) If the deployment has been skipped.
- `latest_stage` (Attributes) The status of the deployment. (see [below for nested schema](#nestedatt--result--latest_stage))
- `modified_on` (String) When the deployment was last modified.
- `project_id` (String) Id of the project.
- `project_name` (String) Name of the project.
- `short_id` (String) Short Id (8 character) of the deployment.
- `source` (Attributes) (see [below for nested schema](#nestedatt--result--source))
- `stages` (Attributes List) List of past stages. (see [below for nested schema](#nestedatt--result--stages))
- `url` (String) The live URL to view this deployment.
- `canonical_deployment` (Attributes) Most recent production deployment of the project. (see [below for nested schema](#nestedatt--result--canonical_deployment))
- `created_on` (String) When the project was created.
- `deployment_configs` (Attributes) Configs for deployments in a project. (see [below for nested schema](#nestedatt--result--deployment_configs))
- `domains` (List of String) A list of associated custom domains for the project.
- `framework` (String) Framework the project is using.
- `framework_version` (String) Version of the framework the project is using.
- `id` (String) ID of the project.
- `latest_deployment` (Attributes) Most recent deployment of the project. (see [below for nested schema](#nestedatt--result--latest_deployment))
- `name` (String) Name of the project.
- `preview_script_name` (String) Name of the preview script.
- `production_branch` (String) Production branch of the project. Used to identify production deployments.
- `production_script_name` (String) Name of the production script.
- `source` (Attributes) Configs for the project source control. (see [below for nested schema](#nestedatt--result--source))
- `subdomain` (String) The Cloudflare subdomain associated with the project.
- `uses_functions` (Boolean) Whether the project uses functions.
<a id="nestedatt--result--build_config"></a>
### Nested Schema for `result.build_config`
@ -62,34 +61,72 @@ Read-Only:
- `build_caching` (Boolean) Enable build caching for the project.
- `build_command` (String) Command used to build project.
- `destination_dir` (String) Output directory of the build.
- `destination_dir` (String) Assets output directory of the build.
- `root_dir` (String) Directory to run the command.
- `web_analytics_tag` (String) The classifying tag for analytics.
- `web_analytics_token` (String, Sensitive) The auth token for analytics.
<a id="nestedatt--result--deployment_trigger"></a>
### Nested Schema for `result.deployment_trigger`
<a id="nestedatt--result--canonical_deployment"></a>
### Nested Schema for `result.canonical_deployment`
Read-Only:
- `metadata` (Attributes) Additional info about the trigger. (see [below for nested schema](#nestedatt--result--deployment_trigger--metadata))
- `type` (String) What caused the deployment.
Available values: "push", "ad_hoc".
- `aliases` (List of String) A list of alias URLs pointing to this deployment.
- `build_config` (Attributes) Configs for the project build process. (see [below for nested schema](#nestedatt--result--canonical_deployment--build_config))
- `created_on` (String) When the deployment was created.
- `deployment_trigger` (Attributes) Info about what caused the deployment. (see [below for nested schema](#nestedatt--result--canonical_deployment--deployment_trigger))
- `env_vars` (Attributes Map) Environment variables used for builds and Pages Functions. (see [below for nested schema](#nestedatt--result--canonical_deployment--env_vars))
- `environment` (String) Type of deploy.
Available values: "preview", "production".
- `id` (String) Id of the deployment.
- `is_skipped` (Boolean) If the deployment has been skipped.
- `latest_stage` (Attributes) The status of the deployment. (see [below for nested schema](#nestedatt--result--canonical_deployment--latest_stage))
- `modified_on` (String) When the deployment was last modified.
- `project_id` (String) Id of the project.
- `project_name` (String) Name of the project.
- `short_id` (String) Short Id (8 character) of the deployment.
- `source` (Attributes) Configs for the project source control. (see [below for nested schema](#nestedatt--result--canonical_deployment--source))
- `stages` (Attributes List) List of past stages. (see [below for nested schema](#nestedatt--result--canonical_deployment--stages))
- `url` (String) The live URL to view this deployment.
- `uses_functions` (Boolean) Whether the deployment uses functions.
<a id="nestedatt--result--deployment_trigger--metadata"></a>
### Nested Schema for `result.deployment_trigger.metadata`
<a id="nestedatt--result--canonical_deployment--build_config"></a>
### Nested Schema for `result.canonical_deployment.build_config`
Read-Only:
- `build_caching` (Boolean) Enable build caching for the project.
- `build_command` (String) Command used to build project.
- `destination_dir` (String) Assets output directory of the build.
- `root_dir` (String) Directory to run the command.
- `web_analytics_tag` (String) The classifying tag for analytics.
- `web_analytics_token` (String, Sensitive) The auth token for analytics.
<a id="nestedatt--result--canonical_deployment--deployment_trigger"></a>
### Nested Schema for `result.canonical_deployment.deployment_trigger`
Read-Only:
- `metadata` (Attributes) Additional info about the trigger. (see [below for nested schema](#nestedatt--result--canonical_deployment--deployment_trigger--metadata))
- `type` (String) What caused the deployment.
Available values: "github:push", "ad_hoc", "deploy_hook".
<a id="nestedatt--result--canonical_deployment--deployment_trigger--metadata"></a>
### Nested Schema for `result.canonical_deployment.deployment_trigger.metadata`
Read-Only:
- `branch` (String) Where the trigger happened.
- `commit_dirty` (Boolean) Whether the deployment trigger commit was dirty.
- `commit_hash` (String) Hash of the deployment trigger commit.
- `commit_message` (String) Message of the deployment trigger commit.
<a id="nestedatt--result--env_vars"></a>
### Nested Schema for `result.env_vars`
<a id="nestedatt--result--canonical_deployment--env_vars"></a>
### Nested Schema for `result.canonical_deployment.env_vars`
Read-Only:
@ -97,8 +134,8 @@ Read-Only:
- `value` (String, Sensitive) Environment variable value.
<a id="nestedatt--result--latest_stage"></a>
### Nested Schema for `result.latest_stage`
<a id="nestedatt--result--canonical_deployment--latest_stage"></a>
### Nested Schema for `result.canonical_deployment.latest_stage`
Read-Only:
@ -110,6 +147,487 @@ Available values: "queued", "initialize", "clone_repo", "build", "deploy".
Available values: "success", "idle", "active", "failure", "canceled".
<a id="nestedatt--result--canonical_deployment--source"></a>
### Nested Schema for `result.canonical_deployment.source`
Read-Only:
- `config` (Attributes) (see [below for nested schema](#nestedatt--result--canonical_deployment--source--config))
- `type` (String) The source control management provider.
Available values: "github", "gitlab".
<a id="nestedatt--result--canonical_deployment--source--config"></a>
### Nested Schema for `result.canonical_deployment.source.config`
Read-Only:
- `deployments_enabled` (Boolean, Deprecated) Whether to enable automatic deployments when pushing to the source repository.
When disabled, no deployments (production or preview) will be triggered automatically.
- `owner` (String) The owner of the repository.
- `owner_id` (String) The owner ID of the repository.
- `path_excludes` (List of String) A list of paths that should be excluded from triggering a preview deployment. Wildcard syntax (`*`) is supported.
- `path_includes` (List of String) A list of paths that should be watched to trigger a preview deployment. Wildcard syntax (`*`) is supported.
- `pr_comments_enabled` (Boolean) Whether to enable PR comments.
- `preview_branch_excludes` (List of String) A list of branches that should not trigger a preview deployment. Wildcard syntax (`*`) is supported. Must be used with `preview_deployment_setting` set to `custom`.
- `preview_branch_includes` (List of String) A list of branches that should trigger a preview deployment. Wildcard syntax (`*`) is supported. Must be used with `preview_deployment_setting` set to `custom`.
- `preview_deployment_setting` (String) Controls whether commits to preview branches trigger a preview deployment.
Available values: "all", "none", "custom".
- `production_branch` (String) The production branch of the repository.
- `production_deployments_enabled` (Boolean) Whether to trigger a production deployment on commits to the production branch.
- `repo_id` (String) The ID of the repository.
- `repo_name` (String) The name of the repository.
<a id="nestedatt--result--canonical_deployment--stages"></a>
### Nested Schema for `result.canonical_deployment.stages`
Read-Only:
- `ended_on` (String) When the stage ended.
- `name` (String) The current build stage.
Available values: "queued", "initialize", "clone_repo", "build", "deploy".
- `started_on` (String) When the stage started.
- `status` (String) State of the current stage.
Available values: "success", "idle", "active", "failure", "canceled".
<a id="nestedatt--result--deployment_configs"></a>
### Nested Schema for `result.deployment_configs`
Read-Only:
- `preview` (Attributes) Configs for preview deploys. (see [below for nested schema](#nestedatt--result--deployment_configs--preview))
- `production` (Attributes) Configs for production deploys. (see [below for nested schema](#nestedatt--result--deployment_configs--production))
<a id="nestedatt--result--deployment_configs--preview"></a>
### Nested Schema for `result.deployment_configs.preview`
Read-Only:
- `ai_bindings` (Attributes Map) Constellation bindings used for Pages Functions. (see [below for nested schema](#nestedatt--result--deployment_configs--preview--ai_bindings))
- `always_use_latest_compatibility_date` (Boolean) Whether to always use the latest compatibility date for Pages Functions.
- `analytics_engine_datasets` (Attributes Map) Analytics Engine bindings used for Pages Functions. (see [below for nested schema](#nestedatt--result--deployment_configs--preview--analytics_engine_datasets))
- `browsers` (Attributes Map) Browser bindings used for Pages Functions. (see [below for nested schema](#nestedatt--result--deployment_configs--preview--browsers))
- `build_image_major_version` (Number) The major version of the build image to use for Pages Functions.
- `compatibility_date` (String) Compatibility date used for Pages Functions.
- `compatibility_flags` (List of String) Compatibility flags used for Pages Functions.
- `d1_databases` (Attributes Map) D1 databases used for Pages Functions. (see [below for nested schema](#nestedatt--result--deployment_configs--preview--d1_databases))
- `durable_object_namespaces` (Attributes Map) Durable Object namespaces used for Pages Functions. (see [below for nested schema](#nestedatt--result--deployment_configs--preview--durable_object_namespaces))
- `env_vars` (Attributes Map) Environment variables used for builds and Pages Functions. (see [below for nested schema](#nestedatt--result--deployment_configs--preview--env_vars))
- `fail_open` (Boolean) Whether to fail open when the deployment config cannot be applied.
- `hyperdrive_bindings` (Attributes Map) Hyperdrive bindings used for Pages Functions. (see [below for nested schema](#nestedatt--result--deployment_configs--preview--hyperdrive_bindings))
- `kv_namespaces` (Attributes Map) KV namespaces used for Pages Functions. (see [below for nested schema](#nestedatt--result--deployment_configs--preview--kv_namespaces))
- `limits` (Attributes) Limits for Pages Functions. (see [below for nested schema](#nestedatt--result--deployment_configs--preview--limits))
- `mtls_certificates` (Attributes Map) mTLS bindings used for Pages Functions. (see [below for nested schema](#nestedatt--result--deployment_configs--preview--mtls_certificates))
- `placement` (Attributes) Placement setting used for Pages Functions. (see [below for nested schema](#nestedatt--result--deployment_configs--preview--placement))
- `queue_producers` (Attributes Map) Queue Producer bindings used for Pages Functions. (see [below for nested schema](#nestedatt--result--deployment_configs--preview--queue_producers))
- `r2_buckets` (Attributes Map) R2 buckets used for Pages Functions. (see [below for nested schema](#nestedatt--result--deployment_configs--preview--r2_buckets))
- `services` (Attributes Map) Services used for Pages Functions. (see [below for nested schema](#nestedatt--result--deployment_configs--preview--services))
- `usage_model` (String, Deprecated) The usage model for Pages Functions.
Available values: "standard", "bundled", "unbound".
- `vectorize_bindings` (Attributes Map) Vectorize bindings used for Pages Functions. (see [below for nested schema](#nestedatt--result--deployment_configs--preview--vectorize_bindings))
- `wrangler_config_hash` (String) Hash of the Wrangler configuration used for the deployment.
<a id="nestedatt--result--deployment_configs--preview--ai_bindings"></a>
### Nested Schema for `result.deployment_configs.preview.ai_bindings`
Read-Only:
- `project_id` (String)
<a id="nestedatt--result--deployment_configs--preview--analytics_engine_datasets"></a>
### Nested Schema for `result.deployment_configs.preview.analytics_engine_datasets`
Read-Only:
- `dataset` (String) Name of the dataset.
<a id="nestedatt--result--deployment_configs--preview--browsers"></a>
### Nested Schema for `result.deployment_configs.preview.browsers`
<a id="nestedatt--result--deployment_configs--preview--d1_databases"></a>
### Nested Schema for `result.deployment_configs.preview.d1_databases`
Read-Only:
- `id` (String) UUID of the D1 database.
<a id="nestedatt--result--deployment_configs--preview--durable_object_namespaces"></a>
### Nested Schema for `result.deployment_configs.preview.durable_object_namespaces`
Read-Only:
- `namespace_id` (String) ID of the Durable Object namespace.
<a id="nestedatt--result--deployment_configs--preview--env_vars"></a>
### Nested Schema for `result.deployment_configs.preview.env_vars`
Read-Only:
- `type` (String) Available values: "plain_text", "secret_text".
- `value` (String, Sensitive) Environment variable value.
<a id="nestedatt--result--deployment_configs--preview--hyperdrive_bindings"></a>
### Nested Schema for `result.deployment_configs.preview.hyperdrive_bindings`
Read-Only:
- `id` (String)
<a id="nestedatt--result--deployment_configs--preview--kv_namespaces"></a>
### Nested Schema for `result.deployment_configs.preview.kv_namespaces`
Read-Only:
- `namespace_id` (String) ID of the KV namespace.
<a id="nestedatt--result--deployment_configs--preview--limits"></a>
### Nested Schema for `result.deployment_configs.preview.limits`
Read-Only:
- `cpu_ms` (Number) CPU time limit in milliseconds.
<a id="nestedatt--result--deployment_configs--preview--mtls_certificates"></a>
### Nested Schema for `result.deployment_configs.preview.mtls_certificates`
Read-Only:
- `certificate_id` (String)
<a id="nestedatt--result--deployment_configs--preview--placement"></a>
### Nested Schema for `result.deployment_configs.preview.placement`
Read-Only:
- `mode` (String) Placement mode.
<a id="nestedatt--result--deployment_configs--preview--queue_producers"></a>
### Nested Schema for `result.deployment_configs.preview.queue_producers`
Read-Only:
- `name` (String) Name of the Queue.
<a id="nestedatt--result--deployment_configs--preview--r2_buckets"></a>
### Nested Schema for `result.deployment_configs.preview.r2_buckets`
Read-Only:
- `jurisdiction` (String) Jurisdiction of the R2 bucket.
- `name` (String) Name of the R2 bucket.
<a id="nestedatt--result--deployment_configs--preview--services"></a>
### Nested Schema for `result.deployment_configs.preview.services`
Read-Only:
- `entrypoint` (String) The entrypoint to bind to.
- `environment` (String) The Service environment.
- `service` (String) The Service name.
<a id="nestedatt--result--deployment_configs--preview--vectorize_bindings"></a>
### Nested Schema for `result.deployment_configs.preview.vectorize_bindings`
Read-Only:
- `index_name` (String)
<a id="nestedatt--result--deployment_configs--production"></a>
### Nested Schema for `result.deployment_configs.production`
Read-Only:
- `ai_bindings` (Attributes Map) Constellation bindings used for Pages Functions. (see [below for nested schema](#nestedatt--result--deployment_configs--production--ai_bindings))
- `always_use_latest_compatibility_date` (Boolean) Whether to always use the latest compatibility date for Pages Functions.
- `analytics_engine_datasets` (Attributes Map) Analytics Engine bindings used for Pages Functions. (see [below for nested schema](#nestedatt--result--deployment_configs--production--analytics_engine_datasets))
- `browsers` (Attributes Map) Browser bindings used for Pages Functions. (see [below for nested schema](#nestedatt--result--deployment_configs--production--browsers))
- `build_image_major_version` (Number) The major version of the build image to use for Pages Functions.
- `compatibility_date` (String) Compatibility date used for Pages Functions.
- `compatibility_flags` (List of String) Compatibility flags used for Pages Functions.
- `d1_databases` (Attributes Map) D1 databases used for Pages Functions. (see [below for nested schema](#nestedatt--result--deployment_configs--production--d1_databases))
- `durable_object_namespaces` (Attributes Map) Durable Object namespaces used for Pages Functions. (see [below for nested schema](#nestedatt--result--deployment_configs--production--durable_object_namespaces))
- `env_vars` (Attributes Map) Environment variables used for builds and Pages Functions. (see [below for nested schema](#nestedatt--result--deployment_configs--production--env_vars))
- `fail_open` (Boolean) Whether to fail open when the deployment config cannot be applied.
- `hyperdrive_bindings` (Attributes Map) Hyperdrive bindings used for Pages Functions. (see [below for nested schema](#nestedatt--result--deployment_configs--production--hyperdrive_bindings))
- `kv_namespaces` (Attributes Map) KV namespaces used for Pages Functions. (see [below for nested schema](#nestedatt--result--deployment_configs--production--kv_namespaces))
- `limits` (Attributes) Limits for Pages Functions. (see [below for nested schema](#nestedatt--result--deployment_configs--production--limits))
- `mtls_certificates` (Attributes Map) mTLS bindings used for Pages Functions. (see [below for nested schema](#nestedatt--result--deployment_configs--production--mtls_certificates))
- `placement` (Attributes) Placement setting used for Pages Functions. (see [below for nested schema](#nestedatt--result--deployment_configs--production--placement))
- `queue_producers` (Attributes Map) Queue Producer bindings used for Pages Functions. (see [below for nested schema](#nestedatt--result--deployment_configs--production--queue_producers))
- `r2_buckets` (Attributes Map) R2 buckets used for Pages Functions. (see [below for nested schema](#nestedatt--result--deployment_configs--production--r2_buckets))
- `services` (Attributes Map) Services used for Pages Functions. (see [below for nested schema](#nestedatt--result--deployment_configs--production--services))
- `usage_model` (String, Deprecated) The usage model for Pages Functions.
Available values: "standard", "bundled", "unbound".
- `vectorize_bindings` (Attributes Map) Vectorize bindings used for Pages Functions. (see [below for nested schema](#nestedatt--result--deployment_configs--production--vectorize_bindings))
- `wrangler_config_hash` (String) Hash of the Wrangler configuration used for the deployment.
<a id="nestedatt--result--deployment_configs--production--ai_bindings"></a>
### Nested Schema for `result.deployment_configs.production.ai_bindings`
Read-Only:
- `project_id` (String)
<a id="nestedatt--result--deployment_configs--production--analytics_engine_datasets"></a>
### Nested Schema for `result.deployment_configs.production.analytics_engine_datasets`
Read-Only:
- `dataset` (String) Name of the dataset.
<a id="nestedatt--result--deployment_configs--production--browsers"></a>
### Nested Schema for `result.deployment_configs.production.browsers`
<a id="nestedatt--result--deployment_configs--production--d1_databases"></a>
### Nested Schema for `result.deployment_configs.production.d1_databases`
Read-Only:
- `id` (String) UUID of the D1 database.
<a id="nestedatt--result--deployment_configs--production--durable_object_namespaces"></a>
### Nested Schema for `result.deployment_configs.production.durable_object_namespaces`
Read-Only:
- `namespace_id` (String) ID of the Durable Object namespace.
<a id="nestedatt--result--deployment_configs--production--env_vars"></a>
### Nested Schema for `result.deployment_configs.production.env_vars`
Read-Only:
- `type` (String) Available values: "plain_text", "secret_text".
- `value` (String, Sensitive) Environment variable value.
<a id="nestedatt--result--deployment_configs--production--hyperdrive_bindings"></a>
### Nested Schema for `result.deployment_configs.production.hyperdrive_bindings`
Read-Only:
- `id` (String)
<a id="nestedatt--result--deployment_configs--production--kv_namespaces"></a>
### Nested Schema for `result.deployment_configs.production.kv_namespaces`
Read-Only:
- `namespace_id` (String) ID of the KV namespace.
<a id="nestedatt--result--deployment_configs--production--limits"></a>
### Nested Schema for `result.deployment_configs.production.limits`
Read-Only:
- `cpu_ms` (Number) CPU time limit in milliseconds.
<a id="nestedatt--result--deployment_configs--production--mtls_certificates"></a>
### Nested Schema for `result.deployment_configs.production.mtls_certificates`
Read-Only:
- `certificate_id` (String)
<a id="nestedatt--result--deployment_configs--production--placement"></a>
### Nested Schema for `result.deployment_configs.production.placement`
Read-Only:
- `mode` (String) Placement mode.
<a id="nestedatt--result--deployment_configs--production--queue_producers"></a>
### Nested Schema for `result.deployment_configs.production.queue_producers`
Read-Only:
- `name` (String) Name of the Queue.
<a id="nestedatt--result--deployment_configs--production--r2_buckets"></a>
### Nested Schema for `result.deployment_configs.production.r2_buckets`
Read-Only:
- `jurisdiction` (String) Jurisdiction of the R2 bucket.
- `name` (String) Name of the R2 bucket.
<a id="nestedatt--result--deployment_configs--production--services"></a>
### Nested Schema for `result.deployment_configs.production.services`
Read-Only:
- `entrypoint` (String) The entrypoint to bind to.
- `environment` (String) The Service environment.
- `service` (String) The Service name.
<a id="nestedatt--result--deployment_configs--production--vectorize_bindings"></a>
### Nested Schema for `result.deployment_configs.production.vectorize_bindings`
Read-Only:
- `index_name` (String)
<a id="nestedatt--result--latest_deployment"></a>
### Nested Schema for `result.latest_deployment`
Read-Only:
- `aliases` (List of String) A list of alias URLs pointing to this deployment.
- `build_config` (Attributes) Configs for the project build process. (see [below for nested schema](#nestedatt--result--latest_deployment--build_config))
- `created_on` (String) When the deployment was created.
- `deployment_trigger` (Attributes) Info about what caused the deployment. (see [below for nested schema](#nestedatt--result--latest_deployment--deployment_trigger))
- `env_vars` (Attributes Map) Environment variables used for builds and Pages Functions. (see [below for nested schema](#nestedatt--result--latest_deployment--env_vars))
- `environment` (String) Type of deploy.
Available values: "preview", "production".
- `id` (String) Id of the deployment.
- `is_skipped` (Boolean) If the deployment has been skipped.
- `latest_stage` (Attributes) The status of the deployment. (see [below for nested schema](#nestedatt--result--latest_deployment--latest_stage))
- `modified_on` (String) When the deployment was last modified.
- `project_id` (String) Id of the project.
- `project_name` (String) Name of the project.
- `short_id` (String) Short Id (8 character) of the deployment.
- `source` (Attributes) Configs for the project source control. (see [below for nested schema](#nestedatt--result--latest_deployment--source))
- `stages` (Attributes List) List of past stages. (see [below for nested schema](#nestedatt--result--latest_deployment--stages))
- `url` (String) The live URL to view this deployment.
- `uses_functions` (Boolean) Whether the deployment uses functions.
<a id="nestedatt--result--latest_deployment--build_config"></a>
### Nested Schema for `result.latest_deployment.build_config`
Read-Only:
- `build_caching` (Boolean) Enable build caching for the project.
- `build_command` (String) Command used to build project.
- `destination_dir` (String) Assets output directory of the build.
- `root_dir` (String) Directory to run the command.
- `web_analytics_tag` (String) The classifying tag for analytics.
- `web_analytics_token` (String, Sensitive) The auth token for analytics.
<a id="nestedatt--result--latest_deployment--deployment_trigger"></a>
### Nested Schema for `result.latest_deployment.deployment_trigger`
Read-Only:
- `metadata` (Attributes) Additional info about the trigger. (see [below for nested schema](#nestedatt--result--latest_deployment--deployment_trigger--metadata))
- `type` (String) What caused the deployment.
Available values: "github:push", "ad_hoc", "deploy_hook".
<a id="nestedatt--result--latest_deployment--deployment_trigger--metadata"></a>
### Nested Schema for `result.latest_deployment.deployment_trigger.metadata`
Read-Only:
- `branch` (String) Where the trigger happened.
- `commit_dirty` (Boolean) Whether the deployment trigger commit was dirty.
- `commit_hash` (String) Hash of the deployment trigger commit.
- `commit_message` (String) Message of the deployment trigger commit.
<a id="nestedatt--result--latest_deployment--env_vars"></a>
### Nested Schema for `result.latest_deployment.env_vars`
Read-Only:
- `type` (String) Available values: "plain_text", "secret_text".
- `value` (String, Sensitive) Environment variable value.
<a id="nestedatt--result--latest_deployment--latest_stage"></a>
### Nested Schema for `result.latest_deployment.latest_stage`
Read-Only:
- `ended_on` (String) When the stage ended.
- `name` (String) The current build stage.
Available values: "queued", "initialize", "clone_repo", "build", "deploy".
- `started_on` (String) When the stage started.
- `status` (String) State of the current stage.
Available values: "success", "idle", "active", "failure", "canceled".
<a id="nestedatt--result--latest_deployment--source"></a>
### Nested Schema for `result.latest_deployment.source`
Read-Only:
- `config` (Attributes) (see [below for nested schema](#nestedatt--result--latest_deployment--source--config))
- `type` (String) The source control management provider.
Available values: "github", "gitlab".
<a id="nestedatt--result--latest_deployment--source--config"></a>
### Nested Schema for `result.latest_deployment.source.config`
Read-Only:
- `deployments_enabled` (Boolean, Deprecated) Whether to enable automatic deployments when pushing to the source repository.
When disabled, no deployments (production or preview) will be triggered automatically.
- `owner` (String) The owner of the repository.
- `owner_id` (String) The owner ID of the repository.
- `path_excludes` (List of String) A list of paths that should be excluded from triggering a preview deployment. Wildcard syntax (`*`) is supported.
- `path_includes` (List of String) A list of paths that should be watched to trigger a preview deployment. Wildcard syntax (`*`) is supported.
- `pr_comments_enabled` (Boolean) Whether to enable PR comments.
- `preview_branch_excludes` (List of String) A list of branches that should not trigger a preview deployment. Wildcard syntax (`*`) is supported. Must be used with `preview_deployment_setting` set to `custom`.
- `preview_branch_includes` (List of String) A list of branches that should trigger a preview deployment. Wildcard syntax (`*`) is supported. Must be used with `preview_deployment_setting` set to `custom`.
- `preview_deployment_setting` (String) Controls whether commits to preview branches trigger a preview deployment.
Available values: "all", "none", "custom".
- `production_branch` (String) The production branch of the repository.
- `production_deployments_enabled` (Boolean) Whether to trigger a production deployment on commits to the production branch.
- `repo_id` (String) The ID of the repository.
- `repo_name` (String) The name of the repository.
<a id="nestedatt--result--latest_deployment--stages"></a>
### Nested Schema for `result.latest_deployment.stages`
Read-Only:
- `ended_on` (String) When the stage ended.
- `name` (String) The current build stage.
Available values: "queued", "initialize", "clone_repo", "build", "deploy".
- `started_on` (String) When the stage started.
- `status` (String) State of the current stage.
Available values: "success", "idle", "active", "failure", "canceled".
<a id="nestedatt--result--source"></a>
### Nested Schema for `result.source`
@ -127,6 +645,7 @@ Read-Only:
- `deployments_enabled` (Boolean, Deprecated) Whether to enable automatic deployments when pushing to the source repository.
When disabled, no deployments (production or preview) will be triggered automatically.
- `owner` (String) The owner of the repository.
- `owner_id` (String) The owner ID of the repository.
- `path_excludes` (List of String) A list of paths that should be excluded from triggering a preview deployment. Wildcard syntax (`*`) is supported.
- `path_includes` (List of String) A list of paths that should be watched to trigger a preview deployment. Wildcard syntax (`*`) is supported.
- `pr_comments_enabled` (Boolean) Whether to enable PR comments.
@ -136,20 +655,7 @@ When disabled, no deployments (production or preview) will be triggered automati
Available values: "all", "none", "custom".
- `production_branch` (String) The production branch of the repository.
- `production_deployments_enabled` (Boolean) Whether to trigger a production deployment on commits to the production branch.
- `repo_id` (String) The ID of the repository.
- `repo_name` (String) The name of the repository.
<a id="nestedatt--result--stages"></a>
### Nested Schema for `result.stages`
Read-Only:
- `ended_on` (String) When the stage ended.
- `name` (String) The current build stage.
Available values: "queued", "initialize", "clone_repo", "build", "deploy".
- `started_on` (String) When the stage started.
- `status` (String) State of the current stage.
Available values: "success", "idle", "active", "failure", "canceled".

View file

@ -41,7 +41,7 @@ Read-Only:
bucket.
- `account` (String)
- `bucket` (String) Name of the bucket on the provider.
- `provider` (String) Available values: "r2".
- `r2_bucket_sippy_provider` (String) Available values: "r2".
<a id="nestedatt--source"></a>
@ -49,8 +49,9 @@ bucket.
Read-Only:
- `bucket` (String) Name of the bucket on the provider.
- `provider` (String) Available values: "aws", "gcs".
- `bucket` (String) Name of the bucket on the provider (AWS, GCS only).
- `bucket_url` (String) S3-compatible URL (Generic S3-compatible providers only).
- `r2_bucket_sippy_provider` (String) Available values: "aws", "gcs", "s3".
- `region` (String) Region where the bucket resides (AWS only).

View file

@ -47,7 +47,6 @@ Available values: "openapi_v3".
Optional:
- `omit_source` (Boolean) Omit the source-files of schemas and only retrieve their meta-data.
- `validation_enabled` (Boolean) Filter for enabled schemas

View file

@ -58,7 +58,6 @@ Available values: "log", "block".
- `host` (String) Select rules with this host in `include`.
- `hostname` (String) Select rules with this host in `include`.
- `id` (String) Select rules with these IDs.
- `rule_id` (String) Select rules with these IDs.
- `token_configuration` (List of String) Select rules using any of these token configurations.

View file

@ -32,7 +32,7 @@ data "cloudflare_workers_custom_domain" "example_workers_custom_domain" {
### Read-Only
- `environment` (String) Worker environment associated with the zone and hostname.
- `environment` (String, Deprecated) Worker environment associated with the zone and hostname.
- `hostname` (String) Hostname of the Worker Domain.
- `id` (String) Identifer of the Worker Domain.
- `service` (String) Worker service associated with the zone and hostname.

View file

@ -47,7 +47,7 @@ data "cloudflare_workers_custom_domains" "example_workers_custom_domains" {
Read-Only:
- `environment` (String) Worker environment associated with the zone and hostname.
- `environment` (String, Deprecated) Worker environment associated with the zone and hostname.
- `hostname` (String) Hostname of the Worker Domain.
- `id` (String) Identifer of the Worker Domain.
- `service` (String) Worker service associated with the zone and hostname.

View file

@ -36,7 +36,7 @@ data "cloudflare_zero_trust_device_posture_rule" "example_zero_trust_device_post
- `name` (String) The name of the device posture rule.
- `schedule` (String) Polling frequency for the WARP client posture check. Default: `5m` (poll every five minutes). Minimum: `1m`.
- `type` (String) The type of device posture rule.
Available values: "file", "application", "tanium", "gateway", "warp", "disk_encryption", "serial_number", "sentinelone", "carbonblack", "firewall", "os_version", "domain_joined", "client_certificate", "client_certificate_v2", "unique_client_id", "kolide", "tanium_s2s", "crowdstrike_s2s", "intune", "workspace_one", "sentinelone_s2s", "custom_s2s".
Available values: "file", "application", "tanium", "gateway", "warp", "disk_encryption", "serial_number", "sentinelone", "carbonblack", "firewall", "os_version", "domain_joined", "client_certificate", "client_certificate_v2", "antivirus", "unique_client_id", "kolide", "tanium_s2s", "crowdstrike_s2s", "intune", "workspace_one", "sentinelone_s2s", "custom_s2s".
<a id="nestedatt--input"></a>
### Nested Schema for `input`
@ -91,6 +91,7 @@ Available values: "online", "offline", "unknown".
- `subject_alternative_names` (List of String) List of certificate Subject Alternative Names.
- `thumbprint` (String) Signing certificate thumbprint.
- `total_score` (Number) For more details on total score, refer to the Tanium documentation.
- `update_window_days` (Number) Number of days that the antivirus should be updated within.
- `version` (String) Version of OS.
- `version_operator` (String) Version Operator.
Available values: "<", "<=", ">", ">=", "==".

View file

@ -45,7 +45,7 @@ Read-Only:
- `name` (String) The name of the device posture rule.
- `schedule` (String) Polling frequency for the WARP client posture check. Default: `5m` (poll every five minutes). Minimum: `1m`.
- `type` (String) The type of device posture rule.
Available values: "file", "application", "tanium", "gateway", "warp", "disk_encryption", "serial_number", "sentinelone", "carbonblack", "firewall", "os_version", "domain_joined", "client_certificate", "client_certificate_v2", "unique_client_id", "kolide", "tanium_s2s", "crowdstrike_s2s", "intune", "workspace_one", "sentinelone_s2s", "custom_s2s".
Available values: "file", "application", "tanium", "gateway", "warp", "disk_encryption", "serial_number", "sentinelone", "carbonblack", "firewall", "os_version", "domain_joined", "client_certificate", "client_certificate_v2", "antivirus", "unique_client_id", "kolide", "tanium_s2s", "crowdstrike_s2s", "intune", "workspace_one", "sentinelone_s2s", "custom_s2s".
<a id="nestedatt--result--input"></a>
### Nested Schema for `result.input`
@ -100,6 +100,7 @@ Available values: "online", "offline", "unknown".
- `subject_alternative_names` (List of String) List of certificate Subject Alternative Names.
- `thumbprint` (String) Signing certificate thumbprint.
- `total_score` (Number) For more details on total score, refer to the Tanium documentation.
- `update_window_days` (Number) Number of days that the antivirus should be updated within.
- `version` (String) Version of OS.
- `version_operator` (String) Version Operator.
Available values: "<", "<=", ">", ">=", "==".

View file

@ -27,6 +27,10 @@ data "cloudflare_zero_trust_device_settings" "example_zero_trust_device_settings
### Read-Only
- `disable_for_time` (Number) Sets the time limit, in seconds, that a user can use an override code to bypass WARP.
- `external_emergency_signal_enabled` (Boolean) Controls whether the external emergency disconnect feature is enabled.
- `external_emergency_signal_fingerprint` (String) The SHA256 fingerprint (64 hexadecimal characters) of the HTTPS server certificate for the external_emergency_signal_url. If provided, the WARP client will use this value to verify the server's identity. The device will ignore any response if the server's certificate fingerprint does not exactly match this value.
- `external_emergency_signal_interval` (String) The interval at which the WARP client fetches the emergency disconnect signal, formatted as a duration string (e.g., "5m", "2m30s", "1h"). Minimum 30 seconds.
- `external_emergency_signal_url` (String) The HTTPS URL from which to fetch the emergency disconnect signal. Must use HTTPS and have an IPv4 or IPv6 address as the host.
- `gateway_proxy_enabled` (Boolean) Enable gateway proxy filtering on TCP.
- `gateway_udp_proxy_enabled` (Boolean) Enable gateway proxy filtering on UDP.
- `root_certificate_installation_enabled` (Boolean) Enable installation of cloudflare managed root certificate.

View file

@ -38,6 +38,7 @@ Cannot be set to false if secret is true
- `name` (String)
- `pattern` (Attributes) (see [below for nested schema](#nestedatt--pattern))
- `profile_id` (String)
- `profiles` (Attributes List) (see [below for nested schema](#nestedatt--profiles))
- `secret` (Boolean)
- `type` (String) Available values: "custom", "predefined", "integration", "exact_data", "document_fingerprint", "word_list".
- `updated_at` (String)
@ -62,6 +63,15 @@ Read-Only:
- `validation` (String, Deprecated) Available values: "luhn".
<a id="nestedatt--profiles"></a>
### Nested Schema for `profiles`
Read-Only:
- `id` (String)
- `name` (String)
<a id="nestedatt--variant"></a>
### Nested Schema for `variant`

View file

@ -38,7 +38,7 @@ data "cloudflare_zero_trust_dlp_dataset" "example_zero_trust_dlp_dataset" {
- `num_cells` (Number)
- `secret` (Boolean)
- `status` (String) Available values: "empty", "uploading", "pending", "processing", "failed", "complete".
- `updated_at` (String) When the dataset was last updated.
- `updated_at` (String) Stores when the dataset was last updated.
This includes name or description changes as well as uploads.
- `uploads` (Attributes List) (see [below for nested schema](#nestedatt--uploads))

View file

@ -47,7 +47,7 @@ Read-Only:
- `num_cells` (Number)
- `secret` (Boolean)
- `status` (String) Available values: "empty", "uploading", "pending", "processing", "failed", "complete".
- `updated_at` (String) When the dataset was last updated.
- `updated_at` (String) Stores when the dataset was last updated.
This includes name or description changes as well as uploads.
- `uploads` (Attributes List) (see [below for nested schema](#nestedatt--result--uploads))

View file

@ -38,6 +38,7 @@ Cannot be set to false if secret is true
- `name` (String)
- `pattern` (Attributes) (see [below for nested schema](#nestedatt--pattern))
- `profile_id` (String)
- `profiles` (Attributes List) (see [below for nested schema](#nestedatt--profiles))
- `secret` (Boolean)
- `type` (String) Available values: "custom", "predefined", "integration", "exact_data", "document_fingerprint", "word_list".
- `updated_at` (String)
@ -62,6 +63,15 @@ Read-Only:
- `validation` (String, Deprecated) Available values: "luhn".
<a id="nestedatt--profiles"></a>
### Nested Schema for `profiles`
Read-Only:
- `id` (String)
- `name` (String)
<a id="nestedatt--variant"></a>
### Nested Schema for `variant`

View file

@ -38,6 +38,7 @@ Cannot be set to false if secret is true
- `name` (String)
- `pattern` (Attributes) (see [below for nested schema](#nestedatt--pattern))
- `profile_id` (String)
- `profiles` (Attributes List) (see [below for nested schema](#nestedatt--profiles))
- `secret` (Boolean)
- `type` (String) Available values: "custom", "predefined", "integration", "exact_data", "document_fingerprint", "word_list".
- `updated_at` (String)
@ -62,6 +63,15 @@ Read-Only:
- `validation` (String, Deprecated) Available values: "luhn".
<a id="nestedatt--profiles"></a>
### Nested Schema for `profiles`
Read-Only:
- `id` (String)
- `name` (String)
<a id="nestedatt--variant"></a>
### Nested Schema for `variant`

View file

@ -38,6 +38,7 @@ Cannot be set to false if secret is true
- `name` (String)
- `pattern` (Attributes) (see [below for nested schema](#nestedatt--pattern))
- `profile_id` (String)
- `profiles` (Attributes List) (see [below for nested schema](#nestedatt--profiles))
- `secret` (Boolean)
- `type` (String) Available values: "custom", "predefined", "integration", "exact_data", "document_fingerprint", "word_list".
- `updated_at` (String)
@ -62,6 +63,15 @@ Read-Only:
- `validation` (String, Deprecated) Available values: "luhn".
<a id="nestedatt--profiles"></a>
### Nested Schema for `profiles`
Read-Only:
- `id` (String)
- `name` (String)
<a id="nestedatt--variant"></a>
### Nested Schema for `variant`

View file

@ -50,7 +50,6 @@ Optional:
- `is_deleted` (Boolean) If `true`, only include deleted routes. If `false`, exclude deleted routes. If empty, all routes will be included.
- `network_subset` (String) If set, only list routes that are contained within this IP range.
- `network_superset` (String) If set, only list routes that contain this IP range.
- `route_id` (String) UUID of the route.
- `tun_types` (List of String) The types of tunnels to filter by, separated by commas.
- `tunnel_id` (String) UUID of the tunnel.
- `virtual_network_id` (String) UUID of the virtual network.

View file

@ -45,7 +45,7 @@ Read-Only:
- `currency` (String) The currency applied to the rate plan subscription.
- `externally_managed` (Boolean) Whether this rate plan is managed externally from Cloudflare.
- `id` (String) The ID of the rate plan.
Available values: "free", "lite", "pro", "pro_plus", "business", "enterprise", "partners_free", "partners_pro", "partners_business", "partners_enterprise".
Available values: "free", "lite", "pro", "pro_plus", "business", "enterprise", "partners_free", "partners_pro", "partners_business", "partners_enterprise", "partners_ent".
- `is_contract` (Boolean) Whether a rate plan is enterprise-based (or newly adopted term contract).
- `public_name` (String) The full name of the rate plan.
- `scope` (String) The scope that this rate plan applies to.

View file

@ -30,7 +30,7 @@ resource "cloudflare_account_member" "example_account_member" {
### Optional
- `policies` (Attributes List) Array of policies associated with this member. (see [below for nested schema](#nestedatt--policies))
- `policies` (Attributes Set) Array of policies associated with this member. (see [below for nested schema](#nestedatt--policies))
- `roles` (List of String) Array of roles associated with this member.
- `status` (String) Available values: "accepted", "pending".
@ -46,12 +46,8 @@ Required:
- `access` (String) Allow or deny operations against the resources.
Available values: "allow", "deny".
- `permission_groups` (Attributes List) A set of permission groups that are specified to the policy. (see [below for nested schema](#nestedatt--policies--permission_groups))
- `resource_groups` (Attributes List) A list of resource groups that the policy applies to. (see [below for nested schema](#nestedatt--policies--resource_groups))
Read-Only:
- `id` (String) Policy identifier.
- `permission_groups` (Attributes Set) A set of permission groups that are specified to the policy. (see [below for nested schema](#nestedatt--policies--permission_groups))
- `resource_groups` (Attributes Set) A list of resource groups that the policy applies to. (see [below for nested schema](#nestedatt--policies--resource_groups))
<a id="nestedatt--policies--permission_groups"></a>
### Nested Schema for `policies.permission_groups`

View file

@ -55,13 +55,15 @@ Available values: "Trial", "Provisioned", "Paid", "AwaitingPayment", "Cancelled"
Optional:
- `id` (String) The ID of the rate plan.
- `scope` (String) The scope that this rate plan applies to.
Read-Only:
- `currency` (String) The currency applied to the rate plan subscription.
- `externally_managed` (Boolean) Whether this rate plan is managed externally from Cloudflare.
- `id` (String) The ID of the rate plan.
Available values: "free", "lite", "pro", "pro_plus", "business", "enterprise", "partners_free", "partners_pro", "partners_business", "partners_enterprise".
- `is_contract` (Boolean) Whether a rate plan is enterprise-based (or newly adopted term contract).
- `public_name` (String) The full name of the rate plan.
- `scope` (String) The scope that this rate plan applies to.
- `sets` (List of String) The list of sets this rate plan applies to.
## Import

View file

@ -18,6 +18,7 @@ resource "cloudflare_byo_ip_prefix" "example_byo_ip_prefix" {
cidr = "192.0.2.0/24"
delegate_loa_creation = true
description = "Internal test prefix"
loa_document_id = "d933b1530bc56c9953cf8ce166da8004"
}
```
@ -34,6 +35,7 @@ resource "cloudflare_byo_ip_prefix" "example_byo_ip_prefix" {
- `delegate_loa_creation` (Boolean) Whether Cloudflare is allowed to generate the LOA document on behalf of the prefix owner.
- `description` (String) Description of the prefix.
- `loa_document_id` (String) Identifier for the uploaded LOA document.
### Read-Only
@ -43,7 +45,6 @@ resource "cloudflare_byo_ip_prefix" "example_byo_ip_prefix" {
- `created_at` (String)
- `id` (String) Identifier of an IP Prefix.
- `irr_validation_state` (String) State of one kind of validation for an IP prefix.
- `loa_document_id` (String) Identifier for the uploaded LOA document.
- `modified_at` (String)
- `on_demand_enabled` (Boolean, Deprecated) Whether advertisement of the prefix to the Internet may be dynamically enabled or disabled.
- `on_demand_locked` (Boolean, Deprecated) Whether advertisement status of the prefix is locked, meaning it cannot be changed.

View file

@ -50,11 +50,40 @@ Available values: 14, 30, 90, 365.
### Read-Only
- `certificates` (Attributes List) Array of certificates in this pack. (see [below for nested schema](#nestedatt--certificates))
- `id` (String) Identifier.
- `primary_certificate` (String) Identifier of the primary certificate in a pack.
- `status` (String) Status of certificate pack.
Available values: "initializing", "pending_validation", "deleted", "pending_issuance", "pending_deployment", "pending_deletion", "pending_expiration", "expired", "active", "initializing_timed_out", "validation_timed_out", "issuance_timed_out", "deployment_timed_out", "deletion_timed_out", "pending_cleanup", "staging_deployment", "staging_active", "deactivating", "inactive", "backup_issued", "holding_deployment".
- `validation_errors` (Attributes List) Domain validation errors that have been received by the certificate authority (CA). (see [below for nested schema](#nestedatt--validation_errors))
- `validation_records` (Attributes List) Certificates' validation records. Only present when certificate pack is in "pending_validation" status (see [below for nested schema](#nestedatt--validation_records))
- `validation_records` (Attributes List) Certificates' validation records. (see [below for nested schema](#nestedatt--validation_records))
<a id="nestedatt--certificates"></a>
### Nested Schema for `certificates`
Read-Only:
- `bundle_method` (String) Certificate bundle method.
- `expires_on` (String) When the certificate from the authority expires.
- `geo_restrictions` (Attributes) Specify the region where your private key can be held locally. (see [below for nested schema](#nestedatt--certificates--geo_restrictions))
- `hosts` (List of String) Hostnames covered by this certificate.
- `id` (String) Certificate identifier.
- `issuer` (String) The certificate authority that issued the certificate.
- `modified_on` (String) When the certificate was last modified.
- `priority` (Number) The order/priority in which the certificate will be used.
- `signature` (String) The type of hash used for the certificate.
- `status` (String) Certificate status.
- `uploaded_on` (String) When the certificate was uploaded to Cloudflare.
- `zone_id` (String) Identifier.
<a id="nestedatt--certificates--geo_restrictions"></a>
### Nested Schema for `certificates.geo_restrictions`
Read-Only:
- `label` (String) Available values: "us", "eu", "highest_security".
<a id="nestedatt--validation_errors"></a>
### Nested Schema for `validation_errors`

View file

@ -22,7 +22,7 @@ resource "cloudflare_cloud_connector_rules" "example_cloud_connector_rules" {
parameters = {
host = "examplebucket.s3.eu-north-1.amazonaws.com"
}
provider = "aws_s3"
cloud_connector_rules_provider = "aws_s3"
}]
}
```

View file

@ -138,7 +138,7 @@ Available values: "A", "AAAA", "CNAME", "HTTPS", "TXT", "SRV", "LOC", "MX", "NS"
Read-Only:
- `count` (Number) Total number of results for the requested service.
- `email_routing_dns_count` (Number) Total number of results for the requested service.
- `page` (Number) Current page within paginated list of results.
- `per_page` (Number) Number of results per page of results.
- `total_count` (Number) Total results available without any search parameters.

View file

@ -76,11 +76,6 @@ Import is supported using the following syntax:
```shell
$ terraform import cloudflare_list_item.example '<account_id>/<list_id>/<item_id>'
$ terraform import cloudflare_list_item.example '<account_id>/<list_id>/<item_id>'
$ terraform import cloudflare_list_item.example '<account_id>/<list_id>/<item_id>'
$ terraform import cloudflare_list_item.example '<account_id>/<list_id>/<item_id>'
$ terraform import cloudflare_list_item.example '<account_id>/<list_id>/<item_id>'
$ terraform import cloudflare_list_item.example '<account_id>/<list_id>/<item_id>'
```

View file

@ -41,12 +41,15 @@ resource "cloudflare_origin_ca_certificate" "example_origin_ca_certificate" {
<!-- schema generated by tfplugindocs -->
## Schema
### Optional
### Required
- `csr` (String) The Certificate Signing Request (CSR). Must be newline-encoded.
- `hostnames` (List of String) Array of hostnames or wildcard names (e.g., *.example.com) bound to the certificate.
- `request_type` (String) Signature type desired on certificate ("origin-rsa" (rsa), "origin-ecc" (ecdsa), or "keyless-certificate" (for Keyless SSL servers).
Available values: "origin-rsa", "origin-ecc", "keyless-certificate".
### Optional
- `requested_validity` (Number) The number of days for which the certificate should be valid.
Available values: 7, 30, 90, 365, 730, 1095, 5475.

View file

@ -18,7 +18,7 @@ description: |-
resource "cloudflare_pages_domain" "example_pages_domain" {
account_id = "023e105f4ecef8ad9ca31a8372d0c353"
project_name = "this-is-my-project-01"
name = "example.com"
name = "this-is-my-domain-01.com"
}
```
<!-- schema generated by tfplugindocs -->
@ -26,8 +26,8 @@ resource "cloudflare_pages_domain" "example_pages_domain" {
### Required
- `account_id` (String) Identifier
- `name` (String)
- `account_id` (String) Identifier.
- `name` (String) The domain name.
- `project_name` (String) Name of the project.
### Read-Only
@ -35,7 +35,7 @@ resource "cloudflare_pages_domain" "example_pages_domain" {
- `certificate_authority` (String) Available values: "google", "lets_encrypt".
- `created_on` (String)
- `domain_id` (String)
- `id` (String) The ID of this resource.
- `id` (String) The domain name.
- `status` (String) Available values: "initializing", "pending", "active", "deactivated", "blocked", "error".
- `validation_data` (Attributes) (see [below for nested schema](#nestedatt--validation_data))
- `verification_data` (Attributes) (see [below for nested schema](#nestedatt--verification_data))

View file

@ -94,15 +94,15 @@ resource "cloudflare_pages_project" "example_pages_project" {
}
r2_buckets = {
R2_BINDING = {
jurisdiction = "eu"
name = "some-bucket"
jurisdiction = "eu"
}
}
services = {
SERVICE_BINDING = {
service = "example-worker"
entrypoint = "MyHandler"
environment = "production"
service = "example-worker"
}
}
usage_model = "standard"
@ -178,15 +178,15 @@ resource "cloudflare_pages_project" "example_pages_project" {
}
r2_buckets = {
R2_BINDING = {
jurisdiction = "eu"
name = "some-bucket"
jurisdiction = "eu"
}
}
services = {
SERVICE_BINDING = {
service = "example-worker"
entrypoint = "MyHandler"
environment = "production"
service = "example-worker"
}
}
usage_model = "standard"
@ -202,6 +202,7 @@ resource "cloudflare_pages_project" "example_pages_project" {
config = {
deployments_enabled = true
owner = "my-org"
owner_id = "12345678"
path_excludes = ["string"]
path_includes = ["string"]
pr_comments_enabled = true
@ -210,6 +211,7 @@ resource "cloudflare_pages_project" "example_pages_project" {
preview_deployment_setting = "all"
production_branch = "main"
production_deployments_enabled = true
repo_id = "12345678"
repo_name = "my-repo"
}
type = "github"
@ -221,7 +223,7 @@ resource "cloudflare_pages_project" "example_pages_project" {
### Required
- `account_id` (String) Identifier
- `account_id` (String) Identifier.
- `name` (String) Name of the project.
- `production_branch` (String) Production branch of the project. Used to identify production deployments.
@ -229,7 +231,7 @@ resource "cloudflare_pages_project" "example_pages_project" {
- `build_config` (Attributes) Configs for the project build process. (see [below for nested schema](#nestedatt--build_config))
- `deployment_configs` (Attributes) Configs for deployments in a project. (see [below for nested schema](#nestedatt--deployment_configs))
- `source` (Attributes) (see [below for nested schema](#nestedatt--source))
- `source` (Attributes) Configs for the project source control. (see [below for nested schema](#nestedatt--source))
### Read-Only
@ -298,7 +300,7 @@ Available values: "standard", "bundled", "unbound".
<a id="nestedatt--deployment_configs--preview--ai_bindings"></a>
### Nested Schema for `deployment_configs.preview.ai_bindings`
Optional:
Required:
- `project_id` (String)
@ -306,7 +308,7 @@ Optional:
<a id="nestedatt--deployment_configs--preview--analytics_engine_datasets"></a>
### Nested Schema for `deployment_configs.preview.analytics_engine_datasets`
Optional:
Required:
- `dataset` (String) Name of the dataset.
@ -318,7 +320,7 @@ Optional:
<a id="nestedatt--deployment_configs--preview--d1_databases"></a>
### Nested Schema for `deployment_configs.preview.d1_databases`
Optional:
Required:
- `id` (String) UUID of the D1 database.
@ -326,7 +328,7 @@ Optional:
<a id="nestedatt--deployment_configs--preview--durable_object_namespaces"></a>
### Nested Schema for `deployment_configs.preview.durable_object_namespaces`
Optional:
Required:
- `namespace_id` (String) ID of the Durable Object namespace.
@ -343,7 +345,7 @@ Required:
<a id="nestedatt--deployment_configs--preview--hyperdrive_bindings"></a>
### Nested Schema for `deployment_configs.preview.hyperdrive_bindings`
Optional:
Required:
- `id` (String)
@ -351,7 +353,7 @@ Optional:
<a id="nestedatt--deployment_configs--preview--kv_namespaces"></a>
### Nested Schema for `deployment_configs.preview.kv_namespaces`
Optional:
Required:
- `namespace_id` (String) ID of the KV namespace.
@ -359,7 +361,7 @@ Optional:
<a id="nestedatt--deployment_configs--preview--limits"></a>
### Nested Schema for `deployment_configs.preview.limits`
Optional:
Required:
- `cpu_ms` (Number) CPU time limit in milliseconds.
@ -367,7 +369,7 @@ Optional:
<a id="nestedatt--deployment_configs--preview--mtls_certificates"></a>
### Nested Schema for `deployment_configs.preview.mtls_certificates`
Optional:
Required:
- `certificate_id` (String)
@ -383,7 +385,7 @@ Optional:
<a id="nestedatt--deployment_configs--preview--queue_producers"></a>
### Nested Schema for `deployment_configs.preview.queue_producers`
Optional:
Required:
- `name` (String) Name of the Queue.
@ -391,26 +393,32 @@ Optional:
<a id="nestedatt--deployment_configs--preview--r2_buckets"></a>
### Nested Schema for `deployment_configs.preview.r2_buckets`
Required:
- `name` (String) Name of the R2 bucket.
Optional:
- `jurisdiction` (String) Jurisdiction of the R2 bucket.
- `name` (String) Name of the R2 bucket.
<a id="nestedatt--deployment_configs--preview--services"></a>
### Nested Schema for `deployment_configs.preview.services`
Required:
- `service` (String) The Service name.
Optional:
- `entrypoint` (String) The entrypoint to bind to.
- `environment` (String) The Service environment.
- `service` (String) The Service name.
<a id="nestedatt--deployment_configs--preview--vectorize_bindings"></a>
### Nested Schema for `deployment_configs.preview.vectorize_bindings`
Optional:
Required:
- `index_name` (String)
@ -448,7 +456,7 @@ Available values: "standard", "bundled", "unbound".
<a id="nestedatt--deployment_configs--production--ai_bindings"></a>
### Nested Schema for `deployment_configs.production.ai_bindings`
Optional:
Required:
- `project_id` (String)
@ -456,7 +464,7 @@ Optional:
<a id="nestedatt--deployment_configs--production--analytics_engine_datasets"></a>
### Nested Schema for `deployment_configs.production.analytics_engine_datasets`
Optional:
Required:
- `dataset` (String) Name of the dataset.
@ -468,7 +476,7 @@ Optional:
<a id="nestedatt--deployment_configs--production--d1_databases"></a>
### Nested Schema for `deployment_configs.production.d1_databases`
Optional:
Required:
- `id` (String) UUID of the D1 database.
@ -476,7 +484,7 @@ Optional:
<a id="nestedatt--deployment_configs--production--durable_object_namespaces"></a>
### Nested Schema for `deployment_configs.production.durable_object_namespaces`
Optional:
Required:
- `namespace_id` (String) ID of the Durable Object namespace.
@ -493,7 +501,7 @@ Required:
<a id="nestedatt--deployment_configs--production--hyperdrive_bindings"></a>
### Nested Schema for `deployment_configs.production.hyperdrive_bindings`
Optional:
Required:
- `id` (String)
@ -501,7 +509,7 @@ Optional:
<a id="nestedatt--deployment_configs--production--kv_namespaces"></a>
### Nested Schema for `deployment_configs.production.kv_namespaces`
Optional:
Required:
- `namespace_id` (String) ID of the KV namespace.
@ -509,7 +517,7 @@ Optional:
<a id="nestedatt--deployment_configs--production--limits"></a>
### Nested Schema for `deployment_configs.production.limits`
Optional:
Required:
- `cpu_ms` (Number) CPU time limit in milliseconds.
@ -517,7 +525,7 @@ Optional:
<a id="nestedatt--deployment_configs--production--mtls_certificates"></a>
### Nested Schema for `deployment_configs.production.mtls_certificates`
Optional:
Required:
- `certificate_id` (String)
@ -533,7 +541,7 @@ Optional:
<a id="nestedatt--deployment_configs--production--queue_producers"></a>
### Nested Schema for `deployment_configs.production.queue_producers`
Optional:
Required:
- `name` (String) Name of the Queue.
@ -541,26 +549,32 @@ Optional:
<a id="nestedatt--deployment_configs--production--r2_buckets"></a>
### Nested Schema for `deployment_configs.production.r2_buckets`
Required:
- `name` (String) Name of the R2 bucket.
Optional:
- `jurisdiction` (String) Jurisdiction of the R2 bucket.
- `name` (String) Name of the R2 bucket.
<a id="nestedatt--deployment_configs--production--services"></a>
### Nested Schema for `deployment_configs.production.services`
Required:
- `service` (String) The Service name.
Optional:
- `entrypoint` (String) The entrypoint to bind to.
- `environment` (String) The Service environment.
- `service` (String) The Service name.
<a id="nestedatt--deployment_configs--production--vectorize_bindings"></a>
### Nested Schema for `deployment_configs.production.vectorize_bindings`
Optional:
Required:
- `index_name` (String)
@ -570,7 +584,7 @@ Optional:
<a id="nestedatt--source"></a>
### Nested Schema for `source`
Optional:
Required:
- `config` (Attributes) (see [below for nested schema](#nestedatt--source--config))
- `type` (String) The source control management provider.
@ -584,6 +598,7 @@ Optional:
- `deployments_enabled` (Boolean, Deprecated) Whether to enable automatic deployments when pushing to the source repository.
When disabled, no deployments (production or preview) will be triggered automatically.
- `owner` (String) The owner of the repository.
- `owner_id` (String) The owner ID of the repository.
- `path_excludes` (List of String) A list of paths that should be excluded from triggering a preview deployment. Wildcard syntax (`*`) is supported.
- `path_includes` (List of String) A list of paths that should be watched to trigger a preview deployment. Wildcard syntax (`*`) is supported.
- `pr_comments_enabled` (Boolean) Whether to enable PR comments.
@ -593,6 +608,7 @@ When disabled, no deployments (production or preview) will be triggered automati
Available values: "all", "none", "custom".
- `production_branch` (String) The production branch of the repository.
- `production_deployments_enabled` (Boolean) Whether to trigger a production deployment on commits to the production branch.
- `repo_id` (String) The ID of the repository.
- `repo_name` (String) The name of the repository.
@ -616,9 +632,10 @@ Available values: "preview", "production".
- `project_id` (String) Id of the project.
- `project_name` (String) Name of the project.
- `short_id` (String) Short Id (8 character) of the deployment.
- `source` (Attributes) (see [below for nested schema](#nestedatt--canonical_deployment--source))
- `source` (Attributes) Configs for the project source control. (see [below for nested schema](#nestedatt--canonical_deployment--source))
- `stages` (Attributes List) List of past stages. (see [below for nested schema](#nestedatt--canonical_deployment--stages))
- `url` (String) The live URL to view this deployment.
- `uses_functions` (Boolean) Whether the deployment uses functions.
<a id="nestedatt--canonical_deployment--build_config"></a>
### Nested Schema for `canonical_deployment.build_config`
@ -627,7 +644,7 @@ Read-Only:
- `build_caching` (Boolean) Enable build caching for the project.
- `build_command` (String) Command used to build project.
- `destination_dir` (String) Output directory of the build.
- `destination_dir` (String) Assets output directory of the build.
- `root_dir` (String) Directory to run the command.
- `web_analytics_tag` (String) The classifying tag for analytics.
- `web_analytics_token` (String, Sensitive) The auth token for analytics.
@ -640,7 +657,7 @@ Read-Only:
- `metadata` (Attributes) Additional info about the trigger. (see [below for nested schema](#nestedatt--canonical_deployment--deployment_trigger--metadata))
- `type` (String) What caused the deployment.
Available values: "push", "ad_hoc".
Available values: "github:push", "ad_hoc", "deploy_hook".
<a id="nestedatt--canonical_deployment--deployment_trigger--metadata"></a>
### Nested Schema for `canonical_deployment.deployment_trigger.metadata`
@ -648,6 +665,7 @@ Available values: "push", "ad_hoc".
Read-Only:
- `branch` (String) Where the trigger happened.
- `commit_dirty` (Boolean) Whether the deployment trigger commit was dirty.
- `commit_hash` (String) Hash of the deployment trigger commit.
- `commit_message` (String) Message of the deployment trigger commit.
@ -692,6 +710,7 @@ Read-Only:
- `deployments_enabled` (Boolean, Deprecated) Whether to enable automatic deployments when pushing to the source repository.
When disabled, no deployments (production or preview) will be triggered automatically.
- `owner` (String) The owner of the repository.
- `owner_id` (String) The owner ID of the repository.
- `path_excludes` (List of String) A list of paths that should be excluded from triggering a preview deployment. Wildcard syntax (`*`) is supported.
- `path_includes` (List of String) A list of paths that should be watched to trigger a preview deployment. Wildcard syntax (`*`) is supported.
- `pr_comments_enabled` (Boolean) Whether to enable PR comments.
@ -701,6 +720,7 @@ When disabled, no deployments (production or preview) will be triggered automati
Available values: "all", "none", "custom".
- `production_branch` (String) The production branch of the repository.
- `production_deployments_enabled` (Boolean) Whether to trigger a production deployment on commits to the production branch.
- `repo_id` (String) The ID of the repository.
- `repo_name` (String) The name of the repository.
@ -738,9 +758,10 @@ Available values: "preview", "production".
- `project_id` (String) Id of the project.
- `project_name` (String) Name of the project.
- `short_id` (String) Short Id (8 character) of the deployment.
- `source` (Attributes) (see [below for nested schema](#nestedatt--latest_deployment--source))
- `source` (Attributes) Configs for the project source control. (see [below for nested schema](#nestedatt--latest_deployment--source))
- `stages` (Attributes List) List of past stages. (see [below for nested schema](#nestedatt--latest_deployment--stages))
- `url` (String) The live URL to view this deployment.
- `uses_functions` (Boolean) Whether the deployment uses functions.
<a id="nestedatt--latest_deployment--build_config"></a>
### Nested Schema for `latest_deployment.build_config`
@ -749,7 +770,7 @@ Read-Only:
- `build_caching` (Boolean) Enable build caching for the project.
- `build_command` (String) Command used to build project.
- `destination_dir` (String) Output directory of the build.
- `destination_dir` (String) Assets output directory of the build.
- `root_dir` (String) Directory to run the command.
- `web_analytics_tag` (String) The classifying tag for analytics.
- `web_analytics_token` (String, Sensitive) The auth token for analytics.
@ -762,7 +783,7 @@ Read-Only:
- `metadata` (Attributes) Additional info about the trigger. (see [below for nested schema](#nestedatt--latest_deployment--deployment_trigger--metadata))
- `type` (String) What caused the deployment.
Available values: "push", "ad_hoc".
Available values: "github:push", "ad_hoc", "deploy_hook".
<a id="nestedatt--latest_deployment--deployment_trigger--metadata"></a>
### Nested Schema for `latest_deployment.deployment_trigger.metadata`
@ -770,6 +791,7 @@ Available values: "push", "ad_hoc".
Read-Only:
- `branch` (String) Where the trigger happened.
- `commit_dirty` (Boolean) Whether the deployment trigger commit was dirty.
- `commit_hash` (String) Hash of the deployment trigger commit.
- `commit_message` (String) Message of the deployment trigger commit.
@ -814,6 +836,7 @@ Read-Only:
- `deployments_enabled` (Boolean, Deprecated) Whether to enable automatic deployments when pushing to the source repository.
When disabled, no deployments (production or preview) will be triggered automatically.
- `owner` (String) The owner of the repository.
- `owner_id` (String) The owner ID of the repository.
- `path_excludes` (List of String) A list of paths that should be excluded from triggering a preview deployment. Wildcard syntax (`*`) is supported.
- `path_includes` (List of String) A list of paths that should be watched to trigger a preview deployment. Wildcard syntax (`*`) is supported.
- `pr_comments_enabled` (Boolean) Whether to enable PR comments.
@ -823,6 +846,7 @@ When disabled, no deployments (production or preview) will be triggered automati
Available values: "all", "none", "custom".
- `production_branch` (String) The production branch of the repository.
- `production_deployments_enabled` (Boolean) Whether to trigger a production deployment on commits to the production branch.
- `repo_id` (String) The ID of the repository.
- `repo_name` (String) The name of the repository.

View file

@ -75,8 +75,9 @@ Optional:
- `access_key_id` (String) Access Key ID of an IAM credential (ideally scoped to a single S3 bucket).
- `bucket` (String) Name of the AWS S3 bucket.
- `bucket_url` (String) URL to the S3-compatible API of the bucket.
- `client_email` (String) Client email of an IAM credential (ideally scoped to a single GCS bucket).
- `cloud_provider` (String) Available values: "aws", "gcs".
- `cloud_provider` (String) Available values: "aws", "gcs", "s3".
- `private_key` (String, Sensitive) Private Key of an IAM credential (ideally scoped to a single GCS bucket).
- `region` (String) Name of the AWS availability zone.
- `secret_access_key` (String, Sensitive) Secret Access Key of an IAM credential (ideally scoped to a single S3 bucket).

View file

@ -14,10 +14,10 @@ description: |-
```terraform
resource "cloudflare_workers_custom_domain" "example_workers_custom_domain" {
account_id = "9a7806061c88ada191ed06f989cc3dac"
environment = "production"
hostname = "foo.example.com"
service = "foo"
zone_id = "593c9c94de529bbbfaac7c53ced0447d"
environment = "production"
}
```
@ -27,11 +27,14 @@ resource "cloudflare_workers_custom_domain" "example_workers_custom_domain" {
### Required
- `account_id` (String) Identifer of the account.
- `environment` (String) Worker environment associated with the zone and hostname.
- `hostname` (String) Hostname of the Worker Domain.
- `service` (String) Worker service associated with the zone and hostname.
- `zone_id` (String) Identifier of the zone.
### Optional
- `environment` (String, Deprecated) Worker environment associated with the zone and hostname.
### Read-Only
- `id` (String) Identifer of the Worker Domain.

View file

@ -40,7 +40,7 @@ resource "cloudflare_zero_trust_device_posture_rule" "example_zero_trust_device_
- `account_id` (String)
- `name` (String) The name of the device posture rule.
- `type` (String) The type of device posture rule.
Available values: "file", "application", "tanium", "gateway", "warp", "disk_encryption", "serial_number", "sentinelone", "carbonblack", "firewall", "os_version", "domain_joined", "client_certificate", "client_certificate_v2", "unique_client_id", "kolide", "tanium_s2s", "crowdstrike_s2s", "intune", "workspace_one", "sentinelone_s2s", "custom_s2s".
Available values: "file", "application", "tanium", "gateway", "warp", "disk_encryption", "serial_number", "sentinelone", "carbonblack", "firewall", "os_version", "domain_joined", "client_certificate", "client_certificate_v2", "antivirus", "unique_client_id", "kolide", "tanium_s2s", "crowdstrike_s2s", "intune", "workspace_one", "sentinelone_s2s", "custom_s2s".
### Optional
@ -107,6 +107,7 @@ Available values: "online", "offline", "unknown".
- `subject_alternative_names` (List of String) List of certificate Subject Alternative Names.
- `thumbprint` (String) Signing certificate thumbprint.
- `total_score` (Number) For more details on total score, refer to the Tanium documentation.
- `update_window_days` (Number) Number of days that the antivirus should be updated within.
- `version` (String) Version of OS.
- `version_operator` (String) Version Operator.
Available values: "<", "<=", ">", ">=", "==".

View file

@ -15,6 +15,10 @@ description: |-
resource "cloudflare_zero_trust_device_settings" "example_zero_trust_device_settings" {
account_id = "699d98642c564d2e855e9661899b7252"
disable_for_time = 0
external_emergency_signal_enabled = true
external_emergency_signal_fingerprint = "abcd1234567890abcd1234567890abcd1234567890abcd1234567890abcd1234"
external_emergency_signal_interval = "5m"
external_emergency_signal_url = "https://192.0.2.1/signal"
gateway_proxy_enabled = true
gateway_udp_proxy_enabled = true
root_certificate_installation_enabled = true
@ -32,6 +36,10 @@ resource "cloudflare_zero_trust_device_settings" "example_zero_trust_device_sett
### Optional
- `disable_for_time` (Number) Sets the time limit, in seconds, that a user can use an override code to bypass WARP.
- `external_emergency_signal_enabled` (Boolean) Controls whether the external emergency disconnect feature is enabled.
- `external_emergency_signal_fingerprint` (String) The SHA256 fingerprint (64 hexadecimal characters) of the HTTPS server certificate for the external_emergency_signal_url. If provided, the WARP client will use this value to verify the server's identity. The device will ignore any response if the server's certificate fingerprint does not exactly match this value.
- `external_emergency_signal_interval` (String) The interval at which the WARP client fetches the emergency disconnect signal, formatted as a duration string (e.g., "5m", "2m30s", "1h"). Minimum 30 seconds.
- `external_emergency_signal_url` (String) The HTTPS URL from which to fetch the emergency disconnect signal. Must use HTTPS and have an IPv4 or IPv6 address as the host.
- `gateway_proxy_enabled` (Boolean) Enable gateway proxy filtering on TCP.
- `gateway_udp_proxy_enabled` (Boolean) Enable gateway proxy filtering on UDP.
- `root_certificate_installation_enabled` (Boolean) Enable installation of cloudflare managed root certificate.

View file

@ -46,6 +46,7 @@ Cannot be set to false if secret is true
- `confidence` (Attributes) (see [below for nested schema](#nestedatt--confidence))
- `created_at` (String)
- `id` (String) The ID of this resource.
- `profiles` (Attributes List) (see [below for nested schema](#nestedatt--profiles))
- `secret` (Boolean)
- `type` (String) Available values: "custom", "predefined", "integration", "exact_data", "document_fingerprint", "word_list".
- `updated_at` (String)
@ -73,6 +74,15 @@ Read-Only:
- `available` (Boolean) Indicates whether this entry has any form of validation that is not an AI remote service.
<a id="nestedatt--profiles"></a>
### Nested Schema for `profiles`
Read-Only:
- `id` (String)
- `name` (String)
<a id="nestedatt--variant"></a>
### Nested Schema for `variant`

View file

@ -58,7 +58,7 @@ If false, the response has no secret and the dataset is uploaded in plaintext.
- `max_cells` (Number)
- `num_cells` (Number)
- `status` (String) Available values: "empty", "uploading", "pending", "processing", "failed", "complete".
- `updated_at` (String) When the dataset was last updated.
- `updated_at` (String) Stores when the dataset was last updated.
This includes name or description changes as well as uploads.
- `uploads` (Attributes List) (see [below for nested schema](#nestedatt--uploads))
@ -90,7 +90,7 @@ Read-Only:
- `num_cells` (Number)
- `secret` (Boolean)
- `status` (String) Available values: "empty", "uploading", "pending", "processing", "failed", "complete".
- `updated_at` (String) When the dataset was last updated.
- `updated_at` (String) Stores when the dataset was last updated.
This includes name or description changes as well as uploads.
- `uploads` (Attributes List) (see [below for nested schema](#nestedatt--dataset--uploads))

View file

@ -47,6 +47,7 @@ Cannot be set to false if secret is true
- `confidence` (Attributes) (see [below for nested schema](#nestedatt--confidence))
- `created_at` (String)
- `id` (String) The ID of this resource.
- `profiles` (Attributes List) (see [below for nested schema](#nestedatt--profiles))
- `secret` (Boolean)
- `updated_at` (String)
- `variant` (Attributes) (see [below for nested schema](#nestedatt--variant))
@ -73,6 +74,15 @@ Read-Only:
- `available` (Boolean) Indicates whether this entry has any form of validation that is not an AI remote service.
<a id="nestedatt--profiles"></a>
### Nested Schema for `profiles`
Read-Only:
- `id` (String)
- `name` (String)
<a id="nestedatt--variant"></a>
### Nested Schema for `variant`

View file

@ -31,8 +31,8 @@ resource "cloudflare_zero_trust_dlp_integration_entry" "example_zero_trust_dlp_i
### Optional
- `profile_id` (String) This field is not actually used as the owning profile for a predefined entry is already set
to a predefined profile
- `profile_id` (String) This field is not used as the owning profile.
For predefined entries it is already set to a predefined profile.
### Read-Only
@ -44,6 +44,7 @@ Cannot be set to false if secret is true
- `id` (String) The ID of this resource.
- `name` (String)
- `pattern` (Attributes) (see [below for nested schema](#nestedatt--pattern))
- `profiles` (Attributes List) (see [below for nested schema](#nestedatt--profiles))
- `secret` (Boolean)
- `type` (String) Available values: "custom", "predefined", "integration", "exact_data", "document_fingerprint", "word_list".
- `updated_at` (String)
@ -68,6 +69,15 @@ Read-Only:
- `validation` (String, Deprecated) Available values: "luhn".
<a id="nestedatt--profiles"></a>
### Nested Schema for `profiles`
Read-Only:
- `id` (String)
- `name` (String)
<a id="nestedatt--variant"></a>
### Nested Schema for `variant`

View file

@ -31,8 +31,8 @@ resource "cloudflare_zero_trust_dlp_predefined_entry" "example_zero_trust_dlp_pr
### Optional
- `profile_id` (String) This field is not actually used as the owning profile for a predefined entry is already set
to a predefined profile
- `profile_id` (String) This field is not used as the owning profile.
For predefined entries it is already set to a predefined profile.
### Read-Only
@ -44,6 +44,7 @@ Cannot be set to false if secret is true
- `id` (String) The ID of this resource.
- `name` (String)
- `pattern` (Attributes) (see [below for nested schema](#nestedatt--pattern))
- `profiles` (Attributes List) (see [below for nested schema](#nestedatt--profiles))
- `secret` (Boolean)
- `type` (String) Available values: "custom", "predefined", "integration", "exact_data", "document_fingerprint", "word_list".
- `updated_at` (String)
@ -68,6 +69,15 @@ Read-Only:
- `validation` (String, Deprecated) Available values: "luhn".
<a id="nestedatt--profiles"></a>
### Nested Schema for `profiles`
Read-Only:
- `id` (String)
- `name` (String)
<a id="nestedatt--variant"></a>
### Nested Schema for `variant`

View file

@ -150,7 +150,6 @@ Available values: "on", "off", "allow", "block", "scan", "noscan", "safesearch",
- `precedence` (Number) Set the order of your rules. Lower values indicate higher precedence. At each processing phase, evaluate applicable rules in ascending order of this value. Refer to [Order of enforcement](http://developers.cloudflare.com/learning-paths/secure-internet-traffic/understand-policies/order-of-enforcement/#manage-precedence-with-terraform) to manage precedence via Terraform.
- `rule_settings` (Attributes) Defines settings for this rule. Settings apply only to specific rule types and must use compatible selectors. If Terraform detects drift, confirm the setting supports your rule type and check whether the API modifies the value. Use API-returned values in your configuration to prevent drift. (see [below for nested schema](#nestedatt--rule_settings))
- `schedule` (Attributes) Defines the schedule for activating DNS policies. Settable only for `dns` and `dns_resolver` rules. (see [below for nested schema](#nestedatt--schedule))
- `sharable` (Boolean) Indicate that this rule is sharable via the Orgs API.
- `traffic` (String) Specify the wirefilter expression used for traffic matching. The API automatically formats and sanitizes expressions before storing them. To prevent Terraform state drift, use the formatted expression returned in the API response.
### Read-Only
@ -159,6 +158,7 @@ Available values: "on", "off", "allow", "block", "scan", "noscan", "safesearch",
- `deleted_at` (String) Indicate the date of deletion, if any.
- `id` (String) Identify the API resource with a UUID.
- `read_only` (Boolean) Indicate that this rule is shared via the Orgs API and read only.
- `sharable` (Boolean) Indicate that this rule is sharable via the Orgs API.
- `source_account` (String) Provide the account tag of the account that created the rule.
- `updated_at` (String)
- `version` (Number) Indicate the version number of the rule(read-only).

View file

@ -38,6 +38,7 @@ resource "cloudflare_zone_subscription" "example_zone_subscription" {
- `frequency` (String) How often the subscription is renewed automatically.
Available values: "weekly", "monthly", "quarterly", "yearly".
Note: Some plans may not support frequency configuration and will return "not-applicable".
- `rate_plan` (Attributes) The rate plan applied to the subscription. (see [below for nested schema](#nestedatt--rate_plan))
### Read-Only
@ -55,13 +56,16 @@ Available values: "Trial", "Provisioned", "Paid", "AwaitingPayment", "Cancelled"
Optional:
- `id` (String) The ID of the rate plan.
Available values: "free", "lite", "pro", "pro_plus", "business", "enterprise", "partners_free", "partners_pro", "partners_business", "partners_enterprise", "partners_ent".
- `scope` (String) The scope that this rate plan applies to.
Read-Only:
- `currency` (String) The currency applied to the rate plan subscription.
- `externally_managed` (Boolean) Whether this rate plan is managed externally from Cloudflare.
- `id` (String) The ID of the rate plan.
Available values: "free", "lite", "pro", "pro_plus", "business", "enterprise", "partners_free", "partners_pro", "partners_business", "partners_enterprise".
- `is_contract` (Boolean) Whether a rate plan is enterprise-based (or newly adopted term contract).
- `public_name` (String) The full name of the rate plan.
- `scope` (String) The scope that this rate plan applies to.
- `sets` (List of String) The list of sets this rate plan applies to.
## Import

View file

@ -4,4 +4,5 @@ resource "cloudflare_byo_ip_prefix" "example_byo_ip_prefix" {
cidr = "192.0.2.0/24"
delegate_loa_creation = true
description = "Internal test prefix"
loa_document_id = "d933b1530bc56c9953cf8ce166da8004"
}

View file

@ -8,6 +8,6 @@ resource "cloudflare_cloud_connector_rules" "example_cloud_connector_rules" {
parameters = {
host = "examplebucket.s3.eu-north-1.amazonaws.com"
}
provider = "aws_s3"
cloud_connector_rules_provider = "aws_s3"
}]
}

View file

@ -1,6 +1 @@
$ terraform import cloudflare_list_item.example '<account_id>/<list_id>/<item_id>'
$ terraform import cloudflare_list_item.example '<account_id>/<list_id>/<item_id>'
$ terraform import cloudflare_list_item.example '<account_id>/<list_id>/<item_id>'
$ terraform import cloudflare_list_item.example '<account_id>/<list_id>/<item_id>'
$ terraform import cloudflare_list_item.example '<account_id>/<list_id>/<item_id>'
$ terraform import cloudflare_list_item.example '<account_id>/<list_id>/<item_id>'

View file

@ -1,5 +1,5 @@
resource "cloudflare_pages_domain" "example_pages_domain" {
account_id = "023e105f4ecef8ad9ca31a8372d0c353"
project_name = "this-is-my-project-01"
name = "example.com"
name = "this-is-my-domain-01.com"
}

View file

@ -76,15 +76,15 @@ resource "cloudflare_pages_project" "example_pages_project" {
}
r2_buckets = {
R2_BINDING = {
jurisdiction = "eu"
name = "some-bucket"
jurisdiction = "eu"
}
}
services = {
SERVICE_BINDING = {
service = "example-worker"
entrypoint = "MyHandler"
environment = "production"
service = "example-worker"
}
}
usage_model = "standard"
@ -160,15 +160,15 @@ resource "cloudflare_pages_project" "example_pages_project" {
}
r2_buckets = {
R2_BINDING = {
jurisdiction = "eu"
name = "some-bucket"
jurisdiction = "eu"
}
}
services = {
SERVICE_BINDING = {
service = "example-worker"
entrypoint = "MyHandler"
environment = "production"
service = "example-worker"
}
}
usage_model = "standard"
@ -184,6 +184,7 @@ resource "cloudflare_pages_project" "example_pages_project" {
config = {
deployments_enabled = true
owner = "my-org"
owner_id = "12345678"
path_excludes = ["string"]
path_includes = ["string"]
pr_comments_enabled = true
@ -192,6 +193,7 @@ resource "cloudflare_pages_project" "example_pages_project" {
preview_deployment_setting = "all"
production_branch = "main"
production_deployments_enabled = true
repo_id = "12345678"
repo_name = "my-repo"
}
type = "github"

View file

@ -1,7 +1,7 @@
resource "cloudflare_workers_custom_domain" "example_workers_custom_domain" {
account_id = "9a7806061c88ada191ed06f989cc3dac"
environment = "production"
hostname = "foo.example.com"
service = "foo"
zone_id = "593c9c94de529bbbfaac7c53ced0447d"
environment = "production"
}

View file

@ -1,6 +1,10 @@
resource "cloudflare_zero_trust_device_settings" "example_zero_trust_device_settings" {
account_id = "699d98642c564d2e855e9661899b7252"
disable_for_time = 0
external_emergency_signal_enabled = true
external_emergency_signal_fingerprint = "abcd1234567890abcd1234567890abcd1234567890abcd1234567890abcd1234"
external_emergency_signal_interval = "5m"
external_emergency_signal_url = "https://192.0.2.1/signal"
gateway_proxy_enabled = true
gateway_udp_proxy_enabled = true
root_certificate_installation_enabled = true

2
go.mod
View file

@ -10,7 +10,7 @@ require (
github.com/aws/aws-sdk-go-v2/credentials v1.17.34
github.com/aws/aws-sdk-go-v2/service/s3 v1.63.0
github.com/cloudflare/cloudflare-go v0.115.0
github.com/cloudflare/cloudflare-go/v6 v6.3.0
github.com/cloudflare/cloudflare-go/v6 v6.4.0
github.com/davecgh/go-spew v1.1.1
github.com/hashicorp/go-uuid v1.0.3
github.com/hashicorp/terraform-plugin-docs v0.21.0

4
go.sum
View file

@ -67,8 +67,8 @@ github.com/cloudflare/circl v1.6.1 h1:zqIqSPIndyBh1bjLVVDHMPpVKqp8Su/V+6MeDzzQBQ
github.com/cloudflare/circl v1.6.1/go.mod h1:uddAzsPgqdMAYatqJ0lsjX1oECcQLIlRpzZh3pJrofs=
github.com/cloudflare/cloudflare-go v0.115.0 h1:84/dxeeXweCc0PN5Cto44iTA8AkG1fyT11yPO5ZB7sM=
github.com/cloudflare/cloudflare-go v0.115.0/go.mod h1:Ds6urDwn/TF2uIU24mu7H91xkKP8gSAHxQ44DSZgVmU=
github.com/cloudflare/cloudflare-go/v6 v6.3.0 h1:6oL/iTOv1fYe6nVT14gRQWp49EyJxVe+OPrO92c/mmE=
github.com/cloudflare/cloudflare-go/v6 v6.3.0/go.mod h1:Lj3MUqjvKctXRpdRhLQxZYRrNZHuRs0XYuH8JtQGyoI=
github.com/cloudflare/cloudflare-go/v6 v6.4.0 h1:uigzhmfDfve+zFAYYWIBOAMEuDoPEJXdPS3NBrEm8/Q=
github.com/cloudflare/cloudflare-go/v6 v6.4.0/go.mod h1:Lj3MUqjvKctXRpdRhLQxZYRrNZHuRs0XYuH8JtQGyoI=
github.com/cyphar/filepath-securejoin v0.4.1 h1:JyxxyPEaktOD+GAnqIqTf9A8tHyAG22rowi7HkoSU1s=
github.com/cyphar/filepath-securejoin v0.4.1/go.mod h1:Sdj7gXlvMcPZsbhwhQ33GguGLDGQL7h7bg04C/+u9jI=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=

View file

@ -130,22 +130,22 @@ func TestAccPreCheck_LogpushToken(t *testing.T) {
}
}
// Test helper method checking the Workspace One environment variables are present.
func TestAccPreCheck_WorkspaceOne(t *testing.T) {
if v := os.Getenv("CLOUDFLARE_WORKSPACE_ONE_CLIENT_ID"); v == "" {
t.Fatal("CLOUDFLARE_WORKSPACE_ONE_CLIENT_ID must be set for this acceptance test.")
// Test helper method checking the CrowdStrike environment variables are present.
func TestAccPreCheck_CrowdStrike(t *testing.T) {
if v := os.Getenv("CLOUDFLARE_CROWDSTRIKE_CLIENT_ID"); v == "" {
t.Skip("Skipping acceptance test as CLOUDFLARE_CROWDSTRIKE_CLIENT_ID is not set")
}
if v := os.Getenv("CLOUDFLARE_WORKSPACE_ONE_CLIENT_SECRET"); v == "" {
t.Fatal("CLOUDFLARE_WORKSPACE_ONE_CLIENT_SECRET must be set for this acceptance test.")
if v := os.Getenv("CLOUDFLARE_CROWDSTRIKE_CLIENT_SECRET"); v == "" {
t.Skip("Skipping acceptance test as CLOUDFLARE_CROWDSTRIKE_CLIENT_SECRET is not set")
}
if v := os.Getenv("CLOUDFLARE_WORKSPACE_ONE_API_URL"); v == "" {
t.Fatal("CLOUDFLARE_WORKSPACE_ONE_API_URL must be set for this acceptance test.")
if v := os.Getenv("CLOUDFLARE_CROWDSTRIKE_API_URL"); v == "" {
t.Skip("Skipping acceptance test as CLOUDFLARE_CROWDSTRIKE_API_URL is not set")
}
if v := os.Getenv("CLOUDFLARE_WORKSPACE_ONE_AUTH_URL"); v == "" {
t.Fatal("CLOUDFLARE_WORKSPACE_ONE_AUTH_URL must be set for this acceptance test.")
if v := os.Getenv("CLOUDFLARE_CROWDSTRIKE_CUSTOMER_ID"); v == "" {
t.Skip("Skipping acceptance test as CLOUDFLARE_CROWDSTRIKE_CUSTOMER_ID is not set")
}
}

View file

@ -580,8 +580,11 @@ func TestEncode(t *testing.T) {
t.Run(name, func(t *testing.T) {
buf := bytes.NewBuffer(nil)
writer := multipart.NewWriter(buf)
writer.SetBoundary("xxx")
err := MarshalRoot(test.val, writer)
err := writer.SetBoundary("xxx")
if err != nil {
t.Errorf("serialization of %v\nfailed with error:\n%v", test.val, err)
}
err = MarshalRoot(test.val, writer)
if err != nil {
t.Errorf("serialization of %v\nfailed with error:\n%v", test.val, err)
}

View file

@ -94,10 +94,10 @@ const (
// Some values had to fudged a bit, for example by converting a string to an
// int, or an enum with extra values.
loose exactness = iota
// There are some extra arguments, but other wise it matches the union.
extras
// Exactly right.
exact
// There are some extra arguments, but other wise it matches the union.
// extras
)
type decoderFunc func(node gjson.Result, value reflect.Value, state *decoderState) error
@ -996,7 +996,7 @@ func shouldUpdatePrimitive(value reflect.Value, behavior TerraformUpdateBehavior
func (d *decoderBuilder) newStructTypeDecoder(t reflect.Type) decoderFunc {
// map of json field name to struct field decoders
decoderFields := map[string]decoderField{}
decoderFields := map[string][]decoderField{}
extraDecoder := (*decoderField)(nil)
inlineDecoder := (*decoderField)(nil)
@ -1063,6 +1063,9 @@ func (d *decoderBuilder) newStructTypeDecoder(t reflect.Type) decoderFunc {
if ptag.metadata {
continue
}
if ptag.name == "-" {
continue
}
oldFormat := d.dateFormat
dateFormat, ok := parseFormatStructTag(field)
@ -1074,7 +1077,7 @@ func (d *decoderBuilder) newStructTypeDecoder(t reflect.Type) decoderFunc {
d.dateFormat = "2006-01-02"
}
}
decoderFields[ptag.name] = decoderField{ptag, d.typeDecoder(field.Type), idx, field.Name}
decoderFields[ptag.name] = append(decoderFields[ptag.name], decoderField{ptag, d.typeDecoder(field.Type), idx, field.Name})
d.dateFormat = oldFormat
d.updateBehavior = Always // reset the flag
}
@ -1108,45 +1111,46 @@ func (d *decoderBuilder) newStructTypeDecoder(t reflect.Type) decoderFunc {
nodeMap := node.Map()
for fieldName, itemNode := range nodeMap {
df, explicit := decoderFields[fieldName]
var (
dest reflect.Value
fn decoderFunc
)
if explicit {
fn = df.fn
dest = value.FieldByIndex(df.idx)
}
if !explicit && extraDecoder != nil {
dest = reflect.New(typedExtraType.Elem()).Elem()
fn = extraDecoder.fn
}
dfs, explicit := decoderFields[fieldName]
for i := range max(len(dfs), 1) {
dest, fn := reflect.Value{}, (decoderFunc)(nil)
if explicit {
df := dfs[i]
fn = df.fn
dest = value.FieldByIndex(df.idx)
}
if !explicit && extraDecoder != nil {
dest = reflect.New(typedExtraType.Elem()).Elem()
fn = extraDecoder.fn
}
if dest.IsValid() {
_ = fn(itemNode, dest, state)
}
if dest.IsValid() {
_ = fn(itemNode, dest, state)
}
if !explicit && extraDecoder != nil {
typedExtraFields.SetMapIndex(reflect.ValueOf(fieldName), dest)
if !explicit && extraDecoder != nil {
typedExtraFields.SetMapIndex(reflect.ValueOf(fieldName), dest)
}
}
}
// Handle struct fields that are not present in the JSON
// this is in case they should be initialized to a "null" value
// that is different from the zero value
for fieldName, df := range decoderFields {
_, existsInJson := nodeMap[fieldName]
if existsInJson {
for fieldName, dfs := range decoderFields {
if _, existsInJson := nodeMap[fieldName]; existsInJson {
continue
}
fn := df.fn
dest := value.FieldByIndex(df.idx)
for _, df := range dfs {
fn := df.fn
dest := value.FieldByIndex(df.idx)
// note that we don't include pointers to structs, because
// that could be recursive and would cause an infinite loop.
// if dest.IsValid() && dest.Kind() == reflect.Struct {
if dest.IsValid() {
_ = fn(gjson.Result{}, dest, state)
// note that we don't include pointers to structs, because
// that could be recursive and would cause an infinite loop.
// if dest.IsValid() && dest.Kind() == reflect.Struct {
if dest.IsValid() {
_ = fn(gjson.Result{}, dest, state)
}
}
}
if extraDecoder != nil && typedExtraFields.Len() > 0 {

View file

@ -56,6 +56,7 @@ type Primitives struct {
D float64 `json:"d"`
E float32 `json:"e"`
F []int `json:"f"`
G int `json:"b"`
}
type PrimitivePointers struct {
@ -220,13 +221,13 @@ var tests = map[string]struct {
"primitive_struct": {
`{"a":false,"b":237628372683,"c":654,"d":9999.43,"e":43.76,"f":[1,2,3,4]}`,
Primitives{A: false, B: 237628372683, C: uint(654), D: 9999.43, E: 43.76, F: []int{1, 2, 3, 4}},
Primitives{A: false, B: 237628372683, C: uint(654), D: 9999.43, E: 43.76, F: []int{1, 2, 3, 4}, G: 237628372683},
},
"slices": {
`{"slices":[{"a":false,"b":237628372683,"c":654,"d":9999.43,"e":43.76,"f":[1,2,3,4]}]}`,
Slices{
Slice: []Primitives{{A: false, B: 237628372683, C: uint(654), D: 9999.43, E: 43.76, F: []int{1, 2, 3, 4}}},
Slice: []Primitives{{A: false, B: 237628372683, C: uint(654), D: 9999.43, E: 43.76, F: []int{1, 2, 3, 4}, G: 237628372683}},
},
},
@ -1701,6 +1702,7 @@ func TestDecodeUnsetBehaviour(t *testing.T) {
type StructWithComputedFields struct {
RegStr types.String `tfsdk:"str" json:"str,optional"`
DerivedStr types.String `tfsdk:"str" json:"str,optional"`
CompStr types.String `tfsdk:"comp_str" json:"comp_str,computed"`
CompOptStr types.String `tfsdk:"opt_str" json:"opt_str,computed_optional"`
CompTime timetypes.RFC3339 `tfsdk:"time" json:"time,computed"`
@ -2315,6 +2317,7 @@ var decode_computed_only_tests = map[string]struct {
exampleNestedJson,
StructWithComputedFields{
RegStr: types.StringNull(),
DerivedStr: types.StringNull(),
CompStr: types.StringNull(),
CompOptStr: types.StringNull(),
CompTime: timetypes.NewRFC3339Null(),
@ -2336,6 +2339,7 @@ var decode_computed_only_tests = map[string]struct {
},
StructWithComputedFields{
RegStr: types.StringNull(),
DerivedStr: types.StringNull(),
CompStr: types.StringValue("comp_str"),
CompOptStr: types.StringValue("opt_str"),
CompTime: timetypes.NewRFC3339TimeValue(time.Date(2006, time.January, 2, 15, 4, 5, 0, time.UTC)),
@ -2372,6 +2376,7 @@ var decode_computed_only_tests = map[string]struct {
exampleNestedJson,
StructWithComputedFields{
RegStr: types.StringUnknown(),
DerivedStr: types.StringUnknown(),
CompStr: types.StringUnknown(),
CompOptStr: types.StringUnknown(),
CompTime: timetypes.NewRFC3339Unknown(),
@ -2388,6 +2393,7 @@ var decode_computed_only_tests = map[string]struct {
},
StructWithComputedFields{
RegStr: types.StringUnknown(),
DerivedStr: types.StringUnknown(),
CompStr: types.StringValue("comp_str"),
CompOptStr: types.StringValue("opt_str"),
CompTime: timetypes.NewRFC3339TimeValue(time.Date(2006, time.January, 2, 15, 4, 5, 0, time.UTC)),
@ -2418,6 +2424,7 @@ var decode_computed_only_tests = map[string]struct {
exampleNestedJson,
StructWithComputedFields{
RegStr: types.StringValue("existing_str"),
DerivedStr: types.StringValue("existing_str"),
CompStr: types.StringValue("existing_comp_str"),
CompOptStr: types.StringValue("existing_opt_str"),
CompTime: timetypes.NewRFC3339TimeValue(time.Date(1970, time.January, 2, 15, 4, 5, 0, time.UTC)),
@ -2449,6 +2456,7 @@ var decode_computed_only_tests = map[string]struct {
},
StructWithComputedFields{
RegStr: types.StringValue("existing_str"),
DerivedStr: types.StringValue("existing_str"),
CompStr: types.StringValue("comp_str"),
CompOptStr: types.StringValue("existing_opt_str"),
CompTime: timetypes.NewRFC3339TimeValue(time.Date(2006, time.January, 2, 15, 4, 5, 0, time.UTC)),
@ -2492,6 +2500,7 @@ var decode_computed_only_tests = map[string]struct {
`{}`,
StructWithComputedFields{
RegStr: types.StringValue("existing_str"),
DerivedStr: types.StringValue("existing_str"),
CompStr: types.StringValue("existing_comp_str"),
CompOptStr: types.StringValue("existing_opt_str"),
CompTime: timetypes.NewRFC3339TimeValue(time.Date(1970, time.January, 2, 15, 4, 5, 0, time.UTC)),
@ -2526,6 +2535,7 @@ var decode_computed_only_tests = map[string]struct {
},
StructWithComputedFields{
RegStr: types.StringValue("existing_str"),
DerivedStr: types.StringValue("existing_str"),
CompStr: types.StringNull(),
CompOptStr: types.StringValue("existing_opt_str"),
CompTime: timetypes.NewRFC3339Null(),

View file

@ -17,13 +17,17 @@ import (
func Middleware(ctx context.Context) option.Middleware {
return func(req *http.Request, next option.MiddlewareNext) (*http.Response, error) {
if req != nil {
LogRequest(ctx, req)
if err := LogRequest(ctx, req); err != nil {
return nil, err
}
}
resp, err := next(req)
if resp != nil {
LogResponse(ctx, resp)
if err := LogResponse(ctx, resp); err != nil {
return nil, err
}
}
return resp, err

View file

@ -234,7 +234,7 @@ func (r *AccessRuleResource) Delete(ctx context.Context, req resource.DeleteRequ
}
func (r *AccessRuleResource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) {
var data *AccessRuleModel = new(AccessRuleModel)
var data = new(AccessRuleModel)
params := firewall.AccessRuleGetParams{}
path_accounts_or_zones, path_account_id_or_zone_id := "", ""

View file

@ -1,15 +1,91 @@
package access_rule_test
import (
"context"
"fmt"
"os"
"testing"
"github.com/cloudflare/cloudflare-go"
"github.com/cloudflare/terraform-provider-cloudflare/internal/acctest"
"github.com/cloudflare/terraform-provider-cloudflare/internal/consts"
"github.com/cloudflare/terraform-provider-cloudflare/internal/utils"
"github.com/hashicorp/terraform-plugin-log/tflog"
"github.com/hashicorp/terraform-plugin-testing/helper/resource"
)
func TestMain(m *testing.M) {
resource.TestMain(m)
}
func init() {
resource.AddTestSweepers("cloudflare_access_rule", &resource.Sweeper{
Name: "cloudflare_access_rule",
F: testSweepCloudflareAccessRules,
})
}
func testSweepCloudflareAccessRules(r string) error {
ctx := context.Background()
client, clientErr := acctest.SharedV1Client()
if clientErr != nil {
tflog.Error(ctx, fmt.Sprintf("Failed to create Cloudflare client: %s", clientErr))
return clientErr
}
// Sweep account-level access rules
accountID := os.Getenv("CLOUDFLARE_ACCOUNT_ID")
if accountID != "" {
accountRulesResp, err := client.ListAccountAccessRules(ctx, accountID, cloudflare.AccessRule{}, 1)
if err != nil {
tflog.Error(ctx, fmt.Sprintf("Failed to fetch account access rules: %s", err))
return fmt.Errorf("failed to fetch account access rules: %w", err)
}
for _, rule := range accountRulesResp.Result {
// Use standard filtering helper on the notes field
if !utils.ShouldSweepResource(rule.Notes) {
continue
}
tflog.Info(ctx, fmt.Sprintf("Deleting account access rule: %s (account: %s)", rule.ID, accountID))
_, err := client.DeleteAccountAccessRule(ctx, accountID, rule.ID)
if err != nil {
tflog.Error(ctx, fmt.Sprintf("Failed to delete account access rule %s: %s", rule.ID, err))
continue
}
tflog.Info(ctx, fmt.Sprintf("Deleted account access rule: %s", rule.ID))
}
}
// Sweep zone-level access rules
zoneID := os.Getenv("CLOUDFLARE_ZONE_ID")
if zoneID != "" {
zoneRulesResp, err := client.ListZoneAccessRules(ctx, zoneID, cloudflare.AccessRule{}, 1)
if err != nil {
tflog.Error(ctx, fmt.Sprintf("Failed to fetch zone access rules: %s", err))
return fmt.Errorf("failed to fetch zone access rules: %w", err)
}
for _, rule := range zoneRulesResp.Result {
// Use standard filtering helper on the notes field
if !utils.ShouldSweepResource(rule.Notes) {
continue
}
tflog.Info(ctx, fmt.Sprintf("Deleting zone access rule: %s (zone: %s)", rule.ID, zoneID))
_, err := client.DeleteZoneAccessRule(ctx, zoneID, rule.ID)
if err != nil {
tflog.Error(ctx, fmt.Sprintf("Failed to delete zone access rule %s: %s", rule.ID, err))
continue
}
tflog.Info(ctx, fmt.Sprintf("Deleted zone access rule: %s", rule.ID))
}
}
return nil
}
func TestAccCloudflareAccessRule_AccountASN(t *testing.T) {
rnd := utils.GenerateRandomResourceName()
name := "cloudflare_access_rule." + rnd

View file

@ -199,7 +199,7 @@ func (r *AccountResource) Delete(ctx context.Context, req resource.DeleteRequest
}
func (r *AccountResource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) {
var data *AccountModel = new(AccountModel)
var data = new(AccountModel)
path := ""
diags := importpath.ParseImportID(

View file

@ -3,7 +3,6 @@ package account_test
import (
"context"
"fmt"
"strings"
"testing"
"github.com/cloudflare/cloudflare-go/v6"
@ -11,6 +10,7 @@ import (
"github.com/cloudflare/terraform-provider-cloudflare/internal/acctest"
"github.com/cloudflare/terraform-provider-cloudflare/internal/utils"
"github.com/hashicorp/terraform-plugin-testing/helper/resource"
"github.com/hashicorp/terraform-plugin-log/tflog"
"github.com/hashicorp/terraform-plugin-testing/knownvalue"
"github.com/hashicorp/terraform-plugin-testing/plancheck"
"github.com/hashicorp/terraform-plugin-testing/statecheck"
@ -36,19 +36,29 @@ func testSweepCloudflareAccount(r string) error {
// List all accounts to find test accounts to sweep
accountsResp, err := client.Accounts.List(ctx, cfaccounts.AccountListParams{})
if err != nil {
return fmt.Errorf("failed to list accounts: %w", err)
tflog.Error(ctx, fmt.Sprintf("Failed to list accounts: %s", err))
return err
}
if len(accountsResp.Result) == 0 {
tflog.Info(ctx, "No Cloudflare accounts to sweep")
return nil
}
for _, account := range accountsResp.Result {
// Only delete accounts that look like test accounts (contain "tf-acc-test" prefix)
if strings.Contains(account.Name, "tf-acc-test") {
_, err := client.Accounts.Delete(ctx, cfaccounts.AccountDeleteParams{
AccountID: cloudflare.F(account.ID),
})
if err != nil {
return fmt.Errorf("failed to delete account %s: %w", account.ID, err)
}
if !utils.ShouldSweepResource(account.Name) {
continue
}
tflog.Info(ctx, fmt.Sprintf("Deleting account: %s (%s)", account.Name, account.ID))
_, err := client.Accounts.Delete(ctx, cfaccounts.AccountDeleteParams{
AccountID: cloudflare.F(account.ID),
})
if err != nil {
tflog.Error(ctx, fmt.Sprintf("Failed to delete account %s (%s): %s", account.Name, account.ID, err))
continue
}
tflog.Info(ctx, fmt.Sprintf("Deleted account: %s (%s)", account.Name, account.ID))
}
return nil

View file

@ -210,7 +210,7 @@ func (r *AccountDNSSettingsInternalViewResource) Delete(ctx context.Context, req
}
func (r *AccountDNSSettingsInternalViewResource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) {
var data *AccountDNSSettingsInternalViewModel = new(AccountDNSSettingsInternalViewModel)
var data = new(AccountDNSSettingsInternalViewModel)
path_account_id := ""
path_view_id := ""

View file

@ -107,7 +107,7 @@ func unmarshalCustom(data []byte, configuredModel *AccountMemberModel) (*Account
if err := json.Unmarshal(data, &fullResponse); err == nil && len(fullResponse.Result.Policies) > 0 {
policies := append([]AccountMemberPoliciesModel(nil), fullResponse.Result.Policies...)
policiesList, diags := customfield.NewObjectList(context.Background(), policies)
policiesList, diags := customfield.NewObjectSet(context.Background(), policies)
if !diags.HasError() {
result.Policies = policiesList
} else {

View file

@ -13,13 +13,13 @@ type AccountMemberResultEnvelope struct {
}
type AccountMemberModel struct {
ID types.String `tfsdk:"id" json:"id,computed"`
AccountID types.String `tfsdk:"account_id" path:"account_id,required"`
Email types.String `tfsdk:"email" json:"email,required"`
Status types.String `tfsdk:"status" json:"status,computed_optional"`
Roles *[]types.String `tfsdk:"roles" json:"roles,optional,no_refresh"`
Policies customfield.NestedObjectList[AccountMemberPoliciesModel] `tfsdk:"policies" json:"policies,computed_optional"`
User customfield.NestedObject[AccountMemberUserModel] `tfsdk:"user" json:"user,computed"`
ID types.String `tfsdk:"id" json:"id,computed"`
AccountID types.String `tfsdk:"account_id" path:"account_id,required"`
Email types.String `tfsdk:"email" json:"email,required"`
Status types.String `tfsdk:"status" json:"status,computed_optional"`
Roles *[]types.String `tfsdk:"roles" json:"roles,optional,no_refresh"`
Policies customfield.NestedObjectSet[AccountMemberPoliciesModel] `tfsdk:"policies" json:"policies,computed_optional"`
User customfield.NestedObject[AccountMemberUserModel] `tfsdk:"user" json:"user,computed"`
}
func (m AccountMemberModel) MarshalJSON() (data []byte, err error) {
@ -31,10 +31,9 @@ func (m AccountMemberModel) MarshalJSONForUpdate(state AccountMemberModel) (data
}
type AccountMemberPoliciesModel struct {
ID types.String `tfsdk:"id" json:"id,computed,force_encode,encode_state_for_unknown"`
Access types.String `tfsdk:"access" json:"access,required"`
PermissionGroups *[]*AccountMemberPoliciesPermissionGroupsModel `tfsdk:"permission_groups" json:"permission_groups,required"`
ResourceGroups *[]*AccountMemberPoliciesResourceGroupsModel `tfsdk:"resource_groups" json:"resource_groups,required"`
Access types.String `tfsdk:"access" json:"access,required"`
PermissionGroups customfield.NestedObjectSet[AccountMemberPoliciesPermissionGroupsModel] `tfsdk:"permission_groups" json:"permission_groups,required"`
ResourceGroups customfield.NestedObjectSet[AccountMemberPoliciesResourceGroupsModel] `tfsdk:"resource_groups" json:"resource_groups,required"`
}
type AccountMemberPoliciesPermissionGroupsModel struct {

View file

@ -206,7 +206,7 @@ func (r *AccountMemberResource) Delete(ctx context.Context, req resource.DeleteR
}
func (r *AccountMemberResource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) {
var data *AccountMemberModel = new(AccountMemberModel)
var data = new(AccountMemberModel)
path_account_id := ""
path_member_id := ""

View file

@ -1,13 +1,21 @@
package account_member_test
import (
"context"
"fmt"
"os"
"strings"
"testing"
"github.com/cloudflare/cloudflare-go"
cloudflarev6 "github.com/cloudflare/cloudflare-go/v6"
"github.com/cloudflare/cloudflare-go/v6/accounts"
"github.com/cloudflare/cloudflare-go/v6/iam"
"github.com/cloudflare/cloudflare-go/v6/zones"
"github.com/cloudflare/terraform-provider-cloudflare/internal/acctest"
"github.com/cloudflare/terraform-provider-cloudflare/internal/consts"
"github.com/cloudflare/terraform-provider-cloudflare/internal/utils"
"github.com/hashicorp/terraform-plugin-log/tflog"
"github.com/hashicorp/terraform-plugin-testing/helper/resource"
"github.com/hashicorp/terraform-plugin-testing/knownvalue"
"github.com/hashicorp/terraform-plugin-testing/plancheck"
@ -23,6 +31,81 @@ import (
// For comprehensive resource lifecycle testing, we rely on the built-in Terraform
// test framework validation and the resource's own Delete implementation.
func TestMain(m *testing.M) {
resource.TestMain(m)
}
func init() {
resource.AddTestSweepers("cloudflare_account_member", &resource.Sweeper{
Name: "cloudflare_account_member",
F: testSweepCloudflareAccountMembers,
})
}
func testSweepCloudflareAccountMembers(r string) error {
ctx := context.Background()
client, clientErr := acctest.SharedV1Client()
if clientErr != nil {
tflog.Error(ctx, fmt.Sprintf("Failed to create Cloudflare client: %s", clientErr))
return clientErr
}
accountID := os.Getenv("CLOUDFLARE_ACCOUNT_ID")
if accountID == "" {
tflog.Info(ctx, "Skipping account members sweep: CLOUDFLARE_ACCOUNT_ID not set")
return nil
}
members, _, err := client.AccountMembers(ctx, accountID, cloudflare.PaginationOptions{})
if err != nil {
tflog.Error(ctx, fmt.Sprintf("Failed to fetch account members: %s", err))
return fmt.Errorf("failed to fetch account members: %w", err)
}
if len(members) == 0 {
tflog.Info(ctx, "No account members to sweep")
return nil
}
for _, member := range members {
// Only sweep test members with @example.com emails or emails matching test patterns
if !strings.HasSuffix(member.User.Email, "@example.com") && !utils.ShouldSweepResource(member.User.Email) {
continue
}
tflog.Info(ctx, fmt.Sprintf("Deleting account member: %s (email: %s, account: %s)", member.ID, member.User.Email, accountID))
err := client.DeleteAccountMember(ctx, accountID, member.ID)
if err != nil {
tflog.Error(ctx, fmt.Sprintf("Failed to delete account member %s: %s", member.ID, err))
continue
}
tflog.Info(ctx, fmt.Sprintf("Deleted account member: %s", member.ID))
}
// List all Resource Groups
client2 := acctest.SharedClient()
resourceGroups, err := client2.IAM.ResourceGroups.List(ctx, iam.ResourceGroupListParams{
AccountID: cloudflarev6.String(accountID),
})
if err != nil {
return fmt.Errorf("failed to fetch account tokens: %w", err)
}
for _, resourceGroup := range resourceGroups.Result {
// Only sweep test resource groups with names matching test patterns
if utils.ShouldSweepResource(resourceGroup.Name) {
err = deleteDomainGroup(accountID, resourceGroup.ID)
if err != nil {
tflog.Error(ctx, fmt.Sprintf("Failed to delete resource group %s: %s", resourceGroup.ID, err))
continue
}
tflog.Info(ctx, fmt.Sprintf("Deleted domain group: %s", resourceGroup.ID))
}
}
return nil
}
func TestAccCloudflareAccountMember_Basic(t *testing.T) {
// Temporarily unset CLOUDFLARE_API_TOKEN as the API token won't have
// permission to manage account members.
@ -84,11 +167,11 @@ func TestAccCloudflareAccountMember_Import(t *testing.T) {
},
},
{
ResourceName: resourceName,
ImportState: true,
ImportStateVerify: true,
ImportStateIdPrefix: fmt.Sprintf("%s/", accountID),
ImportStateVerifyIgnore: []string{"policies.0.resource_groups.0.id"},
ResourceName: resourceName,
ImportState: true,
ImportStateVerify: true,
ImportStateIdPrefix: fmt.Sprintf("%s/", accountID),
ImportStateVerifyIgnore: []string{"policies.0.resource_groups.0.id"},
},
},
})
@ -126,7 +209,6 @@ func TestAccCloudflareAccountMember_DirectAdd(t *testing.T) {
})
}
func testCloudflareAccountMemberBasicConfig(accountID, emailAddress string) string {
return acctest.LoadTestCase("cloudflareaccountmemberbasicconfig.tf", accountID, emailAddress)
}
@ -136,13 +218,16 @@ func TestAccCloudflareAccountMember_RolesUpdate(t *testing.T) {
if os.Getenv("CLOUDFLARE_API_TOKEN") != "" {
t.Setenv("CLOUDFLARE_API_TOKEN", "")
}
if os.Getenv("TF_ACC") == "" {
t.Skip("Acceptance tests skipped unless env 'TF_ACC' set")
}
rnd := utils.GenerateRandomResourceName()
resourceName := "cloudflare_account_member." + rnd
resourceName := "cloudflare_account_member.test_member"
accountID := os.Getenv("CLOUDFLARE_ACCOUNT_ID")
email := fmt.Sprintf("%s@example.com", rnd)
initialRole := "05784afa30c1afe1440e79d9351c7430"
updatedRole := "33666b9c79b9a5273fc7344ff42f953d"
initialRoleID := getRoleId(t, accountID, "Administrator")
updatedRoleID := getRoleId(t, accountID, "Super Administrator - All Privileges")
resource.Test(t, resource.TestCase{
PreCheck: func() {
@ -153,45 +238,49 @@ func TestAccCloudflareAccountMember_RolesUpdate(t *testing.T) {
Steps: []resource.TestStep{
{
// Create with initial role
Config: testCloudflareAccountMemberRolesConfig(rnd, email, accountID, initialRole),
Config: testCloudflareAccountMemberRolesConfig(email, accountID, initialRoleID),
ConfigStateChecks: []statecheck.StateCheck{
statecheck.ExpectKnownValue(resourceName, tfjsonpath.New(consts.AccountIDSchemaKey), knownvalue.StringExact(accountID)),
statecheck.ExpectKnownValue(resourceName, tfjsonpath.New("email"), knownvalue.StringExact(email)),
statecheck.ExpectKnownValue(resourceName, tfjsonpath.New("roles"), knownvalue.ListSizeExact(1)),
statecheck.ExpectKnownValue(resourceName, tfjsonpath.New("roles").AtSliceIndex(0), knownvalue.StringExact(initialRole)),
statecheck.ExpectKnownValue(resourceName, tfjsonpath.New("roles").AtSliceIndex(0), knownvalue.StringExact(initialRoleID)),
},
},
{
// Update role in-place (tests custom marshal logic)
Config: testCloudflareAccountMemberRolesConfig(rnd, email, accountID, updatedRole),
Config: testCloudflareAccountMemberRolesConfig(email, accountID, updatedRoleID),
ConfigPlanChecks: resource.ConfigPlanChecks{
PreApply: []plancheck.PlanCheck{
plancheck.ExpectResourceAction(resourceName, plancheck.ResourceActionUpdate),
plancheck.ExpectKnownValue(resourceName, tfjsonpath.New("roles").AtSliceIndex(0), knownvalue.StringExact(updatedRole)),
plancheck.ExpectKnownValue(resourceName, tfjsonpath.New("roles").AtSliceIndex(0), knownvalue.StringExact(updatedRoleID)),
},
},
ConfigStateChecks: []statecheck.StateCheck{
statecheck.ExpectKnownValue(resourceName, tfjsonpath.New(consts.AccountIDSchemaKey), knownvalue.StringExact(accountID)),
statecheck.ExpectKnownValue(resourceName, tfjsonpath.New("email"), knownvalue.StringExact(email)),
statecheck.ExpectKnownValue(resourceName, tfjsonpath.New("roles"), knownvalue.ListSizeExact(1)),
statecheck.ExpectKnownValue(resourceName, tfjsonpath.New("roles").AtSliceIndex(0), knownvalue.StringExact(updatedRole)),
statecheck.ExpectKnownValue(resourceName, tfjsonpath.New("roles").AtSliceIndex(0), knownvalue.StringExact(updatedRoleID)),
},
},
},
})
}
// Test that using roles ignores auto-generated policies to avoid diffs
func TestAccCloudflareAccountMember_RolesVsPolicies(t *testing.T) {
// Test that using roles ignores auto-generated policies to avoid diffs
if os.Getenv("CLOUDFLARE_API_TOKEN") != "" {
t.Setenv("CLOUDFLARE_API_TOKEN", "")
}
if os.Getenv("TF_ACC") == "" {
t.Skip("Acceptance tests skipped unless env 'TF_ACC' set")
}
rnd := utils.GenerateRandomResourceName()
resourceName := "cloudflare_account_member." + rnd
resourceName := "cloudflare_account_member.test_member"
accountID := os.Getenv("CLOUDFLARE_ACCOUNT_ID")
email := fmt.Sprintf("%s@example.com", rnd)
roleID := "05784afa30c1afe1440e79d9351c7430"
roleID := getRoleId(t, accountID, "Administrator")
resource.Test(t, resource.TestCase{
PreCheck: func() {
@ -201,7 +290,7 @@ func TestAccCloudflareAccountMember_RolesVsPolicies(t *testing.T) {
ProtoV6ProviderFactories: acctest.TestAccProtoV6ProviderFactories,
Steps: []resource.TestStep{
{
Config: testCloudflareAccountMemberRolesConfig(rnd, email, accountID, roleID),
Config: testCloudflareAccountMemberRolesConfig(email, accountID, roleID),
ConfigStateChecks: []statecheck.StateCheck{
statecheck.ExpectKnownValue(resourceName, tfjsonpath.New(consts.AccountIDSchemaKey), knownvalue.StringExact(accountID)),
statecheck.ExpectKnownValue(resourceName, tfjsonpath.New("email"), knownvalue.StringExact(email)),
@ -213,7 +302,7 @@ func TestAccCloudflareAccountMember_RolesVsPolicies(t *testing.T) {
},
{
// Second apply should not cause any changes (stable state)
Config: testCloudflareAccountMemberRolesConfig(rnd, email, accountID, roleID),
Config: testCloudflareAccountMemberRolesConfig(email, accountID, roleID),
ConfigPlanChecks: resource.ConfigPlanChecks{
PreApply: []plancheck.PlanCheck{
plancheck.ExpectResourceAction(resourceName, plancheck.ResourceActionNoop),
@ -233,8 +322,8 @@ func testCloudflareAccountMemberDirectAdd(accountID, emailAddress string) string
return acctest.LoadTestCase("cloudflareaccountmemberdirectadd.tf", accountID, emailAddress)
}
func testCloudflareAccountMemberRolesConfig(resourceID, emailAddress, accountID, roleID string) string {
return acctest.LoadTestCase("cloudflareaccountmemberrolesconfig.tf", resourceID, emailAddress, accountID, roleID)
func testCloudflareAccountMemberRolesConfig(emailAddress, accountID, roleID string) string {
return acctest.LoadTestCase("cloudflareaccountmemberrolesconfig.tf", emailAddress, accountID, roleID)
}
func TestAccCloudflareAccountMember_Policies(t *testing.T) {
@ -244,11 +333,15 @@ func TestAccCloudflareAccountMember_Policies(t *testing.T) {
t.Setenv("CLOUDFLARE_API_TOKEN", "")
}
if os.Getenv("TF_ACC") == "" {
t.Skip("Acceptance tests skipped unless env 'TF_ACC' set")
}
rnd := utils.GenerateRandomResourceName()
resourceName := "cloudflare_account_member." + rnd
resourceName := "cloudflare_account_member.test_member"
accountID := os.Getenv("CLOUDFLARE_ACCOUNT_ID")
email := fmt.Sprintf("%s@example.com", rnd)
permissionGroupID := "8e23b19e4e0d44c29d239c5688ba8cbb"
permissionGroupID := getPermissionGroupId(t, accountID, "all_privileges")
resource.Test(t, resource.TestCase{
PreCheck: func() {
@ -258,7 +351,7 @@ func TestAccCloudflareAccountMember_Policies(t *testing.T) {
ProtoV6ProviderFactories: acctest.TestAccProtoV6ProviderFactories,
Steps: []resource.TestStep{
{
Config: testCloudflareAccountMemberPoliciesConfig(accountID, rnd, accountID, email, permissionGroupID),
Config: testCloudflareAccountMemberPoliciesConfig(accountID, email, permissionGroupID),
ConfigStateChecks: []statecheck.StateCheck{
statecheck.ExpectKnownValue(resourceName, tfjsonpath.New(consts.AccountIDSchemaKey), knownvalue.StringExact(accountID)),
statecheck.ExpectKnownValue(resourceName, tfjsonpath.New("email"), knownvalue.StringExact(email)),
@ -271,7 +364,7 @@ func TestAccCloudflareAccountMember_Policies(t *testing.T) {
},
{
// Second apply should not cause any changes (stable state)
Config: testCloudflareAccountMemberPoliciesConfig(accountID, rnd, accountID, email, permissionGroupID),
Config: testCloudflareAccountMemberPoliciesConfig(accountID, email, permissionGroupID),
ConfigPlanChecks: resource.ConfigPlanChecks{
PreApply: []plancheck.PlanCheck{
plancheck.ExpectResourceAction(resourceName, plancheck.ResourceActionNoop),
@ -287,6 +380,206 @@ func TestAccCloudflareAccountMember_Policies(t *testing.T) {
})
}
func testCloudflareAccountMemberPoliciesConfig(dataSourceAccountID, resourceID, accountID, emailAddress, permissionGroupID string) string {
return acctest.LoadTestCase("cloudflareaccountmemberpoliciesconfig.tf", dataSourceAccountID, resourceID, accountID, emailAddress, permissionGroupID)
func TestAccCloudflareAccountMember_PoliciesAddResourceGroup(t *testing.T) {
t.Skip("Needs a DSR enabled user")
// Temporarily unset CLOUDFLARE_API_TOKEN as the API token won't have
// permission to manage account members.
if os.Getenv("CLOUDFLARE_API_TOKEN") != "" {
t.Setenv("CLOUDFLARE_API_TOKEN", "")
}
if os.Getenv("TF_ACC") == "" {
t.Skip("Acceptance tests skipped unless env 'TF_ACC' set")
}
rnd := utils.GenerateRandomResourceName()
resourceName := "cloudflare_account_member.test_member"
accountID := os.Getenv("CLOUDFLARE_ACCOUNT_ID")
email := fmt.Sprintf("%s@example.com", rnd)
permissionGroupID := getPermissionGroupId(t, accountID, "domain_admin_readonly")
zones := getDomains(t, accountID)
if len(zones) < 2 {
t.Skip("Not enough domains found, need 2 for this test")
}
domainGroupID1 := createDomainGroup(t, rnd, accountID, zones[0].ID)
domainGroupID2 := createDomainGroup(t, rnd, accountID, zones[1].ID)
t.Cleanup(func() {
deleteDomainGroup(accountID, domainGroupID1)
deleteDomainGroup(accountID, domainGroupID2)
})
resource.Test(t, resource.TestCase{
PreCheck: func() {
acctest.TestAccPreCheck_AccountID(t)
acctest.TestAccPreCheck_Credentials(t)
},
ProtoV6ProviderFactories: acctest.TestAccProtoV6ProviderFactories,
Steps: []resource.TestStep{
{
Config: acctest.LoadTestCase("cloudflare_account_member-add-resource-group1.tf", accountID, email, permissionGroupID, domainGroupID1),
ConfigStateChecks: []statecheck.StateCheck{
statecheck.ExpectKnownValue(resourceName, tfjsonpath.New(consts.AccountIDSchemaKey), knownvalue.StringExact(accountID)),
statecheck.ExpectKnownValue(resourceName, tfjsonpath.New("email"), knownvalue.StringExact(email)),
statecheck.ExpectKnownValue(resourceName, tfjsonpath.New("policies"), knownvalue.ListSizeExact(1)),
statecheck.ExpectKnownValue(resourceName, tfjsonpath.New("policies").AtSliceIndex(0).AtMapKey("access"), knownvalue.StringExact("allow")),
statecheck.ExpectKnownValue(resourceName, tfjsonpath.New("policies").AtSliceIndex(0).AtMapKey("permission_groups"), knownvalue.ListSizeExact(1)),
statecheck.ExpectKnownValue(resourceName, tfjsonpath.New("policies").AtSliceIndex(0).AtMapKey("permission_groups").AtSliceIndex(0).AtMapKey("id"), knownvalue.StringExact(permissionGroupID)),
statecheck.ExpectKnownValue(resourceName, tfjsonpath.New("policies").AtSliceIndex(0).AtMapKey("resource_groups"), knownvalue.ListSizeExact(1)),
statecheck.ExpectKnownValue(resourceName, tfjsonpath.New("policies").AtSliceIndex(0).AtMapKey("resource_groups").AtSliceIndex(0).AtMapKey("id"), knownvalue.StringExact(domainGroupID1)),
},
},
{
// Another apply should not cause any changes (stable state)
Config: acctest.LoadTestCase("cloudflare_account_member-add-resource-group1.tf", accountID, email, permissionGroupID, domainGroupID1),
ConfigPlanChecks: resource.ConfigPlanChecks{
PreApply: []plancheck.PlanCheck{
plancheck.ExpectResourceAction(resourceName, plancheck.ResourceActionNoop),
},
},
ConfigStateChecks: []statecheck.StateCheck{
statecheck.ExpectKnownValue(resourceName, tfjsonpath.New(consts.AccountIDSchemaKey), knownvalue.StringExact(accountID)),
statecheck.ExpectKnownValue(resourceName, tfjsonpath.New("email"), knownvalue.StringExact(email)),
statecheck.ExpectKnownValue(resourceName, tfjsonpath.New("policies"), knownvalue.ListSizeExact(1)),
statecheck.ExpectKnownValue(resourceName, tfjsonpath.New("policies").AtSliceIndex(0).AtMapKey("access"), knownvalue.StringExact("allow")),
statecheck.ExpectKnownValue(resourceName, tfjsonpath.New("policies").AtSliceIndex(0).AtMapKey("permission_groups"), knownvalue.ListSizeExact(1)),
statecheck.ExpectKnownValue(resourceName, tfjsonpath.New("policies").AtSliceIndex(0).AtMapKey("permission_groups").AtSliceIndex(0).AtMapKey("id"), knownvalue.StringExact(permissionGroupID)),
statecheck.ExpectKnownValue(resourceName, tfjsonpath.New("policies").AtSliceIndex(0).AtMapKey("resource_groups"), knownvalue.ListSizeExact(1)),
statecheck.ExpectKnownValue(resourceName, tfjsonpath.New("policies").AtSliceIndex(0).AtMapKey("resource_groups").AtSliceIndex(0).AtMapKey("id"), knownvalue.StringExact(domainGroupID1)),
},
},
{
Config: acctest.LoadTestCase("cloudflare_account_member-add-resource-group2.tf", accountID, email, permissionGroupID, domainGroupID1, domainGroupID2),
ConfigStateChecks: []statecheck.StateCheck{
statecheck.ExpectKnownValue(resourceName, tfjsonpath.New(consts.AccountIDSchemaKey), knownvalue.StringExact(accountID)),
statecheck.ExpectKnownValue(resourceName, tfjsonpath.New("email"), knownvalue.StringExact(email)),
statecheck.ExpectKnownValue(resourceName, tfjsonpath.New("policies"), knownvalue.ListSizeExact(1)),
statecheck.ExpectKnownValue(resourceName, tfjsonpath.New("policies").AtSliceIndex(0).AtMapKey("access"), knownvalue.StringExact("allow")),
statecheck.ExpectKnownValue(resourceName, tfjsonpath.New("policies").AtSliceIndex(0).AtMapKey("permission_groups"), knownvalue.ListSizeExact(1)),
statecheck.ExpectKnownValue(resourceName, tfjsonpath.New("policies").AtSliceIndex(0).AtMapKey("permission_groups").AtSliceIndex(0).AtMapKey("id"), knownvalue.StringExact(permissionGroupID)),
statecheck.ExpectKnownValue(resourceName, tfjsonpath.New("policies").AtSliceIndex(0).AtMapKey("resource_groups"), knownvalue.ListSizeExact(2)),
statecheck.ExpectKnownValue(resourceName, tfjsonpath.New("policies").AtSliceIndex(0).AtMapKey("resource_groups").AtSliceIndex(0).AtMapKey("id"), knownvalue.StringExact(domainGroupID1)),
statecheck.ExpectKnownValue(resourceName, tfjsonpath.New("policies").AtSliceIndex(0).AtMapKey("resource_groups").AtSliceIndex(1).AtMapKey("id"), knownvalue.StringExact(domainGroupID2)),
},
},
{
// Another apply should not cause any changes (stable state)
Config: acctest.LoadTestCase("cloudflare_account_member-add-resource-group2.tf", accountID, email, permissionGroupID, domainGroupID1, domainGroupID2),
ConfigPlanChecks: resource.ConfigPlanChecks{
PreApply: []plancheck.PlanCheck{
plancheck.ExpectResourceAction(resourceName, plancheck.ResourceActionNoop),
},
},
ConfigStateChecks: []statecheck.StateCheck{
statecheck.ExpectKnownValue(resourceName, tfjsonpath.New(consts.AccountIDSchemaKey), knownvalue.StringExact(accountID)),
statecheck.ExpectKnownValue(resourceName, tfjsonpath.New("email"), knownvalue.StringExact(email)),
statecheck.ExpectKnownValue(resourceName, tfjsonpath.New("policies"), knownvalue.ListSizeExact(1)),
statecheck.ExpectKnownValue(resourceName, tfjsonpath.New("policies").AtSliceIndex(0).AtMapKey("access"), knownvalue.StringExact("allow")),
statecheck.ExpectKnownValue(resourceName, tfjsonpath.New("policies").AtSliceIndex(0).AtMapKey("permission_groups"), knownvalue.ListSizeExact(1)),
statecheck.ExpectKnownValue(resourceName, tfjsonpath.New("policies").AtSliceIndex(0).AtMapKey("permission_groups").AtSliceIndex(0).AtMapKey("id"), knownvalue.StringExact(permissionGroupID)),
statecheck.ExpectKnownValue(resourceName, tfjsonpath.New("policies").AtSliceIndex(0).AtMapKey("resource_groups"), knownvalue.ListSizeExact(2)),
statecheck.ExpectKnownValue(resourceName, tfjsonpath.New("policies").AtSliceIndex(0).AtMapKey("resource_groups").AtSliceIndex(0).AtMapKey("id"), knownvalue.StringExact(domainGroupID1)),
statecheck.ExpectKnownValue(resourceName, tfjsonpath.New("policies").AtSliceIndex(0).AtMapKey("resource_groups").AtSliceIndex(1).AtMapKey("id"), knownvalue.StringExact(domainGroupID2)),
},
},
{
ResourceName: resourceName,
ImportState: true,
ImportStateVerify: true,
ImportStateIdPrefix: fmt.Sprintf("%s/", accountID),
},
},
})
}
func testCloudflareAccountMemberPoliciesConfig(accountID, emailAddress, permgroupId string) string {
return acctest.LoadTestCase("cloudflareaccountmemberpoliciesconfig.tf", accountID, emailAddress, permgroupId)
}
func getPermissionGroupId(t *testing.T, accountID string, label string) string {
ctx := context.Background()
client := acctest.SharedClient()
res, err := client.IAM.PermissionGroups.List(ctx, iam.PermissionGroupListParams{
AccountID: cloudflarev6.String(accountID),
Label: cloudflarev6.String(label),
})
if err != nil {
t.Fatalf("Failed to list permission groups: %v for account %s", err, accountID)
}
if len(res.Result) == 0 {
t.Fatalf("Expected at least one permission group with label '%s' but got none for account %s", label, accountID)
}
return res.Result[0].ID
}
func getRoleId(t *testing.T, accountID string, label string) string {
ctx := context.Background()
client := acctest.SharedClient()
roles, err := client.Accounts.Roles.List(ctx, accounts.RoleListParams{
AccountID: cloudflarev6.String(accountID),
// this may eventually become a problem if there are too many roles
PerPage: cloudflarev6.Float(100),
})
if err != nil {
t.Fatalf("failed to list roles for account %s: %s", accountID, err)
}
if len(roles.Result) == 0 {
t.Fatalf("no roles available for testing for account %s", accountID)
}
var roleID string
for i, role := range roles.Result {
if role.Name == label {
roleID = roles.Result[i].ID
break
}
}
if roleID == "" {
t.Fatalf("failed to find '%s' role for testing", label)
}
return roleID
}
func getDomains(t *testing.T, accountID string) []zones.Zone {
ctx := context.Background()
client := acctest.SharedClient()
res, err := client.Zones.List(ctx, zones.ZoneListParams{
Account: cloudflarev6.F(zones.ZoneListParamsAccount{
ID: cloudflarev6.F(accountID),
}),
})
if err != nil {
t.Fatalf("Failed to list domains: %v", err)
}
return res.Result
}
func createDomainGroup(t *testing.T, rnd, accountID, domainID string) string {
ctx := context.Background()
client := acctest.SharedClient()
domainGroup, err := client.IAM.ResourceGroups.New(ctx, iam.ResourceGroupNewParams{
AccountID: cloudflarev6.String(accountID),
Name: cloudflarev6.String(fmt.Sprintf("%s-%s", rnd, domainID)),
Scope: cloudflarev6.F(iam.ResourceGroupNewParamsScope{
Key: cloudflarev6.String(fmt.Sprintf("com.cloudflare.api.account.%s", accountID)),
Objects: cloudflarev6.F([]iam.ResourceGroupNewParamsScopeObject{
{
Key: cloudflarev6.String(fmt.Sprintf("com.cloudflare.api.account.zone.%s", domainID)),
},
}),
}),
})
if err != nil {
t.Fatalf("Failed to create domain group: %v", err)
}
return domainGroup.ID
}
func deleteDomainGroup(accountID, domainID string) error {
ctx := context.Background()
client := acctest.SharedClient()
_, err := client.IAM.ResourceGroups.Delete(ctx, domainID, iam.ResourceGroupDeleteParams{
AccountID: cloudflarev6.String(accountID),
})
return err
}

View file

@ -52,17 +52,13 @@ func ResourceSchema(ctx context.Context) schema.Schema {
Optional: true,
ElementType: types.StringType,
},
"policies": schema.ListNestedAttribute{
"policies": schema.SetNestedAttribute{
Description: "Array of policies associated with this member.",
Computed: true,
Optional: true,
CustomType: customfield.NewNestedObjectListType[AccountMemberPoliciesModel](ctx),
CustomType: customfield.NewNestedObjectSetType[AccountMemberPoliciesModel](ctx),
NestedObject: schema.NestedAttributeObject{
Attributes: map[string]schema.Attribute{
"id": schema.StringAttribute{
Description: "Policy identifier.",
Computed: true,
},
"access": schema.StringAttribute{
Description: "Allow or deny operations against the resources.\nAvailable values: \"allow\", \"deny\".",
Required: true,
@ -70,7 +66,7 @@ func ResourceSchema(ctx context.Context) schema.Schema {
stringvalidator.OneOfCaseInsensitive("allow", "deny"),
},
},
"permission_groups": schema.ListNestedAttribute{
"permission_groups": schema.SetNestedAttribute{
Description: "A set of permission groups that are specified to the policy.",
Required: true,
NestedObject: schema.NestedAttributeObject{
@ -82,7 +78,7 @@ func ResourceSchema(ctx context.Context) schema.Schema {
},
},
},
"resource_groups": schema.ListNestedAttribute{
"resource_groups": schema.SetNestedAttribute{
Description: "A list of resource groups that the policy applies to.",
Required: true,
NestedObject: schema.NestedAttributeObject{

View file

@ -0,0 +1,15 @@
resource "cloudflare_account_member" "test_member" {
account_id = "%[1]s"
email = "%[2]s"
status = "pending"
policies = [{
access = "allow"
permission_groups = [{
id = "%[3]s"
}]
resource_groups = [{
id = "%[4]s"
}]
}]
}

View file

@ -0,0 +1,20 @@
resource "cloudflare_account_member" "test_member" {
account_id = "%[1]s"
email = "%[2]s"
status = "pending"
policies = [{
access = "allow"
permission_groups = [{
id = "%[3]s"
}]
resource_groups = [
{
id = "%[4]s"
},
{
id = "%[5]s"
}
]
}]
}

View file

@ -3,14 +3,14 @@ data "cloudflare_resource_groups" "example_resource_groups" {
name = "com.cloudflare.api.account.%[1]s"
}
resource "cloudflare_account_member" "%[2]s" {
account_id = "%[3]s"
email = "%[4]s"
resource "cloudflare_account_member" "test_member" {
account_id = "%[1]s"
email = "%[2]s"
status = "pending"
policies = [{
access = "allow"
permission_groups = [{
id = "%[5]s"
id = "%[3]s"
}]
resource_groups = [{
id = data.cloudflare_resource_groups.example_resource_groups.result[0].id

View file

@ -1,6 +1,6 @@
resource "cloudflare_account_member" "%[1]s" {
account_id = "%[3]s"
email = "%[2]s"
roles = ["%[4]s"]
resource "cloudflare_account_member" "test_member" {
account_id = "%[2]s"
email = "%[1]s"
roles = ["%[3]s"]
status = "pending"
}

View file

@ -64,6 +64,7 @@ func (d *AccountPermissionGroupDataSource) Read(ctx context.Context, req datasou
}
res := new(http.Response)
env := AccountPermissionGroupResultDataSourceEnvelope{*data}
_, err := d.client.IAM.PermissionGroups.Get(
ctx,
data.PermissionGroupID.ValueString(),
@ -76,11 +77,12 @@ func (d *AccountPermissionGroupDataSource) Read(ctx context.Context, req datasou
return
}
bytes, _ := io.ReadAll(res.Body)
err = apijson.UnmarshalComputed(bytes, &data)
err = apijson.UnmarshalComputed(bytes, &env)
if err != nil {
resp.Diagnostics.AddError("failed to deserialize http request", err.Error())
return
}
data = &env.Result
resp.Diagnostics.Append(resp.State.Set(ctx, &data)...)
}

View file

@ -12,6 +12,10 @@ import (
"github.com/hashicorp/terraform-plugin-framework/types"
)
type AccountPermissionGroupResultDataSourceEnvelope struct {
Result AccountPermissionGroupDataSourceModel `json:"result,computed"`
}
type AccountPermissionGroupDataSourceModel struct {
AccountID types.String `tfsdk:"account_id" path:"account_id,required"`
PermissionGroupID types.String `tfsdk:"permission_group_id" path:"permission_group_id,required"`

View file

@ -78,7 +78,7 @@ func DataSourceSchema(ctx context.Context) schema.Schema {
CustomType: customfield.NewNestedObjectType[AccountSubscriptionRatePlanDataSourceModel](ctx),
Attributes: map[string]schema.Attribute{
"id": schema.StringAttribute{
Description: "The ID of the rate plan.\nAvailable values: \"free\", \"lite\", \"pro\", \"pro_plus\", \"business\", \"enterprise\", \"partners_free\", \"partners_pro\", \"partners_business\", \"partners_enterprise\".",
Description: "The ID of the rate plan.\nAvailable values: \"free\", \"lite\", \"pro\", \"pro_plus\", \"business\", \"enterprise\", \"partners_free\", \"partners_pro\", \"partners_business\", \"partners_ent\".",
Computed: true,
Validators: []validator.String{
stringvalidator.OneOfCaseInsensitive(
@ -91,7 +91,7 @@ func DataSourceSchema(ctx context.Context) schema.Schema {
"partners_free",
"partners_pro",
"partners_business",
"partners_enterprise",
"partners_ent",
),
},
},

View file

@ -4,6 +4,7 @@ package account_subscription
import (
"github.com/cloudflare/terraform-provider-cloudflare/internal/apijson"
"github.com/cloudflare/terraform-provider-cloudflare/internal/customfield"
"github.com/hashicorp/terraform-plugin-framework-timetypes/timetypes"
"github.com/hashicorp/terraform-plugin-framework/types"
)
@ -15,7 +16,7 @@ type AccountSubscriptionResultEnvelope struct {
type AccountSubscriptionModel struct {
ID types.String `tfsdk:"id" json:"id,computed"`
AccountID types.String `tfsdk:"account_id" path:"account_id,required"`
Frequency types.String `tfsdk:"frequency" json:"frequency,optional"`
Frequency types.String `tfsdk:"frequency" json:"frequency,computed_optional"`
RatePlan *AccountSubscriptionRatePlanModel `tfsdk:"rate_plan" json:"rate_plan,optional"`
Currency types.String `tfsdk:"currency" json:"currency,computed"`
CurrentPeriodEnd timetypes.RFC3339 `tfsdk:"current_period_end" json:"current_period_end,computed" format:"date-time"`
@ -33,11 +34,11 @@ func (m AccountSubscriptionModel) MarshalJSONForUpdate(state AccountSubscription
}
type AccountSubscriptionRatePlanModel struct {
ID types.String `tfsdk:"id" json:"id,optional"`
Currency types.String `tfsdk:"currency" json:"currency,optional"`
ExternallyManaged types.Bool `tfsdk:"externally_managed" json:"externally_managed,optional"`
IsContract types.Bool `tfsdk:"is_contract" json:"is_contract,optional"`
PublicName types.String `tfsdk:"public_name" json:"public_name,optional"`
Scope types.String `tfsdk:"scope" json:"scope,optional"`
Sets *[]types.String `tfsdk:"sets" json:"sets,optional"`
ID types.String `tfsdk:"id" json:"id,optional"`
Currency types.String `tfsdk:"currency" json:"currency,computed"`
ExternallyManaged types.Bool `tfsdk:"externally_managed" json:"externally_managed,computed"`
IsContract types.Bool `tfsdk:"is_contract" json:"is_contract,computed"`
PublicName types.String `tfsdk:"public_name" json:"public_name,computed"`
Scope types.String `tfsdk:"scope" json:"scope,computed_optional"`
Sets customfield.List[types.String] `tfsdk:"sets" json:"sets,computed"`
}

View file

@ -153,12 +153,22 @@ func (r *AccountSubscriptionResource) Read(ctx context.Context, req resource.Rea
return
}
// Store the account ID for later use
accountID := data.AccountID.ValueString()
subscriptionID := data.ID.ValueString()
res := new(http.Response)
env := AccountSubscriptionResultEnvelope{*data}
// Define a custom response envelope for list response
type SubscriptionListResponse struct {
Result []AccountSubscriptionModel `json:"result"`
Success bool `json:"success"`
}
listResponse := &SubscriptionListResponse{}
_, err := r.client.Accounts.Subscriptions.Get(
ctx,
accounts.SubscriptionGetParams{
AccountID: cloudflare.F(data.ID.ValueString()),
AccountID: cloudflare.F(accountID),
},
option.WithResponseBodyInto(&res),
option.WithMiddleware(logging.Middleware(ctx)),
@ -173,12 +183,32 @@ func (r *AccountSubscriptionResource) Read(ctx context.Context, req resource.Rea
return
}
bytes, _ := io.ReadAll(res.Body)
err = apijson.Unmarshal(bytes, &env)
err = apijson.Unmarshal(bytes, &listResponse)
if err != nil {
resp.Diagnostics.AddError("failed to deserialize http request", err.Error())
return
}
data = &env.Result
// Find the subscription with matching ID
found := false
for _, subscription := range listResponse.Result {
if subscription.ID.ValueString() == subscriptionID {
// Found the subscription, update the data
*data = subscription
// Ensure account ID is set correctly
data.AccountID = types.StringValue(accountID)
found = true
break
}
}
if !found && subscriptionID != "" {
resp.Diagnostics.AddWarning("Resource not found", "The subscription with ID "+subscriptionID+" was not found and will be removed from state.")
resp.State.RemoveResource(ctx)
return
}
resp.Diagnostics.Append(resp.State.Set(ctx, &data)...)
}
@ -209,27 +239,37 @@ func (r *AccountSubscriptionResource) Delete(ctx context.Context, req resource.D
}
func (r *AccountSubscriptionResource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) {
var data *AccountSubscriptionModel = new(AccountSubscriptionModel)
var data = new(AccountSubscriptionModel)
path_account_id := ""
path_subscription_id := ""
path := ""
diags := importpath.ParseImportID(
req.ID,
"<account_id>",
&path,
"<account_id>/<subscription_id>",
&path_account_id,
&path_subscription_id,
)
resp.Diagnostics.Append(diags...)
if resp.Diagnostics.HasError() {
return
}
data.AccountID = types.StringValue(path)
data.AccountID = types.StringValue(path_account_id)
data.ID = types.StringValue(path_subscription_id)
res := new(http.Response)
env := AccountSubscriptionResultEnvelope{*data}
// Define a custom response envelope for list response
type SubscriptionListResponse struct {
Result []AccountSubscriptionModel `json:"result"`
Success bool `json:"success"`
}
listResponse := &SubscriptionListResponse{}
_, err := r.client.Accounts.Subscriptions.Get(
ctx,
accounts.SubscriptionGetParams{
AccountID: cloudflare.F(path),
AccountID: cloudflare.F(data.AccountID.ValueString()),
},
option.WithResponseBodyInto(&res),
option.WithMiddleware(logging.Middleware(ctx)),
@ -239,12 +279,33 @@ func (r *AccountSubscriptionResource) ImportState(ctx context.Context, req resou
return
}
bytes, _ := io.ReadAll(res.Body)
err = apijson.Unmarshal(bytes, &env)
err = apijson.Unmarshal(bytes, &listResponse)
if err != nil {
resp.Diagnostics.AddError("failed to deserialize http request", err.Error())
return
}
data = &env.Result
// Find the subscription with matching ID
found := false
for _, subscription := range listResponse.Result {
if subscription.ID.ValueString() == data.ID.ValueString() {
// Found the subscription, update the data
*data = subscription
// Ensure account ID is set correctly
data.AccountID = types.StringValue(path_account_id)
found = true
break
}
}
if !found {
resp.Diagnostics.AddError(
"Subscription not found",
fmt.Sprintf("Subscription with ID %s not found in account %s", data.ID.ValueString(), data.AccountID.ValueString()),
)
return
}
resp.Diagnostics.Append(resp.State.Set(ctx, &data)...)
}

View file

@ -0,0 +1,215 @@
package account_subscription_test
import (
"fmt"
"os"
"regexp"
"testing"
"github.com/cloudflare/terraform-provider-cloudflare/internal/acctest"
"github.com/cloudflare/terraform-provider-cloudflare/internal/utils"
"github.com/hashicorp/terraform-plugin-testing/helper/resource"
"github.com/hashicorp/terraform-plugin-testing/plancheck"
"github.com/hashicorp/terraform-plugin-testing/terraform"
)
func TestAccCloudflareAccountSubscription_Basic(t *testing.T) {
t.Skip("Account requires an active payment method")
rnd := utils.GenerateRandomResourceName()
accountID := os.Getenv("CLOUDFLARE_ACCOUNT_ID")
resourceName := "cloudflare_account_subscription." + rnd
resource.Test(t, resource.TestCase{
PreCheck: func() {
acctest.TestAccPreCheck(t)
acctest.TestAccPreCheck_AccountID(t)
},
ProtoV6ProviderFactories: acctest.TestAccProtoV6ProviderFactories,
Steps: []resource.TestStep{
// First create a basic configuration
{
Config: testAccCloudflareAccountSubscriptionWithPlan(rnd, accountID, "teams_free"),
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr(resourceName, "account_id", accountID),
resource.TestCheckResourceAttr(resourceName, "rate_plan.id", "teams_free"),
),
},
{
ResourceName: resourceName,
ImportStateIdFunc: func(s *terraform.State) (string, error) {
return importStateIdFuncHelper(s, resourceName, accountID)
},
ImportState: true,
ImportStateVerify: true,
},
// Verify no plan change
{
Config: testAccCloudflareAccountSubscriptionWithPlan(rnd, accountID, "teams_free"),
ConfigPlanChecks: resource.ConfigPlanChecks{
PreApply: []plancheck.PlanCheck{
plancheck.ExpectEmptyPlan(),
},
},
},
},
})
}
// https://github.com/cloudflare/terraform-provider-cloudflare/issues/5803
func TestAccCloudflareAccountSubscription_ImportNoChanges(t *testing.T) {
t.Skip("Account requires an active payment method")
rnd := utils.GenerateRandomResourceName()
accountID := os.Getenv("CLOUDFLARE_ACCOUNT_ID")
resourceName := "cloudflare_account_subscription." + rnd
resource.Test(t, resource.TestCase{
PreCheck: func() {
acctest.TestAccPreCheck(t)
acctest.TestAccPreCheck_AccountID(t)
},
ProtoV6ProviderFactories: acctest.TestAccProtoV6ProviderFactories,
Steps: []resource.TestStep{
// First create a basic configuration
{
Config: testAccCloudflareAccountSubscriptionImportConfig(rnd, accountID),
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr(resourceName, "account_id", accountID),
resource.TestCheckResourceAttr(resourceName, "rate_plan.id", "teams_free"),
),
ConfigPlanChecks: resource.ConfigPlanChecks{
PostApplyPostRefresh: []plancheck.PlanCheck{
plancheck.ExpectEmptyPlan(), // Should show no changes
},
},
},
// Then import the resource and verify it
{
ResourceName: resourceName,
ImportStateIdFunc: func(s *terraform.State) (string, error) {
return importStateIdFuncHelper(s, resourceName, accountID)
},
ImportState: true,
ImportStateVerify: true,
},
},
})
}
// Test that import fails with invalid format
func TestAccCloudflareAccountSubscription_ImportInvalidFormat(t *testing.T) {
t.Skip("Account requires an active payment method")
rnd := utils.GenerateRandomResourceName()
accountID := os.Getenv("CLOUDFLARE_ACCOUNT_ID")
resourceName := "cloudflare_account_subscription." + rnd
resource.Test(t, resource.TestCase{
PreCheck: func() {
acctest.TestAccPreCheck(t)
acctest.TestAccPreCheck_AccountID(t)
},
ProtoV6ProviderFactories: acctest.TestAccProtoV6ProviderFactories,
Steps: []resource.TestStep{
{
Config: testAccCloudflareAccountSubscriptionWithPlan(rnd, accountID, "teams_free"),
},
{
ResourceName: resourceName,
ImportState: true,
ImportStateId: accountID, // Wrong format - missing subscription_id
ExpectError: regexp.MustCompile("invalid ID"),
},
},
})
}
// Test that import fails with non-existent subscription
func TestAccCloudflareAccountSubscription_ImportNonExistent(t *testing.T) {
t.Skip("Account requires an active payment method")
rnd := utils.GenerateRandomResourceName()
accountID := os.Getenv("CLOUDFLARE_ACCOUNT_ID")
resourceName := "cloudflare_account_subscription." + rnd
fakeSubscriptionID := "00000000000000000000000000000000"
resource.Test(t, resource.TestCase{
PreCheck: func() {
acctest.TestAccPreCheck(t)
acctest.TestAccPreCheck_AccountID(t)
},
ProtoV6ProviderFactories: acctest.TestAccProtoV6ProviderFactories,
Steps: []resource.TestStep{
{
Config: testAccCloudflareAccountSubscriptionWithPlan(rnd, accountID, "teams_free"),
ResourceName: resourceName,
ImportState: true,
ImportStateId: fmt.Sprintf("%s/%s", accountID, fakeSubscriptionID),
ExpectError: regexp.MustCompile("Subscription not found"),
},
},
})
}
// Test computed fields are populated correctly after import
func TestAccCloudflareAccountSubscription_ComputedFieldsAfterImport(t *testing.T) {
t.Skip("Account requires an active payment method")
rnd := utils.GenerateRandomResourceName()
accountID := os.Getenv("CLOUDFLARE_ACCOUNT_ID")
resourceName := "cloudflare_account_subscription." + rnd
resource.Test(t, resource.TestCase{
PreCheck: func() {
acctest.TestAccPreCheck(t)
acctest.TestAccPreCheck_AccountID(t)
},
ProtoV6ProviderFactories: acctest.TestAccProtoV6ProviderFactories,
Steps: []resource.TestStep{
{
Config: testAccCloudflareAccountSubscriptionWithPlan(rnd, accountID, "teams_free"),
},
{
ResourceName: resourceName,
ImportStateIdFunc: func(s *terraform.State) (string, error) {
return importStateIdFuncHelper(s, resourceName, accountID)
},
ImportState: true,
Check: resource.ComposeTestCheckFunc(
// Verify computed fields are populated
resource.TestCheckResourceAttrSet(resourceName, "id"),
resource.TestCheckResourceAttrSet(resourceName, "currency"),
resource.TestCheckResourceAttrSet(resourceName, "state"),
resource.TestCheckResourceAttrSet(resourceName, "price"),
resource.TestCheckResourceAttrSet(resourceName, "rate_plan.currency"),
resource.TestCheckResourceAttrSet(resourceName, "rate_plan.public_name"),
resource.TestCheckResourceAttrSet(resourceName, "rate_plan.externally_managed"),
resource.TestCheckResourceAttrSet(resourceName, "rate_plan.is_contract"),
),
},
},
})
}
func testAccCloudflareAccountSubscriptionImportConfig(rnd, zoneID string) string {
return acctest.LoadTestCase("import_config.tf", rnd, zoneID)
}
func testAccCloudflareAccountSubscriptionWithPlan(rnd, zoneID string, planID string) string {
return acctest.LoadTestCase("with_plan.tf", rnd, zoneID, planID)
}
// func testAccCloudflareAccountSubscriptionBasicWithOptionalFields(rnd, zoneID string) string {
// return acctest.LoadTestCase("basic_with_optional_fields.tf", rnd, zoneID)
// }
func importStateIdFuncHelper(s *terraform.State, resourceName string, accountID string) (string, error) {
r, ok := s.RootModule().Resources[resourceName]
if !ok {
return "", fmt.Errorf("not found: %s", resourceName)
}
if r.Primary.ID == "" {
return "", fmt.Errorf("no subscription ID is set")
}
subscriptionID := r.Primary.ID
return fmt.Sprintf("%s/%s", accountID, subscriptionID), nil
}

View file

@ -5,6 +5,7 @@ package account_subscription
import (
"context"
"github.com/cloudflare/terraform-provider-cloudflare/internal/customfield"
"github.com/hashicorp/terraform-plugin-framework-timetypes/timetypes"
"github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator"
"github.com/hashicorp/terraform-plugin-framework/resource"
@ -33,12 +34,14 @@ func ResourceSchema(ctx context.Context) schema.Schema {
"frequency": schema.StringAttribute{
Description: "How often the subscription is renewed automatically.\nAvailable values: \"weekly\", \"monthly\", \"quarterly\", \"yearly\".",
Optional: true,
Computed: true,
Validators: []validator.String{
stringvalidator.OneOfCaseInsensitive(
"weekly",
"monthly",
"quarterly",
"yearly",
"not-applicable",
),
},
},
@ -47,46 +50,34 @@ func ResourceSchema(ctx context.Context) schema.Schema {
Optional: true,
Attributes: map[string]schema.Attribute{
"id": schema.StringAttribute{
Description: "The ID of the rate plan.\nAvailable values: \"free\", \"lite\", \"pro\", \"pro_plus\", \"business\", \"enterprise\", \"partners_free\", \"partners_pro\", \"partners_business\", \"partners_enterprise\".",
Description: "The ID of the rate plan.",
Optional: true,
Validators: []validator.String{
stringvalidator.OneOfCaseInsensitive(
"free",
"lite",
"pro",
"pro_plus",
"business",
"enterprise",
"partners_free",
"partners_pro",
"partners_business",
"partners_enterprise",
),
},
},
"currency": schema.StringAttribute{
Description: "The currency applied to the rate plan subscription.",
Optional: true,
Computed: true,
},
"externally_managed": schema.BoolAttribute{
Description: "Whether this rate plan is managed externally from Cloudflare.",
Optional: true,
Computed: true,
},
"is_contract": schema.BoolAttribute{
Description: "Whether a rate plan is enterprise-based (or newly adopted term contract).",
Optional: true,
Computed: true,
},
"public_name": schema.StringAttribute{
Description: "The full name of the rate plan.",
Optional: true,
Computed: true,
},
"scope": schema.StringAttribute{
Description: "The scope that this rate plan applies to.",
Computed: true,
Optional: true,
},
"sets": schema.ListAttribute{
Description: "The list of sets this rate plan applies to.",
Optional: true,
Computed: true,
CustomType: customfield.NewListType[types.String](ctx),
ElementType: types.StringType,
},
},

View file

@ -0,0 +1,7 @@
resource "cloudflare_account_subscription" "%[1]s" {
account_id = "%[2]s"
rate_plan = {
id = "teams_free"
scope = "account"
}
}

View file

@ -0,0 +1,7 @@
resource "cloudflare_account_subscription" "%[1]s" {
account_id = "%[2]s"
rate_plan = {
id = "%[3]s"
}
}

View file

@ -213,7 +213,7 @@ func (r *AccountTokenResource) Delete(ctx context.Context, req resource.DeleteRe
}
func (r *AccountTokenResource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) {
var data *AccountTokenModel = new(AccountTokenModel)
var data = new(AccountTokenModel)
path_account_id := ""
path_token_id := ""

View file

@ -4,7 +4,6 @@ import (
"context"
"fmt"
"os"
"strings"
"testing"
"time"
@ -12,6 +11,7 @@ import (
"github.com/cloudflare/cloudflare-go/v6/accounts"
"github.com/cloudflare/terraform-provider-cloudflare/internal/acctest"
"github.com/cloudflare/terraform-provider-cloudflare/internal/utils"
"github.com/hashicorp/terraform-plugin-log/tflog"
"github.com/hashicorp/terraform-plugin-testing/compare"
"github.com/hashicorp/terraform-plugin-testing/helper/resource"
"github.com/hashicorp/terraform-plugin-testing/knownvalue"
@ -37,22 +37,41 @@ func testSweepCloudflareAccountToken(r string) error {
client := acctest.SharedClient()
accountID := os.Getenv("CLOUDFLARE_ACCOUNT_ID")
if accountID == "" {
tflog.Info(ctx, "Skipping account tokens sweep: CLOUDFLARE_ACCOUNT_ID not set")
return nil
}
// List all API tokens
tokens, err := client.Accounts.Tokens.List(ctx, accounts.TokenListParams{})
tokens, err := client.Accounts.Tokens.List(ctx, accounts.TokenListParams{
AccountID: cloudflare.F(accountID),
})
if err != nil {
tflog.Error(ctx, fmt.Sprintf("Failed to fetch account tokens: %s", err))
return fmt.Errorf("failed to fetch account tokens: %w", err)
}
if len(tokens.Result) == 0 {
tflog.Info(ctx, "No account tokens to sweep")
return nil
}
// Delete test tokens (those created by our tests)
// Uses utils.ShouldSweepResource() to filter by standard test naming convention
for _, token := range tokens.Result {
if strings.Contains(token.Name, "terraform") {
_, err := client.Accounts.Tokens.Delete(ctx, token.ID, accounts.TokenDeleteParams{
AccountID: cloudflare.F(accountID),
})
if err != nil {
return fmt.Errorf("failed to delete account token %s: %w", token.ID, err)
}
if !utils.ShouldSweepResource(token.Name) {
continue
}
tflog.Info(ctx, fmt.Sprintf("Deleting account token: %s (%s) (account: %s)", token.Name, token.ID, accountID))
_, err := client.Accounts.Tokens.Delete(ctx, token.ID, accounts.TokenDeleteParams{
AccountID: cloudflare.F(accountID),
})
if err != nil {
tflog.Error(ctx, fmt.Sprintf("Failed to delete account token %s (%s): %s", token.Name, token.ID, err))
continue
}
tflog.Info(ctx, fmt.Sprintf("Deleted account token: %s (%s)", token.Name, token.ID))
}
return nil
@ -619,3 +638,76 @@ func TestAccAccountToken_ResourcesFlexible(t *testing.T) {
},
})
}
func TestAccAccountToken_CRUD(t *testing.T) {
// Comprehensive test covering Create, Read, Update, Delete + Import
rnd := utils.GenerateRandomResourceName()
accountID := os.Getenv("CLOUDFLARE_ACCOUNT_ID")
resourceName := "cloudflare_account_token.crud_test"
initialName := rnd + "-initial"
updatedName := rnd + "-updated"
// TTL times
oneDayFromNow := time.Now().UTC().AddDate(0, 0, 1).Format(time.RFC3339)
twoDaysFromNow := time.Now().UTC().AddDate(0, 0, 2).Format(time.RFC3339)
resource.Test(t, resource.TestCase{
PreCheck: func() { acctest.TestAccPreCheck(t) },
ProtoV6ProviderFactories: acctest.TestAccProtoV6ProviderFactories,
CheckDestroy: testAccCheckCloudflareAccountTokenDestroy,
Steps: []resource.TestStep{
// Create and Read
{
Config: acctest.LoadTestCase("account_token-crud.tf", initialName, accountID, oneDayFromNow, "192.0.2.1/32"),
ConfigStateChecks: []statecheck.StateCheck{
statecheck.ExpectKnownValue(resourceName, tfjsonpath.New("name"), knownvalue.StringExact(initialName)),
statecheck.ExpectKnownValue(resourceName, tfjsonpath.New("account_id"), knownvalue.StringExact(accountID)),
statecheck.ExpectKnownValue(resourceName, tfjsonpath.New("expires_on"), knownvalue.StringExact(oneDayFromNow)),
statecheck.ExpectKnownValue(resourceName, tfjsonpath.New("policies"), knownvalue.ListSizeExact(1)),
statecheck.ExpectKnownValue(resourceName, tfjsonpath.New("condition").AtMapKey("request_ip").AtMapKey("in").AtSliceIndex(0), knownvalue.StringExact("192.0.2.1/32")),
},
},
// Update name and TTL
{
Config: acctest.LoadTestCase("account_token-crud.tf", updatedName, accountID, twoDaysFromNow, "192.0.2.1/32"),
ConfigPlanChecks: resource.ConfigPlanChecks{
PreApply: []plancheck.PlanCheck{
plancheck.ExpectResourceAction(resourceName, plancheck.ResourceActionUpdate),
plancheck.ExpectKnownValue(resourceName, tfjsonpath.New("name"), knownvalue.StringExact(updatedName)),
plancheck.ExpectKnownValue(resourceName, tfjsonpath.New("expires_on"), knownvalue.StringExact(twoDaysFromNow)),
},
},
ConfigStateChecks: []statecheck.StateCheck{
statecheck.ExpectKnownValue(resourceName, tfjsonpath.New("name"), knownvalue.StringExact(updatedName)),
statecheck.ExpectKnownValue(resourceName, tfjsonpath.New("account_id"), knownvalue.StringExact(accountID)),
statecheck.ExpectKnownValue(resourceName, tfjsonpath.New("expires_on"), knownvalue.StringExact(twoDaysFromNow)),
statecheck.ExpectKnownValue(resourceName, tfjsonpath.New("condition").AtMapKey("request_ip").AtMapKey("in").AtSliceIndex(0), knownvalue.StringExact("192.0.2.1/32")),
},
},
// Update condition
{
Config: acctest.LoadTestCase("account_token-crud.tf", updatedName, accountID, twoDaysFromNow, "198.51.100.1/32"),
ConfigPlanChecks: resource.ConfigPlanChecks{
PreApply: []plancheck.PlanCheck{
plancheck.ExpectResourceAction(resourceName, plancheck.ResourceActionUpdate),
plancheck.ExpectKnownValue(resourceName, tfjsonpath.New("condition").AtMapKey("request_ip").AtMapKey("in").AtSliceIndex(0), knownvalue.StringExact("198.51.100.1/32")),
},
},
ConfigStateChecks: []statecheck.StateCheck{
statecheck.ExpectKnownValue(resourceName, tfjsonpath.New("name"), knownvalue.StringExact(updatedName)),
statecheck.ExpectKnownValue(resourceName, tfjsonpath.New("account_id"), knownvalue.StringExact(accountID)),
statecheck.ExpectKnownValue(resourceName, tfjsonpath.New("condition").AtMapKey("request_ip").AtMapKey("in").AtSliceIndex(0), knownvalue.StringExact("198.51.100.1/32")),
},
},
// Import
{
ResourceName: resourceName,
ImportState: true,
ImportStateVerify: true,
ImportStateIdPrefix: fmt.Sprintf("%s/", accountID),
ImportStateVerifyIgnore: []string{"value"}, // Token value is write-only
},
},
})
}

View file

@ -0,0 +1,31 @@
data "cloudflare_account_api_token_permission_groups_list" "dns_read" {
account_id = "%[2]s"
name = "DNS Read"
scope = "com.cloudflare.api.account.zone"
}
resource "cloudflare_account_token" "crud_test" {
account_id = "%[2]s"
name = "%[1]s"
expires_on = "%[3]s"
policies = [
{
effect = "allow"
permission_groups = [
{ id = data.cloudflare_account_api_token_permission_groups_list.dns_read.result[0].id }
]
resources = jsonencode({
"com.cloudflare.api.account.%[2]s" : {
"com.cloudflare.api.account.zone.*" = "*"
}
})
}
]
condition = {
request_ip = {
in = ["%[4]s"]
}
}
}

View file

@ -210,7 +210,7 @@ func (r *AddressMapResource) Delete(ctx context.Context, req resource.DeleteRequ
}
func (r *AddressMapResource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) {
var data *AddressMapModel = new(AddressMapModel)
var data = new(AddressMapModel)
path_account_id := ""
path_address_map_id := ""

View file

@ -1,6 +1,7 @@
package address_map_test
import (
"context"
"fmt"
"os"
"testing"
@ -9,9 +10,64 @@ import (
"github.com/cloudflare/terraform-provider-cloudflare/internal/acctest"
"github.com/cloudflare/terraform-provider-cloudflare/internal/consts"
"github.com/cloudflare/terraform-provider-cloudflare/internal/utils"
"github.com/hashicorp/terraform-plugin-log/tflog"
"github.com/hashicorp/terraform-plugin-testing/helper/resource"
)
func TestMain(m *testing.M) {
resource.TestMain(m)
}
func init() {
resource.AddTestSweepers("cloudflare_address_map", &resource.Sweeper{
Name: "cloudflare_address_map",
F: testSweepCloudflareAddressMaps,
})
}
func testSweepCloudflareAddressMaps(r string) error {
ctx := context.Background()
client, clientErr := acctest.SharedV1Client()
if clientErr != nil {
tflog.Error(ctx, fmt.Sprintf("Failed to create Cloudflare client: %s", clientErr))
return clientErr
}
accountID := os.Getenv("CLOUDFLARE_ACCOUNT_ID")
if accountID == "" {
tflog.Info(ctx, "Skipping address maps sweep: CLOUDFLARE_ACCOUNT_ID not set")
return nil
}
addressMaps, err := client.ListAddressMaps(ctx, cloudflare.AccountIdentifier(accountID), cloudflare.ListAddressMapsParams{})
if err != nil {
tflog.Error(ctx, fmt.Sprintf("Failed to fetch address maps: %s", err))
return fmt.Errorf("failed to fetch address maps: %w", err)
}
if len(addressMaps) == 0 {
tflog.Info(ctx, "No address maps to sweep")
return nil
}
for _, addressMap := range addressMaps {
// Use standard filtering helper on the description field
if addressMap.Description == nil || !utils.ShouldSweepResource(*addressMap.Description) {
continue
}
tflog.Info(ctx, fmt.Sprintf("Deleting address map: %s (account: %s)", addressMap.ID, accountID))
err := client.DeleteAddressMap(ctx, cloudflare.AccountIdentifier(accountID), addressMap.ID)
if err != nil {
tflog.Error(ctx, fmt.Sprintf("Failed to delete address map %s: %s", addressMap.ID, err))
continue
}
tflog.Info(ctx, fmt.Sprintf("Deleted address map: %s", addressMap.ID))
}
return nil
}
func TestAccCloudflareAddressMap(t *testing.T) {
acctest.TestAccSkipForDefaultAccount(t, "Pending permission fixes for IP delegation.")

View file

@ -190,7 +190,7 @@ func (r *APIShieldResource) Delete(ctx context.Context, req resource.DeleteReque
}
func (r *APIShieldResource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) {
var data *APIShieldModel = new(APIShieldModel)
var data = new(APIShieldModel)
path := ""
diags := importpath.ParseImportID(

View file

@ -1,16 +1,60 @@
package api_shield_test
import (
"context"
"fmt"
"os"
"testing"
"github.com/cloudflare/cloudflare-go/v6"
"github.com/cloudflare/cloudflare-go/v6/api_gateway"
"github.com/cloudflare/cloudflare-go/v6/option"
"github.com/cloudflare/terraform-provider-cloudflare/internal/acctest"
"github.com/cloudflare/terraform-provider-cloudflare/internal/consts"
"github.com/cloudflare/terraform-provider-cloudflare/internal/utils"
"github.com/hashicorp/terraform-plugin-log/tflog"
"github.com/hashicorp/terraform-plugin-testing/helper/resource"
"github.com/hashicorp/terraform-plugin-testing/terraform"
)
func TestMain(m *testing.M) {
resource.TestMain(m)
}
func init() {
resource.AddTestSweepers("cloudflare_api_shield", &resource.Sweeper{
Name: "cloudflare_api_shield",
F: testSweepCloudflareAPIShield,
})
}
func testSweepCloudflareAPIShield(r string) error {
ctx := context.Background()
client := acctest.SharedClient()
zoneID := os.Getenv("CLOUDFLARE_ZONE_ID")
if zoneID == "" {
tflog.Info(ctx, "Skipping API Shield sweep: CLOUDFLARE_ZONE_ID not set")
return nil
}
tflog.Info(ctx, fmt.Sprintf("Clearing API Shield configuration for zone: %s", zoneID))
_, err := client.APIGateway.Configurations.Update(
ctx,
api_gateway.ConfigurationUpdateParams{
ZoneID: cloudflare.F(zoneID),
},
option.WithRequestBody("application/json", []byte(`{"auth_id_characteristics":[]}`)),
)
if err != nil {
tflog.Error(ctx, fmt.Sprintf("Failed to clear API Shield configuration: %s", err))
return fmt.Errorf("failed to clear API Shield configuration: %w", err)
}
tflog.Info(ctx, "Cleared API Shield configuration")
return nil
}
func TestAccCloudflareAPIShieldBasic(t *testing.T) {
// Temporarily unset CLOUDFLARE_API_TOKEN if it is set as the API token
// endpoint does not yet support the API tokens without an explicit scope.

View file

@ -20,6 +20,7 @@ var _ datasource.DataSourceWithConfigValidators = (*APIShieldDiscoveryOperations
func ListDataSourceSchema(ctx context.Context) schema.Schema {
return schema.Schema{
DeprecationMessage: "This resource is no longer supported. It cannot be imported.",
Attributes: map[string]schema.Attribute{
"zone_id": schema.StringAttribute{
Description: "Identifier.",

View file

@ -17,6 +17,7 @@ var _ resource.ResourceWithConfigValidators = (*APIShieldDiscoveryOperationResou
func ResourceSchema(ctx context.Context) schema.Schema {
return schema.Schema{
DeprecationMessage: "This resource is no longer supported. It cannot be imported.",
Attributes: map[string]schema.Attribute{
"id": schema.StringAttribute{
Description: "UUID.",

View file

@ -97,52 +97,7 @@ func (r *APIShieldOperationResource) Create(ctx context.Context, req resource.Cr
}
func (r *APIShieldOperationResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) {
var data *APIShieldOperationModel
resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...)
if resp.Diagnostics.HasError() {
return
}
var state *APIShieldOperationModel
resp.Diagnostics.Append(req.State.Get(ctx, &state)...)
if resp.Diagnostics.HasError() {
return
}
dataBytes, err := data.MarshalJSONForUpdate(*state)
if err != nil {
resp.Diagnostics.AddError("failed to serialize http request", err.Error())
return
}
res := new(http.Response)
env := APIShieldOperationResultEnvelope{*data}
_, err = r.client.APIGateway.Operations.New(
ctx,
api_gateway.OperationNewParams{
ZoneID: cloudflare.F(data.OperationID.ValueString()),
},
option.WithRequestBody("application/json", dataBytes),
option.WithResponseBodyInto(&res),
option.WithMiddleware(logging.Middleware(ctx)),
)
if err != nil {
resp.Diagnostics.AddError("failed to make http request", err.Error())
return
}
bytes, _ := io.ReadAll(res.Body)
err = apijson.UnmarshalComputed(bytes, &env)
if err != nil {
resp.Diagnostics.AddError("failed to deserialize http request", err.Error())
return
}
data = &env.Result
data.ID = data.OperationID
resp.Diagnostics.Append(resp.State.Set(ctx, &data)...)
// Update is not supported for this resource
}
func (r *APIShieldOperationResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) {
@ -213,7 +168,7 @@ func (r *APIShieldOperationResource) Delete(ctx context.Context, req resource.De
}
func (r *APIShieldOperationResource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) {
var data *APIShieldOperationModel = new(APIShieldOperationModel)
var data = new(APIShieldOperationModel)
path_zone_id := ""
path_operation_id := ""

Some files were not shown because too many files have changed in this diff Show more