https://pulumi.com logo
Title
m

mysterious-australia-14256

06/25/2021, 2:20 PM
Is it possible to deserialize from a config file into a model that had a property of type Pulumi.Input<string>? I have a yaml file with a config I am trying to deserialize it into a custom object model that has a parameter of type Pulumi.Input<string>. The code I have is along the lines of
Pulumi.Config config = new Pulumi.Config();
var mySettings = config.RequireObject<MyModel>("Key");
MyModel contains several properties and I've recently tried to add a new one with a type of Pulumi.Input<string>?. Since adding that if I try to run the code I get an error saying The JSON value could not be converted to Pulumi.Input`1[System.String] Is this possible at all?
b

bored-oyster-3147

06/25/2021, 2:25 PM
does your object property need to be
Input<string>?
? I would just make it
string?
. That can be passed to
Input<string>
without much issue
b

brave-planet-10645

06/25/2021, 2:33 PM
I mean there's nothing to stop you reading in the file, but you will lose all the automatic encryption/decryption. You can deserialise it into a
JsonElement
if you use Structured Config (see example at the bottom), so that should get you started
m

mysterious-australia-14256

06/25/2021, 2:54 PM
Thanks both. My scenario is with trying to specify the Integration Account associated with an Azure Logic App. I have 2 scenarios, one where I specify the ID of an existing Integration Account in the config file and read it in as a string. The second scenario is where the Integration Account is created within the pulumi code and then the Id of this account (which will be type Pulumi.Input<string>) is used. I was hoping to use the single property called "IntegrationAccountId" in my POCO to be able to handle both options. To do that I need to either 1. have the property as "string" (which makes the deserialize process simple) but then somehow extract the actual string value of the ID from a pulumi IntegrationAccount object to support the other scenario, or 2. have the property as Pulumi.Input<string>, which makes it easy to store the Id from a pulumi IntegrationAccount object, but makes the deserialization scenario trickier At the moment I am avoiding the issue and having separate properties (one for the object and one for the ID) but it would be nice to simplify the model if possible
b

bored-oyster-3147

06/25/2021, 3:01 PM
In both scenarios I still think it is easiest to just use
string
in your config.
string
can be implicitly cast to
Input<string>
so that is a non-issue
In the second scenario where the integration account is created in code, you would want to make sure that that declaration occurs on every run so you wouldn't want to preserve the new ID in your config such that that declaration doesnt occur on the next run (because of your existing integration account condition) otherwise the integration account would be deleted on your next run because your pulumi code no longer matches the state
so it should just be 1 id in config, an existing ID. In your pulumi program, if that ID is present, it uses the existing account. If it isn't, it creates a new account. Don't save the newly created ID in config, otherwise your pulumi program behaves differently on the next run
m

mysterious-australia-14256

06/25/2021, 3:56 PM
Thanks Joshua, I think the scenario is possibly a bit more complicated as I am using wrappers around the pulumi code which complicates things a bit in this scenario. If I can't deserialize in to Pulumi.Input<string> I think it might be just easier to keep the 2 properties in my model. Just for your interest, witht he current way I am using Pulumi, when I call one of these wrappers I just pass in the deserialized config object (which contains all of the settings) and then that runs the pulumi specific code. It means that my main stack is very simple, it just has code like this for each object I need to create (e.g. a service bus in this example code)
// create the service bus namespace
var serviceBusSettings = config.RequireObject<ServiceBusNamespaceModel>("ServiceBus");
var serviceBusNamespace = PulumiAzureWrappers.ServiceBusNamespace.Create(
   namespaceSettings: serviceBusSettings, 
   dependsOn: new List<Resource> { resourceGroup }
);
So I have a line that reads all of the setting from a config file into a model (e.g. ServiceBusNamespaceModel) and then I pass that off to a method in a wrapper class to actually run the Pulumi code to create it. The method then returns the relevant Pulumi object (e.g. a Pulumi.AzureNative.ServiceBus.Namespace). The downside is that if I create a resource (such as an IntegrationAccount) the another resource depends on then the Model I pass with all of the settings has to support it. For my Logic App model I have a string property called IntegrationAccountId that I was hoping I could use to pass the string value of the ID from the created Integration Account in but when I tried this it was passing Pulumi.Output`1[System.String] rather than the actual ID. Changing the property from string to Pulumi.Input<string> fixed that issue but broke the deserialization into that property when I was using an ID in a config file rather than using an object. Thanks for your time with this anyway but I think with sticking with 2 properties (one for a string ID and one for a resource) is probably easiest unless I can either deserialize to Pulumi.Input<string> somehow or access the string ID value of a created Pulumi Integration Account to get the actual value rather than the Pulumi.Output`1[System.String]