Key takeaways
- provider-ovh 2.18.0 adds
FileShareACLand removes inlineaccessRulesfromFileShare.- The removed field is silently pruned, not rejected. An untouched
FileSharemanifest keeps applying cleanly while its access rules quietly stop being managed. This is the one thing to check before you upgrade.- Rules already provisioned in OVHcloud are not deleted by the upgrade — adopt them with
crossplane.io/external-name.
Version 2.18.0 of provider-ovh, our Crossplane provider for OVHcloud, was released on 1 August 2026. It tracks OVHcloud Terraform provider 2.18.0 and brings the provider to 166 managed resources per API scope and 337 CRDs.
It is a small release with one sharp edge, so we are leading with the edge.
The breaking change that does not announce itself
Upstream removed the inline access_rules attribute from ovh_cloud_storage_file_share and replaced it with a standalone ACL resource. FileShare therefore loses four paths, in both API groups:
spec.forProvider.accessRulesspec.initProvider.accessRulesstatus.atProvider.accessRulesstatus.atProvider.currentState.accessRules
Here is why this deserves more care than a normal removal. Once the CRDs are upgraded, accessRules is not rejected. The Kubernetes API server prunes unknown fields, so a FileShare manifest you never touched will still apply, still report ready, and still look entirely healthy in kubectl — while the access rules it used to declare are no longer managed by anything.
A breaking change that errors is a nuisance. A breaking change that succeeds is a trap. Audit your FileShare objects for accessRules before you upgrade, not after.
kubectl get fileshares.storage.ovh.edixos.io -A \
-o jsonpath='{range .items[?(@.spec.forProvider.accessRules)]}{.metadata.namespace}{"\t"}{.metadata.name}{"\n"}{end}'
Migrating to FileShareACL
Declare one FileShareACL per rule that was previously inline:
apiVersion: storage.ovh.edixos.io/v1alpha1
kind: FileShareACL
metadata:
name: example-acl
spec:
forProvider:
serviceName: <service-name>
shareIdRef:
name: example-share
accessTo: 10.0.0.0/24
accessLevel: READ_WRITE
accessTo takes a single IP or CIDR. accessLevel is READ_WRITE or READ_ONLY. shareId resolves by reference or selector to a FileShare, so the ACL follows the share rather than hard-coding an ID.
One property to design around: every configurable field forces replacement. There is no in-place update of an ACL — changing accessTo or accessLevel deletes and recreates it. For a rule governing live traffic, that is a brief window with no ACL in place, so schedule changes accordingly rather than discovering it during an incident.
Adopting rules that already exist
The upgrade does not delete access rules already provisioned in OVHcloud. They keep working; they are simply unmanaged. To bring one under Crossplane without creating a duplicate, set the external name:
metadata:
name: example-acl
annotations:
crossplane.io/external-name: <serviceName>/<shareId>/<aclId>
Given that every field forces replacement, adoption is strictly better than recreate-and-hope: it avoids a delete/create cycle on a rule that is currently allowing production traffic.
Also in 2.18.0
BlockVolume gains an optional availabilityZone, plus status.atProvider.currentState.location.availabilityZone. If you run across OVHcloud AZs, you can now pin a volume rather than accepting placement.
BlockVolume no longer replaces the volume when encryption is left unchanged. Upstream now keeps the value from state. Previously an unchanged encryption field could trigger a replacement — on a block volume, meaning data movement. If you had a BlockVolume that seemed to want recreating for no reason, this was likely why.
The provider image now downloads the native Terraform provider binary from the upstream GitHub release assets instead of releases.hashicorp.com. The reason is concrete: that mirror only carries some versions of the OVHcloud provider and has no 2.18.0 at all. Sourcing from the upstream release assets means the provider is never blocked on a mirror that lags or skips a version.
Upgrading
cat <<EOF | kubectl apply -f -
apiVersion: pkg.crossplane.io/v1
kind: Provider
metadata:
name: provider-ovh
spec:
package: xpkg.upbound.io/edixos/provider-ovh:v2.18.0
EOF
Sequence that avoids the trap:
- Audit
FileShareobjects foraccessRulesand record every rule — IP or CIDR, and access level. - Collect the corresponding
aclIdvalues from the OVHcloud API for adoption. - Upgrade the provider.
- Apply one
FileShareACLper recorded rule, withcrossplane.io/external-nameset so each adopts its existing rule. - Confirm each ACL reaches
SYNCEDandREADY, and that no duplicate rule appeared on the share.
Coming from 2.13.x rather than 2.17.0? Read provider-ovh 2.17.0 first — it removes four database engines and their CRDs, which is a larger migration than this one.
Full changelog: v2.17.0…v2.18.0
Where to go next
If you are new to the provider, the step-by-step provider-ovh guide covers installation, credentials and a first managed cluster.
We maintain provider-ovh and build OVHcloud control planes on it: Crossplane consulting · platform engineering · talk to us.
Straight answers
Frequently asked questions
What changed in provider-ovh 2.18.0?
It upgrades to OVHcloud Terraform provider 2.18.0, reaching 166 managed resources per API scope and 337 CRDs. It adds the FileShareACL resource, gives BlockVolume an availabilityZone, and removes the inline accessRules attribute from FileShare.
Why did my FileShare accessRules stop working after upgrading?
Because the field was removed upstream and is silently pruned by the API server rather than rejected. The manifest still applies cleanly and the object still reconciles, but the access rules are no longer managed. Declare one FileShareACL per rule instead.
How do I migrate FileShare accessRules to FileShareACL?
Create one FileShareACL per previously inline rule, with accessTo set to the IP or CIDR and accessLevel to READ_WRITE or READ_ONLY. Existing rules provisioned in OVHcloud are not deleted by the upgrade, so import them by setting crossplane.io/external-name.
What is the external-name format for FileShareACL?
Set the crossplane.io/external-name annotation to serviceName/shareId/aclId. That lets Crossplane adopt an access rule that already exists in OVHcloud instead of creating a duplicate, which matters because every configurable field on FileShareACL forces replacement.
Why does provider-ovh now fetch the Terraform binary from GitHub?
Because releases.hashicorp.com only mirrors some versions of the OVHcloud provider and has no 2.18.0 at all. The provider image now downloads the native binary from the upstream GitHub release assets, which is the authoritative source for every version.