Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Azure Website - configure SSL Bindings with PowerShell or cross-platform CLI

Our situation is that we expect to be frequently adding new custom sub-domains to a number of Azure Websites and we need to be able to automate the process so we can minimize any need for manual intervention and the risk of screwing something up.

The Azure Cross-Platform CLI tools and PowerShell cmdlets provide enough functionality for me to script it all out, with the apparent exception of the SSL bindings... The websites are all HTTPS-only, and every domain that we add requires an SNI SSL binding.

The Azure management portals allow you to manually configure the SSL bindings for a website's domains. How can I achieve the same using the PowerShell cmdlets or the cross-platform CLI tools? If it's not possible using either of those tools, is there some other way I can script out the process for when we add/remove domains to the sites?

like image 834
lethek Avatar asked Oct 28 '14 04:10

lethek


People also ask

How do I bind SSL certificate in Azure App Service?

In the Azure portal, from the left menu, select App Services > <app-name>. From the left navigation of your app, start the TLS/SSL Binding dialog by: Selecting Custom domains > Add binding. Selecting TLS/SSL settings > Add TLS/SSL binding.

How do I add an SSL certificate to my Azure Web App?

In the Azure portal, from the left menu, select App Services > <app-name>. From your app's navigation menu, select TLS/SSL settings > Private Key Certificates (. pfx) > Import App Service Certificate. Select the certificate that you just purchased, and then select OK.

What is SSL binding?

Binding refers to the process of configuring the SSL certificate to use port 443 on the website. The instructions for binding a certificate with the website vary depending on the platform and version of your web server. For instructions, consult your system administrator or your web server's documentation.


1 Answers

I've finally managed to successfully do this by using the Azure Web Sites Management REST API.

The original documentation which I based my example code below on back in 2014 is no longer available, but the Azure Resource Explorer which Zain mentioned and linked to a blog post about in the comments is in my opinion a superior resource. Direct link: https://resources.azure.com/

The Service Management REST API Reference appears to be the closest thing to the original documentation I used but presently lacks anything specifically about Azure Web Apps (previously known as Azure Websites): https://msdn.microsoft.com/library/azure/ee460799.aspx

E.g.:

using System;
using System.Linq;
using System.Net.Http;
using System.Net.Http.Formatting;
using System.Net.Http.Headers;
using System.Security.Cryptography.X509Certificates;
using System.Threading.Tasks;

private const string managementThumbprint = "0000000000000000000000000000000000000000";
private const string subscriptionId = "00000000-0000-0000-0000-000000000000";

private const string sslThumbprint = "0000000000000000000000000000000000000000";
private const string webspace = "eastasiawebspace";
private const string websiteName = "myWebsite";
private const string websiteDomain = "myDomain";
private const SslState sslState = SslState.SniEnabled;

public async Task SetSslState()
{
    //Retrieve management certificate
    var store = new X509Store(StoreName.My, StoreLocation.CurrentUser);
    store.Open(OpenFlags.ReadOnly);
    var certificate = store.Certificates.Cast<X509Certificate2>().First(xc => xc.Thumbprint.Equals(managementThumbprint, StringComparison.OrdinalIgnoreCase));

    //Setup http client
    var handler = new WebRequestHandler();
    handler.ClientCertificates.Add(certificate);
    var client = new HttpClient(handler) {
        BaseAddress = new Uri("https://management.core.windows.net/" + subscriptionId + "/services/WebSpaces/")
    };
    client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
    client.DefaultRequestHeaders.Add("x-ms-version", "2014-06-01");

    var requestData = new {
        HostNameSslStates = new[] {
            new {
                Name = websiteDomain,
                SslState = (long)sslState,
                Thumbprint = sslThumbprint,
                ToUpdate = true
            }
        }
    };
    var response = await client.PutAsJsonAsync(webspace + "/sites/" + websiteName, requestData);
}

public enum SslState
{
    Disabled = 0,
    SniEnabled = 1,
    IpBasedEnabled = 2
}
like image 168
lethek Avatar answered Nov 09 '22 04:11

lethek