Overview
This feature allows platform administrators to:
- Rotate Cassandra credentials in Hashicorp Vault.
 - Roll back to the previous Cassandra credentials in Vault in case of any issues during password rotation.
 - Rotate the Cassandra password for one region at a time, so that you can ensure minimal impact on service availability and maintain control over the rotation process.
 - Track the start, progress, and completion of the rotation for a single region.
 
This feature is available in Apigee Hybrid 1.13.1 and later.
Before you begin
Before setting up credential rotation:
- Backup your Cassandra database. This backup is to ensure recovery is possible to pre-rotated credentials.
 - Ensure the cluster is in a healthy state (i.e. all Apigee resources are running, no state changes are pending).
 
Single region setup
- 
    Create a new 
SecretProviderClassKubernetes resource in your Apigee namespace for the new Cassandra credentials. See Storing Cassandra secrets in Hashicorp Vault for a template to use. This allows a Vault role to access secrets within the Kubernetes namespaces. - 
    Create a new 
SecretRotationcustom resource using the following template:# rotation.yaml apiVersion: apigee.cloud.google.com/v1alpha1 kind: SecretRotation metadata: name: ROTATION_PROCESS_NAME namespace: APIGEE_NAMESPACE spec: organizationId: ORG_NAME rotationId: ROTATION_ID timeoutMinutes: 480 # optional. overrides the default (480m == 8hr). # less than or equal to 0 means infinite timeout. precheck: true cassandra: oldSecretProviderClass: OLD_SPC_NAME newSecretProviderClass: NEW_SPC_NAME jobType: ROTATE- ROTATION_PROCESS_NAME: A unique name for the rotation job. You will need to set 
metadata.nameto a unique value for the rotation precheck job and again for the rotation job. For examplesr-1-precheckfollowed bysr-1. - ROTATION_ID: Set 
spec.rotationIdto a custom identifier, for examplerotation-1-precheck. - NEW_SPC_NAME: Set 
spec.cassandra.newSecretProviderClassto the new secret provider class name you created in the previous step. - OLD_SPC_NAME: Set 
spec.cassandra.oldSecretProviderClassto the SPC name currently being used by theApigeeDatastore. 
 - ROTATION_PROCESS_NAME: A unique name for the rotation job. You will need to set 
 - 
    Trigger the rotation precheck job by applying the 
rotation.yamlfile.kubectl -n APIGEE_NAMESPACE apply -f rotation.yaml
 - 
    Check the job status to verify when the precheck job is complete.
    
kubectl -n APIGEE_NAMESPACE get job sr-(rotationId)-(rotate|rollback|cleanup)-job
 - 
    Once the rotation precheck job completes, change the value of 
metadata.nameand setspec.prechecktofalse. Apply the file again to perform the rotation.kubectl -n APIGEE_NAMESPACE apply -f rotation.yaml
 - 
    After the rotation job completes and you have validated traffic is still flowing correctly, clean up the process with the following two steps:
    
- 
        Update the value of 
metadata.nameand setspec.cassandra.jobTypetoCLEANUP. - 
        Trigger the cleanup job by applying the file.
        
kubectl -n APIGEE_NAMESPACE apply -f rotation.yaml
 
When the cleanup job is completed, the rotation process is complete.
 - 
        Update the value of 
 - Backup your Cassandra database. This backup is to ensure recovery is possible to post-rotated credentials.
 - Delete the old Cassandra credentials, role, and policy from Vault.
 
Multi-region setup
The multi-region setup procedures are divided into two sections: setup for the first region and setup for the remaining regions.
- Complete the following steps in the first region before starting the subsequent regions.
    
- 
        Create a new 
SecretProviderClassKubernetes resource in theAPIGEE_NAMESPACEnamespace for the new Cassandra credentials. See Storing Cassandra secrets in Hashicorp Vault for a template to use. This allows a Vault role to access secrets within the Kubernetes namespaces. - 
        Create a new 
SecretRotationcustom resource using the following template:# rotation.yaml apiVersion: apigee.cloud.google.com/v1alpha1 kind: SecretRotation metadata: name: ROTATION_PROCESS_NAME namespace: APIGEE_NAMESPACE spec: organizationId: ORG_NAME rotationId: ROTATION_ID timeoutMinutes: -1 # this value is required and should not be changed. precheck: true cassandra: oldSecretProviderClass: OLD_SPC_NAME newSecretProviderClass: NEW_SPC_NAME jobType: ROTATE- ROTATION_PROCESS_NAME: A unique name for the rotation job. You will need to set 
metadata.nameto a unique value for the rotation precheck job and again for the rotation job. For examplesr-1-precheckfollowed bysr-1. - ROTATION_ID: Set 
spec.rotationIdto a custom identifier, for examplerotation-1-precheck. - NEW_SPC_NAME: Set 
spec.cassandra.newSecretProviderClassto the new secret provider class name you created in the previous step. - OLD_SPC_NAME: Set 
spec.cassandra.oldSecretProviderClassto the SPC name currently being used by theApigeeDatastore. 
 - ROTATION_PROCESS_NAME: A unique name for the rotation job. You will need to set 
 - 
        Trigger the rotation precheck job by applying the 
rotation.yamlfile.kubectl -n APIGEE_NAMESPACE apply -f rotation.yaml
 - 
        Check the job status to verify when the precheck job is complete.
        
kubectl -n APIGEE_NAMESPACE get job sr-(rotationId)-(rotate|rollback|cleanup)-job
 - 
        Once the rotation precheck job completes:
        
- Change the value of 
metadata.name, for example fromsr-1-prechecktosr-1. - Set 
spec.prechecktofalseto turn off the precheck and perform the rotation. - Set 
spec.rotationIdto a new identifier, for examplerotation-1. 
 - Change the value of 
 - 
        Apply the file again to perform the rotation.
        
kubectl -n APIGEE_NAMESPACE apply -f rotation.yaml
 - 
        Check the state of the 
SecretRotationand wait until it iscomplete.kubectl -n APIGEE_NAMESPACE get sr SR_NAME
 
 - 
        Create a new 
 - 
    In each subsequent region, complete the following steps:
    
- Create a new 
SecretProviderClassKubernetes resource in your Apigee namespace for the new Cassandra credentials. See Storing Cassandra secrets in Hashicorp Vault for a template to use. This should be the same definition as step 1a. - Update your 
overrides.yamland setcassandra.auth.secretProviderClassto the match the value ofspec.cassandra.newSecretProviderClassin therotation.yamlfile.cassandra: auth: secretProviderClass: NEW_SPC_NAME - Apply the operator chart:
        
helm upgrade operator apigee-operator/ \ --namespace APIGEE_NAMESPACE \ --atomic \ -f OVERRIDES_FILE
 - 
        A new 
ReplicaSetwill be created. Check that the new controller-manager pods are using the new SPC:export POD=NEW_CONTROLLER_MANAGER_POD_NAME
kubectl -n APIGEE_NAMESPACE get pods $POD -o jsonpath='{.spec.volumes[?(@.name=="apigee-external-secrets")].csi.volumeAttributes.secretProviderClass}'The result should match the value you set for
spec.cassandra.newSecretProviderClassinrotation.yaml, for example:kubectl -n apigee get pods $POD -o jsonpath='{.spec.volumes[?(@.name=="apigee-external-secrets")].csi.volumeAttributes.secretProviderClass}'my-new-spc - Apply the datastore chart:
        
helm upgrade datastore apigee-datastore/ \ --namespace APIGEE_NAMESPACE \ --atomic \ -f OVERRIDES_FILE
 - The datastore will go into a releasing state. Wait until the datastore has finished releasing and is in the running state.
        
kubectl -n APIGEE_NAMESPACE get apigeedatastore DATASTORE_NAME
DATASTORE_NAME is
defaultin most installations. - Check that the new datastore pods are using the new SPC:
        
export POD=NEW_DATASTORE_POD_NAME
kubectl -n APIGEE_NAMESPACE get pods $POD -o jsonpath='{.spec.volumes[?(@.name=="apigee-external-secrets")].csi.volumeAttributes.secretProviderClass}'The result should match the value you set for
spec.cassandra.newSecretProviderClassinrotation.yaml, for example:kubectl -n apigee get pods $POD -o jsonpath='{.spec.volumes[?(@.name=="apigee-external-secrets")].csi.volumeAttributes.secretProviderClass}'my-new-spc - Wait until the organization and environments are done releasing and have returned to the running state.
        
kubectl -n APIGEE_NAMESPACE get apigeeorg ORG_NAME
kubectl -n APIGEE_NAMESPACE get apigeeenv ENV_NAME - Check that the new MART, runtime, and synchronizer pods are using the new SPC:
        
export POD=NEW_MART_POD_NAME
kubectl -n APIGEE_NAMESPACE get pods $POD -o jsonpath='{.spec.volumes[?(@.name=="apigee-external-secrets")].csi.volumeAttributes.secretProviderClass}'export POD=NEW_RUNTIME_POD_NAMEkubectl -n APIGEE_NAMESPACE get pods $POD -o jsonpath='{.spec.volumes[?(@.name=="apigee-external-secrets")].csi.volumeAttributes.secretProviderClass}'export POD=NEW_SYNCHRONIZER_POD_NAMEkubectl -n APIGEE_NAMESPACE get pods $POD -o jsonpath='{.spec.volumes[?(@.name=="apigee-external-secrets")].csi.volumeAttributes.secretProviderClass}'The result should match the value you set for
spec.cassandra.newSecretProviderClassinrotation.yaml, for example:kubectl -n apigee get pods $POD -o jsonpath='{.spec.volumes[?(@.name=="apigee-external-secrets")].csi.volumeAttributes.secretProviderClass}'my-new-spc 
 - Create a new 
 - 
    After completing the steps in every region and validate traffic is still flowing correctly, clean up the process in the first region with the following two steps:
    
- 
        In the first region, update the value of 
metadata.nameand setspec.cassandra.jobTypetoCLEANUP. - 
        Trigger the cleanup job by applying the file.
        
kubectl -n APIGEE_NAMESPACE apply -f rotation.yaml
 - Check the job status and watch the job logs to verify when the cleanup job is complete.
 
When the cleanup job is completed, the rotation process is complete.
 - 
        In the first region, update the value of 
 - Backup your Cassandra database. This backup is to ensure recovery is possible to post-rotated credentials.
 - Delete the old Cassandra credentials, role, and policy from Vault.