What happened?
When a KMS Key resource has origin: AWS_CLOUDHSM or origin: EXTERNAL, the reconciler fails permanently with:
UnsupportedOperationException: origin is AWS_CLOUDHSM which is not valid for this operation
This happens because isUpToDate calls GetKeyRotationStatus unconditionally on every reconcile loop, and update calls EnableKeyRotation/DisableKeyRotation unconditionally. AWS does not support key rotation APIs for CloudHSM custom key store keys or externally-imported keys — the operation is only valid for AWS_KMS origin keys.
Fix
Guard both call sites with an origin check:
isUpToDate: skip GetKeyRotationStatus unless obj.KeyMetadata.Origin == "AWS_KMS" (origin is available directly from the DescribeKeyOutput already in scope)
update: skip EnableKeyRotation/DisableKeyRotation unless cr.Spec.ForProvider.Origin == "AWS_KMS" or is unset (origin is late-initialized from KeyMetadata.Origin after creation, so it is reliably populated by the time update runs; an empty value preserves existing AWS_KMS behaviour)
How can we reproduce it?
Configure CloudHSM with custom KMS key
What environment did it happen in?
Crossplane version:
Helm Charts v2.1.3
What happened?
When a KMS Key resource has origin: AWS_CLOUDHSM or origin: EXTERNAL, the reconciler fails permanently with:
UnsupportedOperationException: origin is AWS_CLOUDHSM which is not valid for this operation
This happens because isUpToDate calls GetKeyRotationStatus unconditionally on every reconcile loop, and update calls EnableKeyRotation/DisableKeyRotation unconditionally. AWS does not support key rotation APIs for CloudHSM custom key store keys or externally-imported keys — the operation is only valid for AWS_KMS origin keys.
Fix
Guard both call sites with an origin check:
isUpToDate: skip GetKeyRotationStatus unless obj.KeyMetadata.Origin == "AWS_KMS" (origin is available directly from the DescribeKeyOutput already in scope)
update: skip EnableKeyRotation/DisableKeyRotation unless cr.Spec.ForProvider.Origin == "AWS_KMS" or is unset (origin is late-initialized from KeyMetadata.Origin after creation, so it is reliably populated by the time update runs; an empty value preserves existing AWS_KMS behaviour)
How can we reproduce it?
Configure CloudHSM with custom KMS key
What environment did it happen in?
Crossplane version:
Helm Charts v2.1.3