pulumi / pulumi-azure-native

Azure Native Provider
Apache License 2.0
129 stars 35 forks source link

C# Service fabric cluster setup - UnsupportedIssuerThumbprintPair #1040

Open naveenkumarsp opened 3 years ago

naveenkumarsp commented 3 years ago

i have been trying to write pulumi template for deploying service fabric with self signed certificate. For creating certificate. However the certificate is failing in Reverse proxy common names.

Basically the setup was configured using terraform template and it had worked fine. Now i am trying to re-write the template in Pulumi and i was following the examples mentioned in the documentations to setup.

Let me know if i am missing anything.

Template

using Pulumi;
using Pulumi.Azure.Core;
using Pulumi.Azure.Storage;
using AzureNative = Pulumi.AzureNative;
using Azure = Pulumi.Azure;
class MyStack : Stack
{
    public MyStack()
    {
        var config = new Pulumi.Config();
        string ResourceGroupName = config.Require("resourceName");
        string kvName = config.Require("kv_name");
        string networkName = config.Require("core_vnet_name");
        string subnetName = config.Require("core_vnet_db_subnet_name");
        string vmSize = config.Require("vm_size");
        int instanceCount = config.RequireInt32("server_count");
        string vmssName = config.Require("vmss_name");
        string adminUsername = config.Require("admin_username");
        string adminPassword = config.Require("admin_password");
        int dataDiskSize = config.RequireInt32("data_disk_size");

        // Create an Azure Resource Group
        var resourceGroup = new ResourceGroup(ResourceGroupName);

        var azContext = Output.Create(AzureNative.Authorization.GetClientConfig.InvokeAsync());
        var azTenant = azContext.Apply(azContext => azContext.TenantId); 
        // Create an Azure Storage Account
        var storageAccount = new Account("storage", new AccountArgs
        {
            ResourceGroupName = resourceGroup.Name,
            AccountReplicationType = "LRS",
            AccountTier = "Standard"
        });
        //Create Keyvault with access policy
        var galoresfkv = new AzureNative.KeyVault.Vault("galoresfkv", new AzureNative.KeyVault.VaultArgs
        {
            Location = resourceGroup.Location,
            ResourceGroupName = resourceGroup.Name,
            VaultName = kvName,
            Properties = new AzureNative.KeyVault.Inputs.VaultPropertiesArgs
            {
                AccessPolicies = 
                    {
                        new AzureNative.KeyVault.Inputs.AccessPolicyEntryArgs
                        {
                            ObjectId = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
                            TenantId = azTenant,
                            Permissions = new AzureNative.KeyVault.Inputs.PermissionsArgs
                            {
                                Certificates = 
                                {
                                    "get",
                                    "list",
                                    "delete",
                                    "create",
                                    "import",
                                    "update",
                                    "managecontacts",
                                    "getissuers",
                                    "listissuers",
                                    "setissuers",
                                    "deleteissuers",
                                    "manageissuers",
                                    "recover",
                                    "purge",
                                },
                                Keys = 
                                {
                                    "encrypt",
                                    "decrypt",
                                    "wrapKey",
                                    "unwrapKey",
                                    "sign",
                                    "verify",
                                    "get",
                                    "list",
                                    "create",
                                    "update",
                                    "import",
                                    "delete",
                                    "backup",
                                    "restore",
                                    "recover",
                                    "purge",
                                },
                                Secrets = 
                                {
                                    "get",
                                    "list",
                                    "set",
                                    "delete",
                                    "backup",
                                    "restore",
                                    "recover",
                                    "purge",
                                },
                            },
                        },
                    },
                EnabledForDeployment = true,
                EnabledForDiskEncryption = true,
                EnabledForTemplateDeployment = true,
                Sku = new AzureNative.KeyVault.Inputs.SkuArgs
                {
                    Family = "A",
                    Name = AzureNative.KeyVault.SkuName.Standard,

                },
                TenantId = azTenant,
            }
        });
        // Self signed certificate creation using Pulumi.Azure library
        var galoresfcert = new Pulumi.Azure.KeyVault.Certificate("galoresfcert", new Pulumi.Azure.KeyVault.CertificateArgs
        {
            KeyVaultId = galoresfkv.Id,
            CertificatePolicy = new Pulumi.Azure.KeyVault.Inputs.CertificateCertificatePolicyArgs
            {
                IssuerParameters = new Pulumi.Azure.KeyVault.Inputs.CertificateCertificatePolicyIssuerParametersArgs
                {
                    Name = "Self",
                },
                KeyProperties = new Pulumi.Azure.KeyVault.Inputs.CertificateCertificatePolicyKeyPropertiesArgs
                {
                    Exportable = true,
                    KeySize = 2048,
                    KeyType = "RSA",
                    ReuseKey = true,
                },
                LifetimeActions = 
                {
                    new Pulumi.Azure.KeyVault.Inputs.CertificateCertificatePolicyLifetimeActionArgs
                    {
                        Action = new Pulumi.Azure.KeyVault.Inputs.CertificateCertificatePolicyLifetimeActionActionArgs
                        {
                            ActionType = "AutoRenew",
                        },
                        Trigger = new Pulumi.Azure.KeyVault.Inputs.CertificateCertificatePolicyLifetimeActionTriggerArgs
                        {
                            DaysBeforeExpiry = 30,
                        },
                    },
                },
                SecretProperties = new Pulumi.Azure.KeyVault.Inputs.CertificateCertificatePolicySecretPropertiesArgs
                {
                    ContentType = "application/x-pkcs12",
                },
                X509CertificateProperties = new Pulumi.Azure.KeyVault.Inputs.CertificateCertificatePolicyX509CertificatePropertiesArgs
                {
                    ExtendedKeyUsages = 
                    {
                        "1.3.6.1.5.5.7.3.1",
                        "1.3.6.1.5.5.7.3.2",
                    },
                    KeyUsages = 
                    {
                        "cRLSign",
                        "dataEncipherment",
                        "digitalSignature",
                        "keyAgreement",
                        "keyCertSign",
                        "keyEncipherment",
                    },
                    Subject = $"CN=sfdemonav123.westeurope.cloudapp.azure.com",
                    ValidityInMonths = 12,
                },
            },
        });

        //Service fabric cluster creation 
        var cluster = new AzureNative.ServiceFabric.Cluster("cluster", new AzureNative.ServiceFabric.ClusterArgs
        {
            CertificateCommonNames = new AzureNative.ServiceFabric.Inputs.ServerCertificateCommonNamesArgs
            {
                CommonNames = 
                {
                    new AzureNative.ServiceFabric.Inputs.ServerCertificateCommonNameArgs
                    {
                        CertificateCommonName = "sfdemonav123.westeurope.cloudapp.azure.com",
                        CertificateIssuerThumbprint = galoresfcert.Thumbprint,
                    },
                },
                X509StoreName = "My",
            },
            ClientCertificateCommonNames = 
            {
                new AzureNative.ServiceFabric.Inputs.ClientCertificateCommonNameArgs
                {
                    CertificateCommonName = "sfdemonav123.westeurope.cloudapp.azure.com",
                    CertificateIssuerThumbprint = galoresfcert.Thumbprint,
                    IsAdmin = true,
                },
            },
            ClientCertificateThumbprints = 
            {
                new AzureNative.ServiceFabric.Inputs.ClientCertificateThumbprintArgs
                {
                    CertificateThumbprint = galoresfcert.Thumbprint,
                    IsAdmin = true,
                },
            },
            ClusterName = "sfdemonav123",
            DiagnosticsStorageAccountConfig = new AzureNative.ServiceFabric.Inputs.DiagnosticsStorageAccountConfigArgs
            {
                BlobEndpoint = storageAccount.PrimaryBlobEndpoint,
                ProtectedAccountKeyName = "StorageAccountKey1",
                QueueEndpoint = storageAccount.PrimaryQueueEndpoint,
                StorageAccountName = storageAccount.Name,
                TableEndpoint = storageAccount.PrimaryTableEndpoint,
            },
            FabricSettings = 
            {
                new AzureNative.ServiceFabric.Inputs.SettingsSectionDescriptionArgs
                {
                    Name = "UpgradeService",
                    Parameters = 
                    {
                        new AzureNative.ServiceFabric.Inputs.SettingsParameterDescriptionArgs
                        {
                            Name = "AppPollIntervalInSeconds",
                            Value = "60",
                        },
                    },
                },
            },
            Location = resourceGroup.Location,
            ManagementEndpoint = "https://sfdemonav123.westeurope.cloudapp.azure.com:19080",
            NodeTypes = 
            {
                new AzureNative.ServiceFabric.Inputs.NodeTypeDescriptionArgs
                {
                    ApplicationPorts = new AzureNative.ServiceFabric.Inputs.EndpointRangeDescriptionArgs
                    {
                        EndPort = 30000,
                        StartPort = 20000,
                    },
                    ClientConnectionEndpointPort = 19000,
                    DurabilityLevel = "Bronze",
                    EphemeralPorts = new AzureNative.ServiceFabric.Inputs.EndpointRangeDescriptionArgs
                    {
                        EndPort = 64000,
                        StartPort = 49000,
                    },
                    HttpGatewayEndpointPort = 19007,
                    IsPrimary = true,
                    Name = "nt1vm",
                    VmInstanceCount = 3,
                },
            },
            ReverseProxyCertificateCommonNames = new AzureNative.ServiceFabric.Inputs.ServerCertificateCommonNamesArgs
            {
                CommonNames = 
                {
                    new AzureNative.ServiceFabric.Inputs.ServerCertificateCommonNameArgs
                    {
                        CertificateCommonName = "sfdemonav123.westeurope.cloudapp.azure.com",
                        CertificateIssuerThumbprint = galoresfcert.Thumbprint,
                    },
                },
                X509StoreName = "My",
            },
            ReliabilityLevel = "Bronze",
            ResourceGroupName = resourceGroup.Name,
            UpgradeMode = "Automatic",
        });
    }
}

Output

Updating (dev):
     Type                                   Name                      Status                  Info
     pulumi:pulumi:Stack                    servicefabriccluster-dev  **failed**              1 error
 ~   └─ azure-native:servicefabric:Cluster  cluster                   **updating failed**     [diff: +reverseProxyCertificateCommonNames]; 1 error

Diagnostics:
  azure-native:servicefabric:Cluster (cluster):
    error: Code="UnsupportedIssuerThumbprintPair" Message="Issuer thumbprint is not supported for this particular certificate type yet." Details=[]

  pulumi:pulumi:Stack (servicefabriccluster-dev):
    error: update failed

Resources:
    5 unchanged

Duration: 14s

Debug error

    debug: Determining which Resource Providers require Registration
    debug: All required Resource Providers are registered
    debug: Registering resource start: t=azure:core/resourceGroup:ResourceGroup, name=core, custom=True, remote=False
    debug: Preparing resource: t=azure:core/resourceGroup:ResourceGroup, name=core, custom=True, remote=False
    debug: Registering resource monitor end: t=pulumi:pulumi:Stack, name=servicefabriccluster-dev, custom=False, remote=False
    debug: Invoking function: token=azure-native:authorization:getClientConfig asynchronously
    debug: Invoke RPC prepared: token=azure-native:authorization:getClientConfig
    debug: Prepared resource: t=azure:core/resourceGroup:ResourceGroup, name=core, custom=True, remote=False
    debug: Registering resource monitor start: t=azure:core/resourceGroup:ResourceGroup, name=core, custom=True, remote=False
    debug: Registering resource start: t=azure:storage/account:Account, name=storage, custom=True, remote=False
    debug: Preparing resource: t=azure:storage/account:Account, name=storage, custom=True, remote=False
    debug: Registering resource start: t=azure-native:keyvault:Vault, name=galoresfkv, custom=True, remote=False
    debug: Preparing resource: t=azure-native:keyvault:Vault, name=galoresfkv, custom=True, remote=False
    debug: Registering resource start: t=azure:keyvault/certificate:Certificate, name=galoresfcert, custom=True, remote=False
    debug: Preparing resource: t=azure:keyvault/certificate:Certificate, name=galoresfcert, custom=True, remote=False
    error: update failed

  azure:storage:Account (storage):
    debug: Fields to assign: ["isHnsEnabled","secondaryAccessKey","secondaryBlobHost","primaryBlobHost","primaryBlobConnectionString","resourceGroupName","identity","nfsv3Enabled","primaryLocation","secondaryTableHost","secondaryBlobConnectionString","primaryFileEndpoint","accessTier","staticWebsite","primaryBlobEndpoint","primaryQueueEndpoint","minTlsVersion","name","allowBlobPublicAccess","routing","secondaryTableEndpoint","id","secondaryBlobEndpoint","primaryQueueHost","blobProperties","urn","accountKind","largeFileShareEnabled","accountTier","primaryTableHost","secondaryQueueHost","primaryWebEndpoint","primaryFileHost","secondaryWebHost","primaryDfsEndpoint","secondaryDfsEndpoint","secondaryQueueEndpoint","secondaryConnectionString","networkRules","location","azureFilesAuthentication","secondaryWebEndpoint","queueProperties","primaryAccessKey","tags","primaryDfsHost","secondaryFileEndpoint","secondaryLocation","primaryTableEndpoint","secondaryFileHost","accountReplicationType","enableHttpsTrafficOnly","secondaryDfsHost","primaryWebHost","customDomain","primaryConnectionString"]

  azure-native:keyvault:Vault (galoresfkv):
    debug: Fields to assign: ["name","id","urn","type","properties","location","tags"]

  azure:keyvault:Certificate (galoresfcert):
    debug: Fields to assign: ["certificateDataBase64","certificateAttributes","secretId","name","id","urn","certificateData","certificate","thumbprint","tags","certificatePolicy","version","keyVaultId"]

  azure-native:servicefabric:Cluster (cluster):
    error: Code="UnsupportedIssuerThumbprintPair" Message="Issuer thumbprint is not supported for this particular certificate type yet." Details=[]

  azure:core:ResourceGroup (core):
    debug: Fields to assign: ["name","id","urn","location","tags"]

Resources:
    5 unchanged

Duration: 12s
mikhailshilkov commented 3 years ago

Hey @naveenkumarsp thanks for giving Pulumi a try.

This error is coming from Azure services, so to fix it one needs to understand what Azure is complaining about. Unfortunately, I'm no service fabric expert...

I presume you converted this code from an ARM template? Does that ARM template work for you? If so, could you share it?

naveenkumarsp commented 3 years ago

@mikhailshilkov thanks for responding

I have written in terraform where self signed certificate was used and it worked with out any issue.

I can try writing an ARM template and test it out and update you.

naveenkumarsp commented 3 years ago

Here is the example terraform equallent template if that helps

Service fabric terraform template