Generate Azure Stack Hub Certificates using an Enterprise CA - the automated way

Anyone who has had to deploy or operate Azure Stack Hub will tell you that one of the most laborious and tricky tasks is the generation of PKI certificates for the external endpoints. There are quite stringent requirements that can be found here.

I have already written about and created a script that can be used to generate Lets Encrypt signed certificates, but that doesn’t meet everyone’s requirements.

A common scenario is to use a Certificate Authority hosted on Windows Server. Here are the high level tasks that need to be carried out:

  1. Generate the requests

  2. Submit the request to the CA

  3. Approve the request

  4. Retrieve the signed cert

  5. Import the signed cert

  6. Export the certificate as a Pfx file with password

  7. Place the exported Pfx files into specific folders for use by Azure Stack Hub

  8. Test the certs for validity

Microsoft have helped by creating the Azure Stack Readiness Checker PowerShell module, which really is a great tool for generating the certificate requests and checking the validity of the Pfx files, but we need a process to automate all of the steps above.

To help with that, I’ve created a script that will take some inputs and do the rest for you. You can find it here.

The main script is New-AzsHubCertificates.ps1. It takes the following parameters:

Parameter Type Description
azsregion String Azure Stack Hub Region Name
azsCertDir String Directory to store certificates
CaServer String IP address fo the Certificate Authority Server
IdentitySystem String Either AAD or ADFS
CaCredential Credential Credentials to connect to the Certificate Authority Server
AppServer Boolean Choose if App Service Certs should be generated
DBAdapter Boolean Choose if DB Adapter Cert should be generated
EventHubs Boolean Choose if Event Hubs Cert should be generated
IoTHubs Boolean Choose if IOT Hub Cert should be generated
SkipDeployment Boolean Choose if you do not require the deployment certificates generating
pfxPassword SecureString Password for the Pfx Files

It utilizes the Azure Stack Readiness Checker module to generate the cert requests and to also validate that the certificates are fit for purpose, so ensure that you have the module installed. The script also needs to be run from an elevated session as it needs to import and export certificates from the Computer store that you run it from (needless to say you need to run it from a Windows client :) ).

  1. The first thing the script does is create the folder for the certificates. It takes the input you specify and will create a sub-folder from there for the Azure Stack Hub Region, so you could run this script on the same system for multiple stamps.

  2. Next, it uses the New-AzsCertificateSigningRequest function from the Readiness checker module to create the requests. it places them in the \requests directory.

  3. After this, WinRM config is checked to see if the IP address of the CA server exists in Trusted Hosts. If not, it is added. All other entries are maintained.

  4. A Session is established to the CA server, and the request files are copied to it.

  5. On the CA server, Certutil.exe is used to retrieve the Public CA certificate and stored in a file.

  6. On the CA server, CertReq.exe is used to submit each of the requests to the CA.

  7. On the CA server, each request is approved using CertUtil -resubmit .

  8. On the CA server, each Signed cert is retrieved and stored as a p7b and crt file.

  9. Each signed cert is copied from the CA server to the local system where you’re running the script.

  10. The Public CA certificate is copied from the CA server to the local system.

  11. On the CA server, the working folder is deleted.

  12. The remote PS Session is removed.

  13. The Public CA certificate is imported in to the computers root store.

  14. The directory structure required for validating certificates is created.

  15. The signed certificates are imported.

  16. The private certificates are exported and saved as a pfx file with password to the corresponding directory.

  17. The certificates are validated using the Invoke-AzsCertificateValidation function from the Readiness checker module.

The folder structure for the certificates is as follows:

C:\AZSCERTS\AZS1
+---AAD
|   +---ACSBlob
|   |       blob.pfx
|   |
|   +---ACSQueue
|   |       queue.pfx
|   |
|   +---ACSTable
|   |       table.pfx
|   |
|   +---Admin Extension Host
|   |       adminhosting.pfx
|   |
|   +---Admin Portal
|   |       adminportal.pfx
|   |
|   +---ARM Admin
|   |       adminmanagement.pfx
|   |
|   +---ARM Public
|   |       management.pfx
|   |
|   +---KeyVault
|   |       vault.pfx
|   |
|   +---KeyVaultInternal
|   |       adminvault.pfx
|   |
|   +---Public Extension Host
|   |       hosting.pfx
|   |
|   \---Public Portal
|           portal.pfx
|
+---AppServices
|   +---API
|   |       api.pfx
|   |
|   +---DefaultDomain
|   |       wappsvc.pfx
|   |
|   +---Identity
|   |       sso.pfx
|   |
|   \---Publishing
|           ftp.pfx
|
+---DBAdapter
|       DBAdapter.pfx
|
+---EventHubs
|       eventhub.pfx
|
\---IoTHub
        mgmtiothub.pfx


I have written an example script new-AzsHubcertificatesexample.ps1 so that you can generate the correct parameter types, or create a new, unique Pfx password for use by the main script. Change the variables according to your environment. You could take this further by storing the pfx password in a KeyVault; maybe I’ll write a further post on how to do this … :)