https://pulumi.com logo
Title
c

cold-motherboard-88215

12/07/2022, 9:33 PM
Hi there, every time when i destroy my stack I get the following error:
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
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

icy-doctor-13719

12/07/2022, 10:04 PM
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

cold-motherboard-88215

12/08/2022, 3:35 AM
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

icy-doctor-13719

12/08/2022, 3:50 AM
I’m using azure front door CDN profile object… it’s a LOT of code
c

cold-motherboard-88215

12/08/2022, 3:59 AM
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

icy-doctor-13719

12/08/2022, 5:41 AM
I specifically use
AzureNative.Cdn.Profile
with the SKU
Standard_AzureFrontDoor
The new Static Web Apps’s CDN uses this under the hood
c

cold-motherboard-88215

12/08/2022, 11:27 AM
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

icy-doctor-13719

12/08/2022, 4:57 PM
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

cold-motherboard-88215

12/08/2022, 4:59 PM
Thanks I already fixed it ! Really loving this pulumi 😄
i

icy-doctor-13719

12/08/2022, 5:00 PM
i came from Terraform and I’d never go back lol
c

cold-motherboard-88215

12/08/2022, 5:00 PM
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

icy-doctor-13719

12/09/2022, 3:04 PM
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