This message was deleted.
# typescript
s
This message was deleted.
f
Whenever you have
apply(x => x)
you’re likely heading down the wrong path because the apply isn’t really “doing anything.” I’m having a bit of trouble following the code you have above. Do you mind dropping a larger snippet with what you’re trying to do?
I’m not sure if this is helpful, but one way to think about
Output
is that once you go
Output
, you can never really go back. Like how for a
Promise
then(…)
just returns another
Promise
, an
apply
on an
Output
gives you back yet another
Output
. You can feed an
Output
to a resource because they typically accept
Input
(which is defined as
T | Promise<T> | Output<T>
), but you can’t really use an
Output<T>
as
T
c
As Lee said,
.apply(x=>x)
literally does nothing for your code. It sounds like you're trying to use an
Output<string>
in a field that only takes a
string
, like the
name
of a Pulumi resource. In that case, one option is
Copy code
const newResource = createdStuff.rg.name.apply(name => new SomeResource(name, {...}))
Although an annoyance is that
newResource
will be typed as
Output<SomeResource>
instead of just
SomeResource
If this property value isn't a dynamic value it might be best to put it as its own variable and use that in both places
f
Also not recommended to create resources within an
apply
c
though sometimes the only way is not a recommended way 🤷‍♂️
b
I'll paste a bit more of a snippet so you get the jist.. but strange that it's an antipattern when it's basically recommended based on the output:
Copy code
Type                            Name
     pulumi:pulumi:Stack             modularity-modular
     └─ azure-native:keyvault:Vault  Calling [toString] on an [Output<T>] is not supported.

To get the value of an Output<T> as an Output<string> consider either:
1: o.apply(v => `prefix${v}suffix`)
 : pulumi.interpolate `prefix$
Diagnostics:
  azure-native:keyvault:Vault (Calling [toString] on an [Output<T>] is not supported.

To get the value of an Output<T> as an Output<string> consider either:
1: o.apply(v => `prefix${v}suffix`)
2: pulumi.interpolate `prefix${v}suffix`

See <https://pulumi.io/help/outputs> for more details.
So - a slightly longer snippet to see what's going on - first the index.ts:
Copy code
import * as pulumi from "@pulumi/pulumi";
import * as azure from "@pulumi/azure-native";


import { createNetworks } from "./components/network";
import { createStorageAccounts } from "./components/storageAccount";
import { createKeyVault } from "./components/keyvault";

const config = new pulumi.Config("azure");
const ssp : any = config.requireObject("ssp")
const shouldCreate : any = config.requireObject("create")

export = async () => {
    for (group of ssp) {
        const rg = new azure.resources.ResourceGroup(`${group.logicalName}_${group.location}`, {
            location: group.location,
            resourceGroupName: `${group.logicalName}_${group.location}`,
            tags: group.tags
        })
        let rgStack = {
            ssp: group,
            parameters: {
                name:  rg.name.apply(name => name),
                location: rg.location.apply(location => location), 
                id: rg.id.apply(id => id),
                resource: rg
            },
            resources: {}
        }
    }

    if (shouldCreate.network) {
        rgStack = await createNetworks(rgStack);
    }

    if (shouldCreate.storageAccount) {
        rgStack = await createStorageAccounts(rgStack);
    }
    
    if (shouldCreate.keyVault) {
        rgStack = await createKeyVault(rgStack);
    }

}
and the content of `./components/keyvault.ts`:
Copy code
import * as pulumi from "@pulumi/pulumi";
import * as azure from "@pulumi/azure-native";

import * as _ from "lodash" 


const config = new pulumi.Config("azure");
let kvConfiguration : any = config.getObject("keyvault") == undefined ? {} : config.getObject("keyvault")

export const createKeyVault = async function(kvStack : any) : Promise<any> {
    /***
     * Setting up default values
     * 
     */

    const kvDefaults = {       
        sku: {
            family: "A",
            name: "standard"
        },
        tenantId: "-my-tenant-uid", 
        enableRbacAuthorization: true,
        enabledForDiskEncryption: true,
        enabledForDeployment: true,
        enabledForTemplateDeployment: true,
        softDeleteRetentionInDays: 90
    }

    // for some reason erroring out when trying to use RG name in vaultName
    //const vaultName = `${kvStack.parameters.name}vault`
    const vaultName = "staticstringworksfineofcourse"
    kvStack.keyVault = {
        config: {
            vaultName: vaultName,
            location: kvStack.parameters.location,
            resourceGroupName: kvStack.parameters.name,
            tags: kvStack.ssp.tags,
            properties: _.defaultsDeep(kvConfiguration, kvDefaults)
        }
    }
    const kv = new azure.keyvault.Vault(vaultName, kvStack.keyVault.config)
    kvStack.keyVault.resource = kv;
    kvStack.keyVault.parameters = {
        name: kv.name.apply(name => name),
        id: kv.id.apply(id => id),
    }
    
    return kvStack;
}
oh and yes, this is my first time using typescript rather than plain javascript for node type stuff, so pardon my liberal use of <any> types
I also realize that it's rather pointless for the pulumi aspect to be using async/await in the context of resource creation, that's mainly there for auxiliary calls that might be a bit more dependent on flow later on.
f
Right, this is as Mike mentioned earlier where the actual resource names need to be prompt values (and not outputs). Looking at the code above, it seems like this value will be known, so you’ll want to plumb it through and just have `name:
${group.logicalName}_${group.location}
in your parameters.