Quite often you need a certificate that does not necessary need to be properly signed because it will only be used for testing purposes or by your own services. Good example when you are creating a Azure Service Fabric Cluster. One option is to use the Azure Portal to generate the certificate by filling out the details, but if you want to automate the process that is not an option.
Using PowerShell to generate certificate on a Windows machine or openssl on Linux is well documented, but if you want your cert directly generated to an Azure Key Vault you must use Azure modules of PowerShell or Azure CLI.
If you need a simple self signed certificate, you can do that by using the az keyvault certificate create command, the Azure documentation has a sample how to use this:
1 |
az keyvault certificate create --vault-name vaultname -n cert1 -p "$(az keyvault certificate get-default-policy)" |
This will create a certificate in the “vaultname” KeyVault with the name “cert1“.
What if you want some more, e.g. to add subject or even multiple entries to the SAN, what if you want to change the automatic renewal (that is the default) to an email alert, what if you want to explicitly specify the usage of the certificate?
The
-p "$(az keyvault certificate get-default-policy)" was quite suspicious. The “az keyvault certificate create” documentation says:
--policy -p
JSON encoded policy defintion. Use @{file} to load from a file.
If there was a default policy, there must be a way to customize that – I thought… As usual Google was my best friend, so I found some info in the Key Vault REST API Documentation. I wanted to use the cert with multiple domain names, so SubjectAlternativeNames option looked promising, however the “dns_names” parameter did not work as it was documented. That was when I realized that there was a --scaffold parameter of the az keyvault certificate get-default-policy that generates a fully formed policy structure with default values. Here is how to output looks like:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 |
{ "issuerParameters": { "certificateTransparency": null, "certificateType": "(optional) DigiCert, GlobalSign or WoSign", "name": "Unknown, Self, or {IssuerName}" }, "keyProperties": { "curve": null, "exportable": true, "keySize": 2048, "keyType": "(optional) RSA or RSA-HSM (default RSA)", "reuseKey": true }, "lifetimeActions": [ { "action": { "actionType": "AutoRenew" }, "trigger": { "daysBeforeExpiry": 90, "lifetimePercentage": null } } ], "secretProperties": { "contentType": "application/x-pkcs12 or application/x-pem-file" }, "x509CertificateProperties": { "ekus": [ "1.3.6.1.5.5.7.3.1" ], "keyUsage": [ "cRLSign", "dataEncipherment", "digitalSignature", "keyEncipherment", "keyAgreement", "keyCertSign" ], "subject": "C=US, ST=WA, L=Redmond, O=Contoso, OU=Contoso HR, CN=www.contoso.com", "subjectAlternativeNames": { "dnsNames": [ "hr.contoso.com", "m.contoso.com" ], "emails": [ "hello@contoso.com" ], "upns": [] }, "validityInMonths": 24 } } |
All you need is to save this to a file (e.g. cert_policy.json ), modify the relevant sections and give it a go like this:
1 |
az keyvault certificate create --vault-name "mydev-fabric-vlt" -n "mydev-fabric-cer" -p @cert_policy.json |
Voila, your certificate is available in the Key Vault.
The reason I really like this method is that the certificate itself does not need to leave a fully controlled environment, the Azure Key Vault.