Search code examples
c#azurepulumi

Validate that resource exists before retrieving keys


I create a resource group, and a database account:

// Create resourceGroup:
var rg= new ResourceGroup("myRG",
            new ResourceGroupArgs
            {
                Name = "myRG",
                Location = "westeurope"
            });
// Create DBAccount:
var account = new DatabaseAccount(accountName, new Pulumi.AzureNextGen.DocumentDB.Latest.DatabaseAccountArgs
            {
                AccountName = "myAcc",
                DatabaseAccountOfferType = DatabaseAccountOfferType.Standard,
                Location = "WestEurope",
                ResourceGroupName = rg.GetResourceName()
            });

After I did this I want to retrieve the primary key:

var keys = ListDatabaseAccountKeys.InvokeAsync(new ListDatabaseAccountKeysArgs
{
  AccountName = account.GetResourceName(),
  ResourceGroupName = rg.GetResourceName()
});
var cosmosWriteKey = Output.Create(keys).Apply(q => q.PrimaryMasterKey);

On the first start on a blank subscription without any resourcegroup with "pulumi up" I receive an error

Service returned an error. Status=404 Code="ResourceGroupNotFound" Message="Resource group 'myRG' could not be found.

I currently solved this by setting an environment variable disabling the "Key"-Part on the first run and run the code again after the ResourceGroup is created. But maybe there is a more smart way to assure the resourcegroup is created before retrieving the keys?


Solution

  • You should link the account to the resource group by using rg.Name in its constructor and put your ListDatabaseAccountKeys invocation inside an Apply:

    var account = new DatabaseAccount(accountName, new DatabaseAccountArgs
    {
        AccountName = "myAcc",
        DatabaseAccountOfferType = DatabaseAccountOfferType.Standard,
        Location = "WestEurope",
        ResourceGroupName = rg.Name
    });
    
    var cosmosWriteKey = account.Name.Apply(async name =>
    {
        var keys = await ListDatabaseAccountKeys.InvokeAsync(new ListDatabaseAccountKeysArgs
        {
            AccountName = name,
            ResourceGroupName = "myRG"
        });
        return keys.PrimaryMasterKey;
    });
    

    This way, the invocation will only happen after the account is created and the Name output is resolved.

    If you migrate to Azure-Native, you can use auto-naming:

    var rg = new ResourceGroup("myRG");
    
    var account = new DatabaseAccount(accountName, new DatabaseAccountArgs
    {
        DatabaseAccountOfferType = DatabaseAccountOfferType.Standard,
        ResourceGroupName = rg.Name
    });
    
    var cosmosWriteKey = Output.Tuple(rg.Name, account.Name).Apply(async values =>
    {
        var keys = await ListDatabaseAccountKeys.InvokeAsync(new ListDatabaseAccountKeysArgs
        {
            ResourceGroupName = values[0],
            AccountName = values[1]
        });
        return keys.PrimaryMasterKey;
    });