Hi there, every time when i destroy my stack I get...
# azure
c
Hi there, every time when i destroy my stack I get the following error:
Copy code
Service returned an error. Status=<nil> Code="Conflict" Message="Cannot delete custom domain \"XXX" because it is still directly or indirectly (using \"cdnverify\" prefix) CNAMEd to CDN endpoint \"XXX\". Please remove the DNS CNAME record and try again.
It has something to do with my customdomain … within my endpoint of the “Front Door and CDN profiles” …. Every time when i manually delete this customdomain CNAME and wait for at least 10 minutes it’s then possible to destroy .. Does anyone have a fix for this ? or workaround ?
I tries allot with depends on … but without success
Here’s the code
Copy code
import * as storage from "@pulumi/azure-native/storage";
import * as pulumi from "@pulumi/pulumi";
import * as cdn from "@pulumi/azure-native/cdn";
import * as network from "@pulumi/azure-native/network";
import * as resources from "@pulumi/azure-native/resources";
import {cdnProfile} from './food-cdn';
import {dnsZone} from './food-dns-zone';
import { resourceGroup, managedIdentity } from './food-resource-group'

const domain = 'food';
const stack = pulumi.getStack();
const subscriptionId = 'XXX';
const resourceName = 'frontend';

const getId = (id: string) => {
    const dict: { [key: string]: object } = {};
    dict[id] = {};
    return dict;
}

export const storageAccount = new storage.StorageAccount(`${stack}-sa-${resourceName}-${domain}`, {
    enableHttpsTrafficOnly: true,
    accountName: `${stack}${resourceName}${domain}`,
    resourceGroupName: resourceGroup.name,
    identity: {
        type: resources.ManagedServiceIdentityType.UserAssigned,
        userAssignedIdentities: managedIdentity.id.apply(id => getId(id))
    },
    kind: storage.Kind.StorageV2,
    sku: {
        name: storage.SkuName.Standard_LRS
    },
    tags: {
        environment: stack,
        domain
    }
}, {
    dependsOn: [resourceGroup, managedIdentity]
});

// enable static website support
export const staticWebsite = new storage.StorageAccountStaticWebsite(`${resourceName}${domain}${stack}`, {
    accountName: storageAccount.name,
    resourceGroupName: resourceGroup.name,
    indexDocument: "index.html",
    error404Document: "index.html",
}, {
    dependsOn: [storageAccount]
});

export const staticEndpoint = storageAccount.primaryEndpoints.web;

export const endpointOrigin = storageAccount.primaryEndpoints.apply(ep => ep.web.replace("https://", "").replace("/", ""));

export const endpoint = new cdn.Endpoint(`${stack}-cdn-${resourceName}-${domain}`, {
    endpointName: storageAccount.name.apply(sa => `${stack}-cdn-frontend-${domain}`),
    isHttpAllowed: false,
    isHttpsAllowed: true,
    originHostHeader: endpointOrigin,
    origins: [{
        hostName: endpointOrigin,
        httpsPort: 443,
        name: storageAccount.name,
    }],
    profileName: cdnProfile.name,
    queryStringCachingBehavior: cdn.QueryStringCachingBehavior.NotSet,
    resourceGroupName: resourceGroup.name,
    tags: {
        environment: stack,
        domain
    }
}, {
    dependsOn: [staticWebsite, cdnProfile]
});


const cNameRecord = new network.RecordSet(`${stack}-cname-${resourceName}-${domain}`, {
    cnameRecord: {
        cname: endpoint.hostName,
    },
    recordType: "CNAME",
    relativeRecordSetName: `${resourceName}-${domain}`, // frontend-test
    resourceGroupName: resourceGroup.name,
    ttl: 3600,
    zoneName: dnsZone.name,
}, {
    dependsOn: [dnsZone]
});

const customDomainFriendlyName = `${resourceName}-${domain}-${stack}-XXX-com`; 

// create custom domain
const customDomain = new cdn.CustomDomain(`${stack}-custom-domain-${domain}`, {
    customDomainName: customDomainFriendlyName,
    endpointName: endpoint.name,
    hostName: `${resourceName}-${domain}.${stack}.<http://XXX.com|XXX.com>`, 
    profileName: cdnProfile.name,
    resourceGroupName: resourceGroup.name,
}, {
    dependsOn: [],
});


// enable ssl certificate not working
export const azureCliScript = new resources.AzureCliScript(`${stack}-cli-enable-ssl-${resourceName}-${domain}`, {
    resourceGroupName: resourceGroup.name,
    identity: {
        type: resources.ManagedServiceIdentityType.UserAssigned,
        userAssignedIdentities: managedIdentity.id.apply(id => getId(id))
    },
    azCliVersion: "2.42.0",
    kind: "AzureCLI",
    retentionInterval: "P1D",
    scriptContent: pulumi.interpolate `az cdn custom-domain enable-https --resource-group="${resourceGroup.name}" --profile-name="${cdnProfile.name}" --endpoint-name="${endpoint.name}" --name="${customDomainFriendlyName}"`,
    tags: {
        environment: stack,
        domain
    }
}, {
    dependsOn: [storageAccount, customDomain]
});
i
i do AFD + CDN … basically for endpoint I want to expose, I create on the AFD Profile (in order): • Endpoint • Origin Group • Origin • Custom Domain • CNAME • TXT • Route
sounds like there is some sort of dependency on one of your DNS records?
c
Hi Patrick, thank you for replying! Could you please show me your example ? I got the feeling your using a different version of AFD ?
i
I’m using azure front door CDN profile object… it’s a LOT of code
c
Ok I’m not using front door object I think I’m using the classic version I will try that out than .. although it’s much more expensive and a bit overkill when I only want to expose a static website with CDN capabilities
i
I specifically use
AzureNative.Cdn.Profile
with the SKU
Standard_AzureFrontDoor
The new Static Web Apps’s CDN uses this under the hood
c
Can you show me the peace of code you use to perform the validation of the custom domain with the CNAME, TXT and Route ?
Because I have no idea where to get the generated TXT value from …
Fuck I was using to CustomDomain and not the AFDCustomDomain … which has a output property “validationProperties” containing the “validationToken” …. 🙂
i
Copy code
AzureNative.Cdn.AFDEndpoint
AzureNative.Cdn.AFDOriginGroup
AzureNative.Cdn.AFDOrigin
AzureNative.Cdn.AFDCustomDomain
AzureNative.Cdn.Route
AzureNative.Network.RecordSet
AzureNative.Cdn.AFDCustomDomain (domain) -> domain.ValidationProperties.Apply(v=>v.ValidationToken)
assign that last one to the TXT recordset
c
Thanks I already fixed it ! Really loving this pulumi 😄
i
i came from Terraform and I’d never go back lol
c
I fully understand hehe
Hey Patrick, quick question … how would you sole this problem if I have multiple CustomDomains … which I need to verify for SSL ?
with the same route .., because both domains need to be verified with each there own TXT record …
i
you can do multiple domains on the same route … you would create the `AFDCustomDomain`s, add the CNAME + TXT records, and then add them to the
CustomDomains
array when you create
AzureNative.Cdn.Route