0
votes

everyone.

I am a beginner on Internet and Azure. I have a question about adding a certificate to a listener of an Azure application gateway with Python. I describe my problem in detail as follows.

1. Background

The Azure environment I use is:

Resource group name: My_ResourceGroup
Subscription ID: sub_id
Tenant ID: tenant_id
Client: my_client
Service principal password: sp_password

2. Top-domain and sub-domain

In resource group My_ResourceGroup, there are two Azure DNS providers with zones contoso.com and chen.contoso.com respectively. The contoso.com is the top domain while the chen.contoso.com is the sub-domain.

For chen.contoso.com, I created an A record with name www and IP 10.10.10.10 (note that this IP is just used for testing). I also generated a certificate (cert.pfx file) for this domain in order to use HTTPS.

3. Install cert.pfx certificate to a listener

I have a off-the-shelf Azure application gateway contoso-appgw in resource group My_ResourceGroup. In this gateway, there is a listener contoso-appgw-hl and there has been a certificate cert0.pfx in this listener.

What I want to do is appending (or, installing) the cert.pfx certificate to the listener contoso-appgw-hl with Azure Python SDK. After this operation, there should be two certificates in listener contoso-appgw-hl: cert0.pfx (the old one) and cert.pfx (the new one).

4. My code and the references

My Python code is as follows:

from azure.common.credentials import ServicePrincipalCredentials
from azure.mgmt.resource import ResourceManagementClient
from azure.mgmt.network import NetworkManagementClient

# Replace this with your subscription id
subscription_id = 'sub_id'

# Tenant ID for your Azure subscription
TENANT_ID = 'tenant_id'

# Your service principal App ID
CLIENT = 'client'

# Your service principal password
KEY = 'sp_password'

credentials = ServicePrincipalCredentials(
        client_id = CLIENT,
        secret = KEY,
        tenant = TENANT_ID
    )

network_client = NetworkManagementClient(credentials, subscription_id)

network_client.application_gateways.create_or_update(
    'My_ResourceGroup',
    'contoso-appgw',
    {
        'location': 'East US 2',
        'http_listeners': [
            {
                'name': 'contoso-appgw-hl',
                'protocol': 'Https',

                'ssl_certificate': {
                    'data': 'cert.pfx',
                    'name': 'chenkui',
                    'password': '123abc'
                }
            }
        ]
    }
)

I wrote my code based on the following resources:

  1. Sample code: azure application manage sample code
  2. Azure document: definition of create_or_update function

Note that the cert.pfx in my code is a Base-64 format certificate because based on the document a Base-64 format certificate is needed.

5. Error message

The above code is failed. The error message shown in Azure Portal --> contoso-appgw --> Activity log of the above code is:

Operation name:
    Create or Update Application Gateway

Error code:
    InvalidRequestFormat

Message:
    Cannot parse the request.

Even I use the Azure Portal (i.e. instead of using Python code, use GUI Portal in browser), adding the certificate is also failed. The error message shown in Azure Portal --> contoso-appgw --> Activity log is:

Operation name:
    Create or Update Application Gateway

Error code: 
    ApplicationGatewaySslCertificateDataMustBeSpecified

Message:
    Data must be specified for Certificate /subscriptions/c72b5b1b-771e-4b65-ba34-a7db981c9dcf/resourceGroups/My_ResourceGroup/providers/Microsoft.Network/applicationGateways/contoso-appgw/sslCertificates/chenkui.

6. My question

My questions are given as follows:

  1. What are the meaning of these error messages?
  2. Why are these errors given?
  3. What is the problem of my code and how to solve it?

Thank you very much!

2
Could you tell me if you just need to add an SSL cert or you need to change the protocol from http to https? - Jim Xu
@JimXu Thanks for your reply. I want to do them both. Add this SSL cert into a listener and change the protocol from http to https. - zchenkui
Have you referred to docs.microsoft.com/en-us/python/api/azure-mgmt-network/…? According to the document, you need to provide the resource id of SSL certificate. - Jim Xu
Do you follow the flow to upload your cert: listener-choose a cert(create new)- upload a cert- select the pfx file,cert name, and password? Do you use v1 sku app gw? - Nancy Xiong
For me, I get a similar error with gw v2 when I upload the same PFX cert as the existing one via creating a new cert while choosing a cert. - Nancy Xiong

2 Answers

0
votes

If you want to covert listener from http to https, you can use the following powershell script :

$appgw= Get-AzApplicationGateway -Name "AppGWname" -ResourceGroupName "RG Name"

#$listener= Get-AzApplicationGatewayHttpListener -Name listener1 -ApplicationGateway $appgw

$FEC= Get-AzApplicationGatewayFrontendIPConfig -Name "FrontendIP" -ApplicationGateway $appgw


Add-AzApplicationGatewayFrontendPort -ApplicationGateway $appgw -Name "Name of the Port" -Port 443 

$port = Get-AzApplicationGatewayFrontendPort -ApplicationGateway $appgw -Name "Name of Port"

$passwd = ConvertTo-SecureString  "Passoword" -AsPlainText -Force 


Add-AzApplicationGatewaySSLCertificate -Name "Name of the cert" -CertificateFile "Full path of the cert with.pfx" -Password $passwd -ApplicationGateway $appgw

$cert =Get-AzApplicationGatewaySSLCertificate -Name "Name of cert" -ApplicationGateway $appgw

Set-AzApplicationGatewayHttpListener -ApplicationGateway $appgw -Name "Name of the listener" -FrontendIPConfiguration $FEC -FrontendPort $port -Protocol Https -SslCertificate $cert

Set-AzApplicationGateway -ApplicationGateway $appgw
0
votes

I have found a method to update an existing application gateway. When using create_or_update function to update an existing Azure resource, you must get it first. Otherwise, create_or_update will create a new resource instead of updating an existing one.

The following link is a good example. It creates and updates an Azure VM. Create and manage Windows VMs in Azure using Python

Because creating and managing resources in Azure has a uniform method, we can apply the idea given in above link to manage application gateway. The code is as follows.

import base64

from azure.common.credentials import ServicePrincipalCredentials
from azure.mgmt.resource import ResourceManagementClient
from azure.mgmt.network import NetworkManagementClient
from azure.mgmt.network.v2019_06_01.models import ApplicationGateway, ApplicationGatewaySslCertificate


def test_appgw():
    # create credentials
    credentials = ServicePrincipalCredentials(
            client_id = CLIENT,
            secret = KEY,
            tenant = TENANT_ID
        )

    # create network client
    network_client = NetworkManagementClient(credentials, subscription_id)

    # get an existing application gateway
    app_gw = network_client.application_gateways.get(RESOURCE_GROUP_NAME, APPLICATION_GATEWAY_NAME)

    # read the pfx certificate and convert it to base-64 string
    with open('certificate.pfx', 'rb') as binary_cert:
        base64_cert = base64.b64encode(binary_cert.read())
        cert_data = base64_cert.decode('utf-8')

    # create an SSL certificate
    ssl_cert = ApplicationGatewaySslCertificate(
        name=ANY_NAME_IS_OK,
        data=cert_data,
        password=THE_PASSWARD_USED_TO_CREATE_CERTIFICATE
    )

    # app_gw.ssl_certificates is a Python list, so we append the new certificate in it
    app_gw.ssl_certificates.append(ssl_cert)

    # update the application gateway
    network_client.application_gateways.create_or_update(
        RESOURCE_GROUP_NAME,
        APPLICATION_GATEWAY_NAME,
        app_gw
    )

if __name__ == "__main__":
    test_appgw()

Note:

  1. Using get function to obtain an existing application gateway;
  2. The first parameter name of ApplicationGatewaySslCertificate class is a string. You can use any name you like;
  3. The second parameter data is a string. It is NOT a name of a certificate, but a Base-64 string of the content of a pfx certificate;
  4. The third parameter password is a string. It should be the password by which you create your pfx certificate.

Hope this help you.