Does pulumi have the capability to modify a resour...
# general
m
Does pulumi have the capability to modify a resource twice within the same
pulumi up
call. For example can I create a resource, get some unique metadata from it, use that metadata for creating another resource that then provides me with what need to finish setting up the first resource? I am running into a problem where there a re 2 resources that are dependent on each other and the only way I can figure out to get this to work so far is to run pulumi up under one configuration and then re run it again with another configuration.
l
Not as a single resource, no. This is the nature of the declarative paradigm. Pulumi gets around this using a "trick" that, as far as I know, the Terraform developers designed. A separate Pulumi resource is provided, which modifies properties of the first. The classic example is the Route53 / ACM pairing, in which the ACM Certificate resource is updated by a CertificateValidation resource after the requisite Route53 details become available. Something similar is done for VPC peering.
m
yes!!
l
However this solution requires code in the provider class.
m
that is similar to my issue.
I am trying to create an azure container app with a managed certificate and the cert validation is ruining my day.
l
Is that not provided by the Azure (not azure-native) provider?
m
I dont believe it is. I will check. I know that azure-native has managedCertificates and containerApp.config.ingress has a customDomain property.
l
m
i'll check.
l
Remember that azure-native and azure are 100% compatible. They're calling different APIs, but referring to the same resources with the same identifiers.
m
Except I think that is only for app services and not container environments.
l
There might be a similar solution in that package. I don't know the Azure SDK, sorry.
m
My main issue is that the containerApp has to be created to create the fqdn so that I can update the DNS for the cert validation that happens when you create the containerApp. So the containerApp has to be created without the certs and then the certs need to be added.
My question come to how can I add them without doing multiple pulumi up calls.
l
I don't know. I didn't know that the domain name had to be created after the containerApp. They can be created in any order in the ACM case.
m
the fqdn is generated when you create the container.
l
You can't make up your own one? Ah well, if that's how it is, then that's how it is. You can create the certificate from the info in the appcontainer without a problem. How is it solved in Terraform-land? The solution will be the same.
m
I went looking for that and there are a bunch of github tickets for it but no clear resolution that I have seen. However I did just get to this which might be something.
Copy code
azure-native:app/v20241002preview:ManagedCertificate (mapCert):
    error: Status=400 Code="RequireCustomHostnameInEnvironment" Message="Creating managed certificate requires hostname '<http://map.example.com|map.example.com>' added as a custom hostname to a container app in environment 'marketing-env'"
I wonder if it is as simple as this
That gets me closer. This time it created the cert and the custom domains. All I had to do was go into the azure portal and click add binding.
l
I thought I saw binding in the API docs somewhere...
m
That is App services again. but it lead me to this.
Copy code
const azureCustomDomainResource = new azure.containerapp.CustomDomain("azureCustomDomainResource", {
    containerAppId: "string",
    certificateBindingType: "string",
    containerAppEnvironmentCertificateId: "string",
    name: "string",
});
I might be able to call this after managed certificate from azure-native.
l
Remember there is no "after" in Pulumi code. All your code runs before the first (changing) call to the API. It's just setting up the desired state. The Pulumi engine decides on "before" and "after", after all your code has been run.
(Except for
apply()
, of course)
m
that still messes with my head.
I am using apply to get the container app settings that I then pass to the certs and then back to the azure classic customDomain.
l
You're using the Azure SDK directly, to update a managed resource?
m
not exactly. I just want it to kick of creating it. and then let it do it's thing.
l
So you're creating the resource object in an
apply()
?
m
No I create the resource and then later use apply to get the containerapps fqdn. I then make the dns resources depend on the containerApp and pass it the fqdn.
l
Ah. Why do you need an apply? Is the fqdn not available as an output directly?
m
When I didnt use the apply the depends on didn't work.
l
An output and an apply should be equivalent. The dependsOn wouldn't be enough by itself.
m
now I am just hacking through these errors to try to get the azure classic to accept azure-native resources.
Copy code
Diagnostics:
  azure:containerapp:CustomDomain (mapCustomDomain):
    error: azure:containerapp/customDomain:CustomDomain resource 'mapCustomDomain' has a problem: parsing "/subscriptions/[secret]/resourceGroups/marketingResGrp/providers/Microsoft.App/managedEnvironments/marketing-env/managedCertificates/map": parsing segment "staticCertificates": parsing the Certificate ID: the segment at position 8 didn't match

    Expected a Certificate ID that matched:

    > /subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/example-resource-group/providers/Microsoft.App/managedEnvironments/managedEnvironmentName/certificates/certificateName

    However this value was provided:

    > /subscriptions/[secret]/resourceGroups/marketingResGrp/providers/Microsoft.App/managedEnvironments/marketing-env/managedCertificates/map

    The parsed Resource ID was missing a value for the segment at position 8
    (which should be the literal value "certificates").

    . Examine values at 'mapCustomDomain.containerAppEnvironmentCertificateId'.
What is really annoying is that it is working as it I expect it to that point the resources in the errors are getting created.
l
Looks like you're using the wrong kind of certificate? You've got a "managedCertificate" and it wants "certificate"?
m
yeah. It appears that I can omit assigning a certificate and it will just create one. which would simplify this and make most of my day a wash. haha.
l
🤦
m
Turns out that doesn't actually work either. After working through a bunch of those errors I found that the Azure package containerApp and the azure-native app are not compatible. First the resource paths use different casings so I have had to modify the ids as they are passed, but more importantly the azure package does not properly depend on the state of the app in the azure-native package or other resources. I did however figure out a pattern to get them to work in a single
pulumi up
. 1. create the managed env, networking, etc as normal 2. create the containerApp with custom domains that have the
name
set and the
bindingType
set to
disabled
(no other properties in the customDomains should be set). it should have a dependency on the environment 3. Create the DNS records dependent on both the environment and the containerApp 4. create the managedCertificates needed with a dependency on the containerapp 5. At this point you have all the resources configured however the certificate is not bound to the container app and there is not a way to do this through the api. All of the outstanding terraform issues on github show this as unresolved. So the binding needs to be done through the cli using
command.local.command
with
az containerapp hostname bind
This needs to
trigger
on the
cert.systemData.LastModifiedAt
and depend on the containerApp, the Environment, and the Cert. If there are more than one cert being added then youe commands must be dependent on eachother so they fire in series and not in parallel.