Hi everyone, I’m sure this must have come up numer...
# azure
p
Hi everyone, I’m sure this must have come up numerous times before, but I must not be coming up with the correct search keywords, so apologies if this has been asked and answered already: I’m struggling with a “bidirectional dependency” situation while setting up an Azure Web App with a custom hostname binding, using an App Service Managed Certificate, which is a relatively new type of certificate resource that MS provisions and manages for your web app, for any hostname you can prove ownership of (using a CNAME record). To begin with, managed certificates are not yet a supported resource type in the Azure provider, so I’m creating that using a
TemplateDeployment
resource, which works well. I’m even able to get the thumbprint out of it, so all good there. However: • To create a managed certificate, the corresponding
CustomHostnameBinding
resource must already exist • To activate TLS for the
CustomHostnameBinding
, we need to specify the certificate thumbprint • To get the certificate thumbprint, we need to create the managed certificate • => circular dependency… How do we typically work around these things? Is there any way that I can create the
CustomHostnameBinding
resource, and then later in the same Pulumi program, update it with the properties for certificate thumbprint?
Here’s some code, to illustrate the issue further:
t
There’s no way to update the properties of a resource later in the program. This doesn’t quite make sense because resources are created at a later stage than the program execution, not line-by-line so to speak. Usually, circular dependencies are a sign of sub-optimal resource model. In your case, ideally, there would be a certificate resource to gen the thumbprint, a custom hostname binding resource, and a managed certificate resource. Aren’t you able to do so? I.e., can you set the thumbprint for the
TemplateDeployment
instead of getting it back as an output?
p
@tall-librarian-49374 no, because the managed certificate is newly created by MS at the time of deployment. The thumbprint is not known until after it’s been deployed.
Even in the portal, it’s necessary to do this in 2 separate operations, presumably for the same reason.
I get what you’re saying, it’s just a declarative program. What’s the workaround? Two pulimi programs and two separate stacks?
Where the second one just updates the resource?
t
Yeah, this sucks. Do you know if it’s possible to achieve with pure ARM templates? For Pulumi, I’m thinking maybe a dynamic provider that updates the binding.
p
It’s possible with ARM, but you have to use a nested template (which is pretty cumbersome).
A dynamic provider you say? Sounds intriguing! What is it?
t
How do nested templates work around the chicken-and-egg problem? Do they update the same resource twice?
p
I’m not sure, let me find the blog post I saw..
It’s very short, I think it’s basically just a memory note from a guy working on App Service.
t
Yeah, it has two hostname bindings: one in the main without the cert, one in the linked with thumbprint
They then rely on them implicitly merging
p
Yep
t
I wonder if the same would work in Pulumi? Or will it detect the existing binding and fail?
p
Hm… that’s interesting. You mean, Pulumi might detect the duplicate, before it even gets to Azure?
So basically, create two resources with the same Azure name, where one depends on the other?
t
Yes. But the second one depends on the managed certificate.
p
Yes
I can certainly try
t
Are you on 1.x or 2.x of Azure provider?
p
2.1.0
t
2.x become more strict with checking existing resources (there will be a blog post mentioning this, probably later today).
p
bah, ok
Otherwise, looks like this would be a good use case for a dynamic provider, indeed. Is there a public repository of these somewhere? And, do they need to be written in the same runtime as the main program (.NET in our case)?
t
Ah, you are on .NET, I didn’t ask. Dynamic providers aren’t supported there yet 😞
And yes, they have to be in the language of the stack.
p
🤯
@tall-librarian-49374 It didn’t work.
Copy code
error: A resource with the ID "/subscriptions/1788357e-d506-4118-9f88-092c1dcddc16/resourceGroups/orgflow-licensing-dev-rg/providers/Microsoft.Web/sites/orgflow-licensing-dev-app/hostNameBindings/dev.licensing.orgflow.app" already exists - to be managed via Terraform this resource needs to be imported into the State. Please see the resource documentation for "azurerm_app_service_custom_hostname_binding" for more information.
Given that dynamic providers are not supported for .NET, I don’t know what else to try.
t
Okay, so it worked as it should but then you don’t have a hack for your scenario
@white-balloon-205 @gentle-diamond-70147 We have a case of a circular dependency here. Any experience of working around those in the past? (should work in .NET)
p
@tall-librarian-49374 I think I figured out a way. First, create hostname binding (without cert) Second, create template deployment (depends on hostname) which contains: • The certificate • The hostname binding again, but this time in template (depends on certificate, in ARM terms)
t
Makes sense
m
@powerful-football-81694 I need to add a custom domain on my AppService as well with a Managed Certificate. Whould it be possible for you to share some code on how you succeed to do that ?
p
@millions-journalist-34868 Yeah sure. It’s C# code, will that work for you?
m
Yes I am using C# as well
@powerful-football-81694 if you can send the link to a github repo or just copy paste a C# sample here it would be great !
p
OK, let’s see
@millions-journalist-34868 here’s the relevant (redacted) parts of the Pulumi program itself.
And here’s the implementation of the ManagedCertificate resource.
It loads the ARM template in from an embedded resource file:
Hope that helps!
m
That is great, thanks for sharing.