Migrating Self-Hosted to the New Infrastructure
This migration moves a self-hosted CIPP instance off the Function App and Static Web App architecture onto a single Linux container Web App. Your storage account and Key Vault are kept, so credentials and configuration carry across, and the old compute resources are removed as part of the cutover.
Back up first
In CIPP, go to Application Settings, then select Manage Backups on the Backup card. Select Run Backup for a fresh backup, then use the Download Backup action on the row to save the file. It captures your instance configuration in case anything fails during the migration.
Confirm prerequisites
PowerShell 7+ with the Az module, signed in to the Azure subscription that holds CIPP.
Owner on the resource group, or Contributor + User Access Administrator. Owner is needed because the migration creates a role assignment, granting the new Web App's managed identity Contributor on itself, and that needs
roleAssignments/write, which Contributor alone does not have. The script checks this up front and stops if it is missing.Download the files below, both into the same folder. The script loads its template from its own directory.
Finish SSO migration
SSO must be at secrets_stored or complete before you cut over. You can find the SSO setup and its state under CIPP → Advanced → Authentication → SSO. If it is not set up yet, complete it there before going any further: see SSO.
Test run (-TestOnly)
From the folder where you saved both files, run:
Add -CippUrl 'cipp.contoso.com' if you use a custom domain, so the final summary includes the DNS records to create.
A test run changes nothing. It validates the template, detects the resources that would be affected, and confirms you have the permissions the migration needs.
If it reports that the resource group cannot be found even though it exists, the automatic subscription lookup has failed. Pass the subscription explicitly:
Live run
If the test run looks right, run the same command without -TestOnly:
The new Web App is named after your existing Key Vault, because the backend resolves its Key Vault from the site name. Leave -WebAppName alone unless you have a reason to change it, and if you do set it, it has to match the Key Vault name.
If the instance has already been migrated, the script detects it and stops rather than running again. Passing -Force overrides that, and -SkipIamCheck skips the permission check, though a missing permission then surfaces partway through, after resources have been deleted.
If the migration does not complete
Getting here should be rare, and a rebuild is the last resort rather than the expected response. Work through these in order.
Run the script again. A partial run usually leaves the instance in a state the script does not count as migrated, so the same command picks up where it left off. The already-migrated check only trips when a container web app exists, the resource group carries the NG tag, and no function apps remain, which a failed run rarely satisfies.
If it stops and reports the migration as already complete, add -Force.
If re-running does not recover it, rebuild. What survives is the important part: the script preserves the storage account and the Key Vault holding your credentials, so your configuration data and the four CIPP-SAM secrets are still there even when the compute resources have gone.
Leave the old resource group alone. The storage account and Key Vault in it are what the rebuild depends on.
Deploy a fresh self-hosted instance into a new resource group. Follow the self-hosted deployment on Installation. Use a new resource group, because the deployment creates its own Key Vault and the name would collide with the one that survived.
Point the new instance at your existing credentials. Read the four secrets out of the old Key Vault and enter them in the new instance's Setup Wizard under "I have an existing application and would like to manually enter my tokens". Granting yourself access to the vault and reading the values works exactly as it does for a hosted migration: see Migrating to Hosted CIPP.
Restore your backup. In the new instance, go to Application Settings, then Restore Backup, and upload the file you downloaded before starting.
Set up single sign-on and repoint your custom domain, then verify the new instance before removing anything. The remaining sections on this page apply to it in the same way.
Repoint DNS
Point your custom-domain CNAME at the new Web App hostname the script printed, then add the domain in App Service. The script removes custom domains from the Static Web App before deleting it, but does not add them to the new App Service for you.
To add the domain in Azure:
App Service → your CIPP app → Custom domains → Add custom domain
Set Domain provider to All other domain services, TLS/SSL certificate to App Service Managed Certificate, TLS/SSL type to SNI SSL
Enter your hostname and complete validation, then confirm the managed certificate is issued and bound
Add the redirect URI for the new hostname
The instance now answers on a different hostname from the Static Web App it replaced, and each hostname needs its own sign-in redirect URI of https://<hostname>/.auth/login/aad/callback. Any hostname without one fails sign-in with AADSTS50011, including the custom domain you have just added.
In CIPP, go to CIPP → Advanced → Authentication → SSO and select Refresh Sign-in URLs. It adds a redirect URI for every hostname currently bound to the instance and never removes an existing one, so it is safe to run again after any later domain change.
Last updated
Was this helpful?

