VMware Cloud Foundation APIs: Replacing VCF Operations Certificate
A core fleet management capability provided by VMware Cloud Foundation is the ability to replace component certificates across the entire platform from a central location. VMware Cloud Foundation provides direct integration for OpenSSL and Microsoft Certificate Authorities, using this integration you first create a Certificate Signing Request before then replacing the component certificate during which VCF Operations will contact the Certificate Authority request a new signed certificate and then replace the component certificate.
In this post we will look at the steps required to complete the certificate replacement process for VCF Operations using public APIs, this is achieved via VCF Operations. The same process can be used for other components with minor modifications to the JSON payloads.
VCF Operations APIs Used
VMware Cloud Foundation Operations API
- POST /suite-api/api/auth/token/acquire
- POST /suite-api/api/fleet-management/certificate-management/certificates/query
- POST /suite-api/api/fleet-management/certificate-management/csrs
- GET /suite-api/api/workflows/requests
- PUT /suite-api/api/fleet-management/certificate-management/certificates/
Procedure
Connect to a system that has access to your infrastructure and is capable of running CURL.
Replace the values in the sample code with values for your VCF Operations instance and run the commands in the console.
1export vcfOperationsFqdn='flt-ops01a.rainpole.io'
2export vcfOperationsUser='admin'
3export vcfOperationsPass='VMw@re1!VMw@re1!'
- Authenticate to VCF Operations and obtain a token by running the following command:
1vcfOperationsToken=$(curl -k -X POST "https://${vcfOperationsFqdn}/suite-api/api/auth/token/acquire" \
2 --header "Content-Type:application/json" \
3 --header "Accept: application/json" \
4 -d "{\"username\":\"$vcfOperationsUser\", \"password\":\"$vcfOperationsPass\"}" \
5 | jq -r '.token')
- Verify you were able to successfully obtain an authentication token by running the following command:
1echo $vcfOperationsToken
Example Output:
16513db65-1c46-4482-9a4c-d257cd422906::bf144935-712c-4e2e-8881-8005575b47cd
- Retrieve the TLS certificate ID for VCF Operations by running the following command:
1certificateId=$(curl -k -X POST "https://${vcfOperationsFqdn}/suite-api/api/fleet-management/certificate-management/certificates/query" \
2 --header "Authorization: OpsToken ${vcfOperationsToken}" \
3 --header "Content-Type:application/json" \
4 --header "Accept: application/json" \
5 -d '{"appliance": "VCF_OPERATIONS", "category": "TLS_CERT" }' \
6 | jq -r '.vcfCertificateModels[].certificateResourceKey')
Tip
To perform this step against other components within the VMware Cloud Foundation platform simply replace VCF_OPERATIONS with one of the following values: VCENTER, NSXT_MANAGER, SDDC_MANAGER, VCF_AUTOMATION, LOG_MANAGEMENT, VCF_OPERATIONS, VCF_OPS_NETWORKS, IDENTITY_BROKER, VCF_OPS_HCX, ESX, VCF_SERVICES_RUNTIME, AVI_LOAD_BALANCER, LICENSE_SERVER.
- Verify you successfully obtained the TLS certificate ID for VCF Operations by running the following command:
1echo $certificateId
Example Output:
163ab0977-c54c-398e-ac8e-012686689947
- Replace the values in the sample code with your values and run the commands in the console.
1export certificateAuthorityKeySize='2048'
2export certificateAuthorityOrganization='Rainpole'
3export certificateAuthorityOrgUnit='IT'
4export certificateAuthorityCountry='US'
5export certificateAuthorityState='CA'
6export certificateAuthorityLocality='San Francisco'
7export certificateAuthorityCommonName='flt-ops01.rainpole.io'
8export certificateAuthoritySubjectAltNames='"flt-ops01b.rainpole.io", "flt-ops01a.rainpole.io", "flt-ops01.rainpole.io"'
Tip
For other components adjust the certificateAuthorityCommonName and certificateAuthoritySubjectAltNames as needed.
- Create the JSON payload for generating the Certificate Signing Request (CSR) by running the following command:
1cat << EOF > csr-vcf-operations.json
2{
3 "certificateId": "${certificateId}",
4 "generateCsrSpec": {
5 "keySize": "KEY_${certificateAuthorityKeySize}",
6 "keyAlgorithm": "RSA",
7 "organization": "${certificateAuthorityOrganization}",
8 "orgUnit": "${certificateAuthorityOrgUnit}",
9 "country": "${certificateAuthorityCountry}",
10 "state": "${certificateAuthorityState}",
11 "locality": "${certificateAuthorityLocality}",
12 "commonName": "${certificateAuthorityCommonName}",
13 "subjectAltNames": {
14 "dns": [${certificateAuthoritySubjectAltNames}],
15 "ip": []
16 }
17 }
18}
19EOF
- Verify the JSON payload has been populated correctly by running the following command:
1cat csr-vcf-operations.json
Example Output:
1{
2 "certificateId": "63ab0977-c54c-398e-ac8e-012686689947",
3 "generateCsrSpec": {
4 "keySize": "KEY_2048",
5 "keyAlgorithm": "RSA",
6 "organization": "Rainpole",
7 "orgUnit": "IT",
8 "country": "US",
9 "state": "CA",
10 "locality": "San Francisco",
11 "commonName": "flt-ops01.rainpole.io",
12 "subjectAltNames": {
13 "dns": ["flt-ops01b.rainpole.io", "flt-ops01a.rainpole.io", "flt-ops01.rainpole.io"],
14 "ip": []
15 }
16 }
17}
- Request the Certificate Signing Request (CSR) by running the following command:
1requestId=$(curl -k -X POST "https://${vcfOperationsFqdn}/suite-api/api/fleet-management/certificate-management/csrs" \
2 --header "Authorization: OpsToken ${vcfOperationsToken}" \
3 --header "Content-Type:application/json" \
4 --header "Accept: application/json" \
5 -d @csr-vcf-operations.json \
6 | jq -r '.requestId')
- Verify you successfully obtained a request ID by running the following command:
1echo $requestId
Example Output:
1f1ee3760-ded5-43d7-9547-24296ada7f47
- Check the status of the workflow by running the following command:
1curl -k -X GET "https://${vcfOperationsFqdn}/suite-api/api/workflows/requests/${requestId}" \
2 --header "Authorization: OpsToken ${vcfOperationsToken}" \
3 --header "Content-Type:application/json" \
4 --header "Accept: application/json" \
5 | jq
- Replace the certificate of VCF Operations by running the following command:
1requestId=$(curl -k -X PUT "https://${vcfOperationsFqdn}/suite-api/api/fleet-management/certificate-management/certificates/${certificateId}" \
2 --header "Authorization: OpsToken ${vcfOperationsToken}" \
3 --header "Content-Type:application/json" \
4 --header "Accept: application/json" \
5 -d '{"caType": "MSCA"}' \
6 | jq -r '.requestId')
- Verify you successfully obtained a request ID by running the following command:
1echo $requestId
Example Output:
17b96f0e5-4fe1-4667-bb7c-43f518ce6f50
- Check the status of the workflow by running the following command:
1curl -k -X GET "https://${vcfOperationsFqdn}/suite-api/api/workflows/requests/${requestId}" \
2 --header "Authorization: OpsToken ${vcfOperationsToken}" \
3 --header "Content-Type:application/json" \
4 --header "Accept: application/json" \
5 | jq